Files
cad-atlas/internal/web/static/cad-atlas.html
T
mathiasandClaude Opus 4.8 5c6a4ab232
CD / Detect unsubstituted template (push) Successful in 1s
CD / Lint / Test / Vet (push) Has been skipped
CD / Build & Import (push) Has been skipped
CD / Deploy via GitOps (push) Has been skipped
feat: Phase A — serve static CAD Atlas viz + self-contained context
Wire the reel-style CAD workflow atlas (signal→pod) as the served page via
go:embed. Fill PROJECT.md/README with the 9-stage workflow, three governance
gates (Ed25519 admission / dispatch-allow / var-go Oath), phase map A→C,
dogfooding model, brain deep-links and external references.

Fixes two template-go-web latent bugs surfaced by dogfooding:
- templ version skew: go.mod pinned v0.2.778 vs templ@latest generator
- .gitignore pattern *.templ.go did not match generated *_templ.go

Verified: go build · vet · golangci-lint (0 issues) · go test green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 10:34:23 +02:00

273 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CAD Atlas · From Signal to Pod</title>
<style>
:root{
--bg:#080b12; --panel:#0e1420; --panel2:#121a2b; --line:#1e2b44;
--ink:#cdd9ef; --dim:#7f92b5; --mono:#8fb4ff;
--blue:#4aa8ff; --amber:#f5b942; --coral:#ff7a5c; --green:#4ad07a; --violet:#9b8cff; --gold:#e6c15a;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
background:
radial-gradient(circle at 1px 1px,#16213a 1px,transparent 0) 0 0/26px 26px,
var(--bg);
color:var(--ink);
font:14px/1.5 ui-sans-serif,system-ui,Segoe UI,Roboto,sans-serif;
-webkit-font-smoothing:antialiased;
}
.mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
header{
position:sticky;top:0;z-index:30;backdrop-filter:blur(8px);
background:linear-gradient(180deg,rgba(8,11,18,.94),rgba(8,11,18,.72));
border-bottom:1px solid var(--line);
display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;padding:14px 22px;
}
header h1{font-size:19px;margin:0}
header h1 b{color:var(--blue)}
header .sub{color:var(--dim);font-size:12px}
header .sub em{color:var(--amber);font-style:normal}
.controls{margin-left:auto;display:flex;gap:8px}
button{
font:inherit;font-size:12px;color:var(--ink);cursor:pointer;
background:var(--panel2);border:1px solid var(--line);border-radius:8px;
padding:7px 13px;display:inline-flex;align-items:center;gap:7px;
}
button:hover{border-color:var(--blue)}
button.on{border-color:var(--amber);color:var(--amber)}
button .dot{width:7px;height:7px;border-radius:50%;background:var(--blue)}
button.on .dot{background:var(--amber)}
.substrate{display:flex;gap:10px;flex-wrap:wrap;align-items:center;
padding:10px 22px;border-bottom:1px solid var(--line);background:var(--panel)}
.substrate .lbl{color:var(--dim);font-size:11px;letter-spacing:1.5px;margin-right:4px}
.host{border:1px solid var(--line);border-radius:8px;padding:6px 11px;
background:var(--panel2);font-size:12px;display:flex;gap:8px;align-items:center}
.host b{color:var(--blue)}
.host .k{color:var(--dim);font-size:11px}
.host.mesh{border-style:dashed;color:var(--dim)}
.scroll{overflow-x:auto;padding:24px 22px 20px}
.track{position:relative;display:flex;align-items:flex-start;min-width:max-content}
svg.spine{position:absolute;left:0;top:0;z-index:0;pointer-events:none;overflow:visible}
.pulse{position:absolute;top:0;left:0;width:13px;height:13px;border-radius:50%;
background:var(--amber);box-shadow:0 0 15px 4px rgba(245,185,66,.75);
transform:translate(-6.5px,-6.5px);z-index:6}
.stage{width:300px;flex:0 0 300px;padding:0 14px;position:relative;z-index:2}
.stage .no{color:var(--dim);font-size:11px;letter-spacing:2px}
.stage h2{font-size:17px;margin:6px 0 2px}
.stage .path{color:var(--mono);font-size:11.5px;margin-bottom:6px;min-height:16px}
.node{border:1px solid var(--line);border-radius:11px;background:var(--panel);
padding:12px 13px;margin-top:12px;position:relative;
transition:border-color .25s,box-shadow .25s,transform .25s}
.node .t{font-weight:600;margin-bottom:3px;display:flex;align-items:center;gap:7px}
.node .d{color:var(--dim);font-size:12px}
.node .tag{display:inline-block;font-size:10.5px;padding:2px 7px;border-radius:20px;
border:1px solid var(--line);color:var(--dim);margin:6px 6px 0 0}
.pill{width:8px;height:8px;border-radius:50%;flex:0 0 8px}
.stage.telos h2{color:var(--violet)}
.stage.gate h2{color:var(--amber)}
.stage.exec h2{color:var(--coral)}
.stage.cd h2{color:var(--green)}
.node.win{border-color:var(--coral);box-shadow:0 0 0 1px rgba(255,122,92,.25)}
.node.gateway{border-color:var(--amber);background:linear-gradient(180deg,rgba(245,185,66,.06),transparent)}
.node.council{border-color:var(--violet)}
.node.bridge{border-color:var(--blue);border-style:dashed}
.node.oath{border-color:var(--gold);border-style:dashed;background:linear-gradient(180deg,rgba(230,193,90,.05),transparent)}
.stage.active h2{text-shadow:0 0 18px currentColor}
.stage.active .node{border-color:var(--amber);
box-shadow:0 0 0 1px rgba(245,185,66,.35),0 10px 30px -12px rgba(245,185,66,.4);transform:translateY(-2px)}
.risk{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap}
.risk span{font-size:10.5px;padding:2px 7px;border-radius:6px;border:1px solid var(--line)}
.risk .lo{color:var(--green);border-color:rgba(74,208,122,.4)}
.risk .md{color:var(--amber);border-color:rgba(245,185,66,.4)}
.risk .hi{color:var(--coral);border-color:rgba(255,122,92,.4)}
.gatebtns{display:flex;gap:8px;margin-top:10px}
.gatebtns .g{flex:1;text-align:center;padding:8px;border-radius:8px;font-size:12px;border:1px solid}
.gatebtns .ok{border-color:rgba(74,208,122,.5);color:var(--green)}
.gatebtns .no{border-color:rgba(255,122,92,.5);color:var(--coral)}
footer{padding:14px 22px 30px;color:var(--dim);font-size:11px;border-top:1px solid var(--line)}
footer code{color:var(--mono)}
/* ---- responsive: stack vertically, drop the SVG spine ---- */
@media(max-width:820px){
.scroll{overflow-x:visible;padding:16px}
.track{flex-direction:column;min-width:0}
svg.spine,.pulse{display:none}
.stage{width:100%;flex:auto;padding:0;border-left:2px solid var(--line);margin-left:6px;
padding-left:16px;padding-bottom:8px}
.stage.telos{border-color:var(--violet)} .stage.gate{border-color:var(--amber)}
.stage.exec{border-color:var(--coral)} .stage.cd{border-color:var(--green)}
}
</style>
</head>
<body>
<header>
<h1><b>CAD</b> Atlas · From Signal to Pod</h1>
<span class="sub mono">one human gate · everything up- and downstream is agents · <em>v0.3 static snapshot (→ live in Phase C)</em></span>
<div class="controls">
<button id="replay"><span class="dot"></span> Replay</button>
<button id="slowmo">Slow-mo · <span id="slowState">off</span></button>
</div>
</header>
<div class="substrate" id="substrate"><span class="lbl mono">SUBSTRATE</span></div>
<div class="scroll">
<div class="track" id="track">
<svg class="spine" id="spine">
<defs>
<marker id="arw" markerWidth="9" markerHeight="9" refX="6" refY="3" orient="auto">
<path d="M0,0 L6,3 L0,6 Z" fill="#33507f"></path>
</marker>
</defs>
<path id="spinePath" fill="none" stroke="#33507f" stroke-width="2"
marker-mid="url(#arw)" marker-end="url(#arw)"></path>
<path id="loopPath" fill="none" stroke="#9b8cff" stroke-width="1.6"
stroke-dasharray="5 5" opacity=".7"></path>
<text id="loopLbl" fill="#9b8cff" font-size="11"
font-family="ui-monospace,monospace" opacity=".85"></text>
</svg>
<div class="pulse" id="pulse"></div>
</div>
</div>
<footer class="mono">
CAD → CI → CD · intent→specify→dispatch · build→test→validate · deploy→ship.
Dashed violet = feedback bus (stage 08 → TELOS: deploy outcome scored vs originating goal).
Data: static inventory from <code>brain</code> (2026-07-19). Phase C swaps these arrays for live reads of
<code>assessor-loop</code> ledger · <code>session_log</code> · Gitea run API · Flux events.
</footer>
<script>
const SUBSTRATE=[
{n:"koala", k:"RTX 5070 · k3s control-plane · Gitea · LiteLLM :30401 · llama-swap :31234 · searxng"},
{n:"iguana", k:"M2 Ultra · Ollama / mlx"},
{n:"flamingo",k:"daily driver · ~/dev"},
{n:"piguard",k:"NGINX reverse-proxy · ntfy"},
];
const NS="Tailscale mesh · ns: ai-stack · supervisor(→brain) · gitea-mcp · infra-mcp · council";
const STAGES=[
{no:"STAGE 00",cls:"",title:"Signals",path:"→ mathias/signals",nodes:[
{t:"Applied AI Radar",d:"Daily Tier-1 + weekly Tier-2 deep pass. Verified-primary bar (paper/benchmark/code/named-lab).",tags:["cron · daily/weekly","→ signals #126+"]},
{t:"Manual capture",d:"claude.ai strategic drop · brain capture tool.",tags:["ad-hoc"]},
{t:"Aspirational surfaces",pill:"var(--dim)",d:"Telegram / voice / URL → inbox. NOT built.",tags:["gap"]},
]},
{no:"STAGE 01",cls:"telos",title:"TELOS",path:"wiki/telos/",nodes:[
{t:"Intention substrate",pill:"var(--violet)",d:"Mission · goals · problems · strategies · status. Every downstream item traces to a goal.",tags:["brain_query wing=telos"]},
]},
{no:"STAGE 02",cls:"",title:"Strategic session",path:"claude.ai frontier + brain MCP",nodes:[
{t:"Design · ADRs · specs",d:"Human + frontier model. ISC acceptance criteria written here.",tags:["Define / converge"]},
{t:"🏛️ LLM Council",cls:"council",pill:"var(--violet)",d:"fan-out → anonymous cross-review → chairman synth. glm-4.7-flash · qwen36-35b · gemma4-31b (chair).",tags:["hard strategic Q","chat.d-ma.be"]},
{t:"Autoresearch Council",cls:"council",pill:"var(--violet)",d:"Sibling pipe — ratifies research before the gate.",tags:["proposed: → standalone svc"]},
]},
{no:"STAGE 03",cls:"",title:"Spec → Gitea issue",path:"agent-ready contract",nodes:[
{t:"Contract enforced",d:"Binary ISC · declared risk tier · reg-risk assessment · no open human deps.",tags:["LOW / MED / HIGH"]},
{t:"Admission controller",d:"Ed25519-sign issue body at creation (#36). Verify sig + PR alignment at infra boundary.",tags:["chain of custody"]},
{t:"⚖️ var-go Oath",cls:"oath",pill:"var(--gold)",d:"Acceptance contract embedded in the issue as a ```var fenced block. Exactly one — zero/multiple fail closed. Prose → typed steps; failures anchored to byte spans.",tags:["swedsl · var-go","defined here → enforced @06"]},
]},
{no:"STAGE 04",cls:"gate",title:"Human dispatch gate",path:"the only checkpoint",nodes:[
{t:"Human triggers execution",cls:"gateway",pill:"var(--amber)",d:"Ratify proposed-plan + risk tier, then dispatch.",gate:true},
{t:"Session-Dispatch bridge",cls:"bridge",pill:"var(--blue)",d:"claude.ai MCP → gitea:workflow_run_trigger → cad-dispatch.yml → agentsquad. The final design→execution bridge.",tags:["workflow_dispatch"]},
]},
{no:"STAGE 05",cls:"exec",title:"Execute · agentsquad",path:"koala · cmd/agentsquad-serve",nodes:[
{t:"Task API",pill:"var(--coral)",d:"POST /tasks → job id · GET /tasks/{id}. taskqueue + serve (v0.12+).",tags:["single agentsquad.yaml"]},
{t:"Executor + reviewer loop",cls:"win",pill:"var(--coral)",d:"ADK Go + LiteLLM. Frontier models (local qwen spirals). Reviewer on distinct tier — echo-chamber prevention.",risk:true},
{t:"dma-cli · routing + scope",cls:"bridge",pill:"var(--blue)",d:"Harness-config arm: routes agents to the right LLM backend. Three-layer scope policy + confirmation gate = CAD guardrail.",tags:["backend routing","scope guardrail"]},
{t:"assessor-loop ledger",d:"Attestation ledger (audit trail) + brain session_log on completion.",tags:["audit package"]},
]},
{no:"STAGE 06",cls:"",title:"PR → CI",path:"Gitea Actions",nodes:[
{t:"PR + label",d:"Gitea PR · agent-done / agent-blocked label.",tags:[]},
{t:"Mechanical gate",d:"go test · vet · lint · govulncheck. ISC verified mechanically.",tags:["green = proceed"]},
{t:"⚖️ var-go/oath gate",cls:"oath",pill:"var(--gold)",d:"cmd/vargo-gate runs in CI → posts commit status context=var-go/oath. Authoritative FLOOR: failed Oath blocks regardless of reviewer approval (#55 anti-rubber-stamp).",tags:["branch-protection req","enforces @03 Oath"]},
]},
{no:"STAGE 07",cls:"cd",title:"CD → pod",path:"Flux GitOps → k3s",nodes:[
{t:"Deploy on green",pill:"var(--green)",d:"Flux reconciles image → k3s pod on koala. Push ≠ deploy: bump tag in mathias/infra.",tags:["ntfy on deploy"]},
]},
{no:"STAGE 08",cls:"telos",title:"Loop back",path:"→ TELOS (feedback bus)",nodes:[
{t:"Close the loop",pill:"var(--violet)",d:"session_log + attestation → brain. Score deploy outcome vs originating goal. (arc partly manual — improvement target.)",tags:["continuous"]},
]},
];
const sub=document.getElementById('substrate');
SUBSTRATE.forEach(h=>{const el=document.createElement('div');el.className='host';
el.innerHTML=`<b>${h.n}</b><span class="k mono">${h.k}</span>`;sub.appendChild(el);});
const mesh=document.createElement('div');mesh.className='host mesh mono';mesh.textContent=NS;sub.appendChild(mesh);
const track=document.getElementById('track');
const stageEls=[];
STAGES.forEach(s=>{
const st=document.createElement('div');st.className='stage '+s.cls;
let h=`<div class="no mono">${s.no}</div><h2>${s.title}</h2><div class="path mono">${s.path||''}</div>`;
s.nodes.forEach(n=>{
const pill=n.pill?`<span class="pill" style="background:${n.pill}"></span>`:'';
let inner=`<div class="t">${pill}${n.t}</div><div class="d">${n.d}</div>`;
if(n.tags&&n.tags.length)inner+=n.tags.map(t=>`<span class="tag mono">${t}</span>`).join('');
if(n.risk)inner+=`<div class="risk mono"><span class="lo">LOW · auto</span><span class="md">MED · ntfy gate</span><span class="hi">HIGH · blocked</span></div>`;
if(n.gate)inner+=`<div class="gatebtns mono"><div class="g ok">✓ approve</div><div class="g no">✕ reject</div></div>`;
h+=`<div class="node ${n.cls||''}">${inner}</div>`;
});
st.innerHTML=h;track.appendChild(st);stageEls.push(st);
});
/* ---- geometry ---- */
const spine=document.getElementById('spine'), spinePath=document.getElementById('spinePath'),
loopPath=document.getElementById('loopPath'), loopLbl=document.getElementById('loopLbl'),
pulse=document.getElementById('pulse');
const RAILY=70;
let cs=[],loopY=0,spineLen=0,loopLen=0,slow=false,raf=null,t0=null,mobile=false;
function build(){
mobile=window.matchMedia('(max-width:820px)').matches;
if(mobile)return;
cs=stageEls.map(s=>s.offsetLeft+s.offsetWidth/2);
const maxBottom=Math.max(...stageEls.map(s=>s.offsetTop+s.offsetHeight));
loopY=maxBottom+40;
spine.setAttribute('width',track.scrollWidth);
spine.setAttribute('height',loopY+70);
track.style.minHeight=(loopY+70)+'px';
spinePath.setAttribute('d','M '+cs[0]+' '+RAILY+cs.slice(1).map(x=>' L '+x+' '+RAILY).join(''));
const lastX=cs[cs.length-1], telosX=cs[1];
loopPath.setAttribute('d',`M ${lastX} ${RAILY} L ${lastX} ${loopY} L ${telosX} ${loopY} L ${telosX} ${RAILY}`);
loopLbl.setAttribute('x',(telosX+lastX)/2-90);loopLbl.setAttribute('y',loopY-8);
loopLbl.textContent='feedback bus · outcome → goal';
spineLen=spinePath.getTotalLength();loopLen=loopPath.getTotalLength();
}
function run(ts){
if(mobile)return;
if(!t0)t0=ts;
const dur=slow?16000:7000;
const p=Math.min((ts-t0)/dur,1);
const total=spineLen+loopLen, dist=total*p;
let pt,onLoop=dist>spineLen;
pt=onLoop?loopPath.getPointAtLength(dist-spineLen):spinePath.getPointAtLength(dist);
pulse.style.left=pt.x+'px';pulse.style.top=pt.y+'px';
pulse.style.background=onLoop?'var(--violet)':'var(--amber)';
pulse.style.boxShadow=onLoop?'0 0 15px 4px rgba(155,140,255,.75)':'0 0 15px 4px rgba(245,185,66,.75)';
let act=onLoop?1:0; // during loop, highlight TELOS
if(!onLoop)cs.forEach((c,i)=>{if(pt.x>=c-150)act=i;});
stageEls.forEach((s,i)=>s.classList.toggle('active',i===act));
if(p<1)raf=requestAnimationFrame(run);
}
function replay(){cancelAnimationFrame(raf);t0=null;build();if(!mobile)raf=requestAnimationFrame(run);}
document.getElementById('replay').onclick=replay;
document.getElementById('slowmo').onclick=e=>{slow=!slow;e.currentTarget.classList.toggle('on',slow);
document.getElementById('slowState').textContent=slow?'on':'off';replay();};
window.addEventListener('resize',()=>{clearTimeout(window._r);window._r=setTimeout(replay,150);});
window.addEventListener('load',replay);
build();
</script>
</body>
</html>