Skip to content

Commit ec951e2

Browse files
docs(qa): re-point the platform-owner-email item's legacy-grant anchor at grantAnchorsPlatformStanding (#24463)
Fixes #24438 Clause-②: no ## What `pnpm check:platform-checklist` is red on `main` with one problem: `areas/access-security.json` cites `packages/core/src/security/resolve-authz-context.ts#legacyGrantAnchorRetired`, and that file no longer declares the symbol. This PR changes that one citation, in `source[2]` of item `access-security.platform-owner-email-anchor`, to `#grantAnchorsPlatformStanding`. Nothing else changes: not the prose beside the citation, not any clause, step, fixture or oracle, not `scripts/symbol-anchors.mjs`, not the anchor baseline. Diff: 1 file, +1 / -1. ## Where the symbol went `b2e78701f7` (PR #24373) deleted the local flag `const legacyGrantAnchorRetired = postureEnforcesWall(resolveTenancyPosture())` from `resolveUserAuthzGrants`. It added a module-level predicate, `grantAnchorsPlatformStanding(grant, { walled, defaultOrganizationId })`. §6b now asks it of every `admin_full_access` grant: - walled posture: it returns false, so no grant anchors standing; - `single`: the organization-less grant anchors, and so does the Default Organization's grant. The citation's parenthetical reads "the unscoped admin_full_access row derives PLATFORM_ADMIN only when the requested posture enforces no wall". That is still true, and the predicate is now where it is decided: `if (anchor.walled) return false;`, then `organizationId === null || …`. The requested posture is still read by `postureEnforcesWall(resolveTenancyPosture())`, now held in `walled`. So this is a re-point: the behaviour the citation describes did not move. ## Verification - Base `725a5b131` (`origin/main`): `node scripts/check-platform-checklist.mjs` exits 1 with `check-platform-checklist: 1 problem(s)`. That one problem is the ABSENT SYMBOL line the card quotes. - Head `0c177741b`: `pnpm check:platform-checklist` exits 0, self-tests included. Verdict: `check-platform-checklist: OK — 16 areas, 327 items (322 active, 1 planned); … symbol anchors: 855/865 resolved by symbol-anchors.mjs … 18 file floors held`. - `node scripts/pm/dispatch-gates.mjs --commands` on this diff derives 13 commands. All 13 exit 0 at `0c177741b`: `check-ci-filter-parity`, `check-closing-keyword-parity` (and its `--self-test`), `check-comment-mask-corpus`, `check:doc-formula-expressions` (lint), `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`, `check:watch-hint-literal`. - `--ran` reconciliation: "13 derived famil(ies) accounted for — 13 run, 0 NOT-MEASURED (a DERIVED zero — all 13 recorded an exit code and none of them is 3)". - `check:doc-formula-expressions` first exited 3 (PREREQUISITE NOT MET, because lint and formula were not built). That is not a measurement. After `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` it exited 0. - No ablation: the diff changes QA-ledger data, not tested behaviour. The base-red and head-green runs above are the before and after. - No package is touched, so no build closure, package test or typecheck is owed. CI families are read from this PR's check-runs. - Changeset: `docs/qa/**` publishes nothing, so the PR carries `skip-changeset`. ## Acceptance notes - **The revision is not bumped (it stays 3).** The checklist README bumps `revision` "on any semantic edit". This edit changes no step, clause, verify or oracle, so a run record pinned to revision 3 still reads the same item. - Precedent is split. Five code PRs re-pointed a `source` anchor in place with no bump: `52ff308b8`, `646303eae`, `df000d4b2`, `bb7ccde66`, `6868514b1`. Two docs(qa) PRs bumped: `6792be6ab`, and `52c04b360`, which edited a `verify` field. - The card's line budget is one line. If a bump is wanted, the follow-up is about six lines: revision 4 plus one `history` entry. - **The item's own re-author trigger has fired. This is an open question for the access lane, and this PR does not act on it.** - Clause 6's verify ends: "The single half's own fate is #11979's (Choice 4B): if that lands, this clause is re-authored, not read as a regression". PR #24373 landed #11979 at 2026-10-18T19:15Z (state reason `completed`). - The first-user promotion now writes its `admin_full_access` grant with `organization_id` set to the Default Organization (`packages/plugins/plugin-security/src/bootstrap-platform-admin.ts`). The PR's fresh-boot golden moved its grant owner from `null` to `org_default`. - So on the fresh `single` boot this item runs, the seeded admin holds the Default Organization's grant, not the organization-less row. Four phrases describe the older boot: - `personas[0]`: "it is grant-anchored via the unscoped admin_full_access row that first-registrant promotion writes"; - `fixtures.knownGaps[0]`: "also holds the unscoped admin_full_access grant under single"; - `acceptance[0]`: "under single the ADR-0068 D2 unscoped-grant anchor stays the only door"; - `acceptance[5]`: "(clauses 1 and 3 observe it live)". - Every verdict still holds: M is refused, the admin gets its 200, the organization-less row confers nothing under a wall, and the config anchor still confers. - The legacy-row half of clause 6 is still pinned, by the describe '[#11663 L5] the legacy grant row is an anchor under `single`, and NOWHERE else'. The new half is pinned by '[ADR-0131 D5] under `single` the Default Organization's admin_full_access grant is the anchor', in the same test file. The item cites that describe nowhere. - As the dispatch instructs, this PR does not reword the clause. The question, its options and the evidence are in the report on the card. --- _Generated by [Claude Code](https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 964a237 commit ec951e2

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2820,7 +2820,7 @@
28202820
"source": [
28212821
"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)",
28222822
"packages/core/src/security/platform-admin.ts#parsePlatformAdminEmails (parsePlatformAdminEmails whole-variable refusal, resolvePlatformAdminEmails loud-once resolve, matchesConfiguredPlatformAdmin verified-only)",
2823-
"packages/core/src/security/resolve-authz-context.ts#legacyGrantAnchorRetired (#11663 L5 — the unscoped admin_full_access row derives PLATFORM_ADMIN only when the requested posture enforces no wall)",
2823+
"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)",
28242824
"packages/spec/src/security/tenancy-posture.ts#postureEnforcesWall (walled = every posture except single)",
28252825
"packages/core/src/security/admin-standing-surface.ts (the env declared a non-table derivation input — no break-glass write can reach it)",
28262826
"packages/types/src/env.ts#PLATFORM_OWNER_EMAIL_ENV,200 (PLATFORM_OWNER_EMAIL_ENV / resolvePlatformOwnerEmail)",

0 commit comments

Comments
 (0)