autonom completeness gate (n-005) — design + guide
The CORE that makes green ⟺ every surface is wired true. Builds on the pure enumerators in
autonom.md(§2 the completeness equation, §3 discovery). This doc is the n-005 slice: the FEEDERS, the persisted verdict, the allowlist, and the CLI / MCP / viz / release-gate surfaces.Closing a gap = covering a surface with an inject-assert test. How an agent does that — drives the surface headless, reads the emitted DATA, bisects to the bug, and writes the fail-on-bug/pass-on-fix test — is the LAW in
agent-ui-test-fixing.md(the canonical way to fix any UI/gRPC/render test; seetest-matrix.md§0).
1. The equation, made enforceable
Surface = discover::{viz_tabs×{fat,thin}, cli_commands, mcp_tools, facett, unreached_functions}
Covered = a surface node reached by an inject-assert test (call_edges closure / handler match)
Allowed = a checked-in .nornir/autonom-allow.toml entry (excused, WITH a reason)
Gap = Surface − Covered − Allowed
GATE: Gap == ∅ AND no STALE allowlist entry ← HARD zero, not a ratchet
2. Feeders (nornir, iceberg-backed) — src/autonom.rs
The pure enumerators live in nornir-testmatrix (discover + coverage, std+serde, no warehouse). nornir's feeder layer gathers the REAL inputs:
| surface | feeder |
| viz tabs × {fat,thin} | autonom::VIZ_TABS (asserted == viz::app::Tab::ALL by viz_tabs_const_matches_tab_enum) |
| CLI subcommands | live Cli::command().get_subcommands() (clap introspection) |
| MCP tools | autonom::MCP_TOOLS (kept in step with the mcp_matrix tools/list gate) |
| functions | symbol_facts − test-reachable(call_edges) from the warehouse knowledge map |
build_surface_and_covered differences the surface against the test-reachable closure over call_edges (BFS from test-root fns, at identifier granularity — the persisted syn facts record callees as last-segments). A function node only exists when unreached; a discrete surface (tab/cli/mcp) is covered iff a same-named test-reachable handler exists, else it falls to the allowlist.
3. Persisted verdict — surface_coverage (skade schema-evolution)
src/warehouse/surface_coverage.rs writes/reads one row per surface_key × mode × workspace × verdict (mirrors tests/mcp_tool_coverage.json generalized to the whole surface). Additive schema (iceberg_schema::surface_coverage): old binaries keep reading (optional reason). Writer/reader mirror test_results.rs: append_surface_coverage / query_surface_coverage / latest_surface_coverage.
4. The allowlist — .nornir/autonom-allow.toml (SEED → burn down)
A checked-in TOML of [[allow]] entries (key = "kind:id@mode", reason = "TODO…"). nornir test coverage --seed-allowlist rewrites it with every currently- uncovered surface node so the gate is GREEN now. Burn it down by deleting an entry once a real inject-assert test covers that surface. A STALE entry (now-covered, or its surface no longer exists) FAILS the gate — the excuse must not outlive its surface.
5. Surfaces (CLI / MCP parity + viz + release gate)
- CLI:
nornir test coverage [--repo R] [--seed-allowlist] [--json]— discovers, differences, persists, and exits red on any gap or stale entry. - MCP (parity):
test_coveragereturns{total,covered,allowlisted,gap,green,missing[]};release_gate_coverageerrors on a red gate. Both embedded/local (they read the warehouse directly). - viz (the visible half): the 🧪 Test pane shows the verdict under
state_json["test"]["coverage"]—{total,covered,allowlisted,gap,green,missing[]}from the latest persistedsurface_coveragerun (fat/local reads the warehouse; thin == fat parity: the SAMECoverageSummaryrenders identically). - release gate:
release::gate::coverage_gate(&report)fails whenGap ≠ ∅OR any stale entry — alongside the existing gates.
6. Tests (LAW 1 — inject + assert)
- pure (
nornir-testmatrix::coverage): seed surface + covered + allowlist → assert Gap (unreached→gap, reachable→not, allowlisted→excused), seed→green-now, stale→red, rows + summary round-trip through serde. - feeder (
src/autonom.rs): knowledge→rows mapping detects test roots + idents; unreached fn is a gap, reached is not; discrete surface covered when handler reachable else seed→green; allowlist TOML round-trips through a file. - warehouse (
src/warehouse/surface_coverage.rs): append→query exact verdicts,latestpicks the newest run, empty append is a no-op. - viz (
src/viz/test_tab.rs):state_json["test"]["coverage"]null-until-injected then carries the verdict; thin == fat parity. - release (
src/release/gate.rs):coverage_gategreen→ok, gap→err, stale→err. - MCP (
tests/mcp_matrix):test_coverage+release_gate_coverageexercised, asserting the structured verdict (no silent gap in the tools/list).