Routing
Sep 12, 2023208 min read
Route Covenants: Deep Dive #75
AV
Ariel Voss
Principal React Architect
Treaties keep a single transition honest. Covenants keep the system honest over time.
Treaties are negotiated in the moment. Covenants are enforced continuously.
If you’ve ever shipped a refactor that “didn’t touch routing” and still broke routing, you’ve met the problem covenants solve: drift. Drift happens when the system’s guarantees live in people’s heads instead of in a verifiable surface.
A route covenant is an ongoing obligation that must remain true across:
- refactors,
- feature additions,
- performance work,
- and migrations between routing surfaces.
Required docs links:
Extra docs links for this entry:
Covenant doctrine
- Covenants are verifiable checks with stable ids.
- Verification runs at render time (continuous).
- Results are written to a covenant ledger.
- The ledger is rendered into the DOM (evidence-first).
- Posture is fail-forward: render evidence rather than throwing.
Worked Example: covenant registry + verifier for the Invoice Explorer
We'll define covenants that protect our routing system:
- transcripts exist and are renderable
- detail track has at least one switchback frame (safety rail)
- treaty grants remain visible in the shell ledger (
lastTreatyGrant)
Step 1: Covenant shapes
export type CovenantResult =
| { ok: true; id: string; meta?: Record<string, unknown> }
| { ok: false; id: string; reason: string; meta?: Record<string, unknown> };
export type CovenantCheck = (ctx: {
shell: any;
routeId: string;
track: "summary" | "detail";
}) => CovenantResult;
export type CovenantRow = {
at: number;
id: string;
ok: boolean;
reason?: string;
meta?: Record<string, unknown>;
};
Step 2: Registry
export function createCovenantRegistry() {
const checks = new Map<string, CovenantCheck>();
function register(id: string, check: CovenantCheck) {
checks.set(id, check);
return id;
}
function list() {
return [...checks.entries()].map(([id, check]) => ({ id, check }));
}
return { register, list };
}
Step 3: Verifier (writes evidence into the shell ledger)
export function verifyCovenants(registry: ReturnType<typeof createCovenantRegistry>, shell: any) {
const routeId = shell.read("routeId");
const track = shell.read("track");
const rows: CovenantRow[] = registry.list().map(({ id, check }) => {
const result = check({ shell, routeId, track });
return {
at: Date.now(),
id,
ok: result.ok,
reason: (result as any).reason,
meta: result.meta,
};
});
shell.write("covenants", rows);
return rows;
}
Step 4: Define covenants
export function registerInvoiceCovenants(registry: ReturnType<typeof createCovenantRegistry>) {
registry.register("covenant.transcript.present", ({ shell }) => {
const rows = shell.read("transcript");
const ok = Array.isArray(rows);
if (!ok) {
return { ok: false, id: "covenant.transcript.present", reason: "missing" };
}
return { ok: true, id: "covenant.transcript.present", meta: { rows: rows.length } };
});
registry.register("covenant.detail.switchback.available", ({ track, shell }) => {
if (track !== "detail") {
return {
ok: true,
id: "covenant.detail.switchback.available",
meta: { skipped: true },
};
}
const frames = shell.read("switchbacks") ?? [];
const ok = Array.isArray(frames) && frames.length > 0;
if (!ok) {
return { ok: false, id: "covenant.detail.switchback.available", reason: "none" };
}
return {
ok: true,
id: "covenant.detail.switchback.available",
meta: { frames: frames.length },
};
});
registry.register("covenant.params.normalized", ({ shell }) => {
const params = shell.read("params") ?? {};
const ok = typeof params === "object" && params !== null;
if (!ok) {
return { ok: false, id: "covenant.params.normalized", reason: "not-object" };
}
return {
ok: true,
id: "covenant.params.normalized",
meta: { keys: Object.keys(params).length },
};
});
// Treaty covenants: make the grant itself an inspectable surface.
registry.register("covenant.treaty.grant.visible", ({ shell }) => {
const grant = shell.read("lastTreatyGrant");
const ok = Boolean(grant);
if (!ok) return { ok: false, id: "covenant.treaty.grant.visible", reason: "missing" };
return { ok: true, id: "covenant.treaty.grant.visible", meta: { hasGrant: true } };
});
}
Step 5: Shell integration (verify at render time; render ledger)
import { useLiveState, useRenderEffect } from "react";
export function InvoiceCovenantShell() {
const shell = useLiveState("invoice.shell", {
routeId: "file:/invoices/[invoiceId]",
track: "detail",
params: { invoiceId: "92" },
transcript: [],
switchbacks: [],
covenants: [],
});
const registry = createCovenantRegistry();
registerInvoiceCovenants(registry);
useRenderEffect(() => {
verifyCovenants(registry, shell);
});
return (
<section data-shell="invoice-covenants">
<h1>Route Covenants</h1>
<p className="text-sm text-[color:var(--docs-muted)]">
Covenants run continuously. If something drifts, you’ll see it here
before users feel it.
</p>
<pre data-covenants>{JSON.stringify(shell.read("covenants"), null, 2)}</pre>
</section>
);
}
Testing covenants (DOM is the truth surface)
Treat covenant output like transcript output: render it, inspect it, and assert it.
export function assertCovenantOk(root: HTMLElement, id: string) {
const pre = root.querySelector("[data-covenants]") as HTMLElement | null;
if (!pre) throw new Error("missing covenants surface");
const rows = JSON.parse(pre.textContent ?? "[]") as Array<{ id: string; ok: boolean }>;
const row = rows.find((r) => r.id === id);
if (!row) throw new Error(`missing covenant:${id}`);
if (!row.ok) throw new Error(`covenant failed:${id}`);
}
Checklist
- Verifiable checks with stable ids.
- Render-time verification.
- Evidence written to and rendered from the covenant ledger.
- Fail-forward posture.