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

nordisk/edda

crates/nornir-testmatrix/.nornir/testmatrix-utfallsrum.md

utfallsrum — outcome-space coverage (design)

utfallsrum (Swedish: outcome space / sample space) makes a function's whole OUTCOME SPACE a measurable, recordable, persistable thing. It is classic boundary-value + equivalence-partition analysis, made first-class: a test declares the set/range/relation a correct output must satisfy, partitioned into input-classes + boundaries; records which classes it exercised with the exact output per class; and the framework scores utfallsrum_covered ∈ [0,1]. A single-value test scores low even when green — coverage now measures the SHAPE of a check, not just its pass/fail.

Why

The matrix already records, per check, did it pass? (functional_status). What it could not see is how much of the function's outcome space did the test sweep? A correct function maps a partition of its inputs to a known region of its output; one value inside one partition proves nothing the next value in that partition would. The unit that actually moves the needle is one case per equivalence class + the boundaries between them. utfallsrum records coverage at exactly that granularity and turns it into a number the warehouse + gate can carry.

This is a positive quality feature: it rewards rigorous, multi-value, contract-aware tests and surfaces single-value smoke tests for what they are — a start, not a finish.

Model (src/utfallsrum.rs)

OutcomeClass { name, contract, exercised, evidence }   // one equivalence partition / boundary
Outcome      { function, classes: BTreeMap<name, OutcomeClass> }

Emit + persist

Gate consumption (n-005 / AUT2)

coverage.rs gained the utfallsrum-aware covered set:

covered_with_utfallsrum(ran, utfallsrum, min_classes):
    a surface is COVERED ⟺ it is in `ran` (ran end-to-end) AND its outcome-space
    summary meets `min_classes` (≥K classes swept). min_classes == 0 ⇒ legacy ran ⟺ covered.

DEFAULT_UTFALLSRUM_THRESHOLD = 2. The CoverageRow gained utfallsrum_covered: f64 (the per-surface score), rows_for_with_utfallsrum stamps it, and nornir persists it to the surface_coverage Iceberg table (additive field 10, evolution-safe). The workspace dimension is expressed via discover::workspace_surface_key / SERVED_WORKSPACES so the surface is workspace × {cli,viz@{fat,thin},mcp,grpc}.

Tests (inject-assert, across utfallsrum's own outcome space)

In src/utfallsrum.rs + src/coverage.rs:

nornir-side: warehouse/surface_coverage.rs::utfallsrum_score_round_trips_through_iceberg, autonom.rs::utfallsrum_threshold_unflips_a_single_value_smoke_then_reflips_on_second_class, and the worked slice tests/viz_utfallsrum_slice.rs.

Versioning

nornir-testmatrix adds the utfallsrum module + CoverageRow.utfallsrum_covered (additive). Not published to crates.io — release is human-gated.