You are the parent. A child CLI does one bounded task and returns a report. You judge the report. The child is not an oracle.
A CLI, model, or effort the user named wins, for the first spawn and every retry. When none is named fills only what is missing. No personas.
Delegate
- Take the CLI, model, and effort the user named. Spoken names are in references/models.md. Fill each blank from When none is named and do not ask, except where that section says to stop. Cursor, cursor-agent, and Grok Bot are the
cursorfamily. Grok Build isgrok. Claude Code isclaude. Codex iscodex. Antigravity isagy. Muse Code ismuse. - Pass
--efforttoclaude,codex,grok, andmuse. CLI defaults differ from API defaults and change between releases. Foragyandcursor, pass it only when the user named an effort and the model id does not already contain one, such asgemini-3.8-flash-high. Prices are per token. Higher effort spends more tokens at the same rate. - Write
brief.mdin a new temp run directory. Use the shape below. - Run
scripts/spawn.shin the background. On Windows, invoke Git Bash with the script path as an argument. Do not put the brief inside a PowerShell double-quoted string. Writebrief.mdas UTF-8. - Wait until that process exits. Read
report.mdorlast.md, pluscapture-status.txt, plus the exit code. - Say what you agree with, what you do not, and what you will do. Do not paste the report as your whole answer.
& "$env:ProgramFiles\Git\bin\bash.exe" -- "<skill-dir>\scripts\spawn.sh" --backend codex --model Astra --effort high --project "D:/Code/app" --run "C:/Users/<you>/AppData/Local/Temp/harness-subagent/<id>"
--backend may be omitted when the model name belongs to one CLI. --resume-id continues that same child. Do not use --continue or --last.
A child must not delegate. spawn.sh sets HARNESS_SUBAGENT_RUN and refuses a second launch.
When none is named
- Put the task in the row it fits best. If it spans two rows, use the row for the step you delegate.
- Apply what the user named. A named model selects its CLI and replaces the cell's model. A named CLI selects its column. A named effort replaces the cell's effort. If the model does not accept that effort (the Efforts column in references/models.md), stop and tell the user.
- With no CLI named, read the columns left to right. Skip the vendor of the model you are running on. For a review, a refutation, or a second opinion, also skip the vendor that produced the work, when you know it. The same vendor through another CLI is not a second opinion. If you do not know your own vendor, skip nothing for it.
- Skip a CLI whose
scripts/health.shrow ismissing,broken, ornot-logged-in. Keeplogin-unknown. Read the rows, not the exit code. Run it once per session if you do not know. - If no column is left, stop and tell the user why.
- Say one line before you spawn: task row, CLI, model, effort. Do not wait for an answer.
| Task | codex |
claude |
grok |
muse |
|---|---|---|---|---|
| Lookup, extraction, summary, triage | Luna, high | Haiku, medium | Grok 4.7, low | Spark, low |
| Implementation from a clear brief | Sol, medium | Sonnet, medium | Grok 4.7, medium | Spark, medium |
| Debugging, root cause | Sol, high | Sonnet, high | Grok 4.7, high | Spark, high |
| Code review, refuting a plan, second opinion | Sol, high | Sonnet, high | Grok 4.7, high | Spark, high |
| Architecture, ambiguous design | Astra, low | Opus, high | Grok 4.7, high | Wonder, high |
| UI build or visual check | Sol, medium | Sonnet, medium | Grok 4.7, medium | Spark, medium |
| Long autonomous run with clear acceptance | Sol, high | Sonnet, high | Grok 4.7, high | Spark, high |
| Writing, docs, copy | Sol, low | Sonnet, medium | Grok 4.7, medium | Spark, medium |
Each cell starts at the vendor's own starting effort for that kind of work, from the guidance cited in references/models.md. Effort names are calibrated per model, so high on one model is not high on another. Benchmark rows there are evidence, not a ranking.
Antigravity and Cursor serve several vendors, so they have no column. If the user names one of them without a model, list its models (agy models, cursor-agent --list-models) and ask once.
Do not choose max, ultra, Fable, Wonder Full, Grok 4.7 Fast, or an id that scripts/registry.json does not list, unless the user names it. Under claude -p, Fable bills usage credits without asking. Wonder Full runs only on the Muse Power Usage or Maximum Usage plan. Grok 4.7 Fast costs twice the token price of Grok 4.7.
When the result falls short
Exit 0 is not success. Judge the report against "Done when". Then find the cause before you change anything.
- Missing context, tools, or permission. Fix the brief. Keep the model and effort. This retry may resume the same session with
--resume-id. - The child skipped files, tests, or checks. Raise effort one step, at most to
xhigh. - The child had the context and tried, and the reasoning was still wrong. Move one model up within the vendor: Luna to Sol to Astra, Haiku to Sonnet to Opus, Spark to Wonder.
A retry that changes model or effort is a fresh spawn. spawn.sh refuses --resume-id with a different model or effort. Put the failed attempt's evidence in the new brief. Change one setting per retry, and only a setting the user did not name. Stop and tell the user what failed when the next step would change a named setting, when there is no next step (Astra, Opus, Wonder, Grok 4.7, or xhigh), or after two retries. A usage limit is not a quality failure; follow When the child hits a limit.
Brief
# YOU ARE THE WORKER. DO NOT SPAWN.
Do not load harness-subagent. Do not run scripts/spawn.sh.
## Task
One sentence.
## Where to look
Paths, commands, and exclusions.
## Already tried
## Done when
Name paths. Do not paste the repo. spawn.sh appends the report.md path. The child writes that file before it exits. The first line is VERDICT followed by the result.
Grok cannot be relied on to read the temp run directory. spawn.sh copies the prompt into the project for that launch and deletes the copy on exit. Muse's sandbox cannot write outside the project, so it writes its report to a per-run .harness-subagent-report-<uuid>.md in the project and spawn.sh copies it to report.md in the run directory, then deletes it.
When the child hits a limit
spawn.sh reads the CLI text for a reset time.
- The reset is known and within 24 hours. The script waits, then resumes that same session once. Claude Code's own auto-continue refuses waits longer than 24 hours (docs accessed 2026-09-22). This skill uses that cutoff for every CLI.
- There is no reset time, the reset is further away, the message is a credit or spend block, or a second limit arrives. The script stops. Stop with it. Tell the user the evidence and the time, if any. Wait for instructions. Do not switch CLI or model. Do not invent a reset time.
Health
scripts/health.sh prints one row per CLI. Columns are name, version, login, update. --update runs each vendor update command. Exit 0 only when every CLI is present and every CLI with a login check is logged in, so a CLI you never use makes it 1. broken means the binary is on PATH but its version check fails. A failed login check is retried once, because grok reports logged-out on the first call after token expiry while it refreshes silently.
| CLI | Login check | Update |
|---|---|---|
| claude | claude auth status |
claude update |
| codex | codex login status |
codex update |
| grok | grok models must say logged in |
grok update |
| agy | no login command | agy update |
| cursor-agent | cursor-agent status |
cursor-agent update |
| muse | no login command | none; the launcher updates itself |
Capture
spawn.sh writes last.md, capture-status.txt (ok, ok-report, usage-limit, or no-verdict), and session.json. A report containing VERDICT wins over the final stdout, because Claude's last message is only the last turn. ok means text was captured. It does not mean the task succeeded. Exit 0 with no-verdict is not success. On Windows the run directory is handed to the child as C:/... (cygpath -m), never Git Bash's /tmp/..., which a native CLI reads as <drive>:\tmp.
Resume needs the session id from that run. Copy session-id and session.json into a new run directory, write a short continuation brief.md, and pass --resume-id. The auto-wait path does this itself once.