Skip to content

Runtime Invariant Checker - Usage Examples

This document shows how to use the runtime invariant checker in your z0 code.

import { assertInvariant } from '@/platform/lib/invariants';
function createFact(data: any): Fact {
// Assert basic invariants
assertInvariant(
data.type !== undefined,
'Fact must have a type',
'FACT_TYPE_REQUIRED'
);
assertInvariant(
data.timestamp > 0,
'Fact timestamp must be positive',
'FACT_TIMESTAMP_POSITIVE',
{ timestamp: data.timestamp }
);
// ... rest of implementation
}
import { InvariantChecker } from '@/platform/lib/invariants';
async function appendChargeFact(charge: Fact, outcomeId: string): Promise<Fact> {
// Fetch the outcome this charge references
const outcome = await getFactById(outcomeId);
// Verify charge traceability invariant
InvariantChecker.verifyChargeTraceability(charge, outcome);
// Verify temporal ordering
InvariantChecker.verifyChargeTemporalOrdering(charge, outcome);
// Append the fact
return await ledger.appendFact(charge);
}
// In EntityLedger.ts
protected async appendFact(fact: any): Promise<any> {
await this.ensureInitialized();
const id = fact.id ?? crypto.randomUUID();
const timestamp = fact.timestamp ?? Date.now();
const completeFact = { ...fact, id, timestamp };
// ✅ VERIFY INVARIANTS BEFORE STORING
await InvariantChecker.verifyFactInvariants(completeFact, {
entity: this.getEntity(),
sourceFact: fact.source_id ? this.getFactById(fact.source_id) : null,
});
// Store fact
const dataBlob = JSON.stringify(completeFact);
this.sql.exec(
`INSERT INTO facts (id, type, subtype, timestamp, tenant_id, source_id, entity_id, trace_id, external_source, external_id, data)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
completeFact.id,
completeFact.type,
completeFact.subtype ?? null,
completeFact.timestamp,
completeFact.tenant_id,
completeFact.source_id ?? null,
completeFact.entity_id ?? null,
completeFact.trace_id ?? null,
completeFact.external_source ?? null,
completeFact.external_id ?? null,
dataBlob
);
await this.updateCachedState(completeFact);
await this.executeHooks(completeFact);
await this.scheduleReplication();
return completeFact;
}
// In EntityLedger.ts
protected createConfig(config: any): any {
const now = Date.now();
const newConfig = { ...config, version: 1, effective_at: now };
// ✅ VERIFY CONFIG INVARIANTS
InvariantChecker.verifyConfigInvariants(newConfig, {
entity: this.getEntity(),
allConfigs: this.getAllConfigs(), // Get all configs to check uniqueness
});
this.sql.exec(
`INSERT INTO configs (id, version, type, category, name, applies_to, scope, settings, effective_at, superseded_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
newConfig.id,
newConfig.version,
newConfig.type,
newConfig.category,
newConfig.name,
newConfig.applies_to,
newConfig.scope,
JSON.stringify(newConfig.settings),
newConfig.effective_at,
null
);
return newConfig;
}
// In src/platform/api/facts.ts
import { InvariantChecker, InvariantViolation } from '@/platform/lib/invariants';
export async function createFact(request: Request, env: Env): Promise<Response> {
try {
const factData = await request.json();
// Validate basic structure
if (!factData.type || !factData.entity_id) {
return Response.json({ error: 'Missing required fields' }, { status: 400 });
}
// ✅ VERIFY ECONOMIC INVARIANTS
InvariantChecker.verifyEconomicTenantId(factData);
InvariantChecker.verifyAmountCurrency(factData);
InvariantChecker.verifyMoneyFlow(factData);
// Create the fact
const fact = await ledger.appendFact(factData);
return Response.json(fact, { status: 201 });
} catch (error) {
// ✅ HANDLE INVARIANT VIOLATIONS
if (error instanceof InvariantViolation) {
console.error('[Invariant Violation]', {
invariant: error.invariant,
message: error.message,
context: error.context,
});
return Response.json(
{
error: 'Invariant violation',
invariant: error.invariant,
message: error.message,
context: error.context,
},
{ status: 400 }
);
}
throw error;
}
}
async function createCharge(
outcomeId: string,
amount: number,
currency: string
): Promise<Fact> {
// Fetch the outcome
const outcome = await getFactById(outcomeId);
// Create charge fact
const charge: Fact = {
id: generateId('fact_'),
type: 'charge',
subtype: 'incurred',
timestamp: Date.now(),
tenant_id: outcome.tenant_id,
source_id: outcomeId,
entity_id: outcome.entity_id,
amount,
currency,
from_entity: outcome.entity_id,
data: {},
};
// ✅ VERIFY ALL CHARGE INVARIANTS
InvariantChecker.verifyChargeTraceability(charge, outcome);
InvariantChecker.verifyChargeTemporalOrdering(charge, outcome);
InvariantChecker.verifyEconomicTenantId(charge);
InvariantChecker.verifyAmountCurrency(charge);
InvariantChecker.verifyMoneyFlow(charge);
return await ledger.appendFact(charge);
}
async function recordCost(
invocationId: string,
amount: number,
vendorId: string
): Promise<Fact> {
const invocation = await getFactById(invocationId);
const cost: Fact = {
id: generateId('fact_'),
type: 'cost',
timestamp: Date.now(),
tenant_id: invocation.tenant_id,
source_id: invocationId,
entity_id: invocation.entity_id,
amount,
currency: 'USD',
to_entity: vendorId,
data: { vendor_id: vendorId },
};
// ✅ VERIFY COST INVARIANTS
InvariantChecker.verifyCostTraceability(cost, invocation);
InvariantChecker.verifyCostTemporalOrdering(cost, invocation);
return await ledger.appendFact(cost);
}
import { VerifyInvariants } from '@/platform/lib/invariants';
class FactService {
@VerifyInvariants((fact: Fact) => {
InvariantChecker.verifyEconomicTenantId(fact);
InvariantChecker.verifyAmountCurrency(fact);
})
async createFact(data: any): Promise<Fact> {
// Implementation
return await ledger.appendFact(data);
}
}
// In tests
import { InvariantChecker, InvariantViolation } from '@/platform/lib/invariants';
describe('Charge Creation', () => {
it('should throw InvariantViolation if charge lacks outcome', async () => {
const charge = createChargeFixture(entityId, 'nonexistent_outcome', 5000);
await expect(async () => {
InvariantChecker.verifyChargeTraceability(charge, null);
}).rejects.toThrow(InvariantViolation);
});
it('should throw InvariantViolation if outcome timestamp > charge timestamp', async () => {
const outcome = createOutcomeFixture(entityId, invocationId);
outcome.timestamp = Date.now() + 10000; // Future timestamp
const charge = createChargeFixture(entityId, outcome.id, 5000);
charge.timestamp = Date.now();
await expect(async () => {
InvariantChecker.verifyChargeTemporalOrdering(charge, outcome);
}).rejects.toThrow(InvariantViolation);
});
});

You can enable/disable invariant checking based on environment:

// In env.ts or config
export const ENABLE_INVARIANT_CHECKS = process.env.NODE_ENV !== 'production';
// Wrapper function
export function checkInvariant(fn: () => void): void {
if (ENABLE_INVARIANT_CHECKS) {
fn();
}
}
// Usage
checkInvariant(() => {
InvariantChecker.verifyChargeTraceability(charge, outcome);
});
import { InvariantViolation } from '@/platform/lib/invariants';
try {
InvariantChecker.verifyFactInvariants(fact, { entity, sourceFact });
} catch (error) {
if (error instanceof InvariantViolation) {
// Log to observability system
console.error('[INVARIANT_VIOLATION]', {
timestamp: Date.now(),
invariant: error.invariant,
message: error.message,
context: error.context,
stack: error.stack,
});
// Send to monitoring (e.g., Sentry, Datadog)
// monitoringService.captureException(error);
// Optionally re-throw or handle gracefully
throw error;
}
}
  1. Check Early: Verify invariants as early as possible (at API boundaries, before DB writes)
  2. Be Specific: Include context in assertions to aid debugging
  3. Fail Fast: Don’t continue execution if an invariant is violated
  4. Log Everything: Always log invariant violations for observability
  5. Test Violations: Write tests that verify invariants are enforced
  6. Document: Reference the invariant name from INVARIANTS.md in your code

Invariant checking has overhead. Consider:

  • Development: Enable all checks
  • Staging: Enable all checks
  • Production: Enable critical checks only, or use sampling
const CRITICAL_INVARIANTS = ['CHARGE_TRACEABILITY', 'COST_TRACEABILITY', 'FACT_IMMUTABILITY'];
function shouldCheckInvariant(invariant: string): boolean {
if (process.env.NODE_ENV === 'development') return true;
if (process.env.NODE_ENV === 'staging') return true;
return CRITICAL_INVARIANTS.includes(invariant);
}

The runtime invariant checker provides:

  • Type-safe assertions for all 7 invariant categories
  • Detailed error messages with context
  • Composite verification methods for common patterns
  • Decorator support for automatic checking
  • Integration points for API, ledger, and business logic

Use it to enforce the formal constraints defined in INVARIANTS.md at runtime.