assemble
Four models, one answer, many rounds. Each turn reads the current best answer, critiques it from a given role, and writes an improved version. Progress lives in files, not in the conversation, so every turn starts with fresh context (the Ralph Wiggum technique).
Commands
| Command | What to do |
|---|---|
assemble <task> | Start a run with the default schedule (36 turns). |
assemble --quick <task> | One block of 2 passes x 4 models (8 turns). |
assemble resume [<slug>] | Continue the most recent (or named) unfinished run. |
assemble cancel [<slug>] | Set status: cancelled in the state file and stop. |
assemble status | Show iteration, block, open MUST items and models used. |
Before starting
- Load
.assemble/config.jsonif it exists, otherwiseassets/config.example.json. - Pick the model adapter (see below) and tell the user which four models will run, and where their task text will be sent. If any model is outside
allowedModels, orlocalOnlyis true and a model is remote, drop it and say so. - Restate the task and the acceptance criteria in one short paragraph. If the task is unclear, ask the user before spending any rounds.
- Create
.assemble/<slug>/withtask.md,answer.md(empty), andstate.mdas described inreferences/state-format.md. Make sure.assemble/is in.gitignore.
The schedule
A round is one model turn. A pass is all four models taking one turn each, in order.
| Block | Passes | Turns | Running total |
|---|---|---|---|
| 1 | 4 | 16 | 16 |
| 2 | 3 | 12 | 28 |
| 3 | 2 | 8 | 36 |
After turn 36, show the report and ask the user whether to run another block. Never go past 36 without asking.
Roles rotate each pass so every model plays every role: in pass p (0-based), model m plays roles[(m + p) % 4] from references/roles.md.
Each turn
Build the turn prompt from files only, using references/handoff-format.md:
task.md- the current
answer.md - the previous turn's critique (from the latest
round-NN.md) - the role card for this turn
Don't include earlier rounds, and don't say which model wrote the current answer. Then:
- Send the prompt to the model for this turn using the chosen adapter.
- Parse the reply into a critique (each issue tagged
MUSTorNICE), a revised answer, and a verdict. - If the task is code and
checksare configured, apply the revised answer in a scratch copy, run the checks, and add any failures to the critique asMUSTitems. - Write
round-NN.md(role, model id, critique, check results, verdict, line diff size) and overwriteanswer.mdwith the revised answer. - Update
state.md: iteration, block, pass, openMUSTcount, and the no-change streak. - Give the user a one-line progress note:
Round 7/36 · skeptic · 2 MUST, 1 NICE · diff 14 lines.
If a model errors or times out, log it in round-NN.md, skip the turn, and carry on. If two models in a row fail, pause and tell the user.
Stopping
A turn counts as no change when it raises no MUST items and changes fewer than noChangeLines lines of answer.md.
Stop early when either:
- four turns in a row (a full pass) are no change, or
- a turn ends with
<promise>CONVERGED</promise>and the next turn confirms with noMUSTitems.
If the open MUST count hasn't dropped for a full block, stop and write a short "stuck" note: what's blocking, what was tried, and what the user could decide to unblock it.
Report
When the run ends, write .assemble/<slug>/report.md and show it:
- the final answer
- rounds run, and why it stopped
- the top changes in each block
- any open
NICEitems - models used, with failures
- a rough token and cost estimate (sum of prompt and reply sizes, times prices in config if given)
Model adapters
Use the first that's available, and tell the user which one you picked.
- In-tool subagents. If the host can spawn subagents and pick their model, use one per turn. Cursor can mix vendors. Claude Code and Kiro only offer Claude models here, so the four will be Claude variants.
- Vendor CLIs. Run
scripts/run-model.sh <model-id> <prompt-file>once per turn. This is the true multi-vendor option. Check each CLI exists (command -v) before the run starts. - Single model. Run every turn yourself, playing the role for that turn. Read only the turn's files, and treat each turn as a fresh start.
Optional tool-specific helpers, such as a Claude Code stop hook for unattended runs, are in the repo's adapters/ folder.