Skip to content

assertRegistryInvariant

assertRegistryInvariant(registry, spec): void

Defined in: packages/contracts/src/registry-invariant.ts:161

Assert a RegistryInvariantSpec over a registry: for every entry the invariant binds, and every claims fixture, evaluate holds against the entry’s RENDERED read filter and write policies. Pure audit — it renders through the production code paths but changes no runtime behaviour.

Call it at module eval beside the registry (or in a test), the same way assertReadContractPreserved is called, so a violation fails closed rather than shipping.

assertRegistryInvariant(registry, {
name: "private rows are never visible to an anonymous caller",
appliesTo: ["private"],
claimsFixtures: { anonymous: {}, member: { sub: "u-1" } },
holds: ({ fixtureName, renderedWhere }) =>
fixtureName !== "anonymous" || renderedWhere?.where === "false" || "anonymous read is not denied",
});

Two deliberate fail-closed behaviours:

  • An appliesTo class the registry’s declared vocabulary does not contain throws immediately (a typo must not pass as “nothing to check”).
  • An invariant that binds ZERO entries throws. A spec that checks nothing is a bug in the spec — nearly always a wrong class name or an invariant left behind after its class was renamed — and silently passing is the exact failure mode this whole mechanism exists to remove.

Every failing cell is collected and reported together: the header names the invariant, then one entry (fixture): reason line per violation. Never first-failure-only — you fix a classification-wide problem in one pass, not one re-run per entry.

SyncTableRegistry

RegistryInvariantSpec

void