.nornir/assets/jobs-fleet-pane.svg
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="380" font-family="monospace" font-size="13">
<style>
.box{fill:#0f2233;stroke:#6fd3f5;stroke-width:1.5}
.reuse{fill:#12331f;stroke:#7fe0a0;stroke-width:1.5}
.t{fill:#dbeafe}.dim{fill:#9fb6c6}.acc{fill:#7fe0a0}.wire{fill:#f5d76f}
.arr{stroke:#6fd3f5;stroke-width:1.5;fill:none;marker-end:url(#a)}
.arr2{stroke:#7fe0a0;stroke-width:1.5;fill:none;marker-end:url(#b)}
.arrw{stroke:#f5d76f;stroke-width:1.5;fill:none;marker-end:url(#c)}
</style>
<defs>
<marker id="a" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#6fd3f5"/></marker>
<marker id="b" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#7fe0a0"/></marker>
<marker id="c" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#f5d76f"/></marker>
</defs>
<text x="12" y="20" class="acc">Live Jobs + Agent-fleet pane — GREEN = REUSED (jera ledger + facett-jobview); YELLOW = the wire</text>
<!-- jobs source: the jera ledger -->
<text x="12" y="48" class="acc">jera ledger (shared, edda)</text>
<rect class="reuse" x="12" y="60" width="230" height="96"/>
<text x="24" y="84" class="acc">JobStore::open_read_only</text>
<text x="24" y="102" class="dim">list(All) -> JobRecord[]</text>
<text x="24" y="120" class="dim">status · timing</text>
<text x="24" y="138" class="wire">node: Option<String> ← placement</text>
<!-- dwarves run writes it -->
<rect class="box" x="12" y="176" width="230" height="52"/>
<text x="24" y="198" class="t">dwarves run (f4)</text>
<text x="24" y="216" class="dim">writes ci_build job → jobs.redb</text>
<path class="arr" d="M127,176 L127,156"/>
<!-- the pane -->
<rect class="box" x="330" y="70" width="250" height="150"/>
<text x="344" y="94" class="t">JobsFleetPanel (dwarves-embed)</text>
<text x="344" y="116" class="acc">entries_from_records</text>
<text x="344" y="134" class="dim">JobRecord → JobEntry</text>
<text x="344" y="152" class="wire">node → detail + meta + nodes[]</text>
<text x="344" y="176" class="acc">agents_from_wire</text>
<text x="344" y="194" class="dim">AgentRow{..,online}</text>
<text x="344" y="212" class="dim">auto-poll 2s · apply(FleetSnapshot)</text>
<path class="arr2" d="M242,108 L330,120"/>
<!-- fleet source: AgentPool RPC -->
<text x="640" y="48" class="wire">dwarves-server (thin gRPC)</text>
<rect class="box" x="640" y="60" width="260" height="70"/>
<text x="652" y="84" class="wire">Dwarf.AgentPool (f2)</text>
<text x="652" y="102" class="dim">AgentRow[]: id·group·caps</text>
<text x="652" y="120" class="dim">·cores·mem_mb·state</text>
<path class="arrw" d="M640,110 L580,150"/>
<!-- render: facett-jobview -->
<text x="640" y="168" class="acc">facett-jobview (shared)</text>
<rect class="reuse" x="640" y="180" width="260" height="76"/>
<text x="652" y="204" class="acc">JobList (task-manager tree)</text>
<text x="652" y="222" class="dim">sort · fold · select · filter</text>
<text x="652" y="240" class="dim">fed live (no twin)</text>
<path class="arr2" d="M580,150 L640,205"/>
<!-- fixture fallback -->
<rect class="box" x="330" y="250" width="250" height="52"/>
<text x="344" y="272" class="t">fixture fallback (f3)</text>
<text x="344" y="290" class="dim">ledger empty / fleet offline → marked</text>
<path class="arr" d="M455,250 L455,220"/>
<!-- the seam -->
<rect class="box" x="330" y="322" width="570" height="46"/>
<text x="344" y="344" class="t">state_json{source,job_count,nodes,fleet_source,agents,...} / update_json{refresh,auto_poll,sort,fold}</text>
<text x="344" y="362" class="dim">headless robot seam · RED-when-broken: neutralize ledger read → fixture only</text>
<path class="arr" d="M455,322 L455,302"/>
</svg>