Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions public/integrations.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ <h3>x402 Paid Actions</h3>
</div>
</article>

<article class="integration-card">
<h3>Proof Flow Composer</h3>
<p>Compose simulated external adapter events with live runtime signing and live verification under one trace_id.</p>
<div class="integration-links"><a href="/proof-flow-composer.html">Open Proof Flow Composer demo</a></div>
</article>

<article class="integration-card">
<h3>VerifyAgent</h3>
<p>Public verification for signed receipts.</p>
Expand Down
140 changes: 140 additions & 0 deletions public/proof-flow-composer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Proof Flow Composer | CommandLayer</title>
<meta name="description" content="Compose simulated adapter events with live CommandLayer runtime receipts and verification into a single trace-linked workflow." />
<link rel="icon" href="/icon2.png" />
<link rel="stylesheet" href="/css/site.css" />
<style>
.brand img{height:68px;width:auto;object-fit:contain}.brand span{display:none}
.nav-links{display:flex;align-items:center;gap:2px;list-style:none;flex-wrap:wrap;margin:0;padding:0}
.nav-links a{color:var(--muted);text-decoration:none;font-size:14px;font-weight:500;padding:7px 12px;border-radius:8px}
.nav-links a:hover,.nav-drop:hover>a,.nav-drop:focus-within>a,.nav-drop>a.active{color:var(--text);background:var(--surface)}
.nav-drop{position:relative}.nav-drop-menu{position:absolute;top:calc(100% - 1px);left:0;background:#fff;border:1px solid var(--border);border-radius:12px;box-shadow:0 10px 34px rgba(15,23,42,.12);padding:8px;display:none;min-width:260px;z-index:200}
.nav-drop:hover .nav-drop-menu,.nav-drop:focus-within .nav-drop-menu{display:grid}
.doc-shell{padding:56px 0 88px}.doc-card{background:#fff;border:1px solid var(--border);border-radius:18px;padding:24px;margin-bottom:18px}
.steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.step-card{background:#fff;border:1px solid var(--border);border-radius:14px;padding:14px}
.k{font-size:12px;font-weight:800;letter-spacing:.08em;color:#635bff;text-transform:uppercase}
.mode{display:inline-block;margin-top:8px;padding:4px 8px;border-radius:999px;font-size:12px;font-weight:700}
.mode.sim{background:#fff4e5;color:#9a6700}.mode.live{background:#e8f3ff;color:#1257a3}
.controls{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.trace-line{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px}
.trace-pill{border:1px solid var(--border);background:#f8faff;border-radius:999px;padding:9px 12px;font:600 12px/1.2 ui-monospace,monospace;text-align:center}
.trace-pill.done{background:#eaf8f0;border-color:#8bd5ad}
.status{margin-top:12px;padding:10px 12px;border-radius:10px;border:1px solid var(--border);font-size:14px}
.status.err{background:#fff1f2;border-color:#fda4af;color:#9f1239}
.status.ok{background:#f0fdf4;border-color:#86efac;color:#166534}
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}.tab{padding:8px 12px;border:1px solid var(--border);border-radius:999px;cursor:pointer;background:#fff}.tab.active{background:#0f172a;color:#fff}
.panel{display:none}.panel.active{display:block}
pre{white-space:pre-wrap;word-break:break-word;background:#0f172a;color:#e2e8f0;border:1px solid rgba(148,163,184,.3);border-radius:12px;padding:14px;min-height:180px}
.split{display:grid;grid-template-columns:2fr 1fr;gap:14px}
.copy{margin-top:8px}
footer{border-top:1px solid var(--border);background:#fff}.footer-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:24px;padding:36px 0}.footer-grid a{display:block;margin:8px 0}
@media(max-width:1000px){.steps,.trace-line,.split,.footer-grid{grid-template-columns:1fr}}
</style>
</head>
<body>
<nav><div class="container nav-inner"><a href="/" class="brand"><img src="/commandlayer-logo.png" alt="CommandLayer" /><span>CommandLayer</span></a><ul class="nav-links"><li><a href="/">Home</a></li><li><a href="/protocol.html">Protocol</a></li><li><a href="/capabilities.html">Capabilities</a></li><li><a href="/verify.html">Verifier</a></li><li><a href="/sdk-records.html">SDK</a></li><li class="nav-drop"><a href="/docs.html" class="active">Docs ▾</a><div class="nav-drop-menu"><a href="/docs.html">Docs Home</a><a href="/stack-proof-demo.html">Production Proof</a><a href="/runtime.html">Runtime</a><a href="/api.html">API Reference</a><a href="/integrations.html">Integrations</a></div></li><li><a href="/claim.html">Claim</a></li><li><a href="https://github.com/commandlayer" target="_blank" rel="noopener">GitHub</a></li></ul></div></nav>
<section class="hero"><div class="container"><div class="hero-badge"><span class="badge-dot"></span>Demo</div><h1 class="hero-h1">Proof Flow Composer</h1><p class="hero-sub">Compose simulated adapter events with live runtime signing and live VerifyAgent validation in one trace-linked workflow.</p></div></section>
<main class="container doc-shell">
<section class="doc-card">
<h2>Workflow steps</h2>
<div class="steps">
<article class="step-card"><div class="k">Coinbase Webhook</div><h3>simulated verified event</h3><span class="mode sim">simulated adapter event</span></article>
<article class="step-card"><div class="k">x402 Payment</div><h3>simulated accepted payment</h3><span class="mode sim">simulated adapter event</span></article>
<article class="step-card"><div class="k">Runtime Action</div><h3>live signed receipt</h3><span class="mode live">live</span></article>
<article class="step-card"><div class="k">VerifyAgent</div><h3>live verification</h3><span class="mode live">live</span></article>
</div>
<div class="controls">
<button class="btn btn-primary" id="runBtn">Run proof flow</button>
<button class="btn btn-secondary" id="resetBtn">Reset</button>
<button class="btn btn-secondary" id="copyTraceBtn">Copy trace_id</button>
</div>
<p id="traceLabel">trace_id: not started</p>
<div class="trace-line" id="traceLine">
<div class="trace-pill" data-span="coinbase.webhook.verified">coinbase.webhook.verified</div>
<div class="trace-pill" data-span="x402.payment.accepted">x402.payment.accepted</div>
<div class="trace-pill" data-span="agent.action.executed">agent.action.executed</div>
<div class="trace-pill" data-span="verifyagent.receipt.verified">verifyagent.receipt.verified</div>
</div>
<div id="status" class="status">Ready. Coinbase/x402 are simulated in browser. Runtime and VerifyAgent are live network calls.</div>
</section>

<section class="doc-card split">
<div>
<div class="tabs">
<button class="tab active" data-tab="receipt">Final Receipt</button>
<button class="tab" data-tab="trace">Trace</button>
<button class="tab" data-tab="verification">Verification</button>
<button class="tab" data-tab="boundary">Trust Boundary</button>
</div>
<div id="receipt" class="panel active"><pre id="receiptOut">{}</pre><button class="btn btn-secondary copy" data-copy="receiptOut">Copy</button></div>
<div id="trace" class="panel"><pre id="traceOut">{}</pre><button class="btn btn-secondary copy" data-copy="traceOut">Copy</button></div>
<div id="verification" class="panel"><pre id="verifyOut">{}</pre><button class="btn btn-secondary copy" data-copy="verifyOut">Copy</button></div>
<div id="boundary" class="panel"><pre id="boundaryOut">Coinbase and x402 shown here are simulated adapter events for demo UX. They do not prove webhook authenticity or payment settlement. Live trust starts when CommandLayer runtime signs the action receipt; verification checks that signed receipt.</pre><button class="btn btn-secondary copy" data-copy="boundaryOut">Copy</button></div>
</div>
<aside>
<h3>Links</h3>
<p><a href="/integrations.html">Integrations</a></p>
<p><a href="/verify.html">Verify</a></p>
<p><a href="/canonical-receipts.html">Canonical Receipts</a></p>
<p><a href="/sdk-records.html">SDK Records</a></p>
<h3>Verify cURL</h3>
<pre id="curlOut">Run flow to generate cURL.</pre>
<button class="btn btn-secondary copy" data-copy="curlOut">Copy</button>
</aside>
</section>
</main>
<footer><div class="container footer-grid"><div><h4>Product</h4><a href="/protocol.html">Protocol</a><a href="/capabilities.html">Capabilities</a><a href="/verify.html">Verifier</a></div><div><h4>Developers</h4><a href="/docs.html">Docs</a><a href="/sdk-records.html">SDK</a><a href="/api.html">API</a></div><div><h4>Proof</h4><a href="/stack-proof-demo.html">Production Proof</a><a href="/verifyagent.html">VerifyAgent</a><a href="/canonical-receipts.html">Canonical Receipts</a></div></div></footer>
<script>
const state={traceId:null,receipt:null,verification:null,spans:[]};
const runtimeUrl='https://runtime.commandlayer.org/summarize/v1.1.0';
const verifyUrls=['/api/verify','/api/agents/verifyagent'];
const setStatus=(m,ok)=>{const el=document.getElementById('status');el.textContent=m;el.className='status '+(ok?'ok':'err')};
const clearStatus=(m)=>{const el=document.getElementById('status');el.textContent=m;el.className='status'};
const mark=(name)=>{const el=[...document.querySelectorAll('.trace-pill')].find(x=>x.dataset.span===name); if(el)el.classList.add('done');};
const reset=()=>{state.traceId=null;state.receipt=null;state.verification=null;state.spans=[];document.getElementById('traceLabel').textContent='trace_id: not started';document.querySelectorAll('.trace-pill').forEach(p=>p.classList.remove('done'));['receiptOut','traceOut','verifyOut'].forEach(id=>document.getElementById(id).textContent='{}');document.getElementById('curlOut').textContent='Run flow to generate cURL.';clearStatus('Ready. Coinbase/x402 are simulated in browser. Runtime and VerifyAgent are live network calls.');};
const pretty=(v)=>JSON.stringify(v,null,2);
const doRun=async()=>{
reset();
state.traceId=`trace_${Date.now()}_${Math.random().toString(16).slice(2,8)}`;
document.getElementById('traceLabel').textContent=`trace_id: ${state.traceId}`;
const coinbase={span:'coinbase.webhook.verified',mode:'simulated adapter event',provider:'coinbase-cdp-webhook',verified:true,trace_id:state.traceId,timestamp:new Date().toISOString()};
const x402={span:'x402.payment.accepted',mode:'simulated adapter event',provider:'x402',accepted:true,asset:'USD',trace_id:state.traceId,timestamp:new Date().toISOString()};
state.spans.push(coinbase,x402); mark(coinbase.span); mark(x402.span);
clearStatus('Simulated adapter events generated. Executing live runtime action…');
let runtimeRes;
try{
runtimeRes=await fetch(runtimeUrl,{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({input:'Summarize this trace-linked demo action in one sentence.',metadata:{trace_id:state.traceId,trace:{trace_id:state.traceId}}})});
}catch(e){ setStatus('Runtime unreachable. Live step failed before receipt signing.',false); throw e; }
if(!runtimeRes.ok){ setStatus(`Runtime error ${runtimeRes.status}. Live receipt unavailable.`,false); throw new Error('runtime http error'); }
state.receipt=await runtimeRes.json();
state.spans.push({span:'agent.action.executed',mode:'live',trace_id:state.traceId}); mark('agent.action.executed');
document.getElementById('receiptOut').textContent=pretty(state.receipt);

let verifyData=null;
for(const url of verifyUrls){
try{
const vr=await fetch(url,{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({receipt:state.receipt})});
if(vr.ok){ verifyData=await vr.json(); break; }
}catch(_err){}
}
if(!verifyData){ setStatus('Verifier unreachable on /api/verify and /api/agents/verifyagent.',false); throw new Error('verify unavailable'); }
state.verification=verifyData;
state.spans.push({span:'verifyagent.receipt.verified',mode:'live',trace_id:state.traceId}); mark('verifyagent.receipt.verified');
document.getElementById('verifyOut').textContent=pretty(state.verification);
document.getElementById('traceOut').textContent=pretty({trace_id:state.traceId,spans:state.spans});
document.getElementById('curlOut').textContent=`curl -X POST /api/verify -H 'content-type: application/json' -d '${JSON.stringify({receipt:state.receipt}).replace(/'/g,"'\\''")}'`;
setStatus('Flow complete. Simulated adapter events + live runtime receipt + live verification captured.',true);
};
document.getElementById('runBtn').addEventListener('click',()=>doRun().catch(()=>{}));
document.getElementById('resetBtn').addEventListener('click',reset);
document.getElementById('copyTraceBtn').addEventListener('click',()=>navigator.clipboard.writeText(state.traceId||''));
document.querySelectorAll('.tab').forEach(b=>b.addEventListener('click',()=>{document.querySelectorAll('.tab').forEach(x=>x.classList.remove('active'));document.querySelectorAll('.panel').forEach(x=>x.classList.remove('active'));b.classList.add('active');document.getElementById(b.dataset.tab).classList.add('active')}));
document.querySelectorAll('.copy').forEach(b=>b.addEventListener('click',()=>navigator.clipboard.writeText(document.getElementById(b.dataset.copy).textContent)));
</script>
</body>
</html>
Loading