.nornir/assets/machine-jera-routing.svg
<svg xmlns="http://www.w3.org/2000/svg" width="820" height="392" font-family="monospace" font-size="13">
<style>
.box{fill:#12303a;stroke:#6fd3f5;stroke-width:1.5;rx:6}
.old{fill:#3a1c1c;stroke:#e0785a}
.eng{fill:#123a24;stroke:#6fe0a0}
.gap{fill:#3a331c;stroke:#e0c65a}
.t{fill:#dceffa}.d{fill:#8fb8c8}.k{fill:#6fe0a0}.x{fill:#e0785a}.g{fill:#e0c65a}
.arr{stroke:#6fd3f5;stroke-width:1.5;fill:none;marker-end:url(#a)}
</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></defs>
<text x="16" y="24" class="t" font-size="15">machine.rs spawns → jera (edda), the ONE job/container/VM manager</text>
<rect class="box" x="16" y="44" width="240" height="52"/>
<text x="28" y="68" class="t">MachineSpec</text>
<text x="28" y="86" class="d">image · net · mounts · readiness</text>
<path class="arr" d="M136,96 L136,120"/>
<rect class="box eng" x="16" y="120" width="240" height="70"/>
<text x="28" y="142" class="k">#[cfg(feature = "jera")] SEAM</text>
<text x="28" y="160" class="t">.job_policy() → jera::JobPolicy</text>
<text x="28" y="178" class="d">Container ┆ Vm (classifier)</text>
<!-- container branch -->
<path class="arr" d="M256,150 L300,150"/>
<rect class="box eng" x="300" y="120" width="300" height="70"/>
<text x="312" y="142" class="k">JobPolicy::Container — AIRGAP ROUTE LANDED</text>
<text x="312" y="160" class="t">.to_jera_container_spec() net · mounts carry</text>
<text x="312" y="178" class="k">Isolated→NetMode::None→draupnir --network none</text>
<!-- vm branch -->
<rect class="box eng" x="300" y="204" width="300" height="70"/>
<text x="312" y="226" class="k">JobPolicy::Vm (seam landed)</text>
<text x="312" y="244" class="t">.to_jera_vm_spec() / .to_jera_vm_payload()</text>
<text x="312" y="262" class="d">→ jera::vm::BootSpec + agent::VmBoot → draupnir KVM</text>
<path class="arr" d="M136,190 L136,239 L300,239"/>
<!-- container honest gap -->
<rect class="box gap" x="620" y="120" width="184" height="70"/>
<text x="632" y="142" class="g">.jera_unsupported()</text>
<text x="632" y="160" class="k">net=None ✅ mounts ✅</text>
<text x="632" y="178" class="d">gap: named net only</text>
<path class="arr" d="M600,150 L620,150"/>
<!-- vm honest gap -->
<rect class="box gap" x="620" y="204" width="184" height="70"/>
<text x="632" y="226" class="g">.jera_vm_unsupported()</text>
<text x="632" y="244" class="x">disk-boot (no -kernel)</text>
<text x="632" y="262" class="d">net · provision · iso</text>
<path class="arr" d="M600,239 L620,239"/>
<!-- fallback -->
<path class="arr" d="M136,190 L136,300"/>
<rect class="box old" x="16" y="300" width="380" height="76"/>
<text x="28" y="322" class="x">FALLBACK (unchanged, working) — the direct path</text>
<text x="28" y="340" class="d">ContainerController: podman run -d / rm -f / exec</text>
<text x="28" y="358" class="d">KvmController: qemu-system-x86_64 (kept as-is)</text>
<rect class="box gap" x="416" y="300" width="388" height="76"/>
<text x="428" y="322" class="g">.jera_routable() / .jera_vm_routable() — the tripwires</text>
<text x="428" y="340" class="k">container: NAT + AIRGAP + mounts routable (flipped).</text>
<text x="428" y="358" class="d">named-net + vm (disk-boot) still keep the direct</text>
<text x="428" y="374" class="d">qemu/podman fallback; airgap never silently dropped.</text>
</svg>