Download index.html from mars-republic/cortex-loop-demo: direct link, hf CLI and curl.
- Browser
- Download file 9.83 kB
-
https://huggingface.co/spaces/mars-republic/cortex-loop-demo/resolve/main/index.html
- Command line
-
hf download hf://spaces/mars-republic/cortex-loop-demo/index.html
-
curl -L -o index.html https://huggingface.co/spaces/mars-republic/cortex-loop-demo/resolve/main/index.html
9.83 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <title>Cortex Loop - one tick, end to end</title> | |
| <meta name="description" content="A minimal walkthrough of one loop tick: tick, propose, check, try-complete, using a synthetic page-edit ledger."> | |
| <style> | |
| :root{--ink:#111318;--muted:#5b6472;--line:#e3e7ee;--bg:#fbfcfe;--ok:#1a7f4b;--warn:#b45309;--bad:#b91c1c;--accent:#3b4cca} | |
| *{box-sizing:border-box} | |
| body{margin:0;background:var(--bg);color:var(--ink);font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif} | |
| .wrap{max-width:960px;margin:0 auto;padding:48px 24px 80px} | |
| h1{font-size:34px;line-height:1.2;margin:0 0 12px;letter-spacing:-.02em} | |
| .sub{color:var(--muted);font-size:17px;margin:0 0 28px;max-width:70ch} | |
| .flow{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 32px;padding:0;list-style:none} | |
| .flow li{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;padding:6px 12px;border:1px solid var(--line);border-radius:999px;background:#fff;color:var(--muted)} | |
| .flow li.on{border-color:var(--accent);color:var(--accent);font-weight:600} | |
| .card{background:#fff;border:1px solid var(--line);border-radius:14px;padding:22px;margin:0 0 20px} | |
| .card h2{font-size:15px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:0 0 14px} | |
| button{font:inherit;font-weight:600;padding:11px 20px;border-radius:10px;border:1px solid var(--accent);background:var(--accent);color:#fff;cursor:pointer} | |
| button:hover{filter:brightness(1.08)} | |
| button[disabled]{opacity:.45;cursor:not-allowed} | |
| button.ghost{background:#fff;color:var(--accent)} | |
| .row{display:flex;gap:10px;flex-wrap:wrap;align-items:center} | |
| table{width:100%;border-collapse:collapse;font-size:14px} | |
| th,td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:top} | |
| th{font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);font-weight:600} | |
| td.mono,th.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.5px} | |
| .pill{display:inline-block;padding:2px 9px;border-radius:999px;font-size:12px;font-weight:600} | |
| .p-pending{background:#eef1f6;color:#475569} | |
| .p-check{background:#fff7e6;color:var(--warn)} | |
| .p-done{background:#e8f7ee;color:var(--ok)} | |
| .p-blocked{background:#fdeaea;color:var(--bad)} | |
| .log{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;background:#0f1420;color:#d7e0ee;border-radius:12px;padding:18px;min-height:190px;white-space:pre-wrap;overflow:auto} | |
| .log .k{color:#8fb4ff} | |
| .log .g{color:#66d19e} | |
| .log .y{color:#f0c86b} | |
| .log .r{color:#ff8f8f} | |
| .foot{color:var(--muted);font-size:14px;margin-top:36px;padding-top:22px;border-top:1px solid var(--line)} | |
| a{color:var(--accent)} | |
| code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;background:#eef1f6;padding:1px 6px;border-radius:5px} | |
| </style> | |
| </head> | |
| <body> | |
| <div class="wrap"> | |
| <p style="margin:0 0 6px;font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:#5b6472">Cortex Loop</p><h1>Done is a check result, not a claim.</h1> | |
| <p class="sub" style="font-size:18px;color:#111318">A loop should not be able to finish by asserting that it finished. Here is one that cannot.</p> | |
| <p class="sub"><strong>The problem:</strong> an AI agent can always <em>say</em> it finished. Saying it is free. That is why so much "progress" evaporates on inspection.</p><p class="sub"><strong>What this page proves:</strong> a loop that refuses to mark work complete until the evidence matches. Pick a tick, and watch it succeed on three items and <strong>refuse</strong> on two - because the evidence was not there.</p><p class="sub" style="font-size:15px">No model call, no server: the whole state machine runs in your browser over a synthetic ledger.</p> | |
| <ul class="flow" id="flow"> | |
| <li data-p="tick">1 tick</li> | |
| <li data-p="propose">2 propose</li> | |
| <li data-p="check">3 check</li> | |
| <li data-p="complete">4 try-complete</li> | |
| </ul> | |
| <div class="card"> | |
| <h2>Synthetic ledger</h2><p style="margin:0 0 14px;padding:10px 14px;background:#fff7e6;border-radius:9px;font-size:14px;color:#7a4b00"><strong>Note:</strong> items <code>edit-2044</code> and <code>edit-2045</code> are designed to <strong>fail</strong> their check. The loop will refuse them. That refusal is the feature.</p> | |
| <table> | |
| <thead><tr><th class="mono">item</th><th>intent</th><th class="mono">state</th></tr></thead> | |
| <tbody id="ledger"></tbody> | |
| </table> | |
| </div> | |
| <div class="card"> | |
| <h2>Run one tick</h2> | |
| <div class="row"> | |
| <button id="run">Run tick</button> | |
| <button id="reset" class="ghost">Reset ledger</button> | |
| <span id="hint" style="color:var(--muted);font-size:14px">Idle. Press Run tick.</span> | |
| </div> | |
| </div> | |
| <div class="card"> | |
| <h2>Trace</h2> | |
| <div class="log" id="log">waiting for tick...</div> | |
| </div> | |
| <p class="foot" style="border-top:none;padding-top:0;margin-top:8px"><strong>Why it matters:</strong> once completion requires evidence, "done" stops being a claim and starts being a check result. That is the difference between an agent that reports progress and one that produces it.</p><p class="foot"> | |
| The loop engine is open source: <a href="https://github.com/mobfish-ai/cortex-loop" target="_blank" rel="noopener">cortex-loop</a> | |
| and the harness it drives: <a href="https://github.com/mobfish-ai/cortex-harness-open" target="_blank" rel="noopener">cortex-harness-open</a>. | |
| Example targets come from a public storefront, <a href="https://www.themossriver.com/pages/fit-finder?utm_source=huggingface&utm_medium=space&utm_campaign=cortex_loop_demo" target="_blank" rel="noopener">fit finder</a> | |
| and <a href="https://www.themossriver.com/pages/todays-agent-deal?utm_source=huggingface&utm_medium=space&utm_campaign=cortex_loop_demo" target="_blank" rel="noopener">today's deal</a>. | |
| All ledger rows here are synthetic. No customer records, contact details, hostnames, or internal identifiers are used. | |
| </p> | |
| </div> | |
| <script> | |
| const LEDGER_SEED = [ | |
| {id:'edit-2041', intent:'Add a size note beside the buy button', state:'pending'}, | |
| {id:'edit-2042', intent:'Point the article entry link at the product page', state:'pending'}, | |
| {id:'edit-2043', intent:'Rewrite the promo block copy for the current SKU', state:'pending'}, | |
| {id:'edit-2044', intent:'Link a low-traffic landing page into the deal page', state:'pending'}, | |
| {id:'edit-2045', intent:'Refresh the stock badge on a variant', state:'pending'} | |
| ]; | |
| const CHECKS = { | |
| 'edit-2041': {evidence:'note rendered in page body near the buy button', pass:true}, | |
| 'edit-2042': {evidence:'entry anchor resolves to /products/... with tracking', pass:true}, | |
| 'edit-2043': {evidence:'copy names only the linked product', pass:true}, | |
| 'edit-2044': {evidence:'landing page returns 200 and contains the link', pass:false}, | |
| 'edit-2045': {evidence:'variant stock count differs from source of truth', pass:false} | |
| }; | |
| let ledger = JSON.parse(JSON.stringify(LEDGER_SEED)); | |
| const el = id => document.getElementById(id); | |
| const sleep = ms => new Promise(r => setTimeout(r, ms)); | |
| function paint(){ | |
| el('ledger').innerHTML = ledger.map(r => | |
| '<tr><td class="mono">'+r.id+'</td><td>'+r.intent+'</td><td class="mono"><span class="pill p-'+stateClass(r.state)+'">'+r.state+'</span></td></tr>' | |
| ).join(''); | |
| } | |
| function stateClass(s){ | |
| if(s==='pending') return 'pending'; | |
| if(s==='checking') return 'check'; | |
| if(s==='complete') return 'done'; | |
| return 'blocked'; | |
| } | |
| function mark(id, s){ | |
| const r = ledger.find(x => x.id === id); | |
| if(r) r.state = s; | |
| paint(); | |
| } | |
| function phase(p){ | |
| document.querySelectorAll('#flow li').forEach(li => li.classList.toggle('on', li.dataset.p === p)); | |
| } | |
| function log(html){ | |
| const box = el('log'); | |
| box.innerHTML += '\n' + html; | |
| box.scrollTop = box.scrollHeight; | |
| } | |
| async function tick(){ | |
| el('run').disabled = true; | |
| el('log').textContent = ''; | |
| phase('tick'); | |
| const next = ledger.find(r => r.state === 'pending'); | |
| if(!next){ | |
| log('<span class="g">tick: ledger drained, nothing runnable</span>'); | |
| el('hint').textContent = 'Ledger drained.'; | |
| el('run').disabled = false; | |
| return; | |
| } | |
| log('<span class="k">tick</span> picked '+next.id+' from '+ledger.length+' items (rule: first pending)'); | |
| el('hint').textContent = 'Picked ' + next.id; | |
| await sleep(700); | |
| phase('propose'); | |
| log('<span class="k">propose</span> '+next.intent+' -> one concrete change, no side effects yet'); | |
| await sleep(700); | |
| phase('check'); | |
| mark(next.id, 'checking'); | |
| log('<span class="k">check</span> evidence: '+CHECKS[next.id].evidence); | |
| await sleep(900); | |
| phase('complete'); | |
| const ok = CHECKS[next.id].pass; | |
| if(ok){ | |
| mark(next.id, 'complete'); | |
| log('<span class="g">try-complete accepted</span> evidence matched -> state=complete'); | |
| } else { | |
| mark(next.id, 'blocked'); | |
| log('<span class="r">try-complete refused</span> evidence did not match -> state=blocked, tick ends here'); | |
| } | |
| await sleep(500); | |
| const left = ledger.filter(r => r.state === 'pending').length; | |
| log('<span class="y">summary</span> completed='+ledger.filter(r=>r.state==='complete').length+ | |
| ' blocked='+ledger.filter(r=>r.state==='blocked').length+ | |
| ' pending='+left); | |
| el('hint').textContent = ok ? 'Accepted. Press Run tick again.' : 'Refused. This is the point of the check.'; | |
| el('run').disabled = false; | |
| } | |
| el('run').addEventListener('click', tick); | |
| el('reset').addEventListener('click', () => { | |
| ledger = JSON.parse(JSON.stringify(LEDGER_SEED)); | |
| paint(); | |
| phase(''); | |
| el('log').textContent = 'waiting for tick...'; | |
| el('hint').textContent = 'Idle. Press Run tick.'; | |
| el('run').disabled = false; | |
| }); | |
| paint(); | |
| </script> | |
| </body> | |
| </html> | |