Repository navigation
refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write under single and refused under a wall (ADR-0131 D2/D3/D5/D13) #15204
Description
Activity
- addedpriority:p1High: required for production / M2High: required for production / M2
on Sep 4, 2026 Carrier hygiene — director seat (objectstack #12708, session_01LsEjuNMPitCHwEfYftZ1um), 2026-09-04.
needs:contract-reviewremoved from this card. Per the maintainer's 2026-08-28 ruling the carrier is never pre-hung: it marks a real reviewable increment (an open PR), and none exists — the card ispm:blockedbehind #15193 / #15195 / #15196 with no PR (closed_by_pull_requests0). The Clause-② fact stays where it lives, in the card body (a new authoring keyPositionSchema.permissionSets, four objects retired); the carrier goes on the PR and the card the moment a draft PR opens. Labels rewritten read-modify-write, every other label untouched.
Generated by Claude Code
Pointer added after this card was written: the sharing-rule recipient population gained a member on
main.SharingRuleRecipientTypenow includesfield(packages/spec/src/contracts/sharing-service.ts), landed by #14103 under the maintainer's ruling B, with theplugin-sharinghalf in flight as #15072 / PR #15235. This card's recipient text was written on 2026-09-04, before that member existed, so its enumeration is one short.What it does and does not change for this card:
- ⛔ Not an id→name rewrite target. A
fieldrecipient'svalueis a field name on the matched record — held to theFieldSchema.namegrammar at parse — not a reference to a catalog item. It is already a name, so the reference-column work this card describes does not apply to it. ⚠️ But it is a recipient, and it expands per record. Any census, conversion or retirement this card performs over "sharing-rule recipients" must enumerate it and say what happens to it, rather than silently covering the members that existed when the card was written. A card that lists five recipient types and meets six is how a member gets dropped.
⇒ Re-derive the recipient population against the then-current
mainwhen this card is dispatched, exactly as the unlock discipline requires — this pointer is a reason to do it, not a substitute for doing it.Recorded by the ADR-0131 drafting session (
6679d191-11f4-465b-b322-0e0409d76793), which wrote this card's body and owes the correction.- ⛔ Not an id→name rewrite target. A
objectstack-fleet commented
on Oct 6, 2026 ContributorMore actionsv18 pre-opening re-verification (C3): DRIFTED. The retirement list is stale and incomplete. Nothing landed
Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-06T14:36Z. ⛔ Not a claim, ⛔ not a dispatch. Read-only re-verification on objectstackmain6befe19c6e. The cut base was 2026-09-04, 3,298 commits earlier. The maintainer asked for this pre-opening preparation in the triage seat's chat: 「现在就可以处理吧」. Classes, positions and functions only. The claiming seat applies these corrections before building. The body is not rewritten.Holds: every named seeder still exists.
bootstrapBuiltinRoles/bootstrapDeclaredPositions/bootstrapDeclaredPermissions/bootstrapSystemCapabilitiesinplugin-security.bootstrapDeclaredSharingRules(plugin-sharing).bootstrapPlatformAdmin, with the Choice 4A grant row still written owner-less (bootstrap-platform-admin.ts:1137).per-organization-catalog.ts.- The four catalog objects.
Add to the retirement list:
bootstrapDeclaredCapabilities(plugin-security/src/bootstrap-declared-capabilities.ts:460, called atsecurity-plugin.ts:4759). It writessys_capability. Without it, the "zerosys_capabilityrows" acceptance cannot pass.bindBaselineToEveryone, which insertssys_position_permission_setrows at boot (security-plugin.ts:4447).
Corrections:
warnPreFixOrganizationLessRowsis nowwarnOrganizationLessRows(per-organization-catalog.ts:319, renamede3f056fce5). ADR-0131 D13 still uses the old name.- Strike "
reportLegacyPlatformAdminGrantretires in C8". It was removed on 17.x for walled postures (74832b68f2, Amend ADR-0131 D13 to drop the two platform-admin reporter symbols (maintainer ruling B on #18336) — and close thesingle-row NULL-ownership question the drop leaves open #18413). - platform-admin re-anchor L6 (reap): reader census on a walled rig; organization-scope auto-org-admin-grant's resolver; stop minting org-less rows; only then reap #11978 closed
not_planned(09-23). Its step 3 moved here and its census to C7. platform-admin re-anchor follow-up (Choice 4B): config-anchor thesingleposture — first-user promotion becomes development-only fallback #11979 is open,Blocked-by: #15204. - ADR-0094 now lists seven projecting doors, not three (
bcb6a17cf2). PositionSchema.permissionSetsis still absent, andspec/src/identity/position.zod.ts:51carries a closed-shape guidance entry that refuses the key. It must be replaced, not just added beside.- New consumer of the module:
delegated-admin-gate.tsusesresolveOwnOrganizationRow(:720,:1105; fix(plugin-security): the delegated-admin gate resolves a scope's business-unit anchor inside the caller's own organization #19800). Retiring the module moves that helper, and [finding] The delegated-admin gate resolves an EMPTY subtree on a stockobjectstack devboot — seeded business units are organization-less while every session carries an active organization, so every in-scope delegated write is refused #21057's direction says the gate's organization match does not change. - The retirement surface grew since the cut:
- refusal reporting (fix(plugin-security): a permission-set name collision now reaches the author #18022, fix(plugin-security): a capability name collision now reaches the author #18088, fix(plugin-security): the five remaining seeder refusals reach the author #18564, fix(plugin-security): the unowned permission-set refusal moves a counter #19471);
- the environment-authored skip (
234d1d8b7c); - provenance locks (fix(plugin-security): the permission-set lock reads the row's provenance, so org-owned sets, clones and runtime-package sets edit again #21857, fix(plugin-security): a data-door edit of a permission set saved into a writable runtime package updates its own row instead of forking it #21881);
- seed-ownership re-runs (fix(plugin-security): re-run the seed-ownership claim when the background seed settles #17872, fix(plugin-security): run the seed-ownership claim whenever a seed settles, on every boot #21503);
- the platform-admin audit record (feat(security): record platform-admin standing on the audit ledger at boot #19194).
Order: see #15196's note. The C2/C3 order for
permissionSetsis contradictory and goes to the maintainer.
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorMore actionsRuling pointer: batch #283 item 4 (decision card #22006) · B · maintainer 「其他同意」 2026-10-07T01:24Z
Director seat, summon #35,
session_01VYToj6PQehTEKNrjGM9akg(via the relay). The record is 6028793924 on #22006, which is closed. This card stayspm:blockedontarget:v18. Thread-read: 6018622568.- C3 lands the field and its only reader together.
PositionSchema.permissionSetsreplaces the closed-shape refusal atpackages/spec/src/identity/position.zod.ts:51; thesys_position_permission_setrows migrate into the position definitions; the read switches from the join table to the field; the join table retires. C2 (feat(core,objectql,plugin-security,plugin-sharing): the catalog is read from the registry; assignment tables reference it by name (ADR-0131 D2/D3/D4) #15196) keeps reading the join table for this one relation until then. - Not taken: A (the field added in C2, with a transition window of two sources) and C (one XL change set with C2).
- Card face: the triage seat adds "field, migration, read switch" to this card at the v18 re-verification; the ruling itself is the record above.
Generated by Claude Code
- C3 lands the field and its only reader together.
- added a commit that references this issue
on Oct 7, 2026 objectstack-fleet commented
on Oct 7, 2026 ContributorMore actionsScope amended by #22006 (ruled B,
6028793924): C3 gains the position field, the row migration and the read switch, landed togetherTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T12:30Z. ⛔ Not a claim, ⛔ not a dispatch. The v18 line opened in this act (#15193 closed on the maintainer's word,6037915987).What C3 now adds to its retirement scope, in one change set:
PositionSchema.permissionSetsreplaces the closed-shape refusal atpackages/spec/src/identity/position.zod.ts:51;- the
sys_position_permission_setrows migrate into the position definitions; - the position-to-permission-set read switches to the definition. It is the one read C2 (feat(core,objectql,plugin-security,plugin-sharing): the catalog is read from the registry; assignment tables reference it by name (ADR-0131 D2/D3/D4) #15196) leaves on the join table;
- the join table retires.
Why together: the field and its only reader land at once, so no permission computation ever reads two sources. ADR-0131 §8's order is kept: C3 comes after C1 (#15195) and C2 (#15196), and this card stays
pm:blockedbehind them.Its file surface is re-verified at claim, against the then-current
main.objectstack-fleet commented
on Oct 8, 2026 ContributorMore actionsTriage pointer: a measured case for this card's walled-creation refusal (from #22361, closed as a duplicate here)
Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-08T22:56Z. ⛔ Not a claim; this card stayspm:blocked. ⛔ Classes, positions and functions only.- Measured by feat(core,objectql,plugin-security,plugin-sharing): the catalog is read from the registry; assignment tables reference it by name (ADR-0131 D2/D3/D4) #15196 stage S7's round (os-dev-report
6070148106) in theplugin-securityunit harness: a realObjectQLoverSqlDriverplusSecurityPlugin, in the isolated posture with the organization-scoping service.- An organization-bound administrator holding the wildcard set creates a position at the data door.
- The create is accepted and lands as a row of that organization.
position-catalog-refusal.tsjudges assignments only; nothing judges a position create by posture.
- For this card's PR: turn that case into the refusal pin of "tenants are refused creation and may only assign", on the isolated and group postures. Control: an assignment is still accepted.
- The population created before the S8 switch is feat(core,objectql,plugin-security,plugin-sharing): the catalog is read from the registry; assignment tables reference it by name (ADR-0131 D2/D3/D4) #15196's Q3 = A ruling (
6050490870) and C7's inventory (feat(objectql,cli): inventory + migration — four fates per object, mirrors deleted only after the id→name rewrite is verified, per-table boot report (ADR-0131 D10) #15211). It is not this card's to migrate.
- Measured by feat(core,objectql,plugin-security,plugin-sharing): the catalog is read from the registry; assignment tables reference it by name (ADR-0131 D2/D3/D4) #15196 stage S7's round (os-dev-report
- added a commit that references this issue
on Oct 9, 2026
⛔ BLOCKED — the v18 development line is not open.
Blocked-by: #15193
Blocked-by: #15195
Blocked-by: #15196
History: this line read
Blocked-by: #15193, #15195, #15196until 2026-09-27, inside backticks, so no unlock scan could read it (the triage census counted it as a blocked card with no machine target). The same targets now sit one per line, undecorated; nothing else changed (triage seat, session_01W89enF2dYV7K4N2Fbfj33f).Part of #15194 (ADR-0131 execution tree). ⛔ Do not claim, assign or dispatch this card while #15193 is open, whatever its other labels say.
In one sentence. Boot stops writing positions, permission sets, capabilities and sharing rules into any table; the four catalog tables retire (ADR-0094's "the table is only a projection" carried to its end — not even the projection remains); in single-tenant an administrator creating a position or permission set in Setup is writing environment metadata, and on a shared-database multi-tenant deployment tenants are refused creation and may only assign.
Maintainer, 2026-09-04, on who may create catalog items: 「角色、岗位、权限集,Setup 里组织自建的是组织级。这个说的是单库单租户吧,单库多租户我可以禁止他们创建。但是你要支持我绑定到人员。」
Scope. Retire
bootstrapBuiltinRoles,bootstrapDeclaredPositions,bootstrapDeclaredPermissions,bootstrapDeclaredSharingRules,bootstrapSystemCapabilities,bootstrapPlatformAdmin'sdefaultPermissionSetsmaterialization, thesys_permission_setprojector/reconciler (permission-set-projection.ts— ADR-0094 D2/D4; D1 stands), andper-organization-catalog.ts(catalogIsPerOrganization,listSeedOrganizationIds,warnPreFixOrganizationLessRows). Declare the four identity roles and the two audience anchors (everyone,guest) aspositionmetadata in the platform's own declarations. AddPositionSchema.permissionSetstopackages/spec(the one new authoring key of this record; C2 consumes it).bootstrap-platform-admin.tsChoice 4A writes theadmin_full_accessgrant row owned by the Default Organization undersingle; under a wall nothing is written (unchanged);reportLegacyPlatformAdminGrantand the unscoped anchor retire in C8. Tests:per-organization-catalog.test.tscases retire with the module;deal_p1re-justified, not deleted.Absorbs the platform-admin re-anchor family where it overlaps: #11979 (config-anchor the
singleposture) and #11978 (stop minting org-less rows) are decided by ADR-0131 D5 — read both cards before starting, and close them by pointer in this PR if nothing survives them.Acceptance. A fresh boot in every posture writes zero rows to
sys_position,sys_permission_set,sys_position_permission_set,sys_capability,sys_sharing_rule— count pinned, with a positive control that performs one organization-authored create and sees exactly one row.PLATFORM_ADMINstill derives for the config-anchored owner and, undersingle, for the first user. Setup role/position/permission-set pages still show the declared catalog, through C9's registry source.⛔ Stop and report: deleting existing rows (C7 owns every deletion); dropping the four objects' tables (C7/C8).
Refs: ADR-0131 D2, D3, D5, D13 · ADR-0094 D1 (stands) / D2 / D4 · ADR-0090 D5/D9 · ADR-0068 D2 · #10103 Option C (retired) · #13514 L4 · #11973 · #11978 · #11979.