You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Security] Access denied copy — the remaining 38 templates, classified: admin-surface should be RETAINED as developer copy, four end-user sites need their own decision #7475
Successor to #7451, which is closed by PR #7471. Filed unassigned, no domain:* label — routing and grading are the triage seat's call.
#7451 was a ~40-template sweep card. PR #7471 implemented the end-user-facing half under a scope limit set at claim time, and produced an audience classification of every producer template with evidence. This card carries the remainder, so the classification does not die inside a merged PR.
The remainder is not one backlog. It splits into a decision and a short list of open questions, and conflating them is what made #7451 hard to price.
Part 1 — the admin-surface family: recommend RETAIN, do not translate (~30 templates)
These are reached from an admin console by someone administering the system, and most cite ADR clauses (ADR-0090 D5/D9 and D6/D12, ADR-0091 D3, ADR-0103). Localizing copy that cites an ADR clause destroys the citation without helping anyone: the reader is an operator who benefits from the clause number.
This is a decision to record, not work to schedule. The useful outcome is a written verdict — "this family is correctly developer-facing" — so the next census does not re-file it as a translation backlog. If triage agrees, closing this part as not planned with that sentence in the thread is a better artifact than a card that stays open forever.
Part 2 — four end-user-reachable sites that are NOT cleanly one situation
Each was measured as end-user reachable but declined conversion for a stated reason. None is a copy fix; each needs a decision first.
Already filed as #7474. One deny() multiplexes six conditions, three of which are not access verdicts (a metadata defect, a not-found, a null master FK). User copy would tell a user they lack access when their app is misconfigured.
security-plugin.ts:1657 owner_id transfer grant
Plausible end-user situation (record reassignment) but zero measured pull — allowTransfer appears in neither example app. Converting on speculation is the capability-expansion this repo defers.
security-plugin.ts:1069 / :1140 fail-closed
End-user visible during degradation, but the situation is "the check could not run", not "you lack permission". Copy saying the latter would be false. Needs its own message key and arguably its own status.
Reached via a misbuilt or forged client, a configured agent integration, or a team-administration action — not an ordinary business operation.
What PR #7471 leaves for whoever takes any of this
The mechanism is settled and has three consumers: @objectstack/spec/system's renderOperationMessage / BUILTIN_OPERATION_MESSAGES, errors.<key> override address, four-rung ladder.
Successor to #7451, which is closed by PR #7471. Filed unassigned, no
domain:*label — routing and grading are the triage seat's call.#7451 was a ~40-template sweep card. PR #7471 implemented the end-user-facing half under a scope limit set at claim time, and produced an audience classification of every producer template with evidence. This card carries the remainder, so the classification does not die inside a merged PR.
The remainder is not one backlog. It splits into a decision and a short list of open questions, and conflating them is what made #7451 hard to price.
Part 1 — the admin-surface family: recommend RETAIN, do not translate (~30 templates)
delegated-admin-gate.ts(13),suggested-audience-bindings.ts(3),permission-set-projection.ts(1),system-write-guard.ts(1),plugin-auth/invitation-role-cap.ts(3), andsecurity-plugin.ts's admin-door family (:2457,:3314,:3339,:3376,:3389,:3456,:3482,:3500).These are reached from an admin console by someone administering the system, and most cite ADR clauses (ADR-0090 D5/D9 and D6/D12, ADR-0091 D3, ADR-0103). Localizing copy that cites an ADR clause destroys the citation without helping anyone: the reader is an operator who benefits from the clause number.
This is a decision to record, not work to schedule. The useful outcome is a written verdict — "this family is correctly developer-facing" — so the next census does not re-file it as a translation backlog. If triage agrees, closing this part as
not plannedwith that sentence in the thread is a better artifact than a card that stays open forever.Part 2 — four end-user-reachable sites that are NOT cleanly one situation
Each was measured as end-user reachable but declined conversion for a stated reason. None is a copy fix; each needs a decision first.
security-plugin.ts:3981assertControlledByParentWritedeny()multiplexes six conditions, three of which are not access verdicts (a metadata defect, a not-found, a null master FK). User copy would tell a user they lack access when their app is misconfigured.security-plugin.ts:1657owner_id transfer grantallowTransferappears in neither example app. Converting on speculation is the capability-expansion this repo defers.security-plugin.ts:1069/:1140fail-closed:953public-form grant ·:1891tenant wall ·:1094/:1265on-behalf-of ·predicate-guard.ts:122What PR #7471 leaves for whoever takes any of this
@objectstack/spec/system'srenderOperationMessage/BUILTIN_OPERATION_MESSAGES,errors.<key>override address, four-rung ladder.[Security] Access deniedgates stop showing developer copy (#7451) #7471 gave three gates two new keys and reused a third).developerMessageis a sibling ofdetails, never a member, becausedetailsis what the runtime dispatcher serialises.details.positionsdisclosure is The runtime dispatcher serialises a PermissionDeniedError'sdetailsto the client, sopositions/permissionSetsreach the browser on the/datatransport #7450 (needs-user-decision, cli lane), not part of this.[Security] Access deniedgates stop showing developer copy (#7451) #7471's repo-wide grep found three pins, and two more were found only by running the suites — one pinned a fragment, one pinned a regex (toThrow(/denied|permission/i)) that matched only because the English sentence happened to start with "Access denied". Grep is necessary and not sufficient here.Refs: #7451 (predecessor), PR #7471, #7414 / PR #7449, #7307 / PR #7423, #7450, #7474.