quc v0: the cage, the chair, the safeword, the magic words, the replay #241

Merged
teahubxyz merged 5 commits from claude/quc-v0 into main 2026-10-22 18:26:41 +00:00
Owner

Builds the rest of spec #220 in one change, replacing the one-card-an-hour queue (cards #223-#236) and superseding #239, whose run model is folded in here.

Live now from this branch at https://quc.yolopreneur.lol/ (rev ebbd8d3b838f, deployed from hb-5 with the operator env files; /api/health says live: true). A real run on octocat/Spoon-Knife ("add a short friendly footer"): clone, plan, two files rewritten (+23 lines), Grok narrating, a stray message mocked, about 38 s end to end. Replay: https://quc.yolopreneur.lol/run/41b65a50a2

What's in it

  • The cage (agent.js): reads a public repo from GitHub's tarball. Nothing is executed and nothing is pushed. Caps: 15 MB download, 2,000 files, 40 KB a file, 4 files changed, 10 minutes. A coding model (Qwen3 Coder via Venice) plans and rewrites whole files; Grok (grok-4-3 via Venice) narrates. Without a key it gives offline answers.
  • Steps (engine.js): one step per request (clone, plan, rewrite one file, wrap up), so every call stays short. A lock stops double steps, and a re-read after the models answer means a safeword or veto that lands mid-step wins.
  • The chair (page.js): read-only diffs and commentary. Only the owner (cookie) sees the safeword and the box.
  • Safeword: ends the run and throws the edits away.
  • Magic words: "may I say something" lets you leave notes for the agent; "not that one" plus a path vetoes a file and reverts any edit to it; "my repo, my rules" takes the wheel (ends unlocked). Anything else gets mocked. Grok hints at the first one about one line in four.
  • Replay: the same URL for anyone, with a scrubber over every event, the aftermath card and the patch download.
  • API (worker.js): visitor cookie, owner-only actions, same-origin POSTs, 5 runs/day per visitor, 300/day in all.
  • Storage: KV namespace time-quc. KV is eventually consistent; a Durable Object per run is the upgrade when it matters (noted in runs.js).

Checks

  • npm test --prefix quc: 15 pass, including a full run against a fake GitHub tarball, the safeword, all three phrases, veto revert, owner-only API, cross-site refusal and the daily cap.
  • The diff module was fuzzed: 300 random edits all apply cleanly with GNU patch.
  • Browser: start screen, live run, mocking, safeword, aftermath and a stranger's replay view, on desktop (light) and phone (dark), with no console errors.
  • Real models: locally on hb-5 and in production.

Pipeline

ci.yml now runs the quc tests on PRs. quc.yml tests and deploys on pushes to quc/** on main, and skips the deploy until CLOUDFLARE_API_TOKEN is staged as a repo secret (it's still missing; deploys from hb-5 work meanwhile).

Closes #223, closes #224, closes #225, closes #226, closes #227, closes #228, closes #229, closes #230, closes #231, closes #232, closes #233, closes #234, closes #235, closes #236

🤖 Generated with Claude Code

https://claude.ai/code/session_01EVg99kQMY2Tumhobuyg7Fm

Builds the rest of spec #220 in one change, replacing the one-card-an-hour queue (cards #223-#236) and superseding #239, whose run model is folded in here. **Live now** from this branch at https://quc.yolopreneur.lol/ (rev `ebbd8d3b838f`, deployed from hb-5 with the operator env files; `/api/health` says `live: true`). A real run on `octocat/Spoon-Knife` ("add a short friendly footer"): clone, plan, two files rewritten (+23 lines), Grok narrating, a stray message mocked, about 38 s end to end. Replay: https://quc.yolopreneur.lol/run/41b65a50a2 ## What's in it - **The cage** (`agent.js`): reads a public repo from GitHub's tarball. Nothing is executed and nothing is pushed. Caps: 15 MB download, 2,000 files, 40 KB a file, 4 files changed, 10 minutes. A coding model (Qwen3 Coder via Venice) plans and rewrites whole files; Grok (`grok-4-3` via Venice) narrates. Without a key it gives offline answers. - **Steps** (`engine.js`): one step per request (clone, plan, rewrite one file, wrap up), so every call stays short. A lock stops double steps, and a re-read after the models answer means a safeword or veto that lands mid-step wins. - **The chair** (`page.js`): read-only diffs and commentary. Only the owner (cookie) sees the safeword and the box. - **Safeword**: ends the run and throws the edits away. - **Magic words**: "may I say something" lets you leave notes for the agent; "not that one" plus a path vetoes a file and reverts any edit to it; "my repo, my rules" takes the wheel (ends `unlocked`). Anything else gets mocked. Grok hints at the first one about one line in four. - **Replay**: the same URL for anyone, with a scrubber over every event, the aftermath card and the patch download. - **API** (`worker.js`): visitor cookie, owner-only actions, same-origin POSTs, 5 runs/day per visitor, 300/day in all. - **Storage**: KV namespace `time-quc`. KV is eventually consistent; a Durable Object per run is the upgrade when it matters (noted in `runs.js`). ## Checks - `npm test --prefix quc`: 15 pass, including a full run against a fake GitHub tarball, the safeword, all three phrases, veto revert, owner-only API, cross-site refusal and the daily cap. - The diff module was fuzzed: 300 random edits all apply cleanly with GNU `patch`. - Browser: start screen, live run, mocking, safeword, aftermath and a stranger's replay view, on desktop (light) and phone (dark), with no console errors. - Real models: locally on hb-5 and in production. ## Pipeline `ci.yml` now runs the quc tests on PRs. `quc.yml` tests and deploys on pushes to `quc/**` on main, and skips the deploy until `CLOUDFLARE_API_TOKEN` is staged as a repo secret (it's still missing; deploys from hb-5 work meanwhile). Closes #223, closes #224, closes #225, closes #226, closes #227, closes #228, closes #229, closes #230, closes #231, closes #232, closes #233, closes #234, closes #235, closes #236 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EVg99kQMY2Tumhobuyg7Fm
teahubxyz added 5 commits 2026-10-22 18:23:09 +00:00
validate.js is shared by the page and the server; diff.js is a Myers line diff with unified patches (fuzzed against GNU patch); runs.js is #239's run model extended with notes, vetoes, the work store and a memory store for tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVg99kQMY2Tumhobuyg7Fm
agent.js reads a public repo from GitHub's tarball (nothing executed), plans up to 4 files and rewrites them with a coding model, and narrates with Grok, via Venice; offline answers without a key. engine.js runs one step per call (clone, plan, rewrite a file, wrap up), with the safeword, the three key phrases (notes, a file veto that reverts, the wheel) and the patch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVg99kQMY2Tumhobuyg7Fm
page.js: start screen, live chair view (read-only diffs and commentary), the safeword, the box, a replay scrubber for anyone with the link, the aftermath card and patch download. worker.js: the API with a visitor cookie, same-origin POSTs and daily caps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVg99kQMY2Tumhobuyg7Fm
15 tests (the run end to end against a fake GitHub tarball, safeword, the three phrases, veto revert, owner-only API, cross-site refusal, daily cap). dev.mjs takes POST bodies and a memory store. deploy.py creates the time-quc KV namespace and binds the Venice key as a Worker secret. quc.yml tests and deploys on main and skips the deploy until CLOUDFLARE_API_TOKEN is staged; ci.yml runs the quc tests on PRs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVg99kQMY2Tumhobuyg7Fm
In a real run Grok hinted at "may I say something" in nearly every line, which gives it away. The hint is now added to the persona prompt about one time in four.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVg99kQMY2Tumhobuyg7Fm
teahubxyz merged commit f479c5f016 into main 2026-10-22 18:26:41 +00:00
Sign in to join this conversation.