.nornir/assets/test_matrix_pipeline.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 680" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
<defs>
<linearGradient id="board" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#0b1c2e"/>
<stop offset="1" stop-color="#06111d"/>
</linearGradient>
<linearGradient id="chip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#14384f"/>
<stop offset="1" stop-color="#0e2a3e"/>
</linearGradient>
<linearGradient id="rail" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#173d57"/>
<stop offset="1" stop-color="#0c2438"/>
</linearGradient>
<linearGradient id="slot" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#123448"/>
<stop offset="1" stop-color="#0a2032"/>
</linearGradient>
</defs>
<!-- PCB substrate -->
<rect x="0" y="0" width="1180" height="680" fill="url(#board)"/>
<g stroke="#143a52" stroke-width="1">
<line x1="0" y1="76" x2="1180" y2="76"/>
<line x1="0" y1="632" x2="1180" y2="632"/>
</g>
<g fill="#16415c">
<circle cx="40" cy="40" r="2"/><circle cx="1140" cy="40" r="2"/>
<circle cx="40" cy="652" r="2"/><circle cx="1140" cy="652" r="2"/>
</g>
<!-- title -->
<text x="40" y="44" fill="#eaf6ff" font-size="22" font-weight="700">test-matrix</text>
<text x="222" y="44" fill="#9fc9e0" font-size="15">run a repo's native tests → one row per case → the warehouse lights the <tspan fill="#bfe6ff" font-weight="700">green/red board</tspan></text>
<!-- legend -->
<g font-size="12.5">
<line x1="744" y1="60" x2="784" y2="60" stroke="#6fd3f5" stroke-width="3"/>
<text x="792" y="64" fill="#cfe6f5">case → row</text>
<line x1="946" y1="60" x2="986" y2="60" stroke="#ff7a7a" stroke-width="2.5" stroke-dasharray="5 4"/>
<text x="994" y="64" fill="#cfe6f5">stall watchdog</text>
</g>
<!-- ===================== DRIVER (left) ===================== -->
<rect x="36" y="150" width="150" height="120" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="111" y="180" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">nornir test run</text>
<text x="111" y="199" fill="#9fc9e0" font-size="10" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace"><repo> / test all</text>
<text x="111" y="222" fill="#86b3cc" font-size="10" text-anchor="middle">spawns in repo_root</text>
<text x="111" y="237" fill="#86b3cc" font-size="10" text-anchor="middle">CWD = repo's workspace</text>
<text x="111" y="256" fill="#7fa8c4" font-size="9.5" text-anchor="middle">one run_id per invocation</text>
<rect x="186" y="206" width="6" height="8" fill="#6fd3f5"/>
<g stroke="#6fd3f5" stroke-width="3" fill="none"><path d="M186 210 H236"/></g>
<circle cx="236" cy="210" r="4" fill="#bfecff"/>
<!-- ===================== detect_runner ===================== -->
<rect x="236" y="160" width="150" height="100" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="311" y="188" fill="#eaf6ff" font-size="13" font-weight="700" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">detect_runner</text>
<text x="311" y="210" fill="#9fc9e0" font-size="10" text-anchor="middle">nextest on PATH?</text>
<text x="311" y="228" fill="#bfe6ff" font-size="10" text-anchor="middle" font-weight="700">prefer libtest-json</text>
<text x="311" y="246" fill="#86b3cc" font-size="9.5" text-anchor="middle">else cargo test grammar</text>
<rect x="230" y="196" width="6" height="8" fill="#6fd3f5"/>
<rect x="386" y="186" width="6" height="8" fill="#6fd3f5"/>
<rect x="386" y="232" width="6" height="8" fill="#6fd3f5"/>
<!-- two runner paths -->
<g stroke="#6fd3f5" stroke-width="3" fill="none">
<path d="M386 190 H430 V178 H474"/>
<path d="M386 236 H430 V250 H474"/>
</g>
<rect x="474" y="150" width="160" height="58" rx="9" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.6"/>
<text x="554" y="172" fill="#bfe6ff" font-size="11.5" text-anchor="middle" font-weight="700">cargo nextest run</text>
<text x="554" y="189" fill="#86b3cc" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">--message-format libtest-json</text>
<text x="554" y="202" fill="#7fa8c4" font-size="8.5" text-anchor="middle">durations + failure stdout</text>
<rect x="474" y="222" width="160" height="58" rx="9" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.6"/>
<text x="554" y="244" fill="#bfe6ff" font-size="11.5" text-anchor="middle" font-weight="700">cargo test</text>
<text x="554" y="261" fill="#86b3cc" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">--no-fail-fast (human grammar)</text>
<text x="554" y="274" fill="#7fa8c4" font-size="8.5" text-anchor="middle">names only, no durations</text>
<!-- watchdog -->
<rect x="474" y="318" width="160" height="52" rx="9" fill="#2a1416" stroke="#ff7a7a" stroke-width="1.6"/>
<text x="554" y="340" fill="#ffb3b3" font-size="11" text-anchor="middle" font-weight="700">stall watchdog</text>
<text x="554" y="356" fill="#d89a9a" font-size="8.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">NORNIR_TEST_STALL_SECS (120)</text>
<path d="M554 318 V300 H650 V260" stroke="#ff7a7a" stroke-width="2.5" fill="none" stroke-dasharray="6 4"/>
<text x="610" y="296" fill="#d89a9a" font-size="8.5" text-anchor="middle">silent child → killed + red `stalled`</text>
<!-- runners -> parser -->
<g stroke="#6fd3f5" stroke-width="3" fill="none">
<path d="M634 178 H660 V214 H690"/>
<path d="M634 250 H660 V222 H690"/>
</g>
<circle cx="690" cy="218" r="4" fill="#bfecff"/>
<!-- ===================== PARSER -> ROWS ===================== -->
<rect x="690" y="170" width="160" height="120" rx="11" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="770" y="196" fill="#eaf6ff" font-size="13" font-weight="700" text-anchor="middle">Parser → TestCase</text>
<text x="770" y="215" fill="#9fc9e0" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">feed_json / feed_cargo</text>
<text x="770" y="234" fill="#86b3cc" font-size="9" text-anchor="middle">suite · name · status</text>
<text x="770" y="248" fill="#86b3cc" font-size="9" text-anchor="middle">duration_ms · message</text>
<text x="770" y="268" fill="#bfe6ff" font-size="9.5" text-anchor="middle" font-weight="700">TestResultRow / case</text>
<text x="770" y="282" fill="#7fa8c4" font-size="9" text-anchor="middle">shared run_id + ts</text>
<rect x="684" y="222" width="6" height="8" fill="#6fd3f5"/>
<rect x="850" y="222" width="6" height="8" fill="#6fd3f5"/>
<g stroke="#6fd3f5" stroke-width="3" fill="none"><path d="M850 226 H900 V560"/></g>
<!-- ===================== VIZ TEST PANE (right) ===================== -->
<rect x="940" y="120" width="200" height="200" rx="11" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="1040" y="148" fill="#eaf6ff" font-size="14" font-weight="700" text-anchor="middle">🧪 Test pane</text>
<text x="1040" y="166" fill="#9fc9e0" font-size="9.5" text-anchor="middle">run list left, cases right</text>
<g font-family="'DejaVu Sans Mono', monospace" font-size="9">
<rect x="960" y="178" width="160" height="16" rx="3" fill="#0f3324" stroke="#4fbf7f" stroke-width="1"/>
<text x="970" y="190" fill="#9fe6b8">PASS parser::feed_json</text>
<rect x="960" y="198" width="160" height="16" rx="3" fill="#3a1416" stroke="#ff7a7a" stroke-width="1"/>
<text x="970" y="210" fill="#ffb3b3">FAIL round_trip_assert</text>
<rect x="960" y="218" width="160" height="16" rx="3" fill="#332a14" stroke="#e0b24f" stroke-width="1"/>
<text x="970" y="230" fill="#e6d49a">STALL hung_case</text>
<rect x="960" y="238" width="160" height="16" rx="3" fill="#222a30" stroke="#6c7d88" stroke-width="1"/>
<text x="970" y="250" fill="#9fb0bc">IGN slow_case</text>
</g>
<text x="1040" y="276" fill="#86b3cc" font-size="9" text-anchor="middle">newest run on top · P/F/I/S counts</text>
<text x="1040" y="292" fill="#a9d8ee" font-size="9" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">state_json()["test"]</text>
<text x="1040" y="308" fill="#7fa8c4" font-size="9" text-anchor="middle">CLI parity: nornir test history</text>
<rect x="934" y="200" width="6" height="8" fill="#6fd3f5"/>
<g stroke="#6fd3f5" stroke-width="3" fill="none"><path d="M1040 560 V320"/></g>
<circle cx="1040" cy="320" r="4" fill="#bfecff"/>
<text x="1056" y="430" fill="#86b3cc" font-size="10">read</text>
<!-- aspects note (lower-left) -->
<rect x="36" y="372" width="380" height="120" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
<text x="56" y="398" fill="#eaf6ff" font-size="13" font-weight="700">multi-aspect engine (EPIC L)</text>
<text x="56" y="418" fill="#9fc9e0" font-size="10">one run_id, many aspects:</text>
<g font-family="'DejaVu Sans Mono', monospace" font-size="9.5" fill="#bfe6ff">
<text x="56" y="438">build · unit · doctest · clippy · fmt · audit</text>
<text x="56" y="454">coverage · powerset · msrv · examples</text>
</g>
<text x="56" y="476" fill="#86b3cc" font-size="9.5">absent tool → neutral `skip` (never a hard fail)</text>
<text x="56" y="488" fill="#7fa8c4" font-size="9" font-family="'DejaVu Sans Mono', monospace">extracted into the nornir-testmatrix crate · TestSink seam</text>
<!-- ===================== test_results GROUND RAIL ===================== -->
<rect x="236" y="552" width="904" height="56" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
<g fill="#0a1c2c" stroke="#7fc8ea" stroke-width="1.5">
<circle cx="280" cy="580" r="4"/><circle cx="560" cy="580" r="4"/>
<circle cx="820" cy="580" r="4"/><circle cx="1040" cy="580" r="4"/>
</g>
<text x="306" y="579" fill="#dff1ff" font-size="15" font-weight="700">test_results</text>
<text x="446" y="575" fill="#bcd9ec" font-size="11.5">append-only Iceberg table · partitioned by repo (per-repo reads prune)</text>
<text x="446" y="596" fill="#7fa8c4" font-size="10.5" font-family="'DejaVu Sans Mono', monospace">run_id · repo · suite · test_name · status · duration_ms · ts · message · aspect · metric</text>
</svg>