.nornir/assets/yggdrasil-scales.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 720" 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="crown" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#1c4a33"/>
<stop offset="1" stop-color="#0e2e20"/>
</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>
</defs>
<!-- PCB substrate -->
<rect x="0" y="0" width="1180" height="720" fill="url(#board)"/>
<g stroke="#143a52" stroke-width="1">
<line x1="0" y1="76" x2="1180" y2="76"/>
<line x1="0" y1="676" x2="1180" y2="676"/>
</g>
<g fill="#16415c">
<circle cx="40" cy="40" r="2"/><circle cx="1140" cy="40" r="2"/>
<circle cx="40" cy="700" r="2"/><circle cx="1140" cy="700" r="2"/>
</g>
<!-- title -->
<text x="40" y="44" fill="#eaf6ff" font-size="22" font-weight="700">Yggdrasil — the infra crown lands</text>
<text x="470" y="44" fill="#9fc9e0" font-size="14">the warehouse <tspan fill="#bfe6ff" font-weight="700">is</tspan> the graph — one band of Iceberg rows per scale</text>
<!-- legend -->
<g font-size="12.5">
<rect x="812" y="52" width="16" height="12" rx="2" fill="url(#crown)" stroke="#6fe6a6" stroke-width="1.5"/>
<text x="836" y="63" fill="#cfe6f5">landed 2026-07-14</text>
<rect x="984" y="52" width="16" height="12" rx="2" fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.2"/>
<text x="1008" y="63" fill="#cfe6f5">existing</text>
</g>
<!-- ===================== SCALE LADDER (roots -> crown) ===================== -->
<!-- crown (new) -->
<rect x="300" y="104" width="580" height="70" rx="10" fill="url(#crown)" stroke="#6fe6a6" stroke-width="2.5"/>
<text x="590" y="130" fill="#eafff2" font-size="15" font-weight="700" text-anchor="middle">CROWN · infra / deploy</text>
<text x="590" y="152" fill="#b7f0cf" font-size="12" text-anchor="middle">infra_nodes · infra_edges — machines · services · vms · worker-groups</text>
<text x="590" y="168" fill="#8fd6ad" font-size="10.5" text-anchor="middle">runs_on · hosts · deploys · member_of</text>
<!-- runtime band (new) -->
<rect x="300" y="186" width="580" height="52" rx="10" fill="url(#crown)" stroke="#6fe6a6" stroke-width="2.5"/>
<text x="590" y="210" fill="#eafff2" font-size="14" font-weight="700" text-anchor="middle">RUNTIME / trace</text>
<text x="590" y="228" fill="#b7f0cf" font-size="11.5" text-anchor="middle">runtime_spans — span_id · parent · service · op · start · dur_us · machine · status</text>
<!-- existing scales (condensed) -->
<g>
<rect x="300" y="250" width="580" height="34" rx="8" fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.4"/>
<text x="590" y="272" fill="#cfe6f5" font-size="12" text-anchor="middle">architecture / system — architecture_wiring · warehouse_access_edges</text>
<rect x="300" y="292" width="580" height="34" rx="8" fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.4"/>
<text x="590" y="314" fill="#cfe6f5" font-size="12" text-anchor="middle">dependency / repo / crate — dep_graph_edges · clone_events · semver_diffs</text>
<rect x="300" y="334" width="580" height="34" rx="8" fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.4"/>
<text x="590" y="356" fill="#cfe6f5" font-size="12" text-anchor="middle">module / call / symbol — call_edges · symbol_facts · scip_occurrences</text>
<rect x="300" y="376" width="580" height="34" rx="8" fill="url(#chip)" stroke="#3f7a9c" stroke-width="1.2"/>
<text x="590" y="398" fill="#9fc9e0" font-size="12" text-anchor="middle">line / debug · instruction (roots) — dwarf_* · gimli_*</text>
</g>
<!-- ===================== PRODUCER (left) ===================== -->
<rect x="36" y="150" width="196" height="120" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="134" y="180" fill="#eaf6ff" font-size="14" font-weight="700" text-anchor="middle">jera JobRecord</text>
<text x="134" y="200" fill="#bfe6ff" font-size="10.5" text-anchor="middle">the durable job ledger</text>
<text x="134" y="220" fill="#9fc9e0" font-size="10" text-anchor="middle">node → machine</text>
<text x="134" y="236" fill="#9fc9e0" font-size="10" text-anchor="middle">kind → service</text>
<text x="134" y="252" fill="#9fc9e0" font-size="10" text-anchor="middle">elapsed_ms → dur_us</text>
<!-- producer fn -->
<rect x="36" y="288" width="196" height="66" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="134" y="314" fill="#eaf6ff" font-size="12.5" font-weight="700" text-anchor="middle">warehouse::yggdrasil</text>
<text x="134" y="332" fill="#9fc9e0" font-size="10" text-anchor="middle">infra_from_jobs</text>
<text x="134" y="346" fill="#9fc9e0" font-size="10" text-anchor="middle">spans_from_jobs</text>
<!-- trace: ledger -> producer -->
<line x1="134" y1="270" x2="134" y2="288" stroke="#6fd3f5" stroke-width="2.5"/>
<!-- trace: producer -> crown + runtime -->
<path d="M232 316 H266 V139 H300" fill="none" stroke="#6fe6a6" stroke-width="2.5"/>
<path d="M232 322 H278 V212 H300" fill="none" stroke="#6fe6a6" stroke-width="2.5"/>
<polygon points="300,139 292,135 292,143" fill="#6fe6a6"/>
<polygon points="300,212 292,208 292,216" fill="#6fe6a6"/>
<!-- ===================== SINK (right) ===================== -->
<rect x="948" y="150" width="196" height="120" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="1046" y="180" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">IcebergWarehouse</text>
<text x="1046" y="200" fill="#bfe6ff" font-size="10.5" text-anchor="middle">skade-katalog redb</text>
<text x="1046" y="222" fill="#9fc9e0" font-size="10" text-anchor="middle">record_infra_nodes</text>
<text x="1046" y="238" fill="#9fc9e0" font-size="10" text-anchor="middle">record_infra_edges</text>
<text x="1046" y="254" fill="#9fc9e0" font-size="10" text-anchor="middle">record_runtime_spans</text>
<!-- trace: crown/runtime -> warehouse -->
<path d="M880 139 H914 V200 H948" fill="none" stroke="#6fe6a6" stroke-width="2.5"/>
<path d="M880 212 H930 V212 H948" fill="none" stroke="#6fe6a6" stroke-width="2.5"/>
<polygon points="948,200 940,196 940,204" fill="#6fe6a6"/>
<polygon points="948,212 940,208 940,216" fill="#6fe6a6"/>
<!-- caption strip -->
<text x="40" y="430" fill="#86b3cc" font-size="11.5">snapshot-enveloped & workspace-scoped exactly like dep_graph_edges · each record_* writes one snapshot_id + one ts_micros</text>
<!-- wiring note -->
<rect x="300" y="452" width="580" height="200" rx="10" fill="#081722" stroke="#173d57" stroke-width="1.4"/>
<text x="590" y="480" fill="#bfe6ff" font-size="13" font-weight="700" text-anchor="middle">wired producer — monitor::republish_with</text>
<text x="590" y="506" fill="#9fc9e0" font-size="11" text-anchor="middle">every workspace populate reads the job ledger (lock-tolerant) and</text>
<text x="590" y="524" fill="#9fc9e0" font-size="11" text-anchor="middle">persists the crown + runtime band from real ledger rows</text>
<text x="590" y="556" fill="#8fd6ad" font-size="11" text-anchor="middle" font-weight="700">wh.record_yggdrasil_from_jobs(ws, &jobs)</text>
<text x="590" y="586" fill="#86b3cc" font-size="10.5" text-anchor="middle">RED-when-broken test: record N nodes/edges/spans → query back field-identical</text>
<text x="590" y="604" fill="#86b3cc" font-size="10.5" text-anchor="middle">+ workspace-scope isolation + empty-ledger no-op</text>
<text x="590" y="632" fill="#6f9fb8" font-size="10" text-anchor="middle">follow-ups: skidbladnir ServiceSpec · tunnr/draupnir boots · roster cores/mem · read-only supergraph viz pane</text>
</svg>