Commit 4b3955e
fix(objectql): a published BulkDataEvent names the one organization the tenant wall named for the batch (#15687)
* fix(objectql): a published BulkDataEvent names the one organization the tenant wall named for the batch
The bulk producer (`publishBulkDataEvent`, behind the predicate `update()` /
`delete()` branches) never set `BulkDataEventSchema.organizationId`, so every
`data.records.*` event read "not asserted" on the bulk path — the remaining half
of the cross-tenant webhook fan-out leak. It now stamps the key from what it
already holds (the execution context the Layer 0 wall was computed from, and the
posture SecurityPlugin injected), with no second query: present under
`isolated` (active organization) and singleton-membership `group`; omitted for
`single`, `isSystem`, multi-membership `group`, non-walled objects, no injected
posture, a PLATFORM_ADMIN rung or no rung. The value coercion is shared with the
per-record helper (one ladder, two readers). Pins in engine-data-events.test.ts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
* test(objectql): pin the tenancy opt-out case on a declared `tenancy.enabled: false` object
A registered object gets the kernel `organization_id` column injected, and the
security plugin walls on that same injected field set, so `task` is not a
"not tenant-scoped" fixture. The pin now uses the declared opt-out and measures
that the column was withheld before asserting the key is omitted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
* docs(permissions): census the bulk-event `organizationId` omission as `isSystem` read site 107
The bulk producer's new `isSystem` read (no wall composed for a system write,
so no batch organization is asserted) is an elevation behaviour the
system-context page must anchor. Row 30 names it; rows 30-65 renumber to 31-66
with their prose cross-references; the six census-derived counts move 106 -> 107
(property reads 112 -> 113). `--fix` re-anchored the 15 engine.ts lines the
insertion shifted and refused zero files once the row existed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
* fix(objectql): the bulk-event object exit is the wall's own predicate, not a re-spelling of one of its clauses
Patch round R2 on the contract review of PR #15687 (items 1, 3, 4, 5, 7; item 6
re-judged). `bulkEventOrganizationId` answered its object exit with
`resolveTenantFieldName(schema) !== DEFAULT_TENANT_FIELD`, which mirrors ONE of
the clauses Layer 0 folds into `tenancyDisabled`; an object declaring
`systemFields.tenant: false` beside its own `organization_id` composes NO wall
in plugin-security and was still stamped with the caller's organization — a
mislabel (the reviewer's P1). The exit now reads `carriesTenantScopeColumn`,
the registry's binding of the wall's predicate (exported at module level only;
`dist/index.d.ts`, `dist/core.d.ts` and both entries' runtime export lists are
unchanged, measured with a firing control), beside the `external != null`
superset of the phantom-anchor rule. A custom `tenancy.tenantField` is no
longer an exit by itself: the key follows the wall, present iff the object
carries `organization_id`.
Pins: the P1 fixture (absent, matched 3); a federated object (absent); a custom
`tenancy.tenantField` with the kernel column (present) and without it (absent);
and the no-enforcement-layer pin now sets OS_TENANCY_POSTURE=isolated in the
env and still expects omission, so the env-fallback exclusion is pinned by a
test that goes red under the substitution the review measured green.
JSDoc, changeset and the census page name which `tenancyDisabled` clauses the
engine mirrors and which the seam carries; the census re-anchor rewrote 16
anchors and refused zero, population 107 unchanged. Level stays `patch`: no
member reaches this package's published surface.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
* docs(permissions): re-anchor census row 51 on the merged tree
Discharges the os-regen deferral recorded by the merge of origin/main
(5315098): the driver kept this branch's side of the MIXED census page
whole, dropping main's five rest-server.ts anchor moves on row 51 (main's
row 50), and `pnpm gen:system-context-census` re-derives exactly those
five numbers from the merged tree. Population unchanged at 107 in 20
packages across 45 files; a second `--fix` rewrites 0 and refuses 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 54bb2f1 commit 4b3955e
5 files changed
Lines changed: 803 additions & 66 deletions
File tree
- .changeset
- content/docs/permissions
- packages/objectql/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
0 commit comments