Skip to content

Commit f2d4371

Browse files
cemililikclaude
andcommitted
fix(tenancy): make the isolation cases assert what their names claim
Round 1 of Step 11's review, and the finding was that three of the five cases tested something other than their name — one of them nothing at all. Write_With_Foreign_TenantId_Is_Rejected_By_WithCheck performed no INSERT. It asserted that an anonymous POST failed, which a 404 satisfies, so it passed against a DELETED endpoint and against a database with every policy dropped. It now issues the INSERT on the ambient connection, naming a tenant other than the announced one, and asserts the 42501 that WITH CHECK raises. Raw SQL deliberately: a write through EF carries the filter's tenant and could never name a foreign one. Org_X_cannot_read_Org_Y read `organizations`, which is the tenant-WIDE class — within a tenant every organization is visible to every other, by design — and the narrowing came from a Where the probe handler wrote itself. It now reads `tenant_settings`, the organization-scoped class, and narrows nothing. TenantWide_Row_Of_TenantB_Is_Invisible_To_TenantA read `platform_host_to_tenant`, which is platform-scoped and whose policy has no organization term, so it named the wrong mechanism entirely. It now reads the row shape the superseded template actually leaked: tenant-owned, organization_id IS NULL. Unsetting_tenant_context never reached a handler or read a table — it duplicated an existing 404-parity assertion more weakly. It now runs a tenant-owned SELECT under a PlatformHost request, which is the only way to put a real query in front of an unresolved context. The remark about what the suite constrains was half a measurement. Deleting both query filters leaves all five green because RLS holds; disabling RLS leaves the four reads green because the filters hold; removing both turns all five red. Both directions are now recorded, along with the write case being the one that observes a policy alone. Also: the file moved under Database/, where Standards 06 puts Docker-bound tests and where the trait guard can see it; the probe returns ToActionResult() so a refusal is a status rather than a 200 with an empty body; and two Packet 7 comments the sweep missed. Module: Tenancy ADR: 0003, 0036 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent a7bab71 commit f2d4371

3 files changed

Lines changed: 583 additions & 428 deletions

File tree

0 commit comments

Comments
 (0)