4.2 KiB
name, description, allowed-tools
| name | description | allowed-tools |
|---|---|---|
| gremlins | Trains one headless implementer (the base) per build with `claude -p` and forks a gremlin from it per block, so each gremlin starts from the base's reading at prompt-cache prices. | Bash(uv:*) |
Gremlins
A base is a headless claude -p session that reads the code a build touches, writes the trunk notes and changes nothing. A gremlin is a fork of the base's session (--resume <base> --fork-session) that works on one block with a brief.
Commands
G = uv run --script "${CLAUDE_SKILL_DIR}/gremlins.py". Every command prints one JSON object on stdout. Exit codes: 0 ok, 1 the call ended error or stopped, 2 refused or a usage error.
| Command | Does | Boxes |
|---|---|---|
G init --run R --model M [--effort E] [--cwd D] [--agent A] [--binary P] |
Writes run.json: the launch fingerprint (binary, full model id, flags, cwd, appended prompt) and the argv, stored once. Refuses to overwrite an existing run. |
B1 |
G train --run R --base B --brief F |
One blocking call with --session-id; on ok it writes bases/B.json. Prints {status, session_id, cost, …}. |
B1 |
G spawn --run R --base B --job J --brief F |
One blocking fork of B, reusing the stored argv verbatim. The prompt is the spawn template plus a delta header (git changes since the base's commit) plus the brief. Prints {status, cache, note, cost, …}. |
B2, B3, B5 |
G rebase --run R --base B --brief F |
Resumes B without a fork, with the delta header and the brief, then updates bases/B.json (the session id comes from the result). Warns when jobs of B are still running. |
B7 |
G status --run R [--job J] |
Bases with their warmth (warm/expiring/cold, warm_until, ttl_left_s), and the job records. |
B6, B3 |
R is the run log .md; M is a full model id (for example claude-opus-5-5[1m]; aliases are refused). The helper has no kill, wait, ping or continue command.
Call sequence
G init …(foreground).G train …as a blocking Bash call withtimeout: 600000. If it runs past the timeout, the harness moves it to the background, and the completion notice carries the result.- Each
G spawn …as its own Bash call withrun_in_background: true. Several spawns run at once as several background calls. Read the result JSON from each completion notice; do not poll. G status …to see warmth before spawning again, or to re-read a job record.
Every call is reported in ledger.jsonl with the real model (from modelUsage), four token columns and the cost delta against the base (B5). Warmth is reported only; nothing keeps a base warm (B6).
Stopping a gremlin
Use TaskStop on the backgrounded Bash call (B4). That kills claude and its bash wrappers. Known leftover (spec §7): a command the gremlin had in flight (for example a long test run through its Bash) can survive as an orphan and run to its own end. After a hard stop, the job file may stay running with no ledger line. You know which calls you stopped, so status shows that record as it was written.
Briefs carry the rules
The spawn template sets no commit rule. Each brief states whether that gremlin commits, which paths it may touch, and what its gate is. For gremlins that run in parallel, say "do not commit" and list the paths.
State dir
<run log without .md>-gremlins/, next to the run log:
run.json(written once byinit),mcp-empty.json,preamble.md(a frozen copy, so the system prompt and the cache stay stable)bases/<B>.json(written bytrainandrebaseonly);jobs/<J>.json(each written by its own command)ledger.jsonl(one appended line per finished or stopped call)raw/<J>.jsonl(the stream) andraw/<J>.err;briefs/<J>.md(the full prompt sent)notes/<J>.md(the gremlins' handoff notes);logs/(their gate and test output)
Cache hits
A fork hits the base's cache only with the same argv, the same pinned env, the same cwd and an unchanged system prompt. spawn reports cache: hit|partial|miss; a miss is reported, not an error. The env scrub removes Desktop, SDK and uv variables from every launch. The helper uses no platform-specific process code, and it runs on Windows Git Bash, WSL, Linux and macOS (B8).