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

nordisk/nornir

.nornir/assets/saga-replay.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 520" 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" 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>
  </defs>

  <rect x="0" y="0" width="1180" height="520" fill="url(#board)"/>
  <g stroke="#143a52" stroke-width="1"><line x1="0" y1="78" x2="1180" y2="78"/><line x1="0" y1="472" x2="1180" y2="472"/></g>
  <g fill="#16415c"><circle cx="40" cy="40" r="2"/><circle cx="1140" cy="40" r="2"/><circle cx="40" cy="492" r="2"/><circle cx="1140" cy="492" r="2"/></g>

  <text x="40" y="40" fill="#eaf6ff" font-size="22" font-weight="700">saga &#183; record &#8594; replay &#8594; matrix row</text>
  <text x="40" y="62" fill="#9fc9e0" font-size="15">a recorded UI journey becomes a headless robot test &#8212; a vanished widget is a <tspan fill="#ff7a7a" font-weight="700">RED</tspan> matrix row, no human at the screen</text>

  <g font-size="12.5">
    <line x1="900" y1="58" x2="940" y2="58" stroke="#6fd3f5" stroke-width="3" marker-end="url(#arr)"/>
    <text x="948" y="62" fill="#cfe6f5">transform</text>
  </g>

  <!-- record -->
  <rect x="36" y="120" width="262" height="252" rx="12" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
  <text x="167" y="148" fill="#eaf6ff" font-size="15" font-weight="700" text-anchor="middle">1 &#183; record</text>
  <text x="167" y="167" fill="#9fc9e0" font-size="10.5" text-anchor="middle">the live UI emits events</text>
  <g font-family="'DejaVu Sans Mono', monospace">
    <rect x="56" y="184" width="222" height="28" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.3"/><text x="167" y="202" fill="#bfe6ff" font-size="10" text-anchor="middle">nav /offert/7 OffertForm</text>
    <rect x="56" y="218" width="222" height="28" rx="5" fill="url(#slot)" stroke="#7fb0cc" stroke-width="1.3" stroke-dasharray="4 3"/><text x="167" y="236" fill="#9fc9e0" font-size="10" text-anchor="middle">log "loaded form"  (context)</text>
    <rect x="56" y="252" width="222" height="28" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.3"/><text x="167" y="270" fill="#bfe6ff" font-size="10" text-anchor="middle">click Submit</text>
  </g>
  <text x="167" y="306" fill="#86b3cc" font-size="10" text-anchor="middle" font-family="'DejaVu Sans', sans-serif">saga_events table: nav/click/log/error/state</text>
  <text x="167" y="322" fill="#86b3cc" font-size="10" text-anchor="middle" font-family="'DejaVu Sans', sans-serif">keyed by session + git SHA</text>
  <text x="167" y="346" fill="#a9d8ee" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">src/warehouse/saga_events.rs</text>

  <line x1="298" y1="246" x2="346" y2="246" stroke="#6fd3f5" stroke-width="3" marker-end="url(#arr)"/>

  <!-- replay plan -->
  <rect x="352" y="120" width="262" height="252" rx="12" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2.5"/>
  <text x="483" y="148" fill="#eaf6ff" font-size="15" font-weight="700" text-anchor="middle">2 &#183; ReplayPlan</text>
  <text x="483" y="167" fill="#9fc9e0" font-size="10.5" text-anchor="middle">only nav/click become steps</text>
  <g font-family="'DejaVu Sans Mono', monospace">
    <rect x="372" y="184" width="222" height="32" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.3"/><text x="483" y="204" fill="#bfe6ff" font-size="10" text-anchor="middle">step 1 &#183; nav OffertForm</text>
    <rect x="372" y="222" width="222" height="32" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.3"/><text x="483" y="242" fill="#bfe6ff" font-size="10" text-anchor="middle">step 2 &#183; click Submit</text>
  </g>
  <text x="483" y="286" fill="#86b3cc" font-size="10" text-anchor="middle" font-family="'DejaVu Sans', sans-serif">the log line is context, not a step</text>
  <text x="483" y="304" fill="#86b3cc" font-size="10" text-anchor="middle" font-family="'DejaVu Sans', sans-serif">&#9654; Replay turns a session into this plan</text>
  <text x="483" y="346" fill="#a9d8ee" font-size="9.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">engine crates/nornir-saga</text>

  <line x1="614" y1="246" x2="662" y2="246" stroke="#6fd3f5" stroke-width="3" marker-end="url(#arr)"/>

  <!-- matrix -->
  <rect x="668" y="120" width="476" height="252" rx="12" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
  <text x="906" y="148" fill="#eaf6ff" font-size="15" font-weight="700" text-anchor="middle">3 &#183; robot run &#8594; matrix rows</text>
  <text x="906" y="167" fill="#9fc9e0" font-size="10.5" text-anchor="middle">driven headless &#183; aspect robot-ui &#183; one row per step</text>

  <rect x="688" y="184" width="436" height="36" rx="5" fill="url(#slot)" stroke="#7CFFB2" stroke-width="1.6"/>
  <text x="706" y="206" fill="#7CFFB2" font-size="11">&#10003; PASS</text>
  <text x="800" y="206" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">nav OffertForm</text>

  <rect x="688" y="226" width="436" height="36" rx="5" fill="url(#slot)" stroke="#7CFFB2" stroke-width="1.6"/>
  <text x="706" y="248" fill="#7CFFB2" font-size="11">&#10003; PASS</text>
  <text x="800" y="248" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">click Submit</text>
  <text x="1030" y="248" fill="#9fc9e0" font-size="9" text-anchor="end">widget found</text>

  <text x="906" y="288" fill="#9fc9e0" font-size="10.5" text-anchor="middle">delete the Submit widget, re-run &#8594;</text>

  <rect x="688" y="298" width="436" height="36" rx="5" fill="#1a1416" stroke="#ff7a7a" stroke-width="1.6"/>
  <text x="706" y="320" fill="#ff7a7a" font-size="11">&#10007; FAIL</text>
  <text x="800" y="320" fill="#ffd9d9" font-size="10" font-family="'DejaVu Sans Mono', monospace">click Submit</text>
  <text x="1108" y="320" fill="#ff7a7a" font-size="9" text-anchor="end" font-family="'DejaVu Sans Mono', monospace">widget "Submit" not found</text>

  <text x="906" y="356" fill="#7fa8c4" font-size="9.5" text-anchor="middle">that RED row IS the regression report</text>

  <!-- ground -->
  <rect x="36" y="430" width="1108" height="30" rx="8" fill="url(#rail)" stroke="#7fc8ea" stroke-width="1.5"/>
  <text x="60" y="450" fill="#bcd9ec" font-size="11" font-family="'DejaVu Sans Mono', monospace">record &#8594; replay &#8594; matrix is end-to-end green in tests/saga_roundtrip.rs &#183; a replay whose target widget has GONE is the UI-regression seam</text>
</svg>