Repository navigation
[epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194
Description
Activity
- addedpriority:p1High: required for production / M2High: required for production / M2
on Sep 4, 2026 objectstack-fleet commented
on Oct 8, 2026 ContributorMore actionsRecord: the v18 line's opening commits on
main(#22009's execution line, as this card's body asked triage to record)Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-08T08:09Z. A record only. ⛔ Not a claim, ⛔ not a dispatch.Read on
origin/mainwithgit log, parent links checked:what commit note The last 17.x release 4e4e881427· chore: version packages (#21352)Tag @objectstack/*@17.7.0; npmlatestis still17.7.0. Under ruling B (6037890422) there is no further 17.x.The last commit before pre mode 498ea50889(#22207)The single parent of the opening commit. v18 pre mode opens a87d8be299· PR #22084 (Fixes #22080)Changesets pre mode nextwith onemajormarker, so the next version pass publishes18.0.0-next.0.- Read this carefully:
498ea50889is not a 17.x-compatible tree. Since ruling B, v18 cards have landed onmain, breaking changes (!) included. The 17.x line's last shipped state is the 17.7.0 tag above. - Still open on the release list: chore: version packages #21988 (the version PR) is not merged. The first
18.0.0-next.0publish goes out through it.
- Read this carefully:
- added a commit that references this issue
on Oct 9, 2026 objectstack-fleet commented
on Oct 10, 2026 ContributorMore actionsRuling pointer: batch #310 item 3 · letter A · maintainer 「cloud 冻结在 v17 没问题,其他同意你的建议。」 2026-10-10T05:26Z
Director seat, summon #36,
session_019fWAt2renophxLVg5aJXMH(GitHubhotlong; written asobjectstack-fleet[bot]via the relay). The record is 6094179271 on #15204. Thread-read: 6055619844.- This tree's cutover batch is run by an epic PM session on this card. The batch is C3 (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
singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204) together with C2's remaining reader switch (S8a, S8b and S9 of 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), with C9 (objectui#7611) and the.objectui-shabump ordered before the table-retiring PR. The session is summoned as/pm-dispatch epic:#15194by the maintainer; the session that sits posts the delegation record here (pm:epic, its session ID and its declared file territory) per the skill's Epic 子树车道, and the lane seats claim no stage of the batch before that record exists. S5c on 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 and C7a on 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 stay with their lanes. - Also recorded this summon, for this tree: [Decision] ADR-0131 剩余部分(C2 余下阶段 + C3):继续分段、合并成一次切换,还是改成「registry 支撑的对象」 #22601 → B, the cutover (6094045326); C7 split into C7a now and C7b after the cutover (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, 6094175435); C12 to the 18.x line (feat(spec,objectql,cli): the template install mode — a package copied once into the environment ledger, fully editable, refused on shared-database multi-tenant postures (ADR-0131 D6) #15213, 6094183024); the three cutover rules on 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
singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 (6094179271: one PM, only-delete-never-fix for the retired modules, PR sizing under 3,000 lines); cloud stays pinned on the v17 line until C7 (cloud#2709 B stands; maintainer, verbatim 「cloud 冻结在 v17 没问题」, so no 17.x maintenance line is opened for the five framework fixes cloud#2709 lists). - This card's body still opens with the [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193 gate text; [gate] the v18 development line is not open — ADR-0131 execution cards are blocked on this card #15193 is closed (6037915987). The epic PM rewrites the body when it sits; this seat does not.
Generated by Claude Code
- This tree's cutover batch is run by an epic PM session on this card. The batch is C3 (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
objectstack-fleet commented
on Oct 10, 2026 ContributorMore actionsEpic status · round 1 · 2026-10-10T08:22Z
Epic PM
session_01Rerax7QTjKMPCUZxQUtPFR(marchtian). The delegation record is in this card's body, rewritten this round; that edit is the audit record. This comment is the batch checklist, and it is refreshed at round boundaries.The maintainer's instruction for this batch, in this session's chat: 「这个之前是分给各车道开发的,很多已经处理了,你不要重复开发。」 So every stage below is checked against
origin/mainand against in-flight branches and PRs before it is claimed. A dev's first step is to falsify its premises, and a part found done is reported, not rebuilt.Already landed (not part of this batch, not redone)
- C1 feat(objectql,plugin-auth): the Default Organization is load-bearing under
single; an unstamped write is derived there and refused everywhere else (ADR-0131 D3/D9/D11) #15195 and C6 feat(spec,services): deployment-level state has no organization column — settings global rung, plumbing objects, the audit ledger, #12699 made total (ADR-0131 D7) #15207 are closed. - 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 stages S1 feat(core): one by-name read of the security catalog (ADR-0131 C2, stage S1) #22091, S2 feat(plugin-security)!: the six built-in positions are declared position metadata (ADR-0131 C2 stage S2) #22139, S2b fix(plugin-security): the declared-positions seeder reads through the security catalog read (ADR-0131 C2 stage S2b) #22210, S4a feat(plugin-security,plugin-auth,verify): sys_user_permission_set gains the permission-set name column, written by every grant writer (ADR-0131 C2 S4a) #22100, S4b feat(plugin-security): grants stored before the permission-set name column get their name, once, at boot (ADR-0131 C2 S4b) #22143, S5a feat(core,plugin-security,plugin-auth)!: the authorization resolver reads a grant's permission set by name (ADR-0131 D4, C2 stage S5a) #22495, S5b feat(plugin-security,plugin-auth): the grant readers read the permission-set name column (ADR-0131 D4, C2 stage S5b) #22352, S7 feat(plugin-security)!: under single, Setup positions are written through to the environment ledger, and row-only positions are backfilled once (ADR-0131 D3, C2 stage S7) #22388 and S10 feat(plugin-security)!: under single, a Setup position create or rename into a name a package or a built-in holds answers the metadata door's refusal (C2 stage S10) #22582.
- The one-holder and refusal family: feat(objectql)!: positions, permission sets and capabilities hold one name per deployment — a second holder is refused at registration, naming both #22197, feat(objectql)!: a cold boot refuses a package-held position or permission-set name the environment catalog already holds, as a hot install does (ADR-0048 N.3) #22365, fix(plugin-security)!: a package-declared position is refused at the data door, as the metadata door already refuses it #22378, fix(plugin-security)!: a position assignment or permission-set grant scoped to an organization must name a member of it #22275 and fix(objectql): register stack-declared positions under their package so the save door refuses overrides #22262.
- Read on objectstack
origin/main86da194.
Cutover batch (#15204 plan 6094501866)
stage what state 0 catalog-bound module classification; assignment-table names; measured cut in progress (this seat, read-only census). Done here: sys_user_position.positionandsys_user_permission_set.permission_setare name columns on86da1941 PositionSchema.permissionSets+ the resolver reads the registrydispatched: claim 6095611212, cloud dev session_01AGgRrdom7nizSbHc5Gws2U, branchclaude/issue-15204-s1-position-permission-sets2 services readers (S8b), Q (a) same-name refusal waits on 1 3 S9 boot report waits on 2 4 verify/src/rls.tswaits on S5c (#15196, domain:cli, not this lane)5 C9 objectui#7611 + .objectui-shabumpreserved ( pm:epic, 6095619495); dispatched after 1 lands; lands after 2, before 7 and 86a–6c delete the seeders wait on 3 7 retire the projector and both write-throughs waits on 5 and 6 8 retire the four object declarations last T1–Tn test-file deletions each after the code PR it follows Outside the batch, read this round
- C5 feat(metadata-core,metadata-protocol,objectql,plugin-security): the
sys_metadatafamily goes tenant-less; the per-organization overlay axis retires; managed content is sealed (ADR-0131 D6/D7/D13) #15206 (PR feat(metadata-protocol,objectql,rest,spec)!: every metadata read is environment → code; legacy organization rows and sealed overlays are reported at boot, not served (#15206 S5) #22628), in flight. It editspermission-set-projection.ts, which stage 7 deletes, and changes the metadata read scope that stage 1 consumes. Whichever lands second mergesmain. - C7a C7a (ADR-0131 D10, split from #15211): the migration inventory file, the read-only
os migrate --plan, and the design of the ceremony's completion marker #22617 (PR feat(cli): os migrate organization-ownership — the ADR-0131 D10 inventory and the read-only ceremony plan (C7a) #22643), in flight. It designs the fates that C7b applies with stage 1's conversion function. - C4 refactor(plugin-email): templates resolve the registry; the seed and the provenance stamp retire; organization-level editing is closed (ADR-0131 D6/D10) #15205, C7b 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, C8 feat(spec,drivers,objectql,plugin-security):
organization_idNOT NULL per cleared table; one predicate for Layer 0 and every driver; bothorWhereNullarms, the__global__sentinel and the #13491 ledger retire (ADR-0131 D1/D8/D9) — protocol 18 #15212, C11 docs: close out the #13564 family under ADR-0131; supersede #13636; the tenancy docs state the three sentences #15214 and C12 feat(spec,objectql,cli): the template install mode — a package copied once into the environment ledger, fully editable, refused on shared-database multi-tenant postures (ADR-0131 D6) #15213 arepm:blocked. The ADR note docs(adr-0131): §8/D14 execution-plan note — C2's remainder and C3 land as one cutover, C7 splits into C7a/C7b, and C12 moves to the 18.x line (rulings 6094045326, 6094175435, 6094183024) #22619 is in the skills queue. - [Design] Re-anchor platform-admin:
admin_full_accessbecomes a kernel metadata declaration; WHO holds it comes from env-configured verified emails — retiring the org-less row anchor #11663 carriespm:epic, with no session activity since 2026-09-19. It is the platform-admin re-anchor design; stage 6b touchesbootstrap-platform-admin.ts's materialization in its subject area. The overlap is declared only; this seat does not reclaim it (the zombie call is triage's).
- C1 feat(objectql,plugin-auth): the Default Organization is load-bearing under
objectstack-fleet commented
on Oct 10, 2026 ContributorMore actionsEpic status · round 2 · 2026-10-10T13:10Z
Epic PM
session_01Rerax7QTjKMPCUZxQUtPFR(marchtian). This refreshes 6095636190. The usage wall stopped work between about 10:30Z and 12:50Z; every in-flight item was re-read on resume, and none was lost.stage what state 0 census, classification, measured cut done: 6095755866, the cut re-measured and the order corrected 1 PositionSchema.permissionSets+ the resolver reads the registrybuilding: cloud dev session_01AGgRrdom7nizSbHc5Gws2U, branch at7564191e2a, about 2.9k changed lines againstmain; no PR yet2 services readers; the activation door for permission/position;position-catalog-refusalwaits on stage 1's PR 3 S9 boot report ACCEPT (6096484607); draft PR #22671, parked until stage 1 merges (one pending test is enabled then) 4 verify/src/rls.tswaits on S5c (#15196, domain:cli)5 C9, part 1 ACCEPT (objectui 6097840521) after a contract review PASS (6097834214); draft objectui#12089, lands after stage 1; part 2 follows 6b-1a platform capabilities as registry declarations ACCEPT (6096401008); PR #22669 in the merge queue since 12:56Z 6a–6c, 6b-1b, 6c-prep seeder deletions after 2 and 5, per 6095755866 7-pre, 7a, 7b projector and write-through deletions after 5 and 6 new: clone door a server cloneforpermission, per C9's Q1 → A (objectui 6097763840)before 8. Not dispatched: inside the maintainer's veto window 8-pre, 8 row-write gates; retire the four objects last. Stage 8 also waits on #22682 Filed this round: #22682 (
domain:spec,pm:queue): the spec half of C9's Q2 and Q3, catalog references by name in authoring surfaces.Blocked-by: #22682
This
Blocked-by:line is stage 8's, recorded here so the reverse index sees it. The epic itself is not blocked.
Epic PM seated 2026-10-10T08:14Z:
session_01Rerax7QTjKMPCUZxQUtPFR(GitHubmarchtian, writing asobjectstack-fleet[bot]through the relay). The maintainer summoned it as/pm-dispatch epic:#15194, per the director's ruling pointer 6094203467 (batch #310 item 3). This card is the parent of the ADR-0131 tree and carriespm:epicfor the cutover batch below.History: until this edit the body opened with the #15193 gate ("BLOCKED — the v18 development line is not open", with a backticked blocker line). #15193 was closed on the maintainer's word (6037915987), and the v18 line is open. The rest of the record below is unchanged except for one sentence in "Sub-issues", which pointed every card at that gate. Live card states are in this session's status comment, not in the body.
Delegation record
Delegated to this session: the ADR-0131 cutover batch ruled in #22601 → B (record 6094045326) under the three rules of batch #310 (6094179271): one PM runs it; only delete, never fix the retired modules; PRs under 3,000 changed lines where a clean cut exists. The batch is:
singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204, with C2's remaining reader switch folded in (S8a, S8b and S9 of 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);single, read-only under a wall); assignment pages stay data pages; pickers list the registry (objectstack ADR-0131 D3/D7) objectui#7611, which lands before the table-retiring PR;.objectui-shabump, which moves together with C9.The stage plan is on #15204 (6094501866). #22621 → A amends it (6094985249, pointer 6095027530): the metadata door's write authority over the catalog does not change.
Reserved with
pm:epic: #15204 and objectstack-ai/objectui#7611. Other seats do not claim, dispatch or re-route them while this record stands.Not delegated. These stay with their lanes, and the batch orders around them:
domain:cli). 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 keepspm:queuefor it. The batch's stage 4 (verify/src/rls.ts) runs after it.sys_metadatafamily goes tenant-less; the per-organization overlay axis retires; managed content is sealed (ADR-0131 D6/D7/D13) #15206 (in flight,domain:engine).os migrate --plan, and the design of the ceremony's completion marker #22617 (in flight,domain:engine).organization_idNOT NULL per cleared table; one predicate for Layer 0 and every driver; bothorWhereNullarms, the__global__sentinel and the #13491 ledger retire (ADR-0131 D1/D8/D9) — protocol 18 #15212, C11 docs: close out the #13564 family under ADR-0131; supersede #13636; the tenancy docs state the three sentences #15214 and C12 feat(spec,objectql,cli): the template install mode — a package copied once into the environment ledger, fully editable, refused on shared-database multi-tenant postures (ADR-0131 D6) #15213 (allpm:blocked).domain:skills).Declared file territory. Read on objectstack
origin/main86da194and objectuiorigin/main023f00d; the stage that owns each region is named.packages/spec/src/identity/position.zod.ts: thepermissionSetsfield replaces the closed-shape refusal. Its generated baselines come with it (stage 1).packages/core/src/security/:resolve-authz-context.ts,security-catalog.ts, the batch-equivalence golden trace (stage 1), andadmin-standing-surface(stage 8).packages/plugins/plugin-security/src/: the seven seeders,permission-set-projection.ts,position-write-through.ts,per-organization-catalog.ts, the catalog-bound modules stage 0 classifies,delegated-admin-gate.ts,explain-engine, the four object files,manifest.ts, and the boot and registration regions ofsecurity-plugin.tsthat call them (stages 2, 3, 6a–6c, 7, 8).packages/plugins/plugin-sharing/src/:sharing-rule-service.ts's position read (stage 2), andbootstrap-declared-sharing-rules.ts, which stage 0 decides.packages/plugins/plugin-auth/src/: the catalog reads only, inauth-manager,ensure-default-organization,last-admin-guardandauto-org-admin-grant(stage 2).packages/verify/src/rls.ts(stage 4, after S5c).sys_positionandsys_user, and the translations.examples/app-crm/src/security/bind-position-sets.tsandexamples/app-showcase/src/security/bind-position-sets.ts: the bindings move onto the position definitions..objectui-sha.Why the territory is this wide: the batch retires four objects that hundreds of test files and at least ten objectui source files name, so the territory is the measured reader and writer surface. A card from another lane whose fix lands in one of these regions while the batch runs: comment here, and this session names the stage it serializes behind. The territory is declared, not a lock; the merge queue backstops any collision.
Close-out: when #15204 and objectui#7611 are closed, this session posts a summary here, removes
pm:epic, and marks the territory done.Execution tree for ADR-0131 — Total organization ownership: no NULL
organization_id(docs/adr/0131-total-organization-ownership-no-null-organization-id.md, merged via #14976, approved by the maintainer 2026-09-04). §8 of the record is the table these cards are cut from.The three sentences every card in this tree assumes
NOT NULL. References to declared items are by machine name, resolved registry-first.Dependency order
Staging (D14)
Maintainer, 2026-09-04: 「我发 17.3,然后后续这么大的改动应该放到 v18」 and 「我建议18.0 的主要考虑是客户数据变化比较大,而且需要手工执行升级脚本」.
Two cards landed before the 17.3 tag and are not part of this tree: #15024 (
sys_metadata_activationships tenant-less, PR #15155) and #15030 (the NULL-inclusive business-unit screen of #14949 reverted, PR #15078). ⛔ Everything else is one major with one migration. No 17.x card narrows or removes a driver arm, adds a name column beside an id column, or ships half of this record.Open questions the record leaves to the maintainer
ADR-0131 §6 Q1 — what becomes of email-template rows an organization has already customized (
customized: true): kept readable as the Default Organization's overrides, or dropped with a release note. To be ruled when C4 is cut, not before.Sub-issues
The order is the dependency order;
Blocked-by:lines encode it card by card. (Until the epic PM sat, this sentence also said every card carriedpm:blockedbehind #15193. That gate is closed; the epic PM's status comment carries each card's state.)objectql,plugin-authcore,objectql,plugin-security,plugin-sharingplugin-security,platform-objects,specplugin-emailmetadata-core,metadata-protocol,objectql,plugin-securityspec, servicesobjectql,clispec, drivers,objectql,plugin-securityspec,objectql,cliLanded before the 17.3 tag, deliberately outside this tree: #15024 (PR #15155) and #15030 (PR #15078).
Existing cards this tree re-aims
Surveyed 2026-09-04 across the three repositories' open queues at the maintainer's request. Each card named here carries a pointer comment of its own:
ActionParamcarry-over key for a Clone dialog C3 deletes and C9 rebuilds — folded into C9⛔ Not touched, and shipping on their own clock: #14970 / #14971 / #13566 (the p0 cross-tenant webhook family — D7 keeps
sys_http_deliveryandsys_emailtenant data), #14754, #14936, #14937. C1 makes the last three more load-bearing, not less.