Skip to content

Instantly share code, notes, and snippets.

@Ladas
Last active February 7, 2026 19:59
Show Gist options
  • Select an option

  • Save Ladas/ca102327fc0af2d5d8a7b4b8d2d4f910 to your computer and use it in GitHub Desktop.

Select an option

Save Ladas/ca102327fc0af2d5d8a7b4b8d2d4f910 to your computer and use it in GitHub Desktop.
blog/claude-code-agent-ops/01/tdd-ci-loop-animated
Display the source blob
Display the rendered blob
Raw
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 460" font-family="system-ui, -apple-system, sans-serif">
<defs>
<filter id="shadow" x="-2%" y="-2%" width="104%" height="108%">
<feDropShadow dx="1" dy="2" stdDeviation="3" flood-opacity="0.08"/>
</filter>
<marker id="arrow-blue" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#4a9eff"/>
</marker>
<marker id="arrow-red" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#ee5a24"/>
</marker>
<marker id="arrow-green" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#00b894"/>
</marker>
<marker id="arrow-purple" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#8854d0"/>
</marker>
</defs>
<style>
@keyframes flowDash { to { stroke-dashoffset: -16; } }
.flow { stroke-dasharray: 8; animation: flowDash 0.8s linear infinite; }
@keyframes pulse { 0%,100% { stroke-width: 1.5; } 50% { stroke-width: 3; } }
.active { animation: pulse 2s ease-in-out infinite; }
@keyframes travel {
0% { offset-distance: 0%; opacity: 1; }
100% { offset-distance: 100%; opacity: 1; }
}
</style>
<!-- Title -->
<text x="400" y="28" text-anchor="middle" fill="#1a1a2e" font-size="20" font-weight="bold">tdd:ci — Agent-Managed CI Loop</text>
<text x="400" y="48" text-anchor="middle" fill="#666" font-size="12">Automated feedback loop with escalation</text>
<!-- Node: Write Code -->
<rect x="40" y="80" width="150" height="60" rx="10" fill="#f0f7ff" stroke="#4a9eff" stroke-width="1.5" filter="url(#shadow)" class="active"/>
<text x="115" y="107" text-anchor="middle" fill="#4a9eff" font-size="14" font-weight="bold">Write Code</text>
<text x="115" y="127" text-anchor="middle" fill="#888" font-size="11">Claude Code</text>
<!-- Node: Local Checks -->
<rect x="250" y="80" width="150" height="60" rx="10" fill="#f0f7ff" stroke="#4a9eff" stroke-width="1.5" filter="url(#shadow)"/>
<text x="325" y="107" text-anchor="middle" fill="#4a9eff" font-size="14" font-weight="bold">Local Checks</text>
<text x="325" y="127" text-anchor="middle" fill="#888" font-size="11">pre-commit, ruff</text>
<!-- Node: Push -->
<rect x="460" y="80" width="150" height="60" rx="10" fill="#f0f7ff" stroke="#4a9eff" stroke-width="1.5" filter="url(#shadow)"/>
<text x="535" y="107" text-anchor="middle" fill="#4a9eff" font-size="14" font-weight="bold">Push to PR</text>
<text x="535" y="127" text-anchor="middle" fill="#888" font-size="11">git push</text>
<!-- Node: CI Runs -->
<rect x="600" y="190" width="170" height="70" rx="10" fill="#fffbf0" stroke="#e8a817" stroke-width="1.5" filter="url(#shadow)"/>
<text x="685" y="218" text-anchor="middle" fill="#c48a00" font-size="14" font-weight="bold">CI Runs</text>
<text x="685" y="238" text-anchor="middle" fill="#888" font-size="11">12+ checks</text>
<text x="685" y="253" text-anchor="middle" fill="#aaa" font-size="10">gh pr checks --watch</text>
<!-- Node: MERGE -->
<rect x="625" y="315" width="120" height="45" rx="22" fill="#00b894" filter="url(#shadow)"/>
<text x="685" y="344" text-anchor="middle" fill="#fff" font-size="16" font-weight="bold">MERGE</text>
<!-- Node: RCA Analyze -->
<rect x="290" y="295" width="190" height="70" rx="10" fill="#fef5f5" stroke="#ee5a24" stroke-width="1.5" filter="url(#shadow)"/>
<text x="385" y="322" text-anchor="middle" fill="#ee5a24" font-size="14" font-weight="bold">rca:ci Analyze</text>
<text x="385" y="342" text-anchor="middle" fill="#888" font-size="11">5-phase investigation</text>
<text x="385" y="357" text-anchor="middle" fill="#888" font-size="11">→ propose fix</text>
<!-- Node: Human Review -->
<rect x="50" y="295" width="170" height="60" rx="10" fill="#faf5ff" stroke="#8854d0" stroke-width="1.5" filter="url(#shadow)"/>
<text x="135" y="322" text-anchor="middle" fill="#8854d0" font-size="14" font-weight="bold">Human Review</text>
<text x="135" y="342" text-anchor="middle" fill="#888" font-size="11">approve fix, iterate</text>
<!-- Arrows: Happy path -->
<line x1="190" y1="110" x2="248" y2="110" stroke="#4a9eff" stroke-width="2" class="flow" marker-end="url(#arrow-blue)"/>
<line x1="400" y1="110" x2="458" y2="110" stroke="#4a9eff" stroke-width="2" class="flow" marker-end="url(#arrow-blue)"/>
<path d="M 610 110 Q 685 110 685 188" fill="none" stroke="#4a9eff" stroke-width="2" class="flow" marker-end="url(#arrow-blue)"/>
<!-- Arrow: Pass -->
<line x1="685" y1="260" x2="685" y2="313" stroke="#00b894" stroke-width="2" marker-end="url(#arrow-green)"/>
<text x="700" y="288" fill="#00b894" font-size="12" font-weight="bold">Pass</text>
<!-- Arrow: Fail -->
<path d="M 598 225 L 482 320" fill="none" stroke="#ee5a24" stroke-width="2" class="flow" marker-end="url(#arrow-red)"/>
<text x="535" y="270" fill="#ee5a24" font-size="12" font-weight="bold">Fail</text>
<!-- Arrow: RCA → Human -->
<line x1="288" y1="330" x2="222" y2="330" stroke="#8854d0" stroke-width="2" class="flow" marker-end="url(#arrow-purple)"/>
<!-- Arrow: Human → back to Code -->
<path d="M 135 293 Q 135 200 115 142" fill="none" stroke="#8854d0" stroke-width="2" class="flow" marker-end="url(#arrow-purple)"/>
<text x="95" y="218" fill="#8854d0" font-size="11" font-weight="bold" transform="rotate(-90 95 218)">iterate</text>
<!-- Traveling dot on happy path -->
<circle r="5" fill="#4a9eff" opacity="0.8">
<animateMotion dur="5s" repeatCount="indefinite" path="M 115,110 L 325,110 L 535,110 Q 685,110 685,225 L 685,340"/>
<animate attributeName="r" values="4;6;4" dur="1.2s" repeatCount="indefinite"/>
</circle>
<!-- Traveling dot on failure path -->
<circle r="4" fill="#ee5a24" opacity="0.6">
<animateMotion dur="5s" repeatCount="indefinite" begin="2.5s" path="M 600,225 L 385,330 L 135,325 Q 135,200 115,140 L 325,110 L 535,110 Q 685,110 685,225"/>
</circle>
<!-- Escalation note -->
<rect x="50" y="400" width="700" height="48" rx="10" fill="#faf5ff" stroke="#8854d0" stroke-width="1" filter="url(#shadow)"/>
<text x="400" y="422" text-anchor="middle" fill="#8854d0" font-size="13" font-weight="bold">After 3 failures → escalate to tdd:hypershift (live cluster debugging)</text>
<text x="400" y="440" text-anchor="middle" fill="#888" font-size="11">Or use tdd:kind for quick local iteration</text>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment