|
| 1 | +--- |
| 2 | +"@objectstack/platform-objects": patch |
| 3 | +"@objectstack/core": patch |
| 4 | +"@objectstack/objectql": patch |
| 5 | +"@objectstack/service-automation": patch |
| 6 | +--- |
| 7 | + |
| 8 | +fix(platform-objects,core): `sys_metadata_activation` ships tenant-less — drop the reserved organization column (#15024) |
| 9 | + |
| 10 | +The ADR-0126 activation ledger records that **this environment** switched a |
| 11 | +packaged artifact off. That is deployment-level state, owned by no |
| 12 | +organization — so the table ships with no tenant column at all. |
| 13 | + |
| 14 | +It briefly declared one: an `organization_id` marked "RESERVED", nullable, and |
| 15 | +written by nobody, held for a per-organization dimension ADR-0126 §5 |
| 16 | +pre-charted. A reserved nullable tenant column is exactly the shape the |
| 17 | +total-organization-ownership record proposed in PR #14976 rules out, and this |
| 18 | +one had no reader either. **This is a plain removal, not a migration:** the |
| 19 | +table landed after the 17.2.0 tag, so no released version ever carried the |
| 20 | +column and no deployment has data in it. Should a per-organization dimension |
| 21 | +ever be wanted, it returns as a separate org-owned object — never as a column |
| 22 | +on this ledger. |
| 23 | + |
| 24 | +What changed: |
| 25 | + |
| 26 | +- **`sys_metadata_activation` declares `systemFields: { tenant: false }`** and |
| 27 | + no longer declares the column. Both halves are needed: the tenant anchor is |
| 28 | + INJECTED at registration, so deleting the field alone would have left the |
| 29 | + column exactly where it was. ⚠️ Deliberately NOT `tenancy: { enabled: false }` |
| 30 | + — that key is the ADR-0066 D2 platform-global *posture*, which the sibling |
| 31 | + `sys_sso_provider` uses for the opposite shape (a table that KEEPS its tenant |
| 32 | + column and needs the wall over it stood down). Here there is no column to |
| 33 | + wall. Both spellings reach `plugin-security`'s `tenancyDisabled`, which is |
| 34 | + required rather than incidental: a Layer 0 wall composing an equality on a |
| 35 | + column the table does not have denies every row. |
| 36 | +- **The declared unique index states `unique: 'global'`** over |
| 37 | + `(metadata_type, name)` instead of `'organization'`. ⚠️ The materialized DDL |
| 38 | + is unchanged: `normalizeDeclaredIndex` prepends the NULL-safe tenant key part |
| 39 | + only when the table HAS a tenant column, so `'organization'` already degraded |
| 40 | + to exactly these two columns. What changes is that the declaration now states |
| 41 | + the boundary it actually gets, rather than claiming a per-organization one |
| 42 | + that does not exist. Still explicit rather than bare `unique: true`, which |
| 43 | + lint `unique/unscoped-declared-index` warns on and protocol 18 rejects. |
| 44 | +- **`ObjectStoreMetadataActivationStore` drops its NULL filter and its |
| 45 | + org-row skip.** `list()` is now every activation row of its type, scoped by |
| 46 | + the `metadata_type` discriminator alone, and `setActive` takes the single row |
| 47 | + its keyed read returns instead of picking the NULL-organization one out of |
| 48 | + the result. Both guarded a column that no longer exists; the declared unique |
| 49 | + index over the two columns the lookup keys on is what makes that read |
| 50 | + single-valued. `ObjectStoreFlowActivationStore` and |
| 51 | + `ObjectStoreActionActivationStore` inherit the change. |
| 52 | + |
| 53 | +Unchanged, and pinned: the operator gate on activation writes under walled |
| 54 | +postures (ADR-0126 D3), the `execute()`-time flow consult and the dispatch-time |
| 55 | +action consult, "absence of a row means ACTIVE", re-enabling UPDATES the row |
| 56 | +rather than deleting it, and a driver `0` reading as false. The pins that |
| 57 | +asserted the reserved column and the org-row skip are rewritten to pin the |
| 58 | +column's ABSENCE rather than deleted — including at the injection authority |
| 59 | +(`resolveInjectedSystemColumns`, which decides whether the column exists) and |
| 60 | +in a real booted stack, where the row's key set is a reading of the physical |
| 61 | +table. |
0 commit comments