#!/usr/bin/env python3
import argparse, html, json, shutil
from datetime import datetime, timezone
from pathlib import Path

PID='proof-gradient-proof-carrying-intelligence-treasury'
MARKER='SKILLOS_PROOF_GRADIENT_PROOF_CARRYING_INTELLIGENCE_TREASURY_V1'
SCHEMA='skillos.public_command_center.proof_gradient_proof_carrying_intelligence_treasury.v1'

def esc(x):
    if x is None: return ''
    if isinstance(x,(dict,list)): x=json.dumps(x,ensure_ascii=False)[:260]
    return html.escape(str(x))
def pct(x,d=1):
    try: return f'{float(x)*100:.{d}f}%'
    except Exception: return '—'
def write(p,s): p.parent.mkdir(parents=True,exist_ok=True); p.write_text(s,encoding='utf-8')
def receipt(): return json.loads((Path('data')/f'{PID}.json').read_text(encoding='utf-8'))
def css():
    return '''body{margin:0;background:radial-gradient(circle at 15% 10%,#123d5a 0,#0a1328 32%,#17153d 70%,#090b16 100%);color:#f6fbff;font-family:Inter,system-ui,sans-serif;line-height:1.55}body:before{content:"";position:fixed;inset:0;pointer-events:none;background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);background-size:32px 32px}.nav{position:sticky;top:0;z-index:9;display:flex;justify-content:space-between;gap:14px;padding:14px 22px;background:rgba(3,8,18,.88);border-bottom:1px solid rgba(255,255,255,.16);backdrop-filter:blur(18px)}.brand{color:#78f8ff;font-weight:950;text-decoration:none}.nav a{color:#e8f2ff;text-decoration:none;font-weight:850;margin-right:14px}.wrap{max-width:1220px;margin:auto;padding:68px 24px}.hero{display:grid;grid-template-columns:1.1fr .9fr;gap:28px;align-items:center}.h1{font-size:clamp(54px,8vw,112px);line-height:.87;letter-spacing:-.09em;margin:10px 0 18px}.eyebrow{color:#78f8ff;text-transform:uppercase;letter-spacing:.22em;font-size:12px;font-weight:950}.lead{font-size:clamp(18px,2.2vw,25px);color:#dceafe}.panel,.card,.metric{border:1px solid rgba(255,255,255,.18);background:linear-gradient(135deg,rgba(255,255,255,.15),rgba(255,255,255,.055));border-radius:28px;box-shadow:0 26px 90px rgba(0,0,0,.35)}.panel{padding:28px}.card{padding:22px}.metric{padding:20px}.grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}.grid2{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}h2{font-size:clamp(34px,5vw,64px);letter-spacing:-.06em;line-height:.95;margin:76px 0 22px}h3{font-size:23px;letter-spacing:-.03em}.tag{display:inline-block;background:rgba(125,255,178,.16);color:#7dffb2;border-radius:99px;padding:7px 10px;font-size:12px;font-weight:950;letter-spacing:.08em;text-transform:uppercase}.cyan{background:#78f8ff!important;color:#06131a!important}.gold{background:#ffda75!important;color:#151006!important}.btn{display:inline-block;padding:12px 16px;border-radius:99px;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.18);color:#f6fbff;text-decoration:none;font-weight:950;margin:4px}.metric b{display:block;color:#7dffb2;font-size:34px}.muted{color:#b9c7dc}.quote{font-size:clamp(28px,4vw,54px);line-height:1.02;letter-spacing:-.055em}.svgbox{background:rgba(0,0,0,.20);border:1px solid rgba(255,255,255,.16);border-radius:22px;padding:14px;overflow:hidden}.table{width:100%;border-collapse:collapse}.table th,.table td{padding:12px;border-bottom:1px solid rgba(255,255,255,.15);text-align:left}.table th{font-size:12px;text-transform:uppercase;letter-spacing:.13em;color:#bdd7ff}.small{font-size:13px}.footer{text-align:center;color:#b9c7dc;padding:42px 20px;border-top:1px solid rgba(255,255,255,.16)}@media(max-width:900px){.hero,.grid,.grid2,.grid3{grid-template-columns:1fr}.h1{font-size:58px}.nav{display:block}.nav a{display:inline-block;margin-top:8px}}'''
def layout(title,body):
    links=' '.join(f'<a href="{h}">{n}</a>' for n,h in [('Home','index.html'),('Proof','proof-gradient-proof-carrying-intelligence-treasury.html'),('Goals','goals.html'),('Plans','plans.html'),('Skills','skills.html'),('Receipts','receipts.html'),('Run','run.html'),('GitHub','https://github.com/MontrealAI/skillos')])
    return f'<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"><title>{esc(title)}</title><style>{css()}</style></head><body><nav class="nav"><a class="brand" href="index.html">Public SkillOS Command Center</a><div>{links}</div></nav>{body}<footer class="footer"><b>Proof Gradient · Proof-Carrying Intelligence Treasury</b><br>Generated from repository evidence. The root is the Command Center; proofs are rooms.</footer></body></html>'
def metrics(r):
    o=r['observed']; items=[(o['agents'],'agents'),(o['specialist_roles_count'],'roles'),(o['recursive_releases'],'releases'),(o['accepted_upgrades'],'accepted upgrades'),(pct(o['proof_integrity']),'proof integrity'),(pct(o['kardashev_mechanism_coverage']),'mechanism coverage'),(pct(o['negative_control_rejection_rate']),'negative controls'),(pct(o['risk_breach_rate'],2),'risk breach')]
    return ''.join(f'<div class="metric"><b>{esc(v)}</b><span>{esc(k)}</span></div>' for v,k in items)
def cards(items,kind):
    out=[]
    for x in items:
        if kind=='goal': out.append(f'<article class="card"><span class="tag">{esc(x.get("os"))}</span><h3>{esc(x.get("name"))}</h3><p>{esc(x.get("direction"))}</p><p class="small muted"><b>Measure:</b> {esc(x.get("measure"))}<br><b>Threshold:</b> {pct(x.get("threshold"))}</p></article>')
        elif kind=='plan': out.append(f'<article class="card"><span class="tag">{esc(x.get("os"))}</span><h3>{esc(x.get("name"))}</h3><p>{esc(x.get("strategy"))}</p><p class="small muted"><b>Steps:</b> {esc(" → ".join(x.get("steps",[])))}<br><b>Risk budget:</b> {pct(x.get("risk_budget"),1)}</p></article>')
        elif kind=='skill': out.append(f'<article class="card"><span class="tag">{esc(x.get("os"))}</span><h3>{esc(x.get("name"))}</h3><p><b>{esc(x.get("layer"))}</b></p><p>{esc(x.get("purpose"))}</p><p class="small muted"><b>Input:</b> {esc(x.get("input"))}<br><b>Output:</b> {esc(x.get("output"))}<br><b>Verifier:</b> {esc(x.get("verifier"))}</p></article>')
        elif kind=='system': out.append(f'<article class="card"><span class="tag">system</span><h3>{esc(x.get("name"))}</h3><p>{esc(x.get("role"))}</p></article>')
        else: out.append(f'<article class="card"><span class="tag">artifact</span><h3>{esc(x.get("class"))}</h3><p><b>{esc(x.get("artifact"))}</b></p><p>{esc(x.get("description"))}</p></article>')
    return ''.join(out)
def line(curve,field):
    vals=[c[field] for c in curve]; w,h,p=740,260,34; mn,mx=min(vals),max(vals); pts=[]
    for i,v in enumerate(vals):
        x=p+i*(w-2*p)/(len(vals)-1); y=h-p-(v-mn)/(mx-mn+1e-9)*(h-2*p); pts.append((x,y))
    poly=' '.join(f'{x:.1f},{y:.1f}' for x,y in pts); cir=''.join(f'<circle cx="{x:.1f}" cy="{y:.1f}" r="4" fill="#7dffb2"/>' for x,y in pts)
    return f'<svg viewBox="0 0 {w} {h}" width="100%"><path d="M {pts[0][0]:.1f},{h-p} L {poly} L {pts[-1][0]:.1f},{h-p} Z" fill="rgba(125,255,178,.18)"/><polyline points="{poly}" fill="none" stroke="#7dffb2" stroke-width="4"/>{cir}</svg>'
def bars(comp):
    keys=list(comp); w,h,p=760,280,45; slot=(w-2*p)/len(keys); out=''
    for i,k in enumerate(keys):
        v=comp[k]['holdout_success_rate']; x=p+i*slot+20; bh=v*(h-2*p); y=h-p-bh; color='#7dffb2' if k=='proof_carrying_intelligence' else '#ff86a8' if k=='ungated_self_improvement' else '#78f8ff'
        out+=f'<rect x="{x:.1f}" y="{y:.1f}" width="{slot*.55:.1f}" height="{bh:.1f}" rx="10" fill="{color}"/><text x="{x+slot*.275:.1f}" y="{y-7:.1f}" text-anchor="middle" fill="#fff" font-size="12" font-weight="900">{v*100:.1f}%</text>'
    return f'<svg viewBox="0 0 {w} {h}" width="100%">{out}</svg>'
def ladder(vals):
    out='';
    for i,s in enumerate(vals):
        y=28+i*42; bw=620*float(s['score']); out+=f'<text x="20" y="{y+17}" fill="#fff" font-size="13" font-weight="800">{esc(s["stage"])}</text><rect x="170" y="{y}" width="{bw:.1f}" height="24" rx="12" fill="#ffda75"/><text x="{180+bw:.1f}" y="{y+17}" fill="#b9c7dc" font-size="12">{float(s["score"])*100:.0f}%</text>'
    return f'<svg viewBox="0 0 850 340" width="100%">{out}<text x="20" y="326" fill="#b9c7dc" font-size="12">Mechanism proxy only — not a claim of achieved superintelligence or Kardashev Type II.</text></svg>'
def loop_svg():
    return '<svg viewBox="0 0 720 340" width="100%"><circle cx="360" cy="170" r="116" fill="none" stroke="rgba(120,248,255,.25)" stroke-width="18"/><circle cx="360" cy="54" r="34" fill="#78f8ff"/><circle cx="476" cy="170" r="34" fill="#7dffb2"/><circle cx="360" cy="286" r="34" fill="#ffda75"/><circle cx="244" cy="170" r="34" fill="#b6a3ff"/><text x="360" y="59" text-anchor="middle" fill="#06131a" font-weight="950">Commit</text><text x="476" y="175" text-anchor="middle" fill="#06131a" font-weight="950">Execute</text><text x="360" y="291" text-anchor="middle" fill="#151006" font-weight="950">Prove</text><text x="244" y="175" text-anchor="middle" fill="#07101f" font-weight="950">Evolve</text><text x="360" y="165" text-anchor="middle" fill="#fff" font-size="30" font-weight="950">Proof-Carrying</text><text x="360" y="195" text-anchor="middle" fill="#b9c7dc" font-size="17">Intelligence</text></svg>'
def table(r):
    rows=''.join(f'<tr><td><b>{esc(v["label"])}</b></td><td>{pct(v["holdout_success_rate"])}</td><td>{pct(v["value_capture_rate"])}</td><td>{pct(v["risk_breach_rate"],2)}</td><td>{pct(v["proof_integrity"])}</td><td>{pct(v["mechanism_coverage"])}</td><td>{pct(v["rollback_ready"])}</td></tr>' for v in r['comparisons'].values())
    return f'<table class="table"><thead><tr><th>Protocol</th><th>Success</th><th>Value</th><th>Risk</th><th>Proof</th><th>Mechanism</th><th>Rollback</th></tr></thead><tbody>{rows}</tbody></table>'
def index_page(out,r):
    body=f'<main class="wrap"><section class="hero"><div><div class="eyebrow">Montreal.AI / SkillOS / Proof Gradient</div><h1 class="h1">Public SkillOS Command Center</h1><p class="lead">The root is the lobby. Proofs are rooms. This Command Center indexes the Proof Gradient treasury, receipts, goals, plans, skills, graphs, and run instructions.</p><a class="btn gold" href="proof-gradient-proof-carrying-intelligence-treasury.html">Open flagship proof</a><a class="btn cyan" href="skills.html">See skills, plans, goals</a><a class="btn" href="run.html">Run on GitHub</a></div><aside class="panel"><div class="eyebrow">Proof room</div><h2 style="margin:10px 0">Proof-Carrying Intelligence</h2><p class="lead">Commit → Execute → Prove → Evolve.</p><div class="quote">{pct(r["observed"]["proof_integrity"])} proof integrity</div></aside></section><section><h2>Featured proof</h2><div class="panel"><p class="quote">One agent tries. Proof decides. The network evolves.</p><p class="lead">GoalOS gives Direction. PlanOS gives Strategy. SkillOS gives Capability. Proof Gradient gives Evolution.</p><p>{esc(r["bounded_realization"])}</p></div></section><section class="grid">{metrics(r)}</section><section class="grid2"><div class="panel"><h3>Proof-carrying value curve</h3><div class="svgbox">{line(r["release_curve"],"value_capture_rate")}</div></div><div class="panel"><h3>Protocol comparison</h3><div class="svgbox">{bars(r["comparisons"])}</div></div></section><section><h2>Operational stack</h2><div class="grid">{cards(r["systems"],"system")}</div></section></main>'
    write(out/'index.html', layout('Public SkillOS Command Center', body))
def proof_page(out,r):
    cand=[c for c in r['candidate_decisions'] if c['decision']=='accepted'][-12:]
    cand_rows=''.join(f'<tr><td>{esc(c["id"])}</td><td>{esc(c["domain"])}</td><td>{esc(c["goal_name"])}</td><td>{esc(c["plan_name"])}</td><td>{esc(c["skill_name"])}</td><td>{c["proof_gradient"]:.3f}</td></tr>' for c in cand)
    body=f'<main class="wrap"><section class="hero"><div><div class="eyebrow">Third incremental Proof Gradient proof</div><h1 class="h1">Proof-Carrying Intelligence Treasury</h1><p class="lead">One sovereign protocol for compounding agent intelligence: every job becomes a commitment, every execution produces proof, every proven upgrade can earn evolution.</p><a class="btn cyan" href="data/{PID}.json">JSON receipt</a><a class="btn" href="docs/PROOF_GRADIENT_PROOF_CARRYING_INTELLIGENCE_TREASURY_PROOF.md">Markdown report</a><a class="btn gold" href="badges/{PID}.svg">Badge</a></div><aside class="panel"><div class="eyebrow">The protocol</div><div class="svgbox">{loop_svg()}</div></aside></section><section><h2>The doctrine</h2><div class="panel"><p class="quote">Anything that can improve is an Artifact. Anything that changes must carry Proof. Anything that propagates must pass the Evolution Gate.</p></div></section><section><h2>Kardashev-scale mechanism, bounded by proof</h2><div class="panel"><blockquote class="lead">“{esc(r["quote_to_realize"])}”</blockquote><p>{esc(r["bounded_realization"])}</p><div class="svgbox">{ladder(r["value_ladder"])}</div></div></section><section class="grid">{metrics(r)}</section><section class="grid2"><div class="panel"><h3>Compounding value curve</h3><div class="svgbox">{line(r["release_curve"],"value_capture_rate")}</div></div><div class="panel"><h3>Protocol benchmark</h3><div class="svgbox">{bars(r["comparisons"])}</div></div></section><section><h2>Benchmark table</h2><div class="panel">{table(r)}</div></section><section><h2>Goals Used</h2><div class="grid3">{cards(r["goals_used"],"goal")}</div></section><section><h2>Plans Used</h2><div class="grid3">{cards(r["plans_used"],"plan")}</div></section><section><h2>Skills Used</h2><div class="grid3">{cards(r["skills_used"],"skill")}</div></section><section><h2>Artifact classes</h2><div class="grid3">{cards(r["artifact_classes"],"artifact")}</div></section><section><h2>Accepted evolution decisions</h2><div class="panel"><table class="table"><thead><tr><th>Candidate</th><th>Domain</th><th>Goal</th><th>Plan</th><th>Skill</th><th>Gradient</th></tr></thead><tbody>{cand_rows}</tbody></table></div></section><section><h2>Public boundary</h2><div class="panel"><p>{"<br>".join(esc(x) for x in r["public_claim_boundary"])}</p></div></section></main>'
    write(out/'proof-gradient-proof-carrying-intelligence-treasury.html', layout(r['title'], body))
def simple(out,name,title,intro,inner): write(out/name, layout(title, f'<main class="wrap"><div class="eyebrow">Proof Gradient</div><h1 class="h1">{esc(title)}</h1><p class="lead">{esc(intro)}</p>{inner}</main>'))
def aux(out,r):
    simple(out,'goals.html','Goals Used','GoalOS Aim Artifacts used by the proof.',f'<section class="grid3">{cards(r["goals_used"],"goal")}</section>')
    simple(out,'plans.html','Plans Used','PlanOS Strategy Artifacts used by the proof.',f'<section class="grid3">{cards(r["plans_used"],"plan")}</section>')
    simple(out,'skills.html','Skills, Plans, and Goals Used','A beautiful operating ledger of the direction, strategy, and capability artifacts used.',f'<h2>Goals Used</h2><div class="grid3">{cards(r["goals_used"],"goal")}</div><h2>Plans Used</h2><div class="grid3">{cards(r["plans_used"],"plan")}</div><h2>Skills Used</h2><div class="grid3">{cards(r["skills_used"],"skill")}</div>')
    simple(out,'receipts.html','Receipts','Machine-readable proof artifacts generated by the workflow.',f'<section class="panel"><a class="btn cyan" href="data/{PID}.json">Open JSON receipt</a><a class="btn" href="docs/PROOF_GRADIENT_PROOF_CARRYING_INTELLIGENCE_TREASURY_PROOF.md">Open report</a><a class="btn gold" href="badges/{PID}.svg">Open badge</a><pre class="svgbox small" style="white-space:pre-wrap;max-height:520px;overflow:auto">{esc(json.dumps(r,indent=2,sort_keys=True)[:12000])}</pre></section>')
    simple(out,'run.html','Run / Regenerate','Use GitHub Actions to rerun the proof and deploy the Command Center artifact.','<section class="grid2"><article class="card"><span class="tag">workflow</span><h3>Proof Gradient Proof-Carrying Intelligence Treasury Proof</h3><p>Open Actions, select the workflow, and click Run workflow.</p><a class="btn cyan" href="https://github.com/MontrealAI/skillos/actions">Open GitHub Actions</a></article><article class="card"><span class="tag">root contract</span><h3>Command Center owns root</h3><p>/skillos/ and /skillos/index.html are the Public SkillOS Command Center. This proof remains a proof room.</p></article></section>')
    simple(out,'proofs.html','Proofs','Generated proof registry.',f'<section class="grid2"><article class="card"><span class="tag">passed</span><h3>{esc(r["title"])}</h3><p>{esc(r["tagline"])}</p><a class="btn cyan" href="proof-gradient-proof-carrying-intelligence-treasury.html">Open proof</a></article></section>')
    simple(out,'actions.html','Actions','Autonomous workflow and Pages deployment entry points.','<section class="panel"><a class="btn cyan" href="https://github.com/MontrealAI/skillos/actions">Open GitHub Actions</a></section>')
    simple(out,'multi-agent.html','Multi-Agent System','Coordinated specialist roles.', '<section class="grid3">'+''.join(f'<article class="card"><span class="tag">role</span><h3>{esc(role)}</h3><p class="muted">Specialist role in the Proof-Carrying Intelligence treasury.</p></article>' for role in r['specialist_roles'])+'</section>')
    simple(out,'architecture.html','Architecture','One protocol, four systems, seven artifact classes.', f'<h2>Four systems</h2><div class="grid">{cards(r["systems"],"system")}</div><h2>Artifact classes</h2><div class="grid3">{cards(r["artifact_classes"],"artifact")}</div>')
    simple(out,'health.html','Health','Local verification before deployment; live verification after deployment.','<section class="grid2"><article class="card"><span class="tag">local</span><h3>Artifact verifier</h3><p>Checks files, links, root contract, goals, plans, skills, and receipt gates.</p></article><article class="card"><span class="tag">live</span><h3>Root verifier</h3><p>Checks that the public root is the Command Center and the proof lives on a subpage.</p></article></section>')
    simple(out,'runbook.html','Runbook','Simple non-technical guide.','<section class="panel"><ol><li>Upload files.</li><li>Open GitHub Actions.</li><li>Run the Proof Gradient workflow.</li><li>Confirm /skillos/ is the Public SkillOS Command Center.</li><li>Open the proof page.</li></ol></section>')
    write(out/'404.html', layout('SkillOS Page Not Found','<main class="wrap"><h1 class="h1">Room not found.</h1><a class="btn cyan" href="index.html">Home</a></main>'))
    write(out/'force-refresh.html', layout('Force Refresh','<main class="wrap"><h1 class="h1">Refresh complete.</h1><a class="btn cyan" href="index.html?v=pci">Open Command Center</a><script>if(navigator.serviceWorker){navigator.serviceWorker.getRegistrations().then(rs=>rs.forEach(r=>r.unregister()))}</script></main>'))
    write(out/'sw.js',"self.addEventListener('install',e=>self.skipWaiting());self.addEventListener('activate',e=>self.registration.unregister());")
def copy(out,r):
    for d in ['data','docs','badges']: (out/d).mkdir(parents=True,exist_ok=True)
    shutil.copy2(Path('data')/f'{PID}.json',out/'data'/f'{PID}.json'); shutil.copy2(Path('docs')/'PROOF_GRADIENT_PROOF_CARRYING_INTELLIGENCE_TREASURY_PROOF.md',out/'docs'/'PROOF_GRADIENT_PROOF_CARRYING_INTELLIGENCE_TREASURY_PROOF.md'); shutil.copy2(Path('badges')/f'{PID}.svg',out/'badges'/f'{PID}.svg')
    manifest={'schema':SCHEMA,'marker':MARKER,'generated_at':datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace('+00:00','Z'),'root_contract':{'root':'Public SkillOS Command Center','index':'Public SkillOS Command Center','proof_room':'proof-gradient-proof-carrying-intelligence-treasury.html'},'proof_id':PID,'receipt_hash':r.get('receipt_hash'),'goals':len(r.get('goals_used',[])),'plans':len(r.get('plans_used',[])),'skills':len(r.get('skills_used',[]))}
    write(out/'data'/'command-center-manifest.json',json.dumps(manifest,indent=2,sort_keys=True))
    registry=[{'id':PID,'title':r['title'],'status':r['status'],'href':'proof-gradient-proof-carrying-intelligence-treasury.html','receipt':'data/'+PID+'.json','report':'docs/PROOF_GRADIENT_PROOF_CARRYING_INTELLIGENCE_TREASURY_PROOF.md','badge':'badges/'+PID+'.svg','goals_used':len(r['goals_used']),'plans_used':len(r['plans_used']),'skills_used':len(r['skills_used'])}]
    write(out/'proof-registry.json',json.dumps(registry,indent=2,sort_keys=True)); write(out/'robots.txt','User-agent: *\nAllow: /\nSitemap: https://montrealai.github.io/skillos/sitemap.xml\n'); write(out/'sitemap.xml','<?xml version="1.0"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>'); write(out/'version.txt',MARKER+'\n'); write(out/'.nojekyll','')
def main():
    ap=argparse.ArgumentParser(); ap.add_argument('--out',default='dist'); args=ap.parse_args(); out=Path(args.out)
    if out.exists(): shutil.rmtree(out)
    out.mkdir(parents=True); r=receipt(); copy(out,r); index_page(out,r); proof_page(out,r); aux(out,r)
    print(json.dumps({'built':str(out),'marker':MARKER,'proof':PID,'pages':len(list(out.glob('*.html')))},indent=2))
if __name__=='__main__': main()
