Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/nornir

.nornir/autonom.md

autonom — the self-discovering completeness gate (design + guide)

autonom is the autonomous, self-discovering test-matrix framework. It turns the C6 nornir test results recorder into a PROVABLE completeness gate: green ⟺ every surface is wired and works. Reusable across all nordisk (engine in nornir-testmatrix). Forged 2026-06-14 with Rickard. Plan: nordisk_plan.md EPIC AUTONOM (AUT1…AUT8).

1. The problem it kills

A results matrix only records the tests you happen to run, so an unwired surface ships green — e.g. the 🧪 Test tab showed Test.Results RPC TODO in thin mode while every test passed, and Rickard found it by hand. The #1 recurring failure. autonom makes that impossible: the matrix discovers its own surface from the code (never a hand-maintained list, which drifts) and fails the build when any discovered surface has no covering, asserting test.

2. The completeness equation

Surface = every fn/tab/cmd/tool in {viz(thin+fat), CLI, MCP, core fns}      ← discovered, not listed
Covered = every surface reached by an inject-assert test                     ← from call_edges / tools/list / registry
Gap     = Surface − Covered − Allowlist
GATE: Gap == ∅   (else the build/release fails, and the gap is shown in viz + CLI)

3. Discovery — no hand lists (the anti-drift core)

Generalize the proven MCP gate (tests/support/mcp_harness.rs already self-discovers 56 tools over tools/list and fails on any uncovered tool — "no silent gaps") to the whole surface:

surface enumerator (read via nornir MCP, never grep)
facett components {T : impl Facet for T} ∩ registry() (the discovery contract)
viz tabs the tab enum × {thin, fat}
CLI clap subcommand introspection
MCP tools tools/list (done — the template)
functions symbol_facts − test-reachable-closure(call_edges)

4. The thin/fat axis (the key the old matrix missed)

Every data surface has two entrypoints — load() (fat/embedded) and fetch_*() (thin/RPC). Both must be covered, and the invariant is thin == fat parity: the same warehouse must produce an identical state_json through either path. That single property catches the whole Test/Bench-tab "RPC TODO" bug class.

5. Per-surface precondition — the FC contract

A test can only drive+observe a surface if it's structured for it. That's the FC-1…FC-9 component contract: serializable state(), AccessKit labels on every interactive/painted widget, injected clock (determinism), explicit pending quiescence. FC is what makes autonom's assertions possible.

6. Assertions

7. Always-visible matrix (AUT1 — shipped 2026-06-14)

The 🧪 Test grid seeds its axes from the expected surface — workspace repos × ASPECT_DEFAULT (Matrix::build_with_expected + ASPECT_DEFAULT, src/viz/test_matrix_grid.rs; wired in test_tab via set_repos, seeded at construct + workspace switch in app.rs). So the matrix is populated with "not-run-yet" cells before any run, not an empty grid. Data-driven (repos from the workspace, aspects from the standard set) — not a hand list.

8. Coverage → warehouse (schema-evolving)

A new surface_coverage table (one row per surface × mode × workspace, same shape as tests/mcp_tool_coverage.json) added via iceberg/skade schema evolution (no history rewrite, old rows stay valid via serde defaults — exactly how aspect/metric were added in L2). Enforced as a release gate (Gap == ∅), with a nornir test coverage CLI + a viz view + an MCP tool (parity).

9. Freshness

The release-blocking gate runs against the working tree (always fresh). The thin-client staleness badge uses a working-tree content digest (gix, in-process) vs the indexed SHA — because a commit SHA cannot detect uncommitted edits. index_status → {HEAD sha, dirty digest, clean|dirty}.

10. Reusable for all nordisk (AUT8)

The engine lives in nornir-testmatrix (std+serde+anyhow — lean). Each repo plugs its enumerators and ships FC-compliant components; nornir hosts the iceberg-backed sink + the symbol-graph/viz/CLI enumerators. Target: nornir + znippy + skade + facett + korp + knut + holger all run autonom; results land in the warehouse.

See the dead-simple walkthrough in autonom-for-idiots.md.