.nornir/assets/nornir-modes.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 560" font-family="'DejaVu Sans Mono','Liberation Mono',monospace">
<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="trace" x1="0" y1="0" x2="1" y2="0">
<stop offset="0" stop-color="#2a6b86"/><stop offset="1" stop-color="#7fdfff"/>
</linearGradient>
<marker id="arr" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto">
<path d="M0,0 L9,4.5 L0,9 Z" fill="#7fdfff"/>
</marker>
<style>
.lbl{fill:#cfe9f4;font-size:13px} .sub{fill:#6f93a6;font-size:11px}
.hdr{fill:#7fdfff;font-size:14px;font-weight:bold;letter-spacing:1px}
.box{fill:#0e2438;stroke:#2a6b86;stroke-width:1.2;rx:7}
.mode{fill:#10283c;stroke:#4aa3c7;stroke-width:1.4;rx:9}
.wh{fill:#13233a;stroke:#7fdfff;stroke-width:1.6;rx:9}
.trace{stroke:url(#trace);stroke-width:2;fill:none;marker-end:url(#arr)}
.pin{fill:#7fdfff}
</style>
</defs>
<rect x="0" y="0" width="1180" height="560" fill="url(#board)"/>
<rect x="6" y="6" width="1168" height="548" fill="none" stroke="#15324a" stroke-width="1.5" rx="10"/>
<text x="28" y="40" class="hdr">NORNIR · helicopter view — workspaces × 3 access modes × one warehouse each</text>
<!-- ============ WORKSPACES (left) ============ -->
<text x="40" y="80" class="sub">WORKSPACES (registry)</text>
<g>
<rect x="32" y="92" width="150" height="372" class="box" rx="7"/>
<text x="48" y="118" class="lbl">holger</text>
<text x="48" y="150" class="lbl">knut</text>
<text x="48" y="182" class="lbl">znippy</text>
<text x="48" y="214" class="lbl">skade</text>
<text x="48" y="246" class="lbl">korp</text>
<text x="48" y="278" class="lbl">njord</text>
<text x="48" y="318" class="sub">each = git members</text>
<text x="48" y="336" class="sub">+ its own warehouse</text>
<text x="48" y="372" class="sub">~/.nornir/</text>
<text x="48" y="390" class="sub">workspaces/<name>/</text>
<text x="48" y="408" class="sub">{git, builds, funnel}</text>
</g>
<!-- ============ MODES (middle) ============ -->
<text x="300" y="80" class="sub">ACCESS MODES (one process owns the write lock per warehouse)</text>
<!-- FAT -->
<rect x="300" y="92" width="430" height="118" class="mode" rx="9"/>
<text x="318" y="116" class="hdr">FAT · embedded (default)</text>
<text x="318" y="142" class="lbl">human's local checkout → nornir CLI</text>
<text x="318" y="164" class="sub">opens the warehouse IN-PROCESS (holds the redb write lock)</text>
<text x="318" y="186" class="sub">every verb runs locally · `cargo install nornir`</text>
<!-- SERVER -->
<rect x="300" y="222" width="430" height="124" class="mode" rx="9"/>
<text x="318" y="246" class="hdr">SERVER · monitored</text>
<text x="318" y="272" class="lbl">nornir-server clones member git URLs, polls,</text>
<text x="318" y="294" class="lbl">republishes — OWNS the write lock</text>
<text x="318" y="316" class="sub">systemd service · gRPC/tonic + bearer token</text>
<text x="318" y="334" class="sub">serves every workspace (workspaces_list)</text>
<!-- THIN -->
<rect x="300" y="358" width="430" height="106" class="mode" rx="9"/>
<text x="318" y="382" class="hdr">THIN · client</text>
<text x="318" y="408" class="lbl">viz · MCP · CLI → gRPC → server</text>
<text x="318" y="430" class="sub">no local warehouse, no code leaves the box;</text>
<text x="318" y="448" class="sub">reads/writes go over Viz.* / *.Submit RPCs</text>
<!-- ============ WAREHOUSE (right) ============ -->
<text x="800" y="80" class="sub">PER-WORKSPACE WAREHOUSE</text>
<rect x="800" y="92" width="340" height="372" class="wh" rx="9"/>
<text x="820" y="120" class="hdr">Iceberg warehouse</text>
<text x="820" y="146" class="sub">(skade-katalog · one per workspace)</text>
<text x="820" y="180" class="lbl">· plan-DAG events (funnel)</text>
<text x="820" y="206" class="lbl">· dep graph + release lineage</text>
<text x="820" y="232" class="lbl">· bench_runs · test_results</text>
<text x="820" y="258" class="lbl">· full-text + vector index</text>
<text x="820" y="284" class="lbl">· knowledge (syn/DWARF)</text>
<text x="820" y="310" class="lbl">· mcp_requests · viz_actions</text>
<text x="820" y="350" class="sub">append-only · keyed by git SHA</text>
<text x="820" y="372" class="sub">time-travel to any past release</text>
<!-- ============ TRACES ============ -->
<!-- workspaces → modes -->
<path class="trace" d="M182,150 L300,150"/>
<path class="trace" d="M182,210 L300,284"/>
<path class="trace" d="M182,260 L300,410"/>
<!-- FAT → warehouse (direct, owns lock) -->
<path class="trace" d="M730,150 L800,200"/>
<!-- SERVER → warehouse (owns lock) -->
<path class="trace" d="M730,284 L800,278"/>
<!-- THIN → SERVER (gRPC), not warehouse directly -->
<path class="trace" d="M520,358 L520,346"/>
<text x="528" y="354" class="sub">gRPC</text>
<!-- legend -->
<circle cx="40" cy="500" r="4" class="pin"/>
<text x="54" y="504" class="sub">cyan trace = data/dispatch flow · FAT⊕SERVER own the write lock; THIN relays over gRPC</text>
</svg>