.nornir/assets/holger_marriage_flow.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 560" 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="rail" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#173d57"/>
<stop offset="1" stop-color="#0c2438"/>
</linearGradient>
<linearGradient id="slot" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#123448"/>
<stop offset="1" stop-color="#0a2032"/>
</linearGradient>
<marker id="arr" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto">
<path d="M0 0 L7 3 L0 6 Z" fill="#6fd3f5"/>
</marker>
<marker id="arrb" markerWidth="9" markerHeight="9" refX="2" refY="3" orient="auto">
<path d="M7 0 L0 3 L7 6 Z" fill="#6fd3f5"/>
</marker>
<marker id="arrd" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto">
<path d="M0 0 L7 3 L0 6 Z" fill="#7fb0cc"/>
</marker>
</defs>
<!-- PCB substrate -->
<rect x="0" y="0" width="1180" height="560" fill="url(#board)"/>
<g stroke="#143a52" stroke-width="1">
<line x1="0" y1="76" x2="1180" y2="76"/>
<line x1="0" y1="520" x2="1180" y2="520"/>
</g>
<g fill="#16415c">
<circle cx="40" cy="40" r="2"/><circle cx="1140" cy="40" r="2"/>
<circle cx="40" cy="540" r="2"/><circle cx="1140" cy="540" r="2"/>
</g>
<!-- title -->
<text x="40" y="44" fill="#eaf6ff" font-size="22" font-weight="700">The holger marriage — nornir ⇆ holger, in-process</text>
<text x="40" y="66" fill="#9fc9e0" font-size="15">nornir links <tspan fill="#bfe6ff" font-weight="700">holger-server-lib</tspan> and drives a live registry inside its own process — no gRPC, no serialization</text>
<!-- legend -->
<g font-size="12">
<line x1="820" y1="38" x2="856" y2="38" stroke="#6fd3f5" stroke-width="3"/>
<text x="864" y="42" fill="#cfe6f5">in-process call</text>
<line x1="990" y1="38" x2="1026" y2="38" stroke="#7fb0cc" stroke-width="2.5" stroke-dasharray="5 4"/>
<text x="1034" y="42" fill="#cfe6f5">dev / upstream</text>
</g>
<!-- ===================== NORNIR PROCESS (left) ===================== -->
<rect x="36" y="130" width="220" height="300" rx="12" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="146" y="160" fill="#eaf6ff" font-size="15" font-weight="700" text-anchor="middle">nornir process</text>
<text x="146" y="180" fill="#9fc9e0" font-size="10.5" text-anchor="middle">embed-holger feature</text>
<rect x="58" y="200" width="176" height="48" rx="6" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.6"/>
<text x="146" y="220" fill="#bfe6ff" font-size="11" text-anchor="middle">📦 Holger viz pane</text>
<text x="146" y="237" fill="#9fc9e0" font-size="9" text-anchor="middle">lists crates in the dev mirror</text>
<rect x="58" y="262" width="176" height="30" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="146" y="281" fill="#bfe6ff" font-size="10" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">list_repositories()</text>
<rect x="58" y="298" width="176" height="30" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="146" y="317" fill="#bfe6ff" font-size="10" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">backend_repository.list()</text>
<text x="146" y="350" fill="#86b3cc" font-size="10" text-anchor="middle">links holger-server-lib</text>
<text x="146" y="366" fill="#86b3cc" font-size="10" text-anchor="middle">drives a registry in-process</text>
<text x="146" y="386" fill="#7CFFB2" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">same Arc<dyn Backend>, no copy</text>
<text x="146" y="406" fill="#7fa8c4" font-size="9.5" text-anchor="middle">consumer half lives in nornir</text>
<!-- nornir <-> holger lib : in-process, bidirectional -->
<g stroke="#6fd3f5" stroke-width="3" fill="none">
<path d="M260 280 H320" marker-end="url(#arr)" marker-start="url(#arrb)"/>
</g>
<text x="294" y="268" fill="#86b3cc" font-size="9.5" text-anchor="middle">in-process</text>
<!-- ===================== HOLGER-SERVER-LIB (center) ===================== -->
<rect x="324" y="118" width="244" height="324" rx="12" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="446" y="146" fill="#eaf6ff" font-size="15" font-weight="700" text-anchor="middle">holger-server-lib</text>
<text x="446" y="166" fill="#9fc9e0" font-size="10.5" text-anchor="middle">embedded in-process (no gRPC socket)</text>
<!-- Holger functional API -->
<rect x="346" y="184" width="200" height="118" rx="7" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.6"/>
<text x="446" y="203" fill="#bfe6ff" font-size="11" text-anchor="middle" font-weight="700">Holger functional API</text>
<text x="446" y="223" fill="#bfe6ff" font-size="10" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">list_repositories()</text>
<text x="446" y="243" fill="#bfe6ff" font-size="10" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">fetch(repo, &ArtifactId)</text>
<text x="446" y="263" fill="#bfe6ff" font-size="10" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">put(repo, &id, &[u8])</text>
<text x="446" y="283" fill="#9fc9e0" font-size="9" text-anchor="middle">put rejects read-only repos</text>
<text x="446" y="296" fill="#86b3cc" font-size="9" text-anchor="middle">the parsed RON config IS the Holger value</text>
<!-- re-exported trait -->
<rect x="346" y="314" width="200" height="62" rx="7" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.6"/>
<text x="446" y="333" fill="#bfe6ff" font-size="10.5" text-anchor="middle">repositories[i].backend_repository</text>
<text x="446" y="350" fill="#a9d8ee" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">pub use RepositoryBackendTrait</text>
<text x="446" y="365" fill="#a9d8ee" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">ArtifactEntry · ArtifactId</text>
<text x="446" y="396" fill="#86b3cc" font-size="9.5" text-anchor="middle">calls straight through Arc<dyn RepositoryBackendTrait></text>
<text x="446" y="412" fill="#7CFFB2" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">no gRPC · no HTTP · no serialization</text>
<text x="446" y="430" fill="#7fa8c4" font-size="9.5" text-anchor="middle">dev_pair_ron() emits the pair →</text>
<!-- lib -> dev pair -->
<g stroke="#6fd3f5" stroke-width="3" fill="none">
<path d="M572 226 H636 V206 H700" marker-end="url(#arr)"/>
<path d="M572 226 H636 V356 H700" marker-end="url(#arr)"/>
</g>
<circle cx="636" cy="226" r="4" fill="#bfecff"/>
<!-- ===================== DEV PAIR: /cache (top right) ===================== -->
<rect x="704" y="150" width="252" height="112" rx="11" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="830" y="176" fill="#eaf6ff" font-size="14" font-weight="700" text-anchor="middle">/cache — crates.io mirror</text>
<text x="830" y="194" fill="#9fc9e0" font-size="10" text-anchor="middle">writable-znippy primary · crates-io upstream</text>
<text x="830" y="212" fill="#86b3cc" font-size="10" text-anchor="middle">transparent mirror · write-through on miss</text>
<text x="830" y="232" fill="#a9d8ee" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">ron_writable_archive: Some(...)</text>
<text x="830" y="250" fill="#7fa8c4" font-size="9.5" text-anchor="middle">dev shape (not read-only drift)</text>
<!-- /cache upstream dashed exit -->
<path d="M956 188 H1020 V206 H1086" stroke="#7fb0cc" stroke-width="2.5" fill="none" stroke-dasharray="6 4" marker-end="url(#arrd)"/>
<text x="1058" y="184" fill="#86b3cc" font-size="9.5" text-anchor="middle">crates.io</text>
<text x="1058" y="232" fill="#86b3cc" font-size="9.5" text-anchor="middle">fill on miss</text>
<!-- ===================== DEV PAIR: /sparring (bottom right) ===================== -->
<rect x="704" y="300" width="252" height="112" rx="11" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="830" y="326" fill="#eaf6ff" font-size="14" font-weight="700" text-anchor="middle">/sparring — release-rehearsal</text>
<text x="830" y="344" fill="#9fc9e0" font-size="10" text-anchor="middle">writable registry · the rehearsal target</text>
<text x="830" y="362" fill="#86b3cc" font-size="10" text-anchor="middle">cargo publish here, dry-run a release</text>
<text x="830" y="382" fill="#a9d8ee" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">seal → freeze into drift snapshot</text>
<text x="830" y="400" fill="#7fa8c4" font-size="9.5" text-anchor="middle">dev shape (writable, then sealed)</text>
<!-- /sparring seal dashed exit -->
<path d="M956 382 H1020 V356 H1086" stroke="#7fb0cc" stroke-width="2.5" fill="none" stroke-dasharray="6 4" marker-end="url(#arrd)"/>
<text x="1058" y="352" fill="#86b3cc" font-size="9.5" text-anchor="middle">static drift</text>
<text x="1058" y="396" fill="#86b3cc" font-size="9.5" text-anchor="middle">snapshot</text>
<!-- ===================== GROUND RAIL ===================== -->
<rect x="36" y="452" width="920" height="56" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
<g fill="#0a1c2c" stroke="#7fc8ea" stroke-width="1.5">
<circle cx="80" cy="480" r="4"/><circle cx="360" cy="480" r="4"/>
<circle cx="640" cy="480" r="4"/><circle cx="900" cy="480" r="4"/>
</g>
<text x="96" y="479" fill="#dff1ff" font-size="15" font-weight="700">in-process</text>
<text x="236" y="475" fill="#bcd9ec" font-size="11.5">nornir links holger-server-lib · drives a live registry with zero serialization — the nornir ⇆ holger marriage</text>
<text x="236" y="496" fill="#7fa8c4" font-size="10.5" font-family="'DejaVu Sans Mono', monospace">Holger::{list_repositories,fetch,put} · backend_repository via re-exported RepositoryBackendTrait · dev_pair_ron()</text>
</svg>