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

nordisk/nornir

.nornir/coverage-maven.md

Feature N — source coverage, maven-style (design + guide)

LLVM source-based line/region coverage (via cargo-llvm-cov) → the warehouse → the docs/PDF

  • the viz 🧪 Test pane. The maven/JaCoCo-report twin of AUT5: where aut5-surface-coverage-gate.md answers "is every testable surface reached by a test?", THIS answers "what fraction of the source lines/regions did the test run actually execute?" — per crate, per file, per function, with a dedicated ui/gRPC/emitter boundary view. Built 2026-06-18. Plan: nordisk_plan.md (the AUT5 follow-up "viz Test-pane coverage VIEW").

1. The pipeline

 cargo llvm-cov --json   →  parse + demangle  →  CoverageReport  →  warehouse rows  →  docs / viz
   (src/coverage/runner.rs)   (src/coverage/mod.rs)  (overall+crate+file+fn)  (coverage, coverage_fn)
                                      │                                            │
                          name/path boundary tag                       nornir:gen:coverage  +  📐 Test-pane panel
                          (ui · grpc · emitter · core)                 (book/PDF)              (+ boundary view)

2. The CLI verb (parity LAW)

nornir coverage [REPO] [--show] [--boundary] [--json] [-- <extra cargo-llvm-cov args>]

If cargo-llvm-cov / llvm-tools-preview is missing, the verb prints the exact install hint (rustup component add llvm-tools-preview + cargo install cargo-llvm-cov).

3. The warehouse schema

coverage — one row per (run_id, repo, scope), scope ∈ {overall, crate:<name>, file:<path>}:

col type meaning
run_id, ts_micros, repo str/ts/str run id + time + repo (partition key)
scope str overall | crate:<name> | file:<path>
krate, file str crate name / file path ("" where N/A)
lines, lines_covered, regions, regions_covered long the counts → line_pct / region_pct

coverage_fn — one row per function, carrying its layer boundary:

col type meaning
run_id, ts_micros, repo … as above
name, file str demangled fn name + source file
boundary str ui | grpc | emitter | core
lines, lines_covered, regions, regions_covered long per-fn coverage; regions_covered>0 ⇒ exercised

Both schema-evolve additively (ensure_table_schema on append); old binaries keep reading.

4. Boundary classification — the ui/grpc/emitter view (task #4)

Per the layer-boundary-discoverability LAW, a function's boundary is classified by name + file path ([nornir::coverage::classify]), so the hard-to-cover seams are discoverable and the green panel proves they're tested:

The 📐 panel + --boundary then show, e.g., ui 2/2 · grpc 2/2 · emitter 1/2 and list each function with ✓/✗ — so an un-exercised state_json emitter reds the boundary view by name.

5. The viz 📐 panel + emitted data (LAW #6)

The Test pane embeds CoverageLive (mirrors bench_live.rs): a lazy + request_repaint_after warehouse read showing the overall badge, per-crate bars, worst files, a history sparkline, and the boundary view. Everything it paints is exposed as DATA under state_json["test"]["src_coverage"] (line_pct, region_pct, crates, worst_files, history, and boundary.{total,exercised,green,tally,fns}) + the test.coverage.{load,build,…} trace spans, so a robot test asserts the picture without pixels. Remote (thin) mode shows the same "no Viz.Coverage RPC yet" split as the Bench-LIVE / Test / Release panes.

6. Coverage report (generated)

(no coverage recorded — run nornir coverage <repo>)

7. Tests (inject-real / assert-real)

Validated end-to-end against a real cargo llvm-cov --json run of nornir-testmatrix (78.2% overall lines, per-crate rollup, demangled fn names).