A model-agnostic, local-first coding-agent runtime. It never phones home, and "done" means your build and tests actually passed — not that the model said so.
Quick Start · How It Works · Architecture · Security · Roadmap
Real terminal output, recorded from this build — doctor's sandbox/keychain detection, then a run against --provider fake (no API key, no model, exercises the exact same lifecycle a real provider would). Recorded with asciinema + agg; regenerate with bash docs/assets/record-demo.sh after any user-facing CLI change.
$ clutchcode run "fix the failing test" --provider ollama --model qwen2.5-coder:14b
$ clutchcode diff <runId> # review what it actually changed
$ clutchcode approve <runId> # only now does it touch your branchEvery coding agent will tell you it finished. Almost none of them can prove it.
ClutchCode is built around one rule: the model's opinion doesn't count. A run isn't complete until a deterministic gate — your real build, your real tests, your real linter — actually passes. And because a model under pressure will happily delete the assertion that's failing, there's a cheat-detection layer whose only job is catching that.
A model once "fixed" a failing test by deleting its assertion. Verification went green. Cheat detection blocked the run anyway. That scenario is a permanent test in this repo, not an anecdote.
Point it at a task and a model. It works in an isolated git worktree, edits code, runs your toolchain, repairs what it broke, and stops. Nothing reaches your branch until you approve a diff.
|
🔒 Runs sandboxed by default Real OS confinement — bubblewrap namespaces plus a seccomp-BPF filter, verified against the actual kernel. Network is default-deny at the OS level, not just in policy. |
🏠 Local-first, provably No account, no telemetry, no cloud. Enforced by a release-gate test that completes a task offline with egress blocked against a local model. |
|
🧩 Model-agnostic A capability probe adapts edit format, context budget and output reservation to whatever you point it at — frontier API or a 14B model on your own GPU. |
↩️ Nothing lands without review
Every run is a worktree on its own branch, with per-step checkpoints you can roll back to. |
Eleven packages, strict boundaries. apps/* depend only on agent-api — never on runtime internals.
flowchart TB
subgraph clients["🖥️ Clients"]
CLI["apps/cli<br/><i>clutchcode</i>"]
VSC["apps/vscode<br/><i>extension</i>"]
end
subgraph boundary["🚪 Public boundary"]
API["agent-api<br/><i>in-process binding</i>"]
RPC["agent-rpc<br/><i>JSON-RPC over stdio</i>"]
ACP["acp<br/><i>Agent Client Protocol</i>"]
end
subgraph core["⚙️ Core"]
RT["runtime<br/><i>the agent loop</i>"]
CAP["capability<br/><i>model probe + budgets</i>"]
VER["verification<br/><i>gate + cheat detection</i>"]
MEM["memory<br/><i>toolchain facts</i>"]
end
subgraph found["🧱 Foundation"]
TOOLS["tools<br/><i>fs · shell · search</i>"]
SBX["sandbox<br/><i>bwrap · seccomp · policy</i>"]
GIT["git<br/><i>worktrees · checkpoints</i>"]
PROV["providers<br/><i>anthropic · openai · ollama</i>"]
end
CLI --> API
CLI --> ACP
VSC --> RPC
RPC --> API
ACP --> API
API --> RT & CAP & VER & MEM
RT --> TOOLS & GIT & PROV & SBX
VER --> TOOLS
CAP --> PROV
MEM --> VER
TOOLS --> SBX
style boundary fill:#1f6feb22,stroke:#1f6feb
style found fill:#3fb95022,stroke:#3fb950
style core fill:#a371f722,stroke:#a371f7
Why the boundary matters
The CLI, the VS Code extension, and any future editor client all share 100% of the runtime code; only presentation differs. That's why agent-api exists as a hard boundary rather than a convention — and why the same runtime can be driven in-process or over stdio JSON-RPC without a second implementation.
sequenceDiagram
autonumber
participant You
participant Agent as ClutchCode
participant Model as LLM
participant Gate as ✅ Gate
You->>Agent: run "fix the failing test"
Agent->>Agent: 🌿 create isolated worktree
Agent->>Model: task + probed context budget
loop until verified or budget spent
Model-->>Agent: tool calls (read · edit · shell)
Agent->>Agent: 🔐 policy check + OS sandbox
Agent->>Gate: build · test · lint
alt gate red
Gate-->>Agent: classified failure
Agent->>Model: targeted repair prompt
else gate green
Gate->>Gate: 🕵️ cheat detection
end
end
Agent-->>You: diff + VERIFIED status
You->>Agent: approve / reject
Agent->>Agent: 🔀 merge, or discard the worktree entirely
The interesting step is the one most agents skip: after the gate goes green, it gets audited. Deleted assertions, .skip markers, hardcoded return values, snapshot edits with no source rationale — all block completion even in --yes mode.
| Feature | Detail | |
|---|---|---|
| 🔬 | Deterministic completion gate | Real build + test + lint. No self-reported success. |
| 🕵️ | Cheat detection | Catches deleted assertions, skip markers, hardcoded outputs, unjustified snapshot edits. |
| 📦 | Git worktree isolation | Per-run branch, per-step checkpoints, rollback to any of them. |
| 🛡️ | Tier-1 OS sandbox | bubblewrap + seccomp-BPF (x86_64 Linux, kernel-verified). Seatbelt profile for macOS. |
| 🔑 | 3-tier credential storage | OS keychain → encrypted file store → env. Keys read from stdin, never argv. |
| 🧽 | Secret redaction | Every boundary scrubbed, proven by a canary test that injects a fake secret. |
| 🎛️ | Workflow engine | default · quickfix · review-only, plus JSON-Schema-validated custom workflows. |
| ⏸️ | Resumable runs | Hit a budget? resume --extend-steps N continues from the persisted transcript. |
| 🧪 | Replay harness | Recorded transcripts re-run the whole loop with zero API calls. |
| 🔌 | ACP editor binding | clutchcode acp speaks the real Agent Client Protocol — Zed today, any ACP client tomorrow — over a second binding alongside agent-rpc, not a replacement. |
Deliberately dependency-light. The seccomp BPF filter is hand-assembled in TypeScript rather than pulling a native module — the entire runtime's external dependencies are commander, ajv, and smol-toml.
Requirements — Node ≥ 20, pnpm, git. On Linux, bubblewrap for the OS sandbox (without it you get Tier 0 — policy engine only — and doctor will say so).
git clone https://github.com/Derric01/ClutchCode.git
cd ClutchCode && pnpm install && pnpm build1 · Check what your machine supports
clutchcode doctor # sandbox backend, seccomp, keychain, toolchain2 · Run a task
Local model via Ollama — no key needed:
clutchcode run "fix the failing test in src/parser.ts" \
--provider ollama --model qwen2.5-coder:14bHosted provider — key is read from stdin, never argv or shell history:
clutchcode providers set-key anthropic # paste, then Ctrl-D
clutchcode run "add pagination to /users" --provider anthropic --model claude-sonnet-5Bound it: --max-steps, --max-tokens, --cost-ceiling-usd.
3 · Review before anything touches your branch
clutchcode status # all runs and their state
clutchcode diff <runId> # what changed
clutchcode approve <runId> # merge it back
clutchcode reject <runId> # discard the worktree entirely--yes auto-approves only when the gate is green and cheat detection flags nothing.
4 · Try it with no model at all
clutchcode run "…" --provider fakeReplays a scripted transcript through the whole loop. It's how the test suite works.
No invented benchmarks here. The eval scoreboard and the §16.4 A/B now exist — but no VTCR number or delta for any real model is published, because none has been measured (this project's CI has neither an API key nor a local GPU). What the scoreboard gives you is the machinery to measure your own, and a methodology you can argue with: docs/EVAL_METHODOLOGY.md.
| Claim | How it's proven |
|---|---|
| 854 tests, 86 files | pnpm test. Real git repos, real shells, real filesystems — FakeProvider stubs only the model. |
| The suite runs on CI, not just locally | GitHub Actions, Node 20 + 22 on every PR: the same suite plus tsc -b and eslint ., with 16 tests skipped there. Those 16 skips are the bwrap confinement/seccomp suites — a hosted runner cannot create those namespaces, so they skip there and run in full locally (774, 0 skipped). CI green therefore does not prove the sandbox confines; only a bwrap-capable host does. |
| Sandbox actually confines | A test writes outside the workspace, then asserts a sandboxed cat of it fails. Network fetch inside the sandbox asserted unreachable. These run for real wherever bwrap can genuinely create namespaces (this project's dev container can); where it can't — a hosted CI runner, an unprivileged container — they skip and ClutchCode falls back to Tier 0 and says so, rather than claiming a confinement it isn't getting. |
| Seccomp actually blocks | Each denied syscall invoked by number inside real bwrap → EPERM, with an unfiltered control run proving the syscall otherwise succeeds. |
| Secrets don't leak | A canary secret injected into a full recorded run, asserted absent from every transcript, event log and artifact. |
| Cheat detection works | A recorded run where the model deletes an assertion — verification goes green, completion is blocked anyway. |
| The scoreboard can't be fooled by a green gate | Every eval task carries a held-out check, copied in only after the run finishes. A scripted run that changes nothing on an already-passing repo reaches DONE with a green gate — and is scored a false completion, not a success. |
| The eval tasks are real tasks | Eight tasks, six categories, three languages (Node, Python, shell). Every one is validated on each test run against real repos: its held-out check must fail on the pristine repo, pass on the reference solution, and leave the repo's own gate green — and each is also run against the plausible wrong solution a model would write, to prove its oracle discriminates. The validity suite has caught two real defects in this project's own fixtures. |
| Open-weight models can actually call tools | Local models mostly emit the Hermes <tool_call> format, not OpenAI-shaped tool_calls — so we used to read a tool call as prose and score the model toolTransport: "none", costing it a weaker edit format and a smaller context budget. There is now a lexical incremental parser for that format, tested over a real HTTP server and the real SSE path with tags split across chunk boundaries, including a message full of bare <, &, unclosed generics and JSX — the exact content that breaks the XML-based extractors this one deliberately is not. Parser verified; not run against a live model (no GPU/weights here) — see the limitations below. |
| The naked-vs-harness A/B is a real experiment, not a slogan | Both arms of §16.4 now run: the same model under ClutchCode, and the same model naked (one call, no tools, no gate, no repair), graded by the same held-out oracle. Every end-to-end naked test asserts the scripted server's own request counter is 1 — "single-shot" is checked, not asserted in a comment. The delta ships with a Wilson interval per arm and a task-clustered bootstrap interval on the delta, and a report whose interval includes 0 says so in its own notes. |
| Local-first is real | A task completed offline with egress blocked at the OS level, against a local model. |
🔍 Honest limitations — read this before trusting it
- Linux is the verified platform. The macOS Seatbelt profile is written against the documented SBPL grammar but has never run on real macOS. Windows Tier 1 is deliberately doc-only; WSL2 is the recommended path.
- Landlock is not implemented. Seccomp is. The blocker is documented in
HANDOFF.md. - The Hermes tool-call parser has never met a live open-weight model. It is unit-tested against fixtures modeled on the published chat-template token layout and driven through the real streaming path, and the capability probe now scores such a model
nativeinstead ofnone. But this environment has no Ollama, no GPU and no weights, so the end-to-end claim — a real Hermes-3 / Qwen / vLLM--tool-call-parser hermesdeployment drives our tools correctly — is unverified and is flagged as such inpackages/providers/src/hermes.ts. - No benchmark numbers are published for any model. The eval suite, the VTCR/§16.2 metrics, the held-out grading and now the §16.4 naked-vs-harness A/B all work and are tested — but every scored run so far is a deterministic scripted one, because this project's environment has no API key and no local GPU. So the machinery to measure "makes small local models usable" exists and no VTCR delta for a real model is published or may be quoted from it. Running
clutchcode-eval abagainst a 14B-class model on a machine that has one is the remaining step, and it needs no code. The SWE-bench-Verified subset is still not built. Seedocs/EVAL_METHODOLOGY.md§5 and §8. - Eight tasks is still a small suite. Enough to detect a large VTCR delta, not enough to resolve a small one — the A/B's confidence intervals reflect that honestly rather than hiding it. The remaining lever is §16.3a's SWE-bench Verified subset, which needs dataset fetching and per-instance container images this offline harness does not take on.
- Pre-1.0, not yet published to npm.
- Security reviews have been thorough but single-reviewer. See
SECURITY.mdfor the threat model and how to report an issue.
Anything this project can't verify is flagged in a header comment and here — silence implying completeness is treated as a defect.
gantt
dateFormat YYYY-MM-DD
axisFormat %b
title From here to 1.0
section Shipped
Agent loop · edit cascade · worktrees :done, a1, 2026-01-01, 90d
Sandbox Tier 1 · seccomp · credentials :done, a2, after a1, 60d
Workflow engine · VS Code extension :done, a3, after a2, 45d
Eval suite · VTCR scoreboard :done, a4, after a3, 30d
Naked-vs-harness A/B (the North Star) :done, a5, after a4, 20d
ACP editor binding (Zed today) :done, a6, after a5, 15d
section Next
npm release (npx clutchcode) :active, b1, 2026-08-01, 30d
Landlock rung :b3, after b1, 30d
MCP client :b4, after b1, 30d
section Later
SWE-bench Verified subset adapter :c1, after b4, 60d
PageRank repo map :c2, after c1, 45d
Live priority order lives in HANDOFF.md — exactly one row is tagged DO FIRST at any time.
PRs welcome. A few things that are load-bearing here:
pnpm build && pnpm test && pnpm lintmust be clean before every commit.- Reproduce before fixing. A finding is a hypothesis until you've made the bad thing actually happen.
- Prove your test discriminates — stash the fix, watch the test fail, restore it, watch it pass.
- Never skip or disable a test to get green. That falsifies the gate this project exists to enforce.
- Flag what you couldn't verify. Honesty beats completeness.
Full guide in CONTRIBUTING.md (DCO sign-off required). Design rationale is in PROJECT_SPEC.md; engineering history in docs/PROJECT_LOG.md.
Apache-2.0 © ClutchCode contributors.
Reference projects (Aider, Codex, OpenHands, Cline, and others) are study-only — this implementation is clean-room. See LICENSE_AND_REUSE_ANALYSIS.md.
If the idea of an agent that has to prove its work sounds right to you — ⭐ star it, or open an issue.