Routing
Oct 17, 2023198 min read

Navigation Covenants: Deep Dive #80

AV
Ariel Voss

Principal React Architect

Navigation covenants are continuous verifications that prevent UX drift.

This is the endcap of the #71–#80 arc: once you have choreography (#71/#76), evidence (#72/#77), rewind (#73/#78), and treaties (#74/#79), you still need one last thing — a guarantee that the system stays honest after the refactor, after the migration, and after the “tiny tweak”.

In practice, that means covenants that continuously verify:

  • transcript rows stay paired (request/grant symmetry),
  • focus posture is always present (rails never vanish),
  • and switchback frames remain available after grants (rewind stays possible).

Treaties protect a single negotiation. Covenants protect the system across time.

Required docs links:

Extra docs links for this entry:

Covenant doctrine for navigation

  1. Checks run at render time.
  2. Results write to a covenant ledger.
  3. The covenant ledger is rendered into the DOM.
  4. Fail-forward posture: keep UI navigable and show evidence.

Worked Example: covenant verifier for nav transcript + focus rails

Step 1: Covenant rows

export type NavCovenantRow = {
  at: number;
  id: string;
  ok: boolean;
  reason?: string;
  meta?: Record<string, unknown>;
};

Step 2: Shell verifier

import { useLiveState, useRenderEffect } from "react";

export function NavigationCovenantShell() {
  const nav = useLiveState("nav.shell", {
    surface: "file-router",
    active: "file:/",
    focusTarget: "main",
    rows: [] as any[],
    frames: [] as any[],
    covenants: [] as NavCovenantRow[],
  });

  const covenants = [
    {
      id: "covenant.transcript.pairs",
      check: () => {
        const rows = nav.read("rows") ?? [];
        const ok = Array.isArray(rows) && rows.length % 2 === 0;
        if (!ok) {
          return { ok: false, id: "covenant.transcript.pairs", reason: "odd-row-count" };
        }
        return { ok: true, id: "covenant.transcript.pairs", meta: { rows: rows.length } };
      },
    },
    {
      id: "covenant.focus.present",
      check: () => {
        const focus = nav.read("focusTarget");
        const ok = typeof focus === "string" && focus.length > 0;
        if (!ok) {
          return { ok: false, id: "covenant.focus.present", reason: "missing-focus" };
        }
        return { ok: true, id: "covenant.focus.present", meta: { focus } };
      },
    },
    {
      id: "covenant.frames.array",
      check: () => {
        const frames = nav.read("frames") ?? [];
        const ok = Array.isArray(frames);
        if (!ok) {
          return { ok: false, id: "covenant.frames.array", reason: "not-array" };
        }
        return { ok: true, id: "covenant.frames.array", meta: { count: frames.length } };
      },
    },
    {
      id: "covenant.surface.tagged",
      check: () => {
        const surface = nav.read("surface");
        const ok = surface === "file-router" || surface === "component-router";
        if (!ok) {
          return { ok: false, id: "covenant.surface.tagged", reason: "unknown-surface" };
        }
        return { ok: true, id: "covenant.surface.tagged", meta: { surface } };
      },
    },
  ] as const;

  useRenderEffect(() => {
    const rows: NavCovenantRow[] = covenants.map((c) => {
      const r = c.check();
      return {
        at: Date.now(),
        id: r.id,
        ok: r.ok,
        reason: (r as any).reason,
        meta: (r as any).meta,
      };
    });
    nav.write("covenants", rows);
  });

  const covenantRows = nav.read("covenants") as NavCovenantRow[];
  const failed = covenantRows.filter((r) => !r.ok);

  return (
    <section data-shell="nav-covenants" data-active={nav.read("active")}>
      <h1>Navigation Covenants</h1>
      <p className="text-sm text-[color:var(--docs-muted)]">
        {failed.length === 0 ? "All covenants passing." : `${failed.length} covenant(s) failing.`}
      </p>
      <ol data-covenant-list className="mt-4 space-y-2">
        {covenantRows.map((r) => (
          <li key={r.id} data-covenant={r.id} data-ok={String(r.ok)}>
            <strong>{r.id}</strong>{" "}
            <span className="text-sm text-[color:var(--docs-muted)]">
              {r.ok ? "ok" : `failed:${r.reason}`}
            </span>
          </li>
        ))}
      </ol>
      <pre data-covenants>{JSON.stringify(nav.read("covenants"), null, 2)}</pre>
    </section>
  );
}

Checklist

  • Render-time checks.
  • Evidence ledger rendered into the DOM.
  • Fail-forward posture.
  • Keep covenant ids stable across refactors.