Skip to content

Commit 359e497

Browse files
os-steveclaude
andauthored
docs: retarget the general-rule ADR-0057 D10 citations to ADR-0124 D1 (#11780)
ADR-0124 recorded the general enforcement rule ("the server is the enforcement point; client-side gating is a usability courtesy") that ~30 sites had been citing as `ADR-0057 D10` — a number that actually decides Setup-nav capability surfacing. This moves the general-rule citations and leaves the capability-gate citations where they are. Classified per citation, not rewritten mechanically: 31 of 98 occurrences moved; 33 live citing sites that cite D10 for its own subject stay; 34 occurrences in shipped CHANGELOGs and in the two ADRs are records and are not rewritten. Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 1cba33f commit 359e497

19 files changed

Lines changed: 49 additions & 53 deletions

.claude/skills/dogfood-verification/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ dev 工作树、dev-server 端口、preview 浏览器全是**共享的**:并行
112112
- [ ] 确认页面渲染完成*之后*(先截图,再查 selector),DOM dump 没问题。
113113
- [ ] **门的两侧都要测**:`requiresService`/`requiresObject`/权限门要在依赖存在**
114114
缺席两种状态下各验一次。
115-
- [ ] 服务端是权威可见性门(ADR-0057 D10)—— 客户端过滤只是「礼貌」。元数据开关不改
115+
- [ ] 服务端是权威可见性门(ADR-0124 D1)—— 客户端过滤只是「礼貌」。元数据开关不改
116116
UI 时,先查强制在服务端(框架,可在本仓修)还是客户端(objectui console,另一
117117
个仓)。
118118
- [ ]`preview_screenshot`(API 改动用 `preview_network`)向用户证明;loading

docs/audits/2026-07-studio-package-create-ux-dogfood.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ object with fields, enter a record, create an app with navigation, publish, and
66
use the result as an end user — driving a real Chromium against `/_console`
77
(vendored console build `7782698`, matching the `.objectui-sha` pin, so findings
88
are not stale-bundle artifacts). Both sides of the read-only gate were exercised
9-
per ADR-0057 D10.
9+
per ADR-0124 D5.
1010

1111
Run: `objectstack dev --ui --seed-admin` on the showcase example, fresh SQLite DB,
1212
`admin@objectos.ai` seeded admin, headless Chromium via CDP with screenshots at

docs/qa/platform-checklist/RUNNER.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ test-run output the clause's `evidence` field names.
7575
4. **Both sides of every gate.** For any permission/visibility/feature gate, verify
7676
presence for the entitled persona AND absence (or server-side rejection) for the
7777
unentitled one. UI absence alone is a client courtesy; the server is the authority.
78-
(That rule is cited across the framework as `ADR-0057 D10`; treat it as an
79-
attribution — D10 itself decides Setup-nav capability surfacing, and recording the
80-
general rule is tracked in #9628. The rule is not in doubt, only its anchor.)
78+
(That rule is `ADR-0124 D1`, and this rule is its verification half — `ADR-0124 D5`
79+
states it directly: a test that asserts only that the interface hides something has
80+
tested the courtesy layer and left the enforcement point unobserved.)
8181
Where feasible, prove denial with a direct forged request.
8282
5. **Severe findings are hypotheses.** "The whole surface is unreachable" gets
8383
disproven-or-confirmed via screenshot + the server's own metadata before it is

docs/qa/platform-checklist/areas/access-security.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"evidence": "PATCH response + admin re-read"
5252
},
5353
{
54-
"clause": "admin (platform posture) reads the full set — the entitled side of the same gate (both sides, RUNNER rule 4 / ADR-0057 D10)",
54+
"clause": "admin (platform posture) reads the full set — the entitled side of the same gate (both sides, RUNNER rule 4 / ADR-0124 D5)",
5555
"oracle": "api",
5656
"verify": "admin GET list contains every id created in this run",
5757
"evidence": "admin listing"
@@ -83,7 +83,7 @@
8383
},
8484
"source": [
8585
"packages/verify/src/rls.ts",
86-
"ADR-0057 D10",
86+
"ADR-0124 D1",
8787
"packages/qa/dogfood/test/showcase-private-owd.dogfood.test.ts",
8888
"authz-conformance.matrix.ts rows rls-read / rls-by-id-write",
8989
"#7637 (run record) — the by-id spot-check on a skipped object is where the private D11 defect surfaced",
@@ -335,7 +335,7 @@
335335
"evidence": "screenshot + disabled-state DOM read"
336336
},
337337
{
338-
"clause": "the SERVER refuses the same write: direct PUT /api/v1/meta/object/<name> on the read-only package answers 4xx with a ledgered metadata-protocol code (WRITABLE_PACKAGE_REQUIRED, or ITEM_LOCKED for _lock'd items) — UI absence never suffices (ADR-0057 D10)",
338+
"clause": "the SERVER refuses the same write: direct PUT /api/v1/meta/object/<name> on the read-only package answers 4xx with a ledgered metadata-protocol code (WRITABLE_PACKAGE_REQUIRED, or ITEM_LOCKED for _lock'd items) — UI absence never suffices (ADR-0124 D1)",
339339
"oracle": "api",
340340
"verify": "PUT response status >=400 and error.code ∈ {WRITABLE_PACKAGE_REQUIRED, ITEM_LOCKED} (packages/spec/src/api/error-code-ledger.zod.ts, @objectstack/metadata-protocol entry)",
341341
"evidence": "PUT trace"
@@ -421,7 +421,7 @@
421421
"evidence": "the verdict matrix + spot re-reads"
422422
},
423423
{
424-
"clause": "every withheld cell is DENIED SERVER-SIDE with the ledgered code: verbs marked false answer 403 with error.code PERMISSION_DENIED (rest-server maps explicit security denials to 403 PERMISSION_DENIED) — UI absence never counts (ADR-0057 D10)",
424+
"clause": "every withheld cell is DENIED SERVER-SIDE with the ledgered code: verbs marked false answer 403 with error.code PERMISSION_DENIED (rest-server maps explicit security denials to 403 PERMISSION_DENIED) — UI absence never counts (ADR-0124 D1)",
425425
"oracle": "api",
426426
"verify": "per-cell status 403 and body code PERMISSION_DENIED; capture any cell answering a different code for triage",
427427
"evidence": "the verdict matrix"
@@ -1293,7 +1293,7 @@
12931293
}
12941294
],
12951295
"negative": [
1296-
"a Studio panel that greys the save while a direct meta PUT widens is a FAIL — the server gate is the authority (ADR-0057 D10 both-sides)",
1296+
"a Studio panel that greys the save while a direct meta PUT widens is a FAIL — the server gate is the authority (ADR-0124 D1 both-sides)",
12971297
"a stock-deploy packaged-object widening PUT that answers 2xx (or leaves the object widened) is a FAIL",
12981298
"do NOT tick external-principal read/write enforcement: that evaluation is liveness `planned` (#2696) — this item is the save/authoring gate only"
12991299
],
@@ -1310,7 +1310,7 @@
13101310
"packages/lint/src/validate-security-posture.ts (OWD_WIDTH + SECURITY_EXTERNAL_WIDER lint parity)",
13111311
"objectui packages/app-shell/src/views/studio-design/owd-sharing.ts (isExternalWider) + PackageOwdOverviewPanel.tsx + ObjectSettingsPanel.tsx",
13121312
"examples/app-showcase/src/data/objects/announcement.object.ts + account.object.ts (externalSharingModel declarations)",
1313-
"ADR-0090 D11, ADR-0086 D1, ADR-0057 D10, #3050, objectui#2508"
1313+
"ADR-0090 D11, ADR-0086 D1, ADR-0124 D1, #3050, objectui#2508"
13141314
],
13151315
"history": [
13161316
{

docs/qa/platform-checklist/areas/approvals.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@
280280
"evidence": "request read"
281281
},
282282
{
283-
"clause": "the gate is server-side: a forged direct POST of the decision route as the submitter is rejected (ADR-0057 D10 — UI absence alone is a client courtesy)",
283+
"clause": "the gate is server-side: a forged direct POST of the decision route as the submitter is rejected (ADR-0124 D1 — UI absence alone is a client courtesy)",
284284
"oracle": "api",
285285
"verify": "the forged approve answers FORBIDDEN (403-mapped); test BOTH sides — the entitled approver's decision on the same request succeeds",
286286
"evidence": "the rejected call + the entitled approver's accepted call"
@@ -298,7 +298,7 @@
298298
"traps": ["hydration-race", "wrong-persona"],
299299
"source": [
300300
"#3358 §1",
301-
"ADR-0057 D10 (server is the authoritative visibility gate)",
301+
"ADR-0124 D1 (server is the authoritative visibility gate)",
302302
"examples/app-showcase/src/security/seed-approval-demo.ts (Mei Phone: 'a clean submitter — a requester who is never also one of her own approvers')"
303303
],
304304
"history": [

docs/qa/platform-checklist/areas/attachments-storage.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@
233233
}
234234
],
235235
"negative": [
236-
"a gated file downloadable anonymously (silent success) is a FAIL — UI absence of a download button is a client courtesy; the route is the authority (ADR-0057 D10)",
236+
"a gated file downloadable anonymously (silent success) is a FAIL — UI absence of a download button is a client courtesy; the route is the authority (ADR-0124 D1)",
237237
"a deny that surfaces in the panel as 'Download failed (403)' instead of the mapped copy means the error-envelope dialect broke (#3689 note in the panel) — file it against objectui, not storage"
238238
],
239239
"traps": ["wrong-persona", "dispatcher-vs-hono-route", "stale-console-bundle"],

docs/qa/platform-checklist/areas/identity-auth.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@
211211
"evidence": "the screenshot set"
212212
},
213213
{
214-
"clause": "a disabled method is refused SERVER-SIDE, not merely hidden — UI absence is a client courtesy; the server is the authority (ADR-0057 D10)",
214+
"clause": "a disabled method is refused SERVER-SIDE, not merely hidden — UI absence is a client courtesy; the server is the authority (ADR-0124 D1)",
215215
"oracle": "api",
216216
"verify": "firing each disabled method's endpoint returns a non-2xx (the plugin's routes are absent or refuse)",
217217
"evidence": "the forged-request responses"
@@ -347,7 +347,7 @@
347347
],
348348
"negative": [
349349
"an admin-role invitation that returns success, or that leaves ANY row behind, is a FAIL of privilege-escalation severity — file immediately, P0-verify per RUNNER rule 7",
350-
"UI-only enforcement (affordance hidden but the forged request succeeds) is a FAIL — the server is the authority (ADR-0057 D10)",
350+
"UI-only enforcement (affordance hidden but the forged request succeeds) is a FAIL — the server is the authority (ADR-0124 D1)",
351351
"my-delegable-scope OVER-reporting is a FAIL — a position, permission set or BU subtree the caller cannot actually delegate, or (were the shape ever to grow one) a role the caller cannot mint: a client that trusts the scope would offer what the endpoint then refuses. UNDER-reporting is NOT a FAIL and must not be filed as one: the endpoint answering an empty scope while the delegate can still mint a member invitation is the safe direction and the expected state on stock fixtures (run #7663 — DelegableScope has no invitation-role field at all)"
352352
],
353353
"automated": { "kind": "e2e", "ref": "packages/qa/dogfood/test/delegated-admin-invite.dogfood.test.ts" },
@@ -814,7 +814,7 @@
814814
}
815815
],
816816
"negative": [
817-
"an org management surface where the affordance is hidden but the forged endpoint succeeds for a non-admin is a FAIL — the server is the authority (ADR-0057 D10)",
817+
"an org management surface where the affordance is hidden but the forged endpoint succeeds for a non-admin is a FAIL — the server is the authority (ADR-0124 D1)",
818818
"remove-member that drops the roster row but leaves the ex-member's org-scoped access intact is a FAIL — removal must change authorization",
819819
"a role written outside the {owner, admin, delegated_admin, member} vocabulary is a FAIL — including a stored 'guest': the closed list is the write-side guardrail that makes an ungoverned capability grant unrepresentable (ADR-0108), so a 2xx that persists 'guest' is a regression of the closure, not a vocabulary difference. A role change that does not flip any gate is equally a FAIL",
820820
"the Organization nav landing on the raw sys_organization list because {current_org_id} did not resolve (when an active org exists) is a FAIL of the ADR-0081 wiring"

docs/qa/platform-checklist/areas/platform-core.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@
518518
"evidence": "three screenshots"
519519
},
520520
{
521-
"clause": "the app-level gate is server-side, not a client courtesy: a forged member GET /api/v1/meta/app?id=setup is denied/empty at the server, not merely hidden in the launcher (ADR-0057 D10 both-sides)",
521+
"clause": "the app-level gate is server-side, not a client courtesy: a forged member GET /api/v1/meta/app?id=setup is denied/empty at the server, not merely hidden in the launcher (ADR-0124 D1 both-sides)",
522522
"oracle": "api",
523523
"verify": "the forged request's status/body proves server-side denial",
524524
"evidence": "the forged response"

docs/qa/platform-checklist/areas/records-forms.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@
11201120
{
11211121
"clause": "related lists are READ-gated on BOTH ends: a persona WITHOUT read on the child object (showcase_contributor lacks showcase_contact read) sees NO Contacts section on the account detail (UI courtesy — deriveRelatedLists drops children the user cannot read, objectui#2359) AND a direct child query is refused server-side (403); a persona WITH child read (showcase_manager) sees the section AND the query 200s",
11221122
"oracle": "api",
1123-
"verify": "as showcase_contributor: screenshot confirms the Contacts tab is absent, and the forged GET /api/v1/data/showcase_contact?$filter=[[\"account\",\"=\",\"<northwind id>\"]] returns 403; as showcase_manager: the tab renders and the identical query returns 200 with rows — the server is the authority (ADR-0057 D10, RUNNER rule 4), the UI drop is courtesy",
1123+
"verify": "as showcase_contributor: screenshot confirms the Contacts tab is absent, and the forged GET /api/v1/data/showcase_contact?$filter=[[\"account\",\"=\",\"<northwind id>\"]] returns 403; as showcase_manager: the tab renders and the identical query returns 200 with rows — the server is the authority (ADR-0124 D1, RUNNER rule 4), the UI drop is courtesy",
11241124
"evidence": "both personas' detail screenshots + the 403 and the 200 child queries"
11251125
}
11261126
],
@@ -2489,7 +2489,7 @@
24892489
{
24902490
"clause": "the SERVER is the boundary: a forged PUT /api/v1/meta/view/<name> by the non-admin is refused (4xx) — UI absence alone is courtesy",
24912491
"oracle": "api",
2492-
"verify": "the direct non-admin PUT returns a 403-class refusal and no overlay view is created (RUNNER rule 4, ADR-0057 D10)",
2492+
"verify": "the direct non-admin PUT returns a 403-class refusal and no overlay view is created (RUNNER rule 4, ADR-0124 D5)",
24932493
"evidence": "the forged-request refusal"
24942494
}
24952495
],

docs/qa/platform-checklist/areas/studio-authoring.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@
7373
}
7474
],
7575
"negative": [
76-
"silent acceptance of an authoring write into a read-only package is a FAIL (ADR-0057 D10 — the server is the authoritative gate; the client lock is courtesy)",
76+
"silent acceptance of an authoring write into a read-only package is a FAIL (ADR-0124 D1 — the server is the authoritative gate; the client lock is courtesy)",
7777
"a 'published' app absent from the Home launcher, or an end-user list rendering raw picklist values instead of labels, is a FAIL"
7878
],
7979
"traps": ["stale-console-bundle", "automation-input", "hydration-race"],
8080
"source": [
8181
"docs/audits/2026-07-studio-package-create-ux-dogfood.md ('The loop closes' — the canonical walk; findings 1/3/4/6 carried as knownGaps)",
8282
"ADR-0016 §9 (the MVP loop this proves)",
83-
"ADR-0057 D10 (server-side gate authority)",
83+
"ADR-0124 D1 (server-side gate authority)",
8484
"access-security.readonly-package-locks-studio (client-side lock — cross-referenced, not duplicated)"
8585
],
8686
"history": [

0 commit comments

Comments
 (0)