Skip to content

Commit 5e772c7

Browse files
docs(qa): re-author access-security.platform-owner-email-anchor for the Default Organization grant (#25323)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} --> _Requested by **Elon** · [project thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DBZkWHiqgPrYfLLav4s1vTL)_ Fixes #24465 Clause-②: no Metadata-protocol: none ## What changed One file, one item: `access-security.platform-owner-email-anchor` in `docs/qa/platform-checklist/areas/access-security.json`, revision 7 → 8, with one `history` entry naming this card and PR #24463. Clause 6 named its own re-author trigger: "The single half's own fate is #11979's (Choice 4B): if that lands, this clause is re-authored, not read as a regression". It has landed, in two steps: - PR #24373 (`b2e78701f7`) landed #11979. The `single` first-user promotion writes its `admin_full_access` grant with `organization_id` set to the Default Organization (`bootstrap-platform-admin.ts`, ADR-0131 D5). - PR #24872 (`94842bad2a`, 2026-10-20, after this card was filed) removed the organization-less arm from `grantAnchorsPlatformStanding`. Under `single`, only the Default Organization's grant anchors standing now. An organization-less row anchors nothing on any posture, and it no longer applies in any resolution. So the live door the seeded admin's 200 goes through is the Default Organization's grant. Six texts still named the organization-less row as that door. Each one is re-described below. The four the card names are first. | field | before | after | |---|---|---| | `personas[0]` | "grant-anchored via the unscoped admin_full_access row that first-registrant promotion writes, the ADR-0068 D2 contrast; under a walled posture no such row is written" | "grant-anchored via the admin_full_access grant that first-registrant promotion writes, owned by the Default Organization (ADR-0131 D5), the ADR-0068 D2 contrast; an organization-less admin_full_access row anchors nothing on any posture; under a walled posture no such grant is written" | | `fixtures.knownGaps[0]` | "also holds the unscoped admin_full_access grant under single (the posture this item boots)" | "also holds the Default Organization's admin_full_access grant under single (the posture this item boots; ADR-0131 D5)" | | `acceptance[0].clause` | "under single the ADR-0068 D2 unscoped-grant anchor stays the only door" | "under single the ADR-0068 D2 stored-grant anchor — the Default Organization's admin_full_access grant (ADR-0131 D5) — stays the only door" | | `acceptance[5].clause` | "standing resting on the unscoped admin_full_access grant alone still resolves PLATFORM_ADMIN (clauses 1 and 3 observe it live); under a walled posture … the same row confers no PLATFORM_ADMIN standing (the held set still grants its own capabilities; …" | "standing resting on the admin_full_access grant first-registrant promotion writes — owned by the Default Organization (ADR-0131 D5) — alone still resolves PLATFORM_ADMIN (clauses 1 and 3 observe it live as the seeded admin's 200); an organization-less admin_full_access row anchors nothing on any posture; under a walled posture … the same grant confers no PLATFORM_ADMIN standing (the held set still grants its own capabilities in its own organization; …" | | `variants[6]` | "walled posture — the unscoped admin_full_access grant alone confers no PLATFORM_ADMIN standing (unit pin, clause 6)" | "walled posture — the Default Organization's admin_full_access grant alone confers no PLATFORM_ADMIN standing, and an organization-less row anchors nothing on any posture (unit pins, clause 6)" | | `source[2]` parenthetical | "(#11663 L5 — the unscoped admin_full_access row derives PLATFORM_ADMIN only when the requested posture enforces no wall)" | "(ADR-0131 D5 + #11663 L5 — the Default Organization's admin_full_access grant derives PLATFORM_ADMIN only when the requested posture enforces no wall; an organization-less row anchors nothing)" | Also changed: - `acceptance[5].verify` and `automated.ref` now cite the describe `` '[ADR-0131 D5] under `single` the Default Organization's admin_full_access grant is the anchor' ``. It is measured in `packages/core/src/security/resolve-authz-context.platform-admin-config.test.ts` (at `9dc1f42d50`). Clause 6's trailing trigger sentence now records that the trigger fired and that revision 8 re-authored the clause. - `source` gains `packages/plugins/plugin-security/src/bootstrap-platform-admin.ts#readPromotionGrantOwner`, which reads the grant's owner. The gate resolves it as a declaration (987/997 symbol anchors resolved at head, the 10 others on the named residual). ## Verdicts No clause verdict changes. M is refused at baseline, unverified and non-match. The seeded admin answers 200. A verified match confers. A malformed list fails closed. Under a wall the promoted grant confers no standing, and the config anchor still confers. The pins clause 6 cites still exist under the same names. Since PR #24872, the `[#11663 L5]` describes use a fixture of the Default Organization's grant. The new arm, "an organization-less row anchors nothing", is pinned by the last case of the `[ADR-0131 D5]` describe. ## Gates Head `8d7571de`: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 13 commands. Each one ran with its exit code captured before any pipe. All 13 exit 0: `check-ci-filter-parity`, `check-closing-keyword-parity` (and its `--self-test`), `check-comment-mask-corpus`, `check:doc-formula-expressions` (lint, after `pnpm --filter '@objectstack/lint...' build`), `check:cross-package-test-inputs`, `check:doc-authoring`, `check:driver-memory-census`, `check:gitlink-declared`, `check:nul-bytes`, `check:platform-checklist`, `check:refd-timer-probe` and `check:watch-hint-literal`. The `--ran` reconciliation reads: "13 derived famil(ies) accounted for — 13 run, 0 NOT-MEASURED (a DERIVED zero …)". `pnpm check:platform-checklist` verdict: `OK — 16 areas, 329 items (324 active, 1 planned); … symbol anchors: 987/997 resolved … 18 file floors held`. No package is touched, so no build closure, package test or typecheck is owed. CI families are read from this PR's check-runs. `docs/qa/**` publishes nothing, so this PR carries `skip-changeset`. Nothing was ablated: the diff changes QA-ledger data, not tested behaviour. ## Acceptance notes - **Card target re-measured (PR #24872).** The card asked to keep the organization-less row's "single only, nothing under a wall" assertion, now pinned only by tests. That premise was falsified after filing. PR #24872 retired the row's `single` anchor, and the `[ADR-0131 D5]` describe pins "the organization-less row a pre-D5 promotion wrote anchors NOTHING". Keeping the old assertion would claim a capability the runtime no longer has. This PR states the current behaviour instead and does not change the item's verdicts. - **Revision.** The card said 3 → 4, but the item was already at revision 7 (revisions 4 to 7 came from #24717, #24580, #24788 and #25018). This PR bumps 7 → 8. - **Scope.** The card named four phrases. The same stale description also sat in `variants[6]` and `source[2]` of the same item, and both are re-described here. The file surface is unchanged. After this PR, `unscoped` appears 0 times in `access-security.json`. - The attribution block's first line is an HTML comment, which the session requires as the body's first line. That is a declared deviation from `os-dev.md`'s no-HTML-comment rule (same shape as PR #25255). - The work was done in a linked worktree (`../objectstack-issue-24465`) on the branch the claim names, because the primary checkout's guards block edits. --- _Generated by [Claude Code](https://claude.ai/code/session_01JDXz1o5fLjTiZcUdKvNKJN)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6bf0ff5 commit 5e772c7

1 file changed

Lines changed: 16 additions & 9 deletions

File tree

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2919,11 +2919,11 @@
29192919
"title": "OS_PLATFORM_OWNER_EMAIL platform-admin anchor: only a VERIFIED stored-email match confers PLATFORM_ADMIN — unset, unverified match, non-match and malformed lists each confer nothing, fail closed",
29202920
"since": "v17",
29212921
"status": "active",
2922-
"revision": 7,
2922+
"revision": 8,
29232923
"priority": "P1",
29242924
"surface": "api",
29252925
"personas": [
2926-
"admin (seeded dev admin — its address is seed-stamped verified per #11343. Under single, the posture this item boots, it is grant-anchored via the unscoped admin_full_access row that first-registrant promotion writes, the ADR-0068 D2 contrast; under a walled posture no such row is written and an existing one confers no platform-admin standing (#11663 L5), so it would stand only if OS_PLATFORM_OWNER_EMAIL named its address)",
2926+
"admin (seeded dev admin — its address is seed-stamped verified per #11343. Under single, the posture this item boots, it is grant-anchored via the admin_full_access grant that first-registrant promotion writes, owned by the Default Organization (ADR-0131 D5), the ADR-0068 D2 contrast; an organization-less admin_full_access row anchors nothing on any posture; under a walled posture no such grant is written and an existing one confers no platform-admin standing (#11663 L5), so it would stand only if OS_PLATFORM_OWNER_EMAIL named its address)",
29272927
"fresh member M (the config-anchor subject; a fresh sign-up's sys_user row is UNVERIFIED, which is exactly the unverified-match fixture)"
29282928
],
29292929
"fixtures": {
@@ -2933,7 +2933,7 @@
29332933
"a manage_platform_settings-floor probe route: GET /api/v1/datasources answers 401/403 BEFORE any service resolution (packages/services/service-datasource/src/admin-routes.ts; DATASOURCE_ADMIN_CAPABILITY), and admin_full_access carries that capability (packages/spec/src/identity/eval-user.zod.ts) — so the probe discriminates platform-admin standing cleanly"
29342934
],
29352935
"knownGaps": [
2936-
"the ENTITLED live leg needs a VERIFIED second account, and no stock HTTP path verifies one: email_verified is statically readonly at the user-context API (stripped — the write-path-guards class), a fresh sign-up reads unverified, and the seeded dev admin — whose address IS stamped verified at seed time (#11343, auth-plugin.ts) — also holds the unscoped admin_full_access grant under single (the posture this item boots), so its 200s can never attribute to the config anchor. Verify M's address via a verification-enabled boot with mail capture (identity-auth.email-verification-loop's fixture, itself a knownGap there) or a system-context stamp through the same isSystem doorway the seed itself uses; without either, clause 5's live leg scores blocked(fixture) and the entitled side rests on the unit pin. Measured on main c91af8ed6: POST /api/v1/auth/admin/update-user {userId, data: {emailVerified: true}} answers the seeded dev admin 403 YOU_ARE_NOT_ALLOWED_TO_UPDATE_USERS, so the HTTP lane has no verifying door; the run stamped M's email_verified directly on its own scratch database with the server stopped (a system-level write, never on a shared database) and records that it did"
2936+
"the ENTITLED live leg needs a VERIFIED second account, and no stock HTTP path verifies one: email_verified is statically readonly at the user-context API (stripped — the write-path-guards class), a fresh sign-up reads unverified, and the seeded dev admin — whose address IS stamped verified at seed time (#11343, auth-plugin.ts) — also holds the Default Organization's admin_full_access grant under single (the posture this item boots; ADR-0131 D5), so its 200s can never attribute to the config anchor. Verify M's address via a verification-enabled boot with mail capture (identity-auth.email-verification-loop's fixture, itself a knownGap there) or a system-context stamp through the same isSystem doorway the seed itself uses; without either, clause 5's live leg scores blocked(fixture) and the entitled side rests on the unit pin. Measured on main c91af8ed6: POST /api/v1/auth/admin/update-user {userId, data: {emailVerified: true}} answers the seeded dev admin 403 YOU_ARE_NOT_ALLOWED_TO_UPDATE_USERS, so the HTTP lane has no verifying door; the run stamped M's email_verified directly on its own scratch database with the server stopped (a system-level write, never on a shared database) and records that it did"
29372937
]
29382938
},
29392939
"steps": [
@@ -2946,7 +2946,7 @@
29462946
],
29472947
"acceptance": [
29482948
{
2949-
"clause": "unset = ZERO config-derived administrators, and under single the ADR-0068 D2 unscoped-grant anchor stays the only door: M's datasource probe is refused server-side (401/403 per identity, never 200) and M's systemPermissions lacks manage_platform_settings, while the seeded admin's identical probe answers 200 (both sides of the gate)",
2949+
"clause": "unset = ZERO config-derived administrators, and under single the ADR-0068 D2 stored-grant anchor — the Default Organization's admin_full_access grant (ADR-0131 D5) — stays the only door: M's datasource probe is refused server-side (401/403 per identity, never 200) and M's systemPermissions lacks manage_platform_settings, while the seeded admin's identical probe answers 200 (both sides of the gate)",
29502950
"oracle": "api",
29512951
"verify": "M's GET /api/v1/datasources >=400 with the declared code; M's /auth/me/permissions systemPermissions array excludes manage_platform_settings; admin's same GET is 200",
29522952
"evidence": "both personas' traces"
@@ -2976,9 +2976,9 @@
29762976
"evidence": "test output (and, when the fixture exists, M's entitled traces)"
29772977
},
29782978
{
2979-
"clause": "the legacy grant is an anchor under single ONLY, and silently so (#11663 L5): under single, standing resting on the unscoped admin_full_access grant alone still resolves PLATFORM_ADMIN (clauses 1 and 3 observe it live); under a walled posture — postureEnforcesWall, i.e. every posture except single, read from the REQUESTED posture — the same row confers no PLATFORM_ADMIN standing (the held set still grants its own capabilities; only the rung and the built-in platform_admin position go), while the config anchor keeps conferring on that same walled rig; and the request path logs nothing about the row on any posture",
2979+
"clause": "the legacy grant — the admin_full_access grant first-registrant promotion writes, owned by the Default Organization (ADR-0131 D5), as opposed to the config anchor — is an anchor under single ONLY, and silently so (#11663 L5): under single, standing resting on that grant alone still resolves PLATFORM_ADMIN (clauses 1 and 3 observe it live as the seeded admin's 200); an organization-less admin_full_access row anchors nothing on any posture; under a walled posture — postureEnforcesWall, i.e. every posture except single, read from the REQUESTED posture — the same grant confers no PLATFORM_ADMIN standing (the held set still grants its own capabilities in its own organization; only the rung and the built-in platform_admin position go), while the config anchor keeps conferring on that same walled rig; and the request path logs nothing about the row on any posture",
29802980
"oracle": "test",
2981-
"verify": "packages/core/src/security/resolve-authz-context.platform-admin-config.test.ts — the '[#11663 L5] the legacy grant row is an anchor under `single`, and NOWHERE else', '[#11663 L5] the legacy anchor confers only on the rigs Choice 4A keeps it for' and '[#11663 L5] standing across postures' describes; packages/core/src/security/platform-admin.test.ts — '[#11663 L5] the legacy-grant deprecation pointer is retired' (both pointer symbols absent from the module and from the @objectstack/core security entry, with positive controls). The single half's own fate is #11979's (Choice 4B): if that lands, this clause is re-authored, not read as a regression",
2981+
"verify": "packages/core/src/security/resolve-authz-context.platform-admin-config.test.ts — the '[#11663 L5] the legacy grant row is an anchor under `single`, and NOWHERE else', '[#11663 L5] the legacy anchor confers only on the rigs Choice 4A keeps it for' and '[#11663 L5] standing across postures' describes, and the '[ADR-0131 D5] under `single` the Default Organization's admin_full_access grant is the anchor' describe (the Default Organization's grant confers with no config; another organization's grant, a walled rig and the organization-less row a pre-D5 promotion wrote anchor nothing); packages/core/src/security/platform-admin.test.ts — '[#11663 L5] the legacy-grant deprecation pointer is retired' (both pointer symbols absent from the module and from the @objectstack/core security entry, with positive controls). The single half's fate was #11979's (Choice 4B): it landed (PR #24373), and this clause was re-authored for it at revision 8 rather than read as a regression",
29822982
"evidence": "test output"
29832983
}
29842984
],
@@ -2995,20 +2995,21 @@
29952995
"non-match (nothing)",
29962996
"comma-separated list — duplicates collapsed, trim+lowercase normalization (platform-admin.ts)",
29972997
"malformed entry (whole-variable refusal, loud once)",
2998-
"walled posture — the unscoped admin_full_access grant alone confers no PLATFORM_ADMIN standing (unit pin, clause 6)"
2998+
"walled posture — the Default Organization's admin_full_access grant alone confers no PLATFORM_ADMIN standing, and an organization-less row anchors nothing on any posture (unit pins, clause 6)"
29992999
],
30003000
"traps": [
30013001
"wrong-persona",
30023002
"auth-state-leak"
30033003
],
30043004
"automated": {
30053005
"kind": "unit",
3006-
"ref": "packages/core/src/security/resolve-authz-context.platform-admin-config.test.ts (the acceptance criterion, all four fail-closed arms, the ⭐ stored-row-not-seed pin, the #11663 L5 posture split of the legacy grant anchor) + packages/core/src/security/platform-admin.test.ts (parse/refusal/memo) + packages/core/src/security/admin-standing-surface.test.ts. STILL MANUAL: the live-HTTP arms over a real boot (clauses 1-4; clause 6 is test-only) — the pins run the derivation in-process; this item's live legs prove the same verdicts through the mounted server"
3006+
"ref": "packages/core/src/security/resolve-authz-context.platform-admin-config.test.ts (the acceptance criterion, all four fail-closed arms, the ⭐ stored-row-not-seed pin, the #11663 L5 posture split of the legacy grant anchor, the '[ADR-0131 D5] under `single` the Default Organization's admin_full_access grant is the anchor' describe) + packages/core/src/security/platform-admin.test.ts (parse/refusal/memo) + packages/core/src/security/admin-standing-surface.test.ts. STILL MANUAL: the live-HTTP arms over a real boot (clauses 1-4; clause 6 is test-only) — the pins run the derivation in-process; this item's live legs prove the same verdicts through the mounted server"
30073007
},
30083008
"source": [
30093009
"packages/core/src/security/resolve-authz-context.ts#hasPlatformAdminStanding (§6b-config — the config anchor inside the ONE derivation site; additive, never subtractive) + (hasPlatformAdminStanding, the id-shaped projection)",
30103010
"packages/core/src/security/platform-admin.ts#parsePlatformAdminEmails (parsePlatformAdminEmails whole-variable refusal, resolvePlatformAdminEmails loud-once resolve, matchesConfiguredPlatformAdmin verified-only)",
3011-
"packages/core/src/security/resolve-authz-context.ts#grantAnchorsPlatformStanding (#11663 L5 — the unscoped admin_full_access row derives PLATFORM_ADMIN only when the requested posture enforces no wall)",
3011+
"packages/core/src/security/resolve-authz-context.ts#grantAnchorsPlatformStanding (ADR-0131 D5 + #11663 L5 — the Default Organization's admin_full_access grant derives PLATFORM_ADMIN only when the requested posture enforces no wall; an organization-less row anchors nothing)",
3012+
"packages/plugins/plugin-security/src/bootstrap-platform-admin.ts#readPromotionGrantOwner (ADR-0131 D5 — the single first-user promotion writes its admin_full_access grant owned by the Default Organization, never with a NULL organization)",
30123013
"packages/spec/src/security/tenancy-posture.ts#postureEnforcesWall (walled = every posture except single)",
30133014
"packages/core/src/security/admin-standing-surface.ts (the env declared a non-table derivation input — no break-glass write can reach it)",
30143015
"packages/types/src/env.ts#PLATFORM_OWNER_EMAIL_ENV + packages/types/src/env.ts#resolvePlatformOwnerEmail (the variable's name, and its live per-call read)",
@@ -3058,6 +3059,12 @@
30583059
"date": "2026-10-21",
30593060
"change": "Respelled — fixtures.knownGaps[0]: 'its own isolated scratch database' → 'its own scratch database'. PR #25003's out-of-scope finding (round 17 of wave anchor #24579; ACCEPT 6304389370, landing record 6304641541): 22 non-history texts in 17 items named the own-port boot or its DB with 'isolated' in other words, the phrasing round 12 found a runner reading as the `isolated` tenancy posture (OS_TENANCY_POSTURE=isolated). The new spelling names the boot or the DB by what it is, the run's own port and DB (RUNNER.md's trap-table counter: own port/DB, skill §0), and names no posture. Read at base 93e6c1a5f8. steps[0]'s 'a walled posture (group / isolated)' names the posture and is left as written. No clause changed",
30603061
"ref": "#25018"
3062+
},
3063+
{
3064+
"revision": 8,
3065+
"date": "2026-10-23",
3066+
"change": "Re-authored for the Default Organization grant — clause 6's own re-author trigger fired. #11979 (Choice 4B) landed by PR #24373 (b2e78701f7): the single first-user promotion writes its admin_full_access grant owned by the Default Organization (ADR-0131 D5, bootstrap-platform-admin.ts). PR #24872 (94842bad2a) then retired the organization-less row's single-posture anchor: grantAnchorsPlatformStanding answers yes for the Default Organization's grant only. Six texts still named the organization-less row as the live door — personas[0], fixtures.knownGaps[0], acceptance[0], acceptance[5], variants[6], source[2]; each now names the Default Organization's grant, and personas[0], acceptance[5], variants[6] and source[2] add that an organization-less row anchors nothing on any posture. Clause 6's verify and automated.ref cite the '[ADR-0131 D5] under `single` the Default Organization's admin_full_access grant is the anchor' describe; source gains bootstrap-platform-admin.ts#readPromotionGrantOwner. PR #24463 had re-pointed source[2]'s anchor at grantAnchorsPlatformStanding and left the revision at 3. Read at base 9dc1f42d50. No clause verdict changed: M is refused, the seeded admin answers 200, the walled grant confers no standing, the config anchor confers",
3067+
"ref": "#24465"
30613068
}
30623069
]
30633070
},

0 commit comments

Comments
 (0)