crates/jera/.nornir/assets/container-spec-flow.svg
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="470" viewBox="0 0 900 470" font-family="ui-sans-serif,system-ui,sans-serif">
<defs>
<marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0 0 L10 5 L0 10 z" fill="#6fd3f5"/>
</marker>
<marker id="arrG" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0 0 L10 5 L0 10 z" fill="#c9a24b"/>
</marker>
</defs>
<style>
.box{fill:#0f1720;stroke:#6fd3f5;stroke-width:1.5;rx:8}
.eng{fill:#0c1a12;stroke:#5fbf7f;stroke-width:1.4;rx:8}
.led{fill:#1a1409;stroke:#c9a24b;stroke-width:1.4;rx:8}
.gap{fill:#1c0f12;stroke:#e0705f;stroke-width:1.4;stroke-dasharray:5 3;rx:8}
.t{fill:#dfe9f0;font-size:13px}
.h{fill:#6fd3f5;font-size:13px;font-weight:700}
.hg{fill:#7fe0a0;font-size:13px;font-weight:700}
.hl{fill:#d9b968;font-size:13px;font-weight:700}
.hr{fill:#e69182;font-size:13px;font-weight:700}
.s{fill:#9fb3c0;font-size:11px}
.e{stroke:#6fd3f5;stroke-width:1.6;fill:none}
.eg{stroke:#c9a24b;stroke-width:1.6;fill:none;stroke-dasharray:4 3}
.er{stroke:#e0705f;stroke-width:1.6;fill:none;stroke-dasharray:5 3}
</style>
<text x="20" y="26" class="h" font-size="15">jera::container — ContainerSpec → draupnir's ONE OCI engine (net + mounts knobs)</text>
<text x="20" y="44" class="s">jera keeps the descriptor; instance-firing lives in draupnir. net/mounts are additive, default = unchanged.</text>
<!-- ContainerSpec -->
<rect class="box" x="20" y="76" width="250" height="200"/>
<text x="34" y="98" class="h">ContainerSpec</text>
<text x="34" y="120" class="t">image · name · cmd · env · ports</text>
<text x="34" y="146" class="hg">net: NetMode (airgap knob)</text>
<text x="34" y="164" class="s">Default | None | Host | Bridge</text>
<text x="34" y="182" class="hl">mounts: Vec<BindMount> (-v)</text>
<text x="34" y="200" class="s">host : container [: ro]</text>
<text x="34" y="224" class="s">all fields #[serde(default)] +</text>
<text x="34" y="240" class="s">skip-when-empty ⇒ existing</text>
<text x="34" y="256" class="s">specs byte-identical (additive)</text>
<!-- mappers -->
<rect class="box" x="330" y="76" width="240" height="60"/>
<text x="344" y="98" class="h">to_draupnir()</text>
<text x="344" y="120" class="s">image + name + cmd/env/ports → BootSpec</text>
<rect class="eng" x="330" y="152" width="240" height="52"/>
<text x="344" y="174" class="hl">bind_strings()</text>
<text x="344" y="192" class="s">mounts → ["host:container:ro", …]</text>
<rect class="gap" x="330" y="220" width="240" height="56"/>
<text x="344" y="242" class="hr">network_arg() → --network none</text>
<text x="344" y="260" class="s">rendered contract; engine hook = draupnir TODO</text>
<!-- draupnir engine -->
<rect class="eng" x="630" y="120" width="250" height="120"/>
<text x="644" y="142" class="hg">draupnir::container</text>
<text x="644" y="164" class="hg">ContainerBoot</text>
<text x="644" y="188" class="t">run_to_completion_with_binds</text>
<text x="644" y="206" class="s">bollard/podman REST · HostConfig</text>
<text x="644" y="226" class="s">binds ✓ applied · network_mode ✗ (gap)</text>
<!-- ledger -->
<rect class="led" x="330" y="330" width="550" height="80"/>
<text x="344" y="352" class="hl">run_recorded — one ledger wrap (L5)</text>
<text x="344" y="374" class="s">open running row → drive engine → done|failed + Health(Starting→Gone|Failed)</text>
<text x="344" y="396" class="s">production carries bind_strings(); the generic mock seam proves it daemon-free</text>
<!-- edges -->
<path class="e" d="M270 140 H326" marker-end="url(#arr)"/>
<path class="eg" d="M270 176 H326" marker-end="url(#arrG)"/>
<path class="er" d="M270 244 H326" marker-end="url(#arrG)"/>
<path class="e" d="M570 106 C600 106 610 150 626 160" marker-end="url(#arr)"/>
<path class="eg" d="M570 178 H626" marker-end="url(#arrG)"/>
<path class="er" d="M570 248 C600 260 700 250 720 244" marker-end="url(#arrG)"/>
<path class="eg" d="M755 240 V326" marker-end="url(#arrG)"/>
</svg>