Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

.nornir/assets/replication-flow.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 820 380" font-family="ui-sans-serif,system-ui,sans-serif" font-size="13">
  <defs>
    <marker id="arw" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto" markerUnits="strokeWidth">
      <path d="M0,0 L7,3 L0,6 Z" fill="#64748b"/>
    </marker>
    <style>
      .box{fill:#0f172a;stroke:#334155;stroke-width:1.5}
      .lbl{fill:#e2e8f0}
      .sub{fill:#94a3b8;font-size:11px}
      .copy{fill:#065f46;stroke:#10b981}
      .skip{fill:#1e3a5f;stroke:#38bdf8}
      .edge{stroke:#64748b;stroke-width:1.5;fill:none}
      @media (prefers-color-scheme: light){
        .box{fill:#f1f5f9;stroke:#cbd5e1}
        .lbl{fill:#0f172a}.sub{fill:#475569}
        .copy{fill:#d1fae5;stroke:#059669}.skip{fill:#dbeafe;stroke:#2563eb}
      }
    </style>
  </defs>

  <text x="20" y="26" class="lbl" font-size="15" font-weight="700">Repository replication — read-from-source / write-to-dest, content-id idempotent</text>

  <rect class="box" x="20" y="64" width="170" height="90" rx="8"/>
  <text x="105" y="90" class="lbl" text-anchor="middle" font-weight="700">SOURCE store</text>
  <text x="105" y="110" class="sub" text-anchor="middle">repo.list() → ids</text>
  <text x="105" y="126" class="sub" text-anchor="middle">repo.fetch(id) → bytes</text>
  <text x="105" y="142" class="sub" text-anchor="middle">read-only (never mutated)</text>

  <rect class="box" x="325" y="52" width="180" height="130" rx="8"/>
  <text x="415" y="76" class="lbl" text-anchor="middle" font-weight="700">replicate_pairs()</text>
  <text x="415" y="98" class="sub" text-anchor="middle">for each source artifact:</text>
  <text x="415" y="114" class="sub" text-anchor="middle">cid = sha256(bytes)</text>
  <text x="415" y="130" class="sub" text-anchor="middle">dest.fetch(id) present</text>
  <text x="415" y="146" class="sub" text-anchor="middle">&amp; sha256 == cid ?</text>
  <text x="415" y="168" class="sub" text-anchor="middle">execute ⇒ dest.put()</text>

  <rect class="box copy" x="620" y="60" width="170" height="52" rx="8"/>
  <text x="705" y="82" class="lbl" text-anchor="middle" font-weight="700">COPY → dest</text>
  <text x="705" y="99" class="sub" text-anchor="middle">absent / content differs</text>

  <rect class="box skip" x="620" y="128" width="170" height="52" rx="8"/>
  <text x="705" y="150" class="lbl" text-anchor="middle" font-weight="700">SKIP</text>
  <text x="705" y="167" class="sub" text-anchor="middle">present by content id</text>

  <path class="edge" d="M190,110 L321,110" marker-end="url(#arw)"/>
  <text x="250" y="102" class="sub">list + fetch</text>
  <path class="edge" d="M505,100 C560,92 560,88 616,86" marker-end="url(#arw)"/>
  <path class="edge" d="M505,132 C560,140 560,150 616,152" marker-end="url(#arw)"/>

  <rect class="box" x="325" y="235" width="180" height="70" rx="8"/>
  <text x="415" y="261" class="lbl" text-anchor="middle" font-weight="700">DESTINATION store</text>
  <text x="415" y="281" class="sub" text-anchor="middle">writable repos only</text>
  <text x="415" y="296" class="sub" text-anchor="middle">read-only ⇒ fail closed</text>
  <path class="edge" d="M705,112 C620,180 520,200 440,231" marker-end="url(#arw)"/>

  <rect class="box" x="560" y="235" width="230" height="70" rx="8"/>
  <text x="675" y="257" class="lbl" text-anchor="middle" font-weight="700">ReplicationReport</text>
  <text x="675" y="277" class="sub" text-anchor="middle">examined · copied · skipped</text>
  <text x="675" y="292" class="sub" text-anchor="middle">would_copy · failed · truncated</text>
  <path class="edge" d="M505,270 L556,270" marker-end="url(#arw)"/>

  <text x="20" y="345" class="sub">Idempotent: a re-run over an unchanged source copies nothing (every artifact SKIPs). Dry-run (default) writes nothing; --execute copies.</text>
  <text x="20" y="363" class="sub">Two surfaces, one engine: CLI `replicate --from --to` (two separate file stores) · gRPC `ReplicationService.Replicate` (two repos, one server).</text>
</svg>