.nornir/assets/architecture_wiring.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1320 1180" 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="rpcchip" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#3a2a14"/>
<stop offset="1" stop-color="#2a1e0c"/>
</linearGradient>
</defs>
<!-- PCB substrate -->
<rect x="0" y="0" width="1320" height="1180" fill="url(#board)"/>
<g stroke="#143a52" stroke-width="1">
<line x1="0" y1="92" x2="1320" y2="92"/>
<line x1="0" y1="1132" x2="1320" y2="1132"/>
</g>
<g fill="#16415c">
<circle cx="40" cy="40" r="2"/><circle cx="1280" cy="40" r="2"/>
<circle cx="40" cy="1152" r="2"/><circle cx="1280" cy="1152" r="2"/>
</g>
<!-- title -->
<text x="40" y="44" fill="#eaf6ff" font-size="22" font-weight="700">nornir architecture wiring</text>
<text x="320" y="44" fill="#9fc9e0" font-size="14">every viz pane routes left → right: <tspan fill="#6fd3f5" font-weight="700">fat</tspan> opens the warehouse direct · <tspan fill="#e0aa55" font-weight="700">thin</tspan> calls a gRPC verb on the server that owns the redb lock</text>
<text x="40" y="68" fill="#86b3cc" font-size="12">16 UI panes → Viz.* / Warehouse.* / Knowledge.* / Release.* / Funnel.* / Mimir.* gRPC verbs → Apache-Iceberg warehouse tables (skade-katalog redb catalog)</text>
<!-- legend -->
<g font-size="12.5">
<line x1="850" y1="64" x2="888" y2="64" stroke="#6fd3f5" stroke-width="3"/>
<text x="896" y="68" fill="#cfe6f5">fat: direct warehouse open</text>
<line x1="1090" y1="64" x2="1128" y2="64" stroke="#e0aa55" stroke-width="2.5" stroke-dasharray="6 4"/>
<text x="1136" y="68" fill="#cfe6f5">thin: gRPC RPC</text>
</g>
<!-- ===== column headers ===== -->
<text x="150" y="112" fill="#a9d8ee" font-size="13" font-weight="700" text-anchor="middle">UI PANE (egui / facett)</text>
<text x="660" y="112" fill="#e8c98a" font-size="13" font-weight="700" text-anchor="middle">gRPC VERB (thin mode)</text>
<text x="1130" y="112" fill="#bfe6ff" font-size="13" font-weight="700" text-anchor="middle">WAREHOUSE TABLE(S)</text>
<!-- ===================== ROWS ===================== -->
<!-- Each row: pane chip (left) -> rpc chip (mid) -> table chip (right). 16 rows. -->
<!-- y baselines -->
<g font-family="'DejaVu Sans Mono', monospace">
<!-- helper grid lines (subtle traces) -->
<g stroke="#6fd3f5" stroke-width="2.5" fill="none" opacity="0.9">
<path d="M300 140 H470"/>
<path d="M300 196 H470"/>
<path d="M300 252 H470"/>
<path d="M300 308 H470"/>
<path d="M300 364 H470"/>
<path d="M300 420 H470"/>
<path d="M300 476 H470"/>
<path d="M300 532 H470"/>
<path d="M300 588 H470"/>
<path d="M300 644 H470"/>
<path d="M300 700 H470"/>
<path d="M300 756 H470"/>
<path d="M300 812 H470"/>
<path d="M300 868 H470"/>
<path d="M300 924 H470"/>
<path d="M300 980 H470"/>
</g>
<!-- rpc -> table (dashed amber = thin verb resolves to table) -->
<g stroke="#e0aa55" stroke-width="2.3" fill="none" stroke-dasharray="6 4" opacity="0.9">
<path d="M850 140 H980"/>
<path d="M850 196 H980"/>
<path d="M850 252 H980"/>
<path d="M850 308 H980"/>
<path d="M850 364 H980"/>
<path d="M850 420 H980"/>
<path d="M850 476 H980"/>
<path d="M850 532 H980"/>
<path d="M850 588 H980"/>
<path d="M850 644 H980"/>
<path d="M850 700 H980"/>
<path d="M850 756 H980"/>
<path d="M850 812 H980"/>
<path d="M850 868 H980"/>
<path d="M850 924 H980"/>
<path d="M850 980 H980"/>
</g>
</g>
<!-- PANE chips (x=20..300) -->
<g font-family="'DejaVu Sans Mono', monospace" font-size="13">
<!-- macro: rect + label per row -->
<g fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.6">
<rect x="20" y="126" width="280" height="28" rx="6"/>
<rect x="20" y="182" width="280" height="28" rx="6"/>
<rect x="20" y="238" width="280" height="28" rx="6"/>
<rect x="20" y="294" width="280" height="28" rx="6"/>
<rect x="20" y="350" width="280" height="28" rx="6"/>
<rect x="20" y="406" width="280" height="28" rx="6"/>
<rect x="20" y="462" width="280" height="28" rx="6"/>
<rect x="20" y="518" width="280" height="28" rx="6"/>
<rect x="20" y="574" width="280" height="28" rx="6"/>
<rect x="20" y="630" width="280" height="28" rx="6"/>
<rect x="20" y="686" width="280" height="28" rx="6"/>
<rect x="20" y="742" width="280" height="28" rx="6"/>
<rect x="20" y="798" width="280" height="28" rx="6"/>
<rect x="20" y="854" width="280" height="28" rx="6"/>
<rect x="20" y="910" width="280" height="28" rx="6"/>
<rect x="20" y="966" width="280" height="28" rx="6"/>
</g>
<g fill="#eaf6ff">
<text x="34" y="145">🧵 Timeline</text>
<text x="34" y="201">🔗 DepGraph</text>
<text x="34" y="257">🕸 CallGraph</text>
<text x="34" y="313">🗂 Funnel</text>
<text x="34" y="369">⏳ TimeTravel</text>
<text x="34" y="425">📡 LiveRun</text>
<text x="34" y="481">🚀 Release</text>
<text x="34" y="537">🗺 Knowledge</text>
<text x="34" y="593">🗄 Warehouse</text>
<text x="34" y="649">📞 Mcp</text>
<text x="34" y="705">🔍 Search</text>
<text x="34" y="761">🚦 Gates</text>
<text x="34" y="817">📈 Bench</text>
<text x="34" y="873">🧪 Test</text>
<text x="34" y="929">🏆 Leaderboard</text>
<text x="34" y="985">🛡 Security</text>
</g>
<!-- pin pads -->
<g fill="#6fd3f5">
<rect x="300" y="136" width="6" height="8"/><rect x="300" y="192" width="6" height="8"/>
<rect x="300" y="248" width="6" height="8"/><rect x="300" y="304" width="6" height="8"/>
<rect x="300" y="360" width="6" height="8"/><rect x="300" y="416" width="6" height="8"/>
<rect x="300" y="472" width="6" height="8"/><rect x="300" y="528" width="6" height="8"/>
<rect x="300" y="584" width="6" height="8"/><rect x="300" y="640" width="6" height="8"/>
<rect x="300" y="696" width="6" height="8"/><rect x="300" y="752" width="6" height="8"/>
<rect x="300" y="808" width="6" height="8"/><rect x="300" y="864" width="6" height="8"/>
<rect x="300" y="920" width="6" height="8"/><rect x="300" y="976" width="6" height="8"/>
</g>
</g>
<!-- RPC chips (x=470..850) -->
<g font-family="'DejaVu Sans Mono', monospace" font-size="12.5">
<g fill="url(#rpcchip)" stroke="#c9912f" stroke-width="1.6">
<rect x="470" y="126" width="380" height="28" rx="6"/>
<rect x="470" y="182" width="380" height="28" rx="6"/>
<rect x="470" y="238" width="380" height="28" rx="6"/>
<rect x="470" y="294" width="380" height="28" rx="6"/>
<rect x="470" y="350" width="380" height="28" rx="6"/>
<rect x="470" y="406" width="380" height="28" rx="6"/>
<rect x="470" y="462" width="380" height="28" rx="6"/>
<rect x="470" y="518" width="380" height="28" rx="6"/>
<rect x="470" y="574" width="380" height="28" rx="6"/>
<rect x="470" y="630" width="380" height="28" rx="6"/>
<rect x="470" y="686" width="380" height="28" rx="6"/>
<rect x="470" y="742" width="380" height="28" rx="6"/>
<rect x="470" y="798" width="380" height="28" rx="6"/>
<rect x="470" y="854" width="380" height="28" rx="6"/>
<rect x="470" y="910" width="380" height="28" rx="6"/>
<rect x="470" y="966" width="380" height="28" rx="6"/>
</g>
<g fill="#f3dca8">
<text x="484" y="145">Viz.Timeline</text>
<text x="484" y="201">Viz.Timeline (dep snapshots)</text>
<text x="484" y="257">Warehouse.Scan</text>
<text x="484" y="313">Funnel.Show / History / SubmitIdea</text>
<text x="484" y="369">Viz.Timeline</text>
<text x="484" y="425">Viz.ReleaseEvents + Release.Progress</text>
<text x="484" y="481">Viz.ReleaseEvents</text>
<text x="484" y="537">Viz.Knowledge (server scans clones)</text>
<text x="484" y="593">Warehouse.Tables / Warehouse.Scan</text>
<text x="484" y="649">Warehouse.Scan</text>
<text x="484" y="705">Search.Query / Vector.Search / Index.Stats</text>
<text x="484" y="761">Release.GateAll / Release.Trace</text>
<text x="484" y="817">Viz.BenchTelemetry + Bench.History</text>
<text x="484" y="873">Viz.TestResults</text>
<text x="484" y="929">Viz.BakeoffResults</text>
<text x="484" y="985">Mimir.SecurityScan</text>
</g>
<!-- pin pads in/out -->
<g fill="#e0aa55">
<rect x="464" y="136" width="6" height="8"/><rect x="464" y="192" width="6" height="8"/>
<rect x="464" y="248" width="6" height="8"/><rect x="464" y="304" width="6" height="8"/>
<rect x="464" y="360" width="6" height="8"/><rect x="464" y="416" width="6" height="8"/>
<rect x="464" y="472" width="6" height="8"/><rect x="464" y="528" width="6" height="8"/>
<rect x="464" y="584" width="6" height="8"/><rect x="464" y="640" width="6" height="8"/>
<rect x="464" y="696" width="6" height="8"/><rect x="464" y="752" width="6" height="8"/>
<rect x="464" y="808" width="6" height="8"/><rect x="464" y="864" width="6" height="8"/>
<rect x="464" y="920" width="6" height="8"/><rect x="464" y="976" width="6" height="8"/>
</g>
</g>
<!-- TABLE chips (x=980..1300) -->
<g font-family="'DejaVu Sans Mono', monospace" font-size="12">
<g fill="url(#rail)" stroke="#7fc8ea" stroke-width="1.6">
<rect x="980" y="126" width="320" height="28" rx="6"/>
<rect x="980" y="182" width="320" height="28" rx="6"/>
<rect x="980" y="238" width="320" height="28" rx="6"/>
<rect x="980" y="294" width="320" height="28" rx="6"/>
<rect x="980" y="350" width="320" height="28" rx="6"/>
<rect x="980" y="406" width="320" height="28" rx="6"/>
<rect x="980" y="462" width="320" height="28" rx="6"/>
<rect x="980" y="518" width="320" height="28" rx="6"/>
<rect x="980" y="574" width="320" height="28" rx="6"/>
<rect x="980" y="630" width="320" height="28" rx="6"/>
<rect x="980" y="686" width="320" height="28" rx="6"/>
<rect x="980" y="742" width="320" height="28" rx="6"/>
<rect x="980" y="798" width="320" height="28" rx="6"/>
<rect x="980" y="854" width="320" height="28" rx="6"/>
<rect x="980" y="910" width="320" height="28" rx="6"/>
<rect x="980" y="966" width="320" height="28" rx="6"/>
</g>
<g fill="#dff1ff">
<text x="994" y="145">release_lineage + dep_graph_edges</text>
<text x="994" y="201">dep_graph_edges</text>
<text x="994" y="257">symbol_facts + call_edges</text>
<text x="994" y="313">funnel_events</text>
<text x="994" y="369">release_lineage + dep_graph_edges</text>
<text x="994" y="425">release_events (+ /tmp ndjson tail)</text>
<text x="994" y="481">release_events</text>
<text x="994" y="537">symbol_facts + call_edges (live syn scan)</text>
<text x="994" y="593">ALL tables (generic browser)</text>
<text x="994" y="649">mcp_requests</text>
<text x="994" y="705">tantivy_index + embeddings + symbol_facts</text>
<text x="994" y="761">bench_history.jsonl (no iceberg table)</text>
<text x="994" y="817">bench_telemetry + bench_runs</text>
<text x="994" y="873">test_results</text>
<text x="994" y="929">agent_model_runs</text>
<text x="994" y="985">vuln_findings + sbom_components</text>
</g>
<g fill="#7fc8ea">
<rect x="974" y="136" width="6" height="8"/><rect x="974" y="192" width="6" height="8"/>
<rect x="974" y="248" width="6" height="8"/><rect x="974" y="304" width="6" height="8"/>
<rect x="974" y="360" width="6" height="8"/><rect x="974" y="416" width="6" height="8"/>
<rect x="974" y="472" width="6" height="8"/><rect x="974" y="528" width="6" height="8"/>
<rect x="974" y="584" width="6" height="8"/><rect x="974" y="640" width="6" height="8"/>
<rect x="974" y="696" width="6" height="8"/><rect x="974" y="752" width="6" height="8"/>
<rect x="974" y="808" width="6" height="8"/><rect x="974" y="864" width="6" height="8"/>
<rect x="974" y="920" width="6" height="8"/><rect x="974" y="976" width="6" height="8"/>
</g>
</g>
<!-- ===================== GROUND RAIL: the warehouse ===================== -->
<rect x="20" y="1040" width="1280" height="70" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
<text x="44" y="1072" fill="#dff1ff" font-size="17" font-weight="700">IcebergWarehouse</text>
<text x="44" y="1094" fill="#7fa8c4" font-size="11.5" font-family="'DejaVu Sans Mono', monospace">Apache Iceberg (iceberg-rust) over a single-file skade-katalog redb catalog · append-only · snapshot = free time-travel</text>
<text x="980" y="1072" fill="#bcd9ec" font-size="12" text-anchor="start">FAT: CLI/viz opens it in-process</text>
<text x="980" y="1090" fill="#e8c98a" font-size="12" text-anchor="start">THIN/SERVER: nornir-server holds the lock</text>
<!-- ties from table column down to rail -->
<g stroke="#7fc8ea" stroke-width="1.5" fill="none" opacity="0.5" stroke-dasharray="3 4">
<path d="M1140 994 V1040"/>
</g>
</svg>