⛔ BLOCKED — the v18 development line is not open.
Blocked-by: #15193
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. In a single-tenant deployment the one organization must exist before anyone writes anything, because from now on every row has an owner; a write that arrives without an organization is refused in every posture, and only single-tenant can derive the owner.
Scope. (1) ensureDefaultOrganization (packages/plugins/plugin-auth/src/ensure-default-organization.ts) becomes a boot invariant under single: failure is a boot error, not a best-effort warning; it runs before application seed datasets load (SeedLoaderService.load, packages/metadata-protocol/src/seed-loader.ts) and before the first authenticated request — today seeds land during start() and the organization is created by a later sign-up, so a first boot's business seeds (and every sys_business_unit seed, #14547) land NULL. (1b) The seed loader's exemption of sys_ / cloud_ / ai_ seeds from organization stamping (fallbackOrgId never applied to platform seeds) is withdrawn: there are no platform-global seeds left; every seed row is stamped with the resolved organization or the load refuses (D9). seed-tenancy-backfill.ts becomes the attribution path for existing first-boot residue (C7). (2) resolveSystemInsertOrganization (packages/objectql/src/tenancy/system-write-organization.ts): derived only when exactly one organization exists (single), refused otherwise, in every posture; the unclassified branch and the isPlatformObjectOutOfTenantAuditScope gate are bypassed for objects carrying the column (C8 removes them outright). Message per ADR-0123 D4. (3) ⛔ No default to any other owner — the "platform organization" was considered and rejected in ADR-0131 §5.
Collision to read before starting: #11973 (platform-admin re-anchor L3) re-points the same ensure-default-organization function and moves the same trigger. Its re-pointing half is absorbed here; its last-admin-guard re-pricing half is not and stays on that card. Read it first and say in the PR body which half you found already done.
Acceptance. Fresh single boot: the Default Organization is present before the HTTP listener accepts, and an isSystem insert on a tenant-column object with no organization lands stamped with it. Fresh isolated / group boot: the same insert is refused with a message naming the missing organization — positive control: the identical insert carrying tenantId succeeds.
⛔ Stop and report rather than proceeding: touching applyTenantScope (C8 owns it); editing any seeder (C3 owns them).
Refs: ADR-0131 D3, D9, D11 · ADR-0093 · ADR-0123 D2–D4 · #8844 · #14547.
⛔ BLOCKED — the v18 development line is not open.
Blocked-by: #15193Part 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. In a single-tenant deployment the one organization must exist before anyone writes anything, because from now on every row has an owner; a write that arrives without an organization is refused in every posture, and only single-tenant can derive the owner.
Scope. (1)
ensureDefaultOrganization(packages/plugins/plugin-auth/src/ensure-default-organization.ts) becomes a boot invariant undersingle: failure is a boot error, not a best-effort warning; it runs before application seed datasets load (SeedLoaderService.load,packages/metadata-protocol/src/seed-loader.ts) and before the first authenticated request — today seeds land duringstart()and the organization is created by a later sign-up, so a first boot's business seeds (and everysys_business_unitseed, #14547) land NULL. (1b) The seed loader's exemption ofsys_/cloud_/ai_seeds from organization stamping (fallbackOrgIdnever applied to platform seeds) is withdrawn: there are no platform-global seeds left; every seed row is stamped with the resolved organization or the load refuses (D9).seed-tenancy-backfill.tsbecomes the attribution path for existing first-boot residue (C7). (2)resolveSystemInsertOrganization(packages/objectql/src/tenancy/system-write-organization.ts):derivedonly when exactly one organization exists (single),refusedotherwise, in every posture; theunclassifiedbranch and theisPlatformObjectOutOfTenantAuditScopegate are bypassed for objects carrying the column (C8 removes them outright). Message per ADR-0123 D4. (3) ⛔ No default to any other owner — the "platform organization" was considered and rejected in ADR-0131 §5.Collision to read before starting: #11973 (platform-admin re-anchor L3) re-points the same
ensure-default-organizationfunction and moves the same trigger. Its re-pointing half is absorbed here; itslast-admin-guardre-pricing half is not and stays on that card. Read it first and say in the PR body which half you found already done.Acceptance. Fresh
singleboot: the Default Organization is present before the HTTP listener accepts, and anisSysteminsert on a tenant-column object with no organization lands stamped with it. Freshisolated/groupboot: the same insert is refused with a message naming the missing organization — positive control: the identical insert carryingtenantIdsucceeds.⛔ Stop and report rather than proceeding: touching
applyTenantScope(C8 owns it); editing any seeder (C3 owns them).Refs: ADR-0131 D3, D9, D11 · ADR-0093 · ADR-0123 D2–D4 · #8844 · #14547.