Skip to content

Commit 8d7571d

Browse files
committed
docs(qa): re-author access-security.platform-owner-email-anchor for the Default Organization grant
The item's clause 6 named its own re-author trigger (#11979, Choice 4B), which PR #24373 landed: the single first-user promotion now writes its admin_full_access grant owned by the Default Organization (ADR-0131 D5), and PR #24872 retired the organization-less row's single-posture anchor. Six texts that still named the organization-less row as the live door now name the Default Organization's grant; clause 6's verify and automated.ref cite the [ADR-0131 D5] describe. Revision 7 -> 8 with one history entry. No clause verdict changes. Claude-Session: https://claude.ai/code/session_01JDXz1o5fLjTiZcUdKvNKJN Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9dc1f42 commit 8d7571d

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 is an anchor under single ONLY, and silently so (#11663 L5): under single, 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 — 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)