How muxcode works
The route one change takes through muxcode, the questions every tool call is asked, and where the sandbox fits, with drawings you can step through.
muxcode splits the work in two. The models you sign in to do the thinking: they plan, write the code and judge the result. The app on your Mac does the deciding: which seat runs next, which checks must pass, and which tool calls may run without asking you. A model can ask for anything. Only the app can say yes.
This post follows one change through that split, then one tool call, then the sandbox. The first two drawings are interactive, and every rule in them is one the app enforces today.
One change, start to finish
Select a step to read what runs there, or use the arrow keys to walk it in order. The seats name the roster muxcode ships with; you can change any of them in Settings.
Select a step to see what runs there.
Your prompt
A task in plain words. Every seat is given your own words, so nothing is lost to a paraphrase.
- Starts on your Mac, in a worktree of its own
Plan
The Architect reads the code it needs and writes a contract: the change, what it must not touch, and the verification that proves it.
- Its brief carries the checks your repository's manifests define
- Every change starts here
Contract screen
Before a worker starts, the contract is read for gaps: a check you named that nothing runs, or verification that cannot fail. The host lints the plan first.
- The shipped roster has no separate critic: the Architect re-reads its own plan
Baseline
Your project's typecheck, lint and tests run once on the untouched tree, with the tree watched for writes. What passes here is what the change may not break.
- Checks that would download their tool are never run
- Frozen for the run before the first worker
Route
Jev is asked one choice: which worker in your pool fits this contract. A sure answer picks that rung. An unsure one, missing evidence or high risk keeps your configured worker.
- Jev never moves the judge's model
- The shipped roster has one worker, so nothing is routed
Implement
The worker edits inside the contract. Before each generation it checks its effort: Jev may raise it for the next 1, 2, 5 or 10 steps, never below where it started.
- The contract's post-edit checks run after every edit
- Every tool call still goes through the permission gate
Paused for you
A worker that needs what only you can give, an answer or a tool to install, pauses instead of failing. Resume puts the configured worker back.
- A pause is not a failure: no retry is spent
Gate
Code settles what code can: real exit codes, a check that passed at baseline and now fails twice, a secret the change added, a write to the tree. Where reading is needed, Jev answers at 0.85 or the code's fallback decides.
- Coverage and mutation testing inform the judge, never gate
- A gate reads only what this route changed
Judge
The Architect reads the result against the goal through four lenses. An accept that fails any lens is a reject, and nothing the gate found can be argued away.
- A fact from the gate always stands
Retry seat
A failed check or a judged reject goes to the retry seat, a different model, and its change goes back through the gate.
- A retry never returns to the seat that failed
- A second opinion, not the same attempt again
Ready to land
An accepted change is yours: commit and push from the app, or fetch the branch a sandbox task left. Nothing lands on its own.
- The run keeps its record: seats, time, tokens and every command it asked to run
Three things decide the shape of that route.
Every change starts with a plan. The Architect writes a contract before any code is written: the change, what it must not touch, and the checks that prove it. Every step after it is checked against that contract.
Code settles what code can. The gate trusts exit codes, not descriptions of them. A check that passed on the untouched tree and fails after the change fails the change, and nothing the judge says can argue it away. Coverage and mutation testing are shown to the judge, but they never block a change on their own.
A retry is a second opinion. A rejected change goes to a different model, not back to the seat that failed. Its work goes back through the same gate.
Where Jev fits
Jev is a small, fast classifier that reads along. It answers typed yes-or-no questions: is this contract missing a check, which worker in your pool fits this job, does this still-failing test fail in a new way. muxcode only acts on an answer that clears a fixed bar. When Jev is unsure, or not available, the configured choice stands.
Jev is never a seat. It cannot widen a permission, move the judge’s model, or replace your Architect. It helps choose; the app decides.
Every tool call goes through the gate
The agent asks, and the gate on your Mac answers. Pick a permission mode and a call to see the questions the gate asks, in the order it asks them, and where it stops.
Asks you
It changes the project, and no rule of yours covers it.
The agent wants to run pnpm add zod.
A few of these answers surprise people.
- Plan mode refuses without a card. Plan mode is for research and proposals, so anything that changes a file or runs a changing command is refused, and the agent is told why.
- A
.gitfolder always asks. What is written there decides which programs git runs, so no mode and no rule lets an edit through unasked. - Bypass has one narrowing. A command the classifier is very sure would send data out, touch credentials or change the machine is put to you first. Everything else runs.
When the gate asks, the card names the exact call and offers a rule you can keep, so the same call is not asked about again.
The models are yours
muxcode serves no hosted models. The seats are filled from the sign-ins you already have, and the work around them belongs to you, not to whichever model ran it.
- Tasks and worktrees
- Session history
- Notes and decisions
- Permission rules
- Your workspace's code index
Swap the Worker from Opus to anything else your sign-ins offer and the task, its worktree, its history and your permission rules stay exactly where they were.
Where the sandbox fits
On Pro and Team, a task can run in a sandbox on Cloudflare instead of on your Mac. The split holds: the conversation, the model keys and every permission decision stay on your desktop, and the sandbox only carries out the reads, edits and commands it is sent.
over HTTPS
reads only
- MethodRequestAnswerRule
- GET registry.npmjs.org/zod forwarded download-read
- GET static.crates.io/crates/serde forwarded download-read
- POST github.com/acme/ledger.git forwarded git-fetch
- POST github.com/acme/ledger.git refused read-only-methods
- PUT registry.npmjs.org/zod refused read-only-methods
- GET paste.example.com/raw refused host-allowlist
The container reaches the internet through one gateway. It can download packages and fetch from GitHub; it cannot push, publish or reach a host that is not on the list, and every decision is logged with the rule that made it. The task works on its own fork of the project and checkpoints to a branch, so nothing reaches your repository until you fetch it and choose to land it.
What this adds up to
You can hand muxcode a task and walk away. The change comes back planned, checked against your own tests, judged, and waiting on a branch. Anything that needed your say was asked, with the reason on the card.
Download muxcode for macOS or read how the sandbox is held in.