|
| 1 | +--- |
| 2 | +'@objectstack/objectql': patch |
| 3 | +'@objectstack/runtime': patch |
| 4 | +'@objectstack/plugin-dev': patch |
| 5 | +'@objectstack/driver-sql': patch |
| 6 | +'@objectstack/cli': patch |
| 7 | +'@objectstack/cloud-connection': patch |
| 8 | +--- |
| 9 | + |
| 10 | +fix(tenancy): eight sites answered "is this deployment multi-org?" with the demoted `OS_MULTI_ORG_ENABLED` (#5262) |
| 11 | + |
| 12 | +ADR-0105 D1 made `OS_TENANCY_POSTURE` the authoritative knob and demoted |
| 13 | +`OS_MULTI_ORG_ENABLED` to a back-compat *input* of `resolveTenancyPosture()`. |
| 14 | +A deployment configured the documented way — `OS_TENANCY_POSTURE=isolated` (or |
| 15 | +`group`), legacy boolean unset — therefore reads `false` from |
| 16 | +`resolveMultiOrgEnabled()` while running a fully mounted organization wall. |
| 17 | +#5233 corrected two sites in `plugin-auth`; a census found eight more, all |
| 18 | +written before that function's doc comment was corrected. Third recurrence of |
| 19 | +the shape (cloud#1020, #5233). |
| 20 | + |
| 21 | +Each site was judged separately for **which** posture answers its question — |
| 22 | +what the operator REQUESTED, or what the `tenancy` service reports is actually |
| 23 | +IN FORCE — rather than converted mechanically: |
| 24 | + |
| 25 | +- `objectql` `SchemaRegistry` — the env-derived multi-tenant default. Reads the |
| 26 | + REQUESTED posture (it is constructed below the kernel, with no service |
| 27 | + registry to ask). The `organization_id` column was always provisioned; what |
| 28 | + diverged is its INDEX, so a posture-only deployment ran the Layer 0 wall's |
| 29 | + hottest predicate unindexed while SecurityPlugin compiled that same wall. |
| 30 | +- `plugin-dev` — whether to load the enterprise `@objectstack/organizations`. |
| 31 | + REQUESTED posture, mirroring `serve.ts`: this branch is what mounts the wall, |
| 32 | + so asking whether the wall is up would be circular. A posture-only dev stack |
| 33 | + previously never loaded the package at all and served traffic unwalled. Its |
| 34 | + diagnostic now names the posture that was requested instead of asserting |
| 35 | + `OS_MULTI_ORG_ENABLED=true` at an operator who never set it. |
| 36 | +- `runtime` `AppPlugin` (inline seed + hot-reload seeder) — EFFECTIVE posture, |
| 37 | + via the `tenancy` service. These ask "will the per-org replay run instead of |
| 38 | + me?", and on an ADR-0093 D5 degraded boot that replay does not exist, so |
| 39 | + keying on the request would defer to a replay that can never happen. Walled |
| 40 | + deployments previously inline-seeded exactly the NULL-organization rows the |
| 41 | + code's own comment exists to avoid. |
| 42 | +- `cloud-connection` marketplace local install (install-time seed + rehydrate |
| 43 | + heal) — EFFECTIVE posture, same reasoning. The install path is a write path: |
| 44 | + a walled deployment wrote every sample row with no `organization_id`, landing |
| 45 | + the app's data outside the wall its own reads apply. |
| 46 | +- `driver-sql` `isMultiTenantMode()` — REQUESTED posture (a driver has no |
| 47 | + kernel to ask, and a suppressed warning is the costlier error for a |
| 48 | + diagnostic). It also no longer memoises into `_multiTenantMode`: that froze a |
| 49 | + process-level fact into a per-instance verdict on whichever write landed |
| 50 | + first. The gate now resolves live, which is affordable because |
| 51 | + `auditMissingTenant` consults it only after the `tenantId` early-out. |
| 52 | +- `cli` `os verify` — REQUESTED posture. This one produced a green verification |
| 53 | + run over an unverified property: a posture-only deployment silently skipped |
| 54 | + every multi-tenant proof and exited 0. |
| 55 | + |
| 56 | +**No configuration change is needed anywhere.** Deployments setting only |
| 57 | +`OS_MULTI_ORG_ENABLED=true` keep working unchanged — `resolveTenancyPosture()` |
| 58 | +falls back to it — and the `OS_TENANCY_POSTURE=isolated` + `OS_MULTI_ORG_ENABLED=true` |
| 59 | +belt-and-braces configuration stays valid. Deployments that set only |
| 60 | +`OS_TENANCY_POSTURE` can now drop the redundant boolean. Single-org behaviour is |
| 61 | +unchanged at every site; only the knob each one reads is corrected. |
0 commit comments