Leg L2 of the accepted #11663 platform-admin re-anchor design. Provenance: design document = #11663 comment 5394453215 (§2, §3, §4 Choices 1–3 and 7, §6 row L2); maintainer acceptance = #11663 comment 5404675670 (2026-08-25, verbatim 「接受你的建议,继续」, bundle 1A/2B/3A/4A/5A/6A/7A). Filed by PM session session_01KWRU3s15AJz7PGW7a7wdCh.
Blocked-by: #11965
Blocked-by: #10348
(#10348-C consolidates the stray judges onto resolve-authz-context.ts — the stated prerequisite so this derivation changes in exactly one place; #11965 is the spec capability declaration this leg reads.)
Surface: packages/core — new security/platform-admin.ts (promoted isEmailVerified, normalization, list parse, derivation); the config branch in resolve-authz-context.ts §6b; + @objectstack/types dependency (Choice 7A — measured acyclic); ADMIN_STANDING_SURFACE update.
Ruled shape (⛔ not re-litigable here):
- 1A: reuse
OS_PLATFORM_OWNER_EMAIL (packages/types/src/env.ts:172); no second variable. - 2B: comma-separated list; one normalization (lowercase), duplicates collapsed, blanks dropped, any unparseable entry fails the whole variable closed — never skip-and-continue.
- 3A: live env read per derivation with a per-process memo keyed on the raw string; ⛔ no runtime mutation endpoint.
- Verified-email match only (an unverified account holding a configured address confers nothing); empty/unset config = zero platform admins, fail closed (dev-admin seed stays development-only).
- Derived standing is added; the legacy row-id grant read is still honoured in this leg (migration step 3 — nothing revoked here).
Known cost, stated up front: this moves the pinned golden — reading email_verified makes the sys_user read unconditional for authenticated principals, and the query multiset is pinned in resolve-authz-context.batch-equivalence.test.ts + .golden.json. Move it with an explanation; ⛔ never silently re-baseline. Also touches packages/verify/src/harness.ts:360-371 + two CLI e2e fixtures (verified-email shape after #11343).
Discipline: Clause-②: yes (authorization derivation); needs:contract-review at review; contract-review tier mandatory.
Acceptance criterion: with OS_PLATFORM_OWNER_EMAIL=a@b.c and a verified account a@b.c, derivation yields PLATFORM_ADMIN with the declared capability set; unset/empty/malformed variable yields zero config-derived admins (loudly); legacy grant path still honoured and logging its deprecation pointer.
Leg L2 of the accepted #11663 platform-admin re-anchor design. Provenance: design document = #11663 comment 5394453215 (§2, §3, §4 Choices 1–3 and 7, §6 row L2); maintainer acceptance = #11663 comment 5404675670 (2026-08-25, verbatim 「接受你的建议,继续」, bundle 1A/2B/3A/4A/5A/6A/7A). Filed by PM session
session_01KWRU3s15AJz7PGW7a7wdCh.Blocked-by: #11965
Blocked-by: #10348
(#10348-C consolidates the stray judges onto
resolve-authz-context.ts— the stated prerequisite so this derivation changes in exactly one place; #11965 is the spec capability declaration this leg reads.)Surface:
packages/core— newsecurity/platform-admin.ts(promotedisEmailVerified, normalization, list parse, derivation); the config branch inresolve-authz-context.ts§6b;+ @objectstack/typesdependency (Choice 7A — measured acyclic);ADMIN_STANDING_SURFACEupdate.Ruled shape (⛔ not re-litigable here):
OS_PLATFORM_OWNER_EMAIL(packages/types/src/env.ts:172); no second variable.Known cost, stated up front: this moves the pinned golden — reading
email_verifiedmakes thesys_userread unconditional for authenticated principals, and the query multiset is pinned inresolve-authz-context.batch-equivalence.test.ts+.golden.json. Move it with an explanation; ⛔ never silently re-baseline. Also touchespackages/verify/src/harness.ts:360-371+ two CLI e2e fixtures (verified-email shape after #11343).Discipline: Clause-②: yes (authorization derivation);
needs:contract-reviewat review; contract-review tier mandatory.Acceptance criterion: with
OS_PLATFORM_OWNER_EMAIL=a@b.cand a verified accounta@b.c, derivation yieldsPLATFORM_ADMINwith the declared capability set; unset/empty/malformed variable yields zero config-derived admins (loudly); legacy grant path still honoured and logging its deprecation pointer.