provisioning-code/resources/diagrams/tries/arch-diag-v2_cosmos.svg

500 lines
31 KiB
XML
Raw Normal View History

2026-07-09 20:36:57 +01:00
<svg viewBox="0 0 1280 900" xmlns="http://www.w3.org/2000/svg">
<style>
.orbit-flow { animation: orbit-dash 4s linear infinite; }
@keyframes orbit-dash { from { stroke-dashoffset: 40; } to { stroke-dashoffset: 0; } }
.ring-glow { animation: ring-breathe 3s ease-in-out infinite; }
@keyframes ring-breathe { 0%,100% { opacity: 0.06; } 50% { opacity: 0.18; } }
.spoke { animation: spoke-dash 2s linear infinite; }
@keyframes spoke-dash { from { stroke-dashoffset: 16; } to { stroke-dashoffset: 0; } }
.health { animation: pulse 2.2s ease-in-out infinite; }
.health-d1 { animation-delay: 0.4s; }
.health-d2 { animation-delay: 0.8s; }
.health-d3 { animation-delay: 1.2s; }
.health-d4 { animation-delay: 1.6s; }
@keyframes pulse { 0%,100% { opacity: 0.35; } 50% { opacity: 1; } }
.https-beam { animation: https-p 4s ease-in-out infinite; }
@keyframes https-p { 0%,100% { opacity: 0.15; stroke-width: 1.5; } 50% { opacity: 0.7; stroke-width: 2.5; } }
.https-label { animation: https-lbl 4s ease-in-out infinite; }
@keyframes https-lbl { 0%,100% { opacity: 0.3; } 50% { opacity: 1; } }
.solid-border { animation: solid-glow 3.5s ease-in-out infinite; }
@keyframes solid-glow { 0%,100% { stroke-opacity: 0.3; } 50% { stroke-opacity: 0.7; } }
.hub-pulse { animation: hub-beat 3s ease-in-out infinite; }
@keyframes hub-beat { 0%,100% { opacity: 0.3; } 50% { opacity: 0.6; } }
.cred-dot { opacity: 0; }
.db-flow { animation: db-dash 2.5s linear infinite; }
@keyframes db-dash { from { stroke-dashoffset: 12; } to { stroke-dashoffset: 0; } }
</style>
<defs>
<filter id="glow-blue" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-orange" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-pink" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-purple" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-cyan" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glow-gold" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="soft-shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="2" stdDeviation="8" flood-color="#000" flood-opacity="0.5"/>
</filter>
<filter id="ring-glow-f" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<radialGradient id="bg-radial" cx="50%" cy="42%" r="55%">
<stop offset="0%" stop-color="#111520"/>
<stop offset="100%" stop-color="#0a0c10"/>
</radialGradient>
<radialGradient id="hub-glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#94a3b8" stop-opacity="0.12"/>
<stop offset="100%" stop-color="#94a3b8" stop-opacity="0"/>
</radialGradient>
<linearGradient id="orch-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#2a2016"/><stop offset="100%" stop-color="#1a150f"/>
</linearGradient>
<linearGradient id="ctrl-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#1a1630"/><stop offset="100%" stop-color="#110f1e"/>
</linearGradient>
<linearGradient id="vault-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#2a1630"/><stop offset="100%" stop-color="#1a0f1e"/>
</linearGradient>
<linearGradient id="ext-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#2a1620"/><stop offset="100%" stop-color="#1a0f14"/>
</linearGradient>
<linearGradient id="mcp-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#0f2a2e"/><stop offset="100%" stop-color="#0a1c1e"/>
</linearGradient>
<linearGradient id="surreal-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#1a1428"/><stop offset="100%" stop-color="#110e1c"/>
</linearGradient>
<linearGradient id="cli-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#1a2a42"/><stop offset="100%" stop-color="#0f1a2e"/>
</linearGradient>
<marker id="arr-blue" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
<polygon points="0 0, 8 3, 0 6" fill="#4a9eff"/>
</marker>
<marker id="arr-silver" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
<polygon points="0 0, 8 3, 0 6" fill="#94a3b8"/>
</marker>
<marker id="arr-gold" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto">
<polygon points="0 0, 8 3, 0 6" fill="#fbbf24"/>
</marker>
<!-- Orbital paths for animateMotion -->
<path id="orbit-cw" d="M 640,192 A 180,180 0 1,1 640,552 A 180,180 0 1,1 640,192 Z" fill="none"/>
<path id="orbit-ccw" d="M 640,192 A 180,180 0 1,0 640,552 A 180,180 0 1,0 640,192 Z" fill="none"/>
<!-- Credential flow: Orch(top) ↔ Vault(upper-left) short arcs -->
<path id="path-orch-vault" d="M 640,192 A 180,180 0 0,0 469,316" fill="none"/>
<path id="path-vault-orch" d="M 469,316 A 180,180 0 0,1 640,192" fill="none"/>
<path id="path-cli-orch" d="M 640,98 L 640,117" fill="none"/>
</defs>
<!-- ═══ BACKGROUND ═══ -->
<rect width="1280" height="900" fill="url(#bg-radial)"/>
<g opacity="0.03">
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#fff" stroke-width="0.5"/>
</pattern>
<rect width="1280" height="900" fill="url(#grid)"/>
</g>
<!-- Star field -->
<g opacity="0.35">
<circle cx="95" cy="145" r="0.8" fill="#fff"/><circle cx="340" cy="78" r="0.6" fill="#fff"/>
<circle cx="890" cy="115" r="1" fill="#fff"/><circle cx="1120" cy="210" r="0.7" fill="#fff"/>
<circle cx="180" cy="460" r="0.5" fill="#fff"/><circle cx="1160" cy="510" r="0.8" fill="#fff"/>
<circle cx="72" cy="660" r="0.6" fill="#fff"/><circle cx="960" cy="710" r="0.9" fill="#fff"/>
<circle cx="1210" cy="375" r="0.5" fill="#fff"/><circle cx="285" cy="760" r="0.7" fill="#fff"/>
<circle cx="750" cy="42" r="0.6" fill="#fff"/><circle cx="440" cy="840" r="0.8" fill="#fff"/>
</g>
<!-- ═══ TITLE ═══ -->
<text x="640" y="28" text-anchor="middle" fill="#e2e6ee" font-family="'DM Sans',sans-serif" font-weight="700" font-size="17" letter-spacing="1.5">INFRASTRUCTURE PROVISIONING SYSTEM</text>
<text x="640" y="48" text-anchor="middle" fill="#5a6070" font-family="'IBM Plex Mono',monospace" font-size="10" letter-spacing="3">CONTROL PLANE ARCHITECTURE</text>
<line x1="510" y1="56" x2="770" y2="56" stroke="#333" stroke-width="0.8"/>
<!-- ═══ CLI ═══ -->
<g>
<rect x="535" y="64" width="210" height="34" rx="8" fill="url(#cli-grad)" filter="url(#soft-shadow)"/>
<rect x="535" y="64" width="210" height="34" rx="8" fill="none" stroke="#1c2a3a" stroke-width="1"/>
<rect x="535" y="67" width="3" height="28" rx="1.5" fill="#4a9eff" opacity="0.6"/>
<circle cx="556" cy="78" r="7" fill="#2d3748" stroke="#4a9eff" stroke-width="1" opacity="0.8"/>
<text x="556" y="81" text-anchor="middle" fill="#4a9eff" font-size="8" font-family="'IBM Plex Mono',monospace">$</text>
<text x="570" y="78" fill="#4a9eff" font-family="'DM Sans',sans-serif" font-weight="600" font-size="11">CLI</text>
<text x="548" y="92" fill="#6b8aaa" font-family="'IBM Plex Mono',monospace" font-size="8">provisioning create server</text>
</g>
<!-- Arrow: CLI → Orchestrator -->
<line x1="640" y1="98" x2="640" y2="115" stroke="#4a9eff" stroke-width="1.5" stroke-dasharray="5 3" class="spoke" opacity="0.7" marker-end="url(#arr-blue)"/>
<!-- ═══════════════════════════════════════ -->
<!-- NATS ORBITAL RING SYSTEM -->
<!-- ═══════════════════════════════════════ -->
<!-- Ring outer glow -->
<circle cx="640" cy="372" r="183" fill="none" stroke="#94a3b8" stroke-width="10" opacity="0.04" class="ring-glow" filter="url(#ring-glow-f)"/>
<!-- Main orbit ring (visible, flowing dashes) -->
<circle cx="640" cy="372" r="180" fill="none" stroke="#94a3b8" stroke-width="2" stroke-dasharray="10 8" class="orbit-flow" opacity="0.45"/>
<!-- Inner engine ring (counter-rotating via SMIL) -->
<circle cx="640" cy="372" r="110" fill="none" stroke="#5a6278" stroke-width="1" stroke-dasharray="6 6" opacity="0.3">
<animateTransform attributeName="transform" type="rotate" from="360 640 372" to="0 640 372" dur="15s" repeatCount="indefinite"/>
</circle>
<!-- Second inner ring (even smaller, clockwise) -->
<circle cx="640" cy="372" r="70" fill="none" stroke="#3a4050" stroke-width="0.8" stroke-dasharray="4 4" opacity="0.2">
<animateTransform attributeName="transform" type="rotate" from="0 640 372" to="360 640 372" dur="25s" repeatCount="indefinite"/>
</circle>
<!-- Hub center glow -->
<circle cx="640" cy="372" r="50" fill="url(#hub-glow)" class="hub-pulse"/>
<!-- Hub core dot -->
<circle cx="640" cy="372" r="5" fill="#94a3b8" opacity="0.5" class="hub-pulse"/>
<!-- Hub labels -->
<text x="640" y="358" text-anchor="middle" fill="#c8d0dc" font-family="'DM Sans',sans-serif" font-weight="700" font-size="14" letter-spacing="1.5">NATS</text>
<text x="640" y="374" text-anchor="middle" fill="#8090a0" font-family="'IBM Plex Mono',monospace" font-size="9" letter-spacing="2">JETSTREAM</text>
<text x="640" y="388" text-anchor="middle" fill="#5a6278" font-family="'IBM Plex Mono',monospace" font-size="8">:4222</text>
<!-- Subject labels inside hub -->
<g font-family="'IBM Plex Mono',monospace" font-size="7" fill="#4a5268" opacity="0.7">
<text x="600" y="410" text-anchor="middle">tasks.&gt;</text>
<text x="680" y="410" text-anchor="middle">vault.&gt;</text>
<text x="600" y="423" text-anchor="middle">auth.&gt;</text>
<text x="680" y="423" text-anchor="middle">audit.&gt;</text>
<text x="600" y="436" text-anchor="middle">workspace.&gt;</text>
<text x="680" y="436" text-anchor="middle">health.&gt;</text>
</g>
<!-- ═══════════════════════════════════════ -->
<!-- SATELLITE SERVICES -->
<!-- ═══════════════════════════════════════ -->
<!-- ─── ORCHESTRATOR (top, 0°) ─── -->
<g>
<rect x="527" y="107" width="226" height="84" rx="14" fill="none" stroke="#f59e0b" stroke-width="1.5" stroke-dasharray="8 4" class="solid-border"/>
<rect x="535" y="115" width="210" height="68" rx="10" fill="url(#orch-grad)" filter="url(#soft-shadow)"/>
<rect x="535" y="115" width="210" height="68" rx="10" fill="none" stroke="#3a2e1c" stroke-width="1"/>
<rect x="535" y="118" width="3" height="62" rx="1.5" fill="#f59e0b" opacity="0.5"/>
<circle cx="556" cy="137" r="8" fill="#2d3748" stroke="#f59e0b" stroke-width="1" opacity="0.8"/>
<text x="556" y="141" text-anchor="middle" fill="#f59e0b" font-size="9">&#x25b6;</text>
<text x="570" y="140" fill="#d8ccc0" font-family="'DM Sans',sans-serif" font-weight="600" font-size="12" letter-spacing="0.5">Orchestrator</text>
<text x="720" y="140" text-anchor="end" fill="#f59e0b" font-family="'IBM Plex Mono',monospace" font-size="8" opacity="0.5">:9011</text>
<circle cx="732" cy="137" r="3.5" fill="#f59e0b" class="health"/>
<text x="548" y="158" fill="#8a7a60" font-family="'IBM Plex Mono',monospace" font-size="8">Task Engine &#xb7; Provider API &#xb7; SSH</text>
<text x="548" y="172" fill="#6b6050" font-family="'IBM Plex Mono',monospace" font-size="7">Webhooks &#xb7; Rollback &#xb7; Audit Collector</text>
</g>
<rect x="554" y="188" width="152" height="12" rx="6" fill="#f59e0b" opacity="0.08"/>
<text x="630" y="197" text-anchor="middle" fill="#f59e0b" font-family="'IBM Plex Mono',monospace" font-size="6" font-weight="700" opacity="0.6">SOLID: SOLE PROVIDER + SSH</text>
<!-- ─── CONTROL CENTER (72°, upper-right) ─── -->
<g>
<rect x="755" y="257" width="190" height="68" rx="10" fill="url(#ctrl-grad)" filter="url(#soft-shadow)"/>
<rect x="755" y="257" width="190" height="68" rx="10" fill="none" stroke="#2e2848" stroke-width="1"/>
<rect x="941" y="260" width="3" height="62" rx="1.5" fill="#818cf8" opacity="0.5"/>
<circle cx="776" cy="279" r="8" fill="#2d3748" stroke="#818cf8" stroke-width="1" opacity="0.8"/>
<text x="776" y="283" text-anchor="middle" fill="#818cf8" font-size="9">&#x25c9;</text>
<text x="790" y="282" fill="#c0c0d8" font-family="'DM Sans',sans-serif" font-weight="600" font-size="12" letter-spacing="0.5">Control Center</text>
<text x="920" y="282" text-anchor="end" fill="#818cf8" font-family="'IBM Plex Mono',monospace" font-size="8" opacity="0.5">:9012</text>
<circle cx="932" cy="279" r="3.5" fill="#818cf8" class="health health-d1"/>
<text x="768" y="300" fill="#7070a0" font-family="'IBM Plex Mono',monospace" font-size="8">Cedar Policies &#xb7; JWT &#xb7; Sessions</text>
<text x="768" y="314" fill="#5a5878" font-family="'IBM Plex Mono',monospace" font-size="7">WebSocket &#xb7; RBAC &#xb7; Solo: auto-session</text>
</g>
<!-- ─── AI/MCP (144°, lower-right) ─── -->
<g>
<rect x="685" y="510" width="190" height="68" rx="10" fill="url(#mcp-grad)" filter="url(#soft-shadow)"/>
<rect x="685" y="510" width="190" height="68" rx="10" fill="none" stroke="#1c3038" stroke-width="1"/>
<rect x="871" y="513" width="3" height="62" rx="1.5" fill="#22d3ee" opacity="0.5"/>
<circle cx="706" cy="532" r="8" fill="#2d3748" stroke="#22d3ee" stroke-width="1" opacity="0.8"/>
<text x="706" y="536" text-anchor="middle" fill="#22d3ee" font-size="9">&#x1f9e0;</text>
<text x="720" y="535" fill="#c0d8d8" font-family="'DM Sans',sans-serif" font-weight="600" font-size="12" letter-spacing="0.5">AI &#xb7; MCP</text>
<text x="850" y="535" text-anchor="end" fill="#22d3ee" font-family="'IBM Plex Mono',monospace" font-size="8" opacity="0.5">:9082</text>
<circle cx="862" cy="532" r="3.5" fill="#22d3ee" class="health health-d2"/>
<text x="698" y="553" fill="#508888" font-family="'IBM Plex Mono',monospace" font-size="8">RAG Engine &#xb7; MCP Server &#xb7; Tools</text>
<text x="698" y="567" fill="#385a58" font-family="'IBM Plex Mono',monospace" font-size="7">Embeddings &#xb7; Model Routing &#xb7; KGraph</text>
</g>
<!-- ─── EXTENSION REGISTRY (216°, lower-left) ─── -->
<g>
<rect x="405" y="510" width="190" height="68" rx="10" fill="url(#ext-grad)" filter="url(#soft-shadow)"/>
<rect x="405" y="510" width="190" height="68" rx="10" fill="none" stroke="#3a1c28" stroke-width="1"/>
<rect x="405" y="513" width="3" height="62" rx="1.5" fill="#ef4444" opacity="0.5"/>
<circle cx="426" cy="532" r="8" fill="#2d3748" stroke="#ef4444" stroke-width="1" opacity="0.8"/>
<text x="426" y="536" text-anchor="middle" fill="#ef4444" font-size="9">&#x2699;</text>
<text x="440" y="535" fill="#d8c0c8" font-family="'DM Sans',sans-serif" font-weight="600" font-size="11" letter-spacing="0.5">Ext Registry</text>
<text x="570" y="535" text-anchor="end" fill="#ef4444" font-family="'IBM Plex Mono',monospace" font-size="8" opacity="0.5">:8084</text>
<circle cx="582" cy="532" r="3.5" fill="#ef4444" class="health health-d3"/>
<text x="418" y="553" fill="#884848" font-family="'IBM Plex Mono',monospace" font-size="8">Gitea &#xb7; Forgejo &#xb7; OCI &#xb7; LRU</text>
<text x="418" y="567" fill="#5a3848" font-family="'IBM Plex Mono',monospace" font-size="7">Providers &#xb7; Taskservs &#xb7; vault:// creds</text>
</g>
<!-- ─── VAULT SERVICE (288°, upper-left) ─── -->
<g>
<rect x="335" y="257" width="190" height="68" rx="10" fill="url(#vault-grad)" filter="url(#soft-shadow)"/>
<rect x="335" y="257" width="190" height="68" rx="10" fill="none" stroke="#3a1c30" stroke-width="1"/>
<rect x="335" y="260" width="3" height="62" rx="1.5" fill="#ec4899" opacity="0.5"/>
<circle cx="356" cy="279" r="8" fill="#2d3748" stroke="#ec4899" stroke-width="1" opacity="0.8"/>
<text x="356" y="283" text-anchor="middle" fill="#ec4899" font-size="9">&#x1f6e1;</text>
<text x="370" y="282" fill="#d8c0d0" font-family="'DM Sans',sans-serif" font-weight="600" font-size="12" letter-spacing="0.5">Vault Service</text>
<text x="500" y="282" text-anchor="end" fill="#ec4899" font-family="'IBM Plex Mono',monospace" font-size="8" opacity="0.5">:9094</text>
<circle cx="512" cy="279" r="3.5" fill="#ec4899" class="health health-d4"/>
<text x="348" y="300" fill="#885070" font-family="'IBM Plex Mono',monospace" font-size="8">Lease Lifecycle &#xb7; Key Mgmt</text>
<text x="348" y="314" fill="#5a3850" font-family="'IBM Plex Mono',monospace" font-size="7">SOPS &#xb7; Age &#xb7; Secrets never in NATS</text>
</g>
<!-- ═══ HTTPS CREDENTIAL BEAM (Vault ↔ Orch, bypasses ring) ═══ -->
<line x1="520" y1="265" x2="545" y2="188" stroke="#fbbf24" stroke-width="2" class="https-beam" filter="url(#glow-gold)"/>
<line x1="520" y1="265" x2="545" y2="188" stroke="#fbbf24" stroke-width="1" stroke-dasharray="4 3" class="https-beam" opacity="0.4"/>
<text x="515" y="228" fill="#fbbf24" font-family="'IBM Plex Mono',monospace" font-size="7" font-weight="700" class="https-label" transform="rotate(-70,515,228)">HTTPS ONLY</text>
<!-- ═══ ORBITAL PARTICLES (events flowing through the ring) ═══ -->
<!-- Particle 1: orange (tasks) clockwise 8s -->
<circle r="3.5" fill="#f59e0b" opacity="0" filter="url(#glow-orange)">
<animateMotion dur="8s" begin="0s" repeatCount="indefinite">
<mpath href="#orbit-cw"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.9;0.9;0" keyTimes="0;0.05;0.92;1" dur="8s" repeatCount="indefinite"/>
</circle>
<!-- Particle 2: pink (vault) clockwise 10s -->
<circle r="2.5" fill="#ec4899" opacity="0" filter="url(#glow-pink)">
<animateMotion dur="10s" begin="2s" repeatCount="indefinite">
<mpath href="#orbit-cw"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.8;0.8;0" keyTimes="0;0.05;0.92;1" dur="10s" begin="2s" repeatCount="indefinite"/>
</circle>
<!-- Particle 3: blue counter-clockwise 7s -->
<circle r="3" fill="#4a9eff" opacity="0" filter="url(#glow-blue)">
<animateMotion dur="7s" begin="1s" repeatCount="indefinite">
<mpath href="#orbit-ccw"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.85;0.85;0" keyTimes="0;0.05;0.92;1" dur="7s" begin="1s" repeatCount="indefinite"/>
</circle>
<!-- Particle 4: purple clockwise 9s -->
<circle r="2.5" fill="#818cf8" opacity="0" filter="url(#glow-purple)">
<animateMotion dur="9s" begin="4s" repeatCount="indefinite">
<mpath href="#orbit-cw"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.7;0.7;0" keyTimes="0;0.05;0.92;1" dur="9s" begin="4s" repeatCount="indefinite"/>
</circle>
<!-- Particle 5: cyan counter-clockwise 11s -->
<circle r="3" fill="#22d3ee" opacity="0" filter="url(#glow-cyan)">
<animateMotion dur="11s" begin="3s" repeatCount="indefinite">
<mpath href="#orbit-ccw"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.75;0.75;0" keyTimes="0;0.05;0.92;1" dur="11s" begin="3s" repeatCount="indefinite"/>
</circle>
<!-- Particle 6: red clockwise 12s -->
<circle r="2" fill="#ef4444" opacity="0" filter="url(#glow-orange)">
<animateMotion dur="12s" begin="5s" repeatCount="indefinite">
<mpath href="#orbit-cw"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.7;0.7;0" keyTimes="0;0.05;0.92;1" dur="12s" begin="5s" repeatCount="indefinite"/>
</circle>
<!-- ═══ CREDENTIAL FLOW PARTICLES ═══ -->
<!-- Orch → Vault lease request (short arc) -->
<circle r="4" fill="#f59e0b" opacity="0" filter="url(#glow-gold)">
<animateMotion dur="2.5s" begin="0s" repeatCount="indefinite">
<mpath href="#path-orch-vault"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.95;0.95;0" keyTimes="0;0.1;0.8;1" dur="2.5s" repeatCount="indefinite"/>
</circle>
<!-- Vault → Orch lease issued (reverse arc) -->
<circle r="3.5" fill="#ec4899" opacity="0" filter="url(#glow-pink)">
<animateMotion dur="2.5s" begin="4s" repeatCount="indefinite">
<mpath href="#path-vault-orch"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.9;0.9;0" keyTimes="0;0.1;0.8;1" dur="2.5s" begin="4s" repeatCount="indefinite"/>
</circle>
<!-- CLI → Orch task submission -->
<circle r="3" fill="#4a9eff" opacity="0" filter="url(#glow-blue)">
<animateMotion dur="1.2s" begin="0s" repeatCount="indefinite">
<mpath href="#path-cli-orch"/>
</animateMotion>
<animate attributeName="opacity" values="0;0.85;0.85;0" keyTimes="0;0.15;0.7;1" dur="1.2s" repeatCount="indefinite"/>
</circle>
<!-- ═══ CONNECTIONS TO SURREALDB ═══ -->
<g opacity="0.3">
<line x1="640" y1="552" x2="640" y2="614" stroke="#a78bfa" stroke-width="1" stroke-dasharray="4 3" class="db-flow" marker-end="url(#arr-silver)"/>
<line x1="500" y1="540" x2="380" y2="614" stroke="#a78bfa" stroke-width="0.8" stroke-dasharray="4 3" class="db-flow" marker-end="url(#arr-silver)"/>
<line x1="780" y1="540" x2="900" y2="614" stroke="#a78bfa" stroke-width="0.8" stroke-dasharray="4 3" class="db-flow" marker-end="url(#arr-silver)"/>
</g>
<!-- ═══════════════════════════════════════ -->
<!-- SURREALDB PERSISTENCE LAYER -->
<!-- ═══════════════════════════════════════ -->
<g>
<rect x="100" y="616" width="1080" height="54" rx="8" fill="url(#surreal-grad)" filter="url(#soft-shadow)"/>
<rect x="100" y="616" width="1080" height="54" rx="8" fill="none" stroke="#2e2450" stroke-width="1"/>
<rect x="100" y="666" width="1080" height="4" rx="2" fill="#a78bfa" opacity="0.2"/>
<text x="640" y="632" text-anchor="middle" fill="#c4b5e0" font-family="'DM Sans',sans-serif" font-weight="700" font-size="11" letter-spacing="1">SURREALDB PERSISTENCE</text>
<text x="1120" y="632" text-anchor="end" fill="#a78bfa" font-family="'IBM Plex Mono',monospace" font-size="7" opacity="0.4">Solo: RocksDB &#xb7; Multi: WebSocket</text>
<g font-family="'IBM Plex Mono',monospace" font-size="7">
<rect x="128" y="642" width="140" height="18" rx="4" fill="#110e1c" stroke="#2e2450" stroke-width="0.5"/>
<text x="198" y="654" text-anchor="middle" fill="#a78bfa" opacity="0.8">orchestrator</text>
<rect x="282" y="642" width="120" height="18" rx="4" fill="#110e1c" stroke="#2e2450" stroke-width="0.5"/>
<text x="342" y="654" text-anchor="middle" fill="#a78bfa" opacity="0.8">vault</text>
<rect x="416" y="642" width="150" height="18" rx="4" fill="#110e1c" stroke="#2e2450" stroke-width="0.5"/>
<text x="491" y="654" text-anchor="middle" fill="#a78bfa" opacity="0.8">control_center</text>
<rect x="580" y="642" width="100" height="18" rx="4" fill="#110e1c" stroke="#2e2450" stroke-width="0.5"/>
<text x="630" y="654" text-anchor="middle" fill="#a78bfa" opacity="0.8">audit</text>
<rect x="694" y="642" width="140" height="18" rx="4" fill="#110e1c" stroke="#2e2450" stroke-width="0.5"/>
<text x="764" y="654" text-anchor="middle" fill="#a78bfa" opacity="0.8">workspace</text>
<rect x="848" y="642" width="110" height="18" rx="4" fill="none" stroke="#2e2450" stroke-width="0.4"/>
<text x="903" y="654" text-anchor="middle" fill="#5a4878" opacity="0.6">Nickel config</text>
</g>
</g>
<!-- ═══ SOLID ENFORCEMENT INDICATORS ═══ -->
<g transform="translate(100, 690)">
<text x="0" y="0" fill="#3a3e48" font-family="'IBM Plex Mono',monospace" font-weight="600" font-size="8" letter-spacing="1.5">SOLID ENFORCEMENT LAYERS</text>
<g font-family="'IBM Plex Mono',monospace" font-size="7">
<rect x="0" y="8" width="84" height="14" rx="4" fill="#f59e0b" opacity="0.06" stroke="#f59e0b" stroke-width="0.4" stroke-opacity="0.2"/>
<text x="42" y="19" text-anchor="middle" fill="#f59e0b" opacity="0.6">Compile-time</text>
<rect x="92" y="8" width="72" height="14" rx="4" fill="#818cf8" opacity="0.06" stroke="#818cf8" stroke-width="0.4" stroke-opacity="0.2"/>
<text x="128" y="19" text-anchor="middle" fill="#818cf8" opacity="0.6">Dev-time</text>
<rect x="172" y="8" width="78" height="14" rx="4" fill="#ec4899" opacity="0.06" stroke="#ec4899" stroke-width="0.4" stroke-opacity="0.2"/>
<text x="211" y="19" text-anchor="middle" fill="#ec4899" opacity="0.6">Pre-commit</text>
<rect x="258" y="8" width="52" height="14" rx="4" fill="#ef4444" opacity="0.06" stroke="#ef4444" stroke-width="0.4" stroke-opacity="0.2"/>
<text x="284" y="19" text-anchor="middle" fill="#ef4444" opacity="0.6">CI/CD</text>
<rect x="318" y="8" width="64" height="14" rx="4" fill="#22d3ee" opacity="0.06" stroke="#22d3ee" stroke-width="0.4" stroke-opacity="0.2"/>
<text x="350" y="19" text-anchor="middle" fill="#22d3ee" opacity="0.6">Runtime</text>
<rect x="390" y="8" width="52" height="14" rx="4" fill="#94a3b8" opacity="0.06" stroke="#94a3b8" stroke-width="0.4" stroke-opacity="0.2"/>
<text x="416" y="19" text-anchor="middle" fill="#94a3b8" opacity="0.6">Audit</text>
</g>
<g font-family="'IBM Plex Mono',monospace" font-size="7" fill="#3a3e48" opacity="0.5">
<text x="500" y="12">Provider APIs: Orchestrator only</text>
<text x="500" y="24">SSH: Orchestrator + Machines only</text>
<text x="750" y="12">Auth: Control Center only</text>
<text x="750" y="24">Secrets: Vault Service API only</text>
</g>
</g>
<!-- ═══ LEGEND ═══ -->
<g transform="translate(100, 732)" font-family="'IBM Plex Mono',monospace" font-size="9">
<text x="0" y="0" fill="#3a3e48" font-weight="600" font-size="8" letter-spacing="1.5">PLATFORM SERVICES</text>
<circle cx="8" cy="14" r="3.5" fill="#f59e0b" opacity="0.8"/>
<text x="17" y="18" fill="#6b6050">Orchestrator (tasks, provider, SSH)</text>
<circle cx="8" cy="28" r="3.5" fill="#818cf8" opacity="0.8"/>
<text x="17" y="32" fill="#5a5878">Control Center (auth, sessions, Cedar)</text>
<circle cx="8" cy="42" r="3.5" fill="#ec4899" opacity="0.8"/>
<text x="17" y="46" fill="#5a3850">Vault Service (secrets, leases, crypto)</text>
<circle cx="8" cy="56" r="3.5" fill="#ef4444" opacity="0.8"/>
<text x="17" y="60" fill="#5a3848">Catalog Registry (providers, OCI)</text>
<circle cx="8" cy="70" r="3.5" fill="#22d3ee" opacity="0.8"/>
<text x="17" y="74" fill="#385a58">AI &#xb7; MCP (RAG, tools, models)</text>
<text x="360" y="0" fill="#3a3e48" font-weight="600" font-size="8" letter-spacing="1.5">INFRASTRUCTURE</text>
<circle cx="368" cy="14" r="6" fill="none" stroke="#94a3b8" stroke-width="1.5" stroke-dasharray="2 2"/>
<text x="382" y="18" fill="#5a6278">NATS Orbital Ring (event bus, :4222)</text>
<line x1="360" y1="28" x2="376" y2="28" stroke="#a78bfa" stroke-width="2"/>
<text x="382" y="32" fill="#5a4878">SurrealDB (global store, embedded/WS)</text>
<line x1="360" y1="42" x2="376" y2="42" stroke="#fbbf24" stroke-width="2"/>
<text x="382" y="46" fill="#6b6050">HTTPS direct (credentials only)</text>
<line x1="360" y1="56" x2="376" y2="56" stroke="#4a9eff" stroke-width="1.5" stroke-dasharray="4 3"/>
<text x="382" y="60" fill="#4a6a8a">CLI &#x2192; HTTP &#x2192; Orchestrator</text>
<text x="700" y="0" fill="#3a3e48" font-weight="600" font-size="8" letter-spacing="1.5">MODES</text>
<rect x="700" y="8" width="48" height="12" rx="3" fill="#34d399" opacity="0.1" stroke="#34d399" stroke-width="0.4" stroke-opacity="0.3"/>
<text x="724" y="17" text-anchor="middle" fill="#34d399" font-size="7" font-weight="600">SOLO</text>
<text x="754" y="17" fill="#4a7a5a" font-size="8">Embedded RocksDB, local NATS, auto-session</text>
<rect x="700" y="26" width="48" height="12" rx="3" fill="#818cf8" opacity="0.1" stroke="#818cf8" stroke-width="0.4" stroke-opacity="0.3"/>
<text x="724" y="35" text-anchor="middle" fill="#818cf8" font-size="7" font-weight="600">MULTI</text>
<text x="754" y="35" fill="#5a5878" font-size="8">WS SurrealDB, NATS cluster, JWT+Cedar</text>
<text x="700" y="56" fill="#3a3e48" font-size="7" opacity="0.6">Same architecture, same NATS subjects,</text>
<text x="700" y="66" fill="#3a3e48" font-size="7" opacity="0.6">same schema. Only auth differs.</text>
</g>
<!-- ═══ DEPLOYMENT TARGETS ═══ -->
<g transform="translate(0, 828)" font-family="'IBM Plex Mono',monospace">
<rect x="140" y="0" width="130" height="34" rx="7" fill="#2a1515" stroke="#2a1010" stroke-width="0.8"/>
<circle cx="156" cy="13" r="3.5" fill="#ef4444" opacity="0.8"/>
<text x="166" y="16" fill="#d0a0a0" font-size="9" font-weight="500">Production</text>
<text x="156" y="28" fill="#5a3838" font-size="7">Hetzner &#xb7; AWS</text>
<rect x="290" y="0" width="130" height="34" rx="7" fill="#2a2010" stroke="#1a1810" stroke-width="0.8"/>
<circle cx="306" cy="13" r="3.5" fill="#f59e0b" opacity="0.8"/>
<text x="316" y="16" fill="#d0c0a0" font-size="9" font-weight="500">Staging</text>
<text x="306" y="28" fill="#5a5038" font-size="7">K8s cluster</text>
<rect x="440" y="0" width="130" height="34" rx="7" fill="#1a2820" stroke="#0a1810" stroke-width="0.8"/>
<circle cx="456" cy="13" r="3.5" fill="#34d399" opacity="0.8"/>
<text x="466" y="16" fill="#a0d0b8" font-size="9" font-weight="500">Dev</text>
<text x="456" y="28" fill="#385a48" font-size="7">Solo mode</text>
<rect x="590" y="0" width="130" height="34" rx="7" fill="#1a182a" stroke="#0a0a1a" stroke-width="0.8"/>
<circle cx="606" cy="13" r="3.5" fill="#818cf8" opacity="0.8"/>
<text x="616" y="16" fill="#b0b0d8" font-size="9" font-weight="500">Edge</text>
<text x="606" y="28" fill="#48486a" font-size="7">On-prem &#xb7; IoT</text>
<rect x="740" y="0" width="130" height="34" rx="7" fill="#1a2020" stroke="#0a1010" stroke-width="0.8"/>
<circle cx="756" cy="13" r="3.5" fill="#22d3ee" opacity="0.8"/>
<text x="766" y="16" fill="#a0c8c8" font-size="9" font-weight="500">Custom</text>
<text x="756" y="28" fill="#385858" font-size="7">GitOps &#xb7; Webhook</text>
</g>
<!-- ═══ VERSION ═══ -->
<text x="1180" y="888" text-anchor="end" fill="#5a6070" font-family="'IBM Plex Mono',monospace" font-size="9" letter-spacing="0.5">v4.0 &#xb7; Control Plane Architecture</text>
</svg>