Files
gstack/ship/DRIVER.md.tmpl
Garry Tanandcapy-ai[bot] 71af16c60b v1.91.362.0 ship: one call per review pass on Capy (GSTA-167 calls PR 2) (#3665)
* ship: poll readers in-program, never wait on wakes; 32 KB returns; gated fix program; unattended push defers the guard offer; calls meter (GSTA-167 calls PR 1)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (inventory lib/ship-release.ts as a GSTACK_SESSION_KIND reader)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* docs(ship-budget): document calls and dotted --step notes

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* ship: one call per review pass on Capy; staged dispatch manifest, chunked briefs, intent before create (GSTA-167 calls PR 2)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: pre-landing review fixes (pass program reruns a failed review-log start and stops on a failed reader every run)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: Step 11 review fixes (PASS: none read from the last line only, queued readers reconciled and timed out, a budget stop ends the pass)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* ship: judge treats a missing severity as invalid; Capy passes rendered briefs via cat (replay C1-34 breaks)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: the batched reviewer reads its checklists by path, as the render CLI is given them (PR #3665 review)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix: keep the Capy skill under its context budget after the main merge

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* chore: drop PR 1's changelog fragment, which main's v1.91.355.0 stamp already consumed

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(ship): the pass program takes extras as JSON and a cwd, and waits a minute for a done reader's summary (replay C2-34)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-31 11:01:11 +00:00

127 lines
9.8 KiB
Cheetah

# /ship driver: run /ship from a parent agent
Read this instead of `ship/SKILL.md` when a parent agent on any host runs /ship
(`SESSION_KIND: unattended`). Commands live in `<root>/bin/` (`<root>` holds `ship/`); run each with
the `GSTACK_LAUNCH` assignments your installer printed (`. <the GSTACK_LAUNCH_FILE it printed>`), never
`export $(...)`, `env`, `printenv` or a bare `set` in a tool fence.
**Rules.** Each phase below is one call: one program (Capy: an execute program; else a
script) that runs the bins, reads, dispatches and waits, returning only result lines and reader
outputs; print them verbatim. The model keeps only lead judgment, fixes, CHANGELOG and PR prose, the
gates and the report. `STOP:` (exit 3) means nothing after it ran; `NEXT:` names
the next act. Read a section only when a phase or the list at the end sends you, never
up front. A STOP or decision this file does not cover: read `ship/SKILL.md` at that step, finish it
there, come back. Unattended, a question with a recommended option takes it (log it); a gate
disposition and every approval stay pending and end the run. Keep a private invocation record (the
`--record` file): write its six headings at Phase 1, then fill each as its phase ends: **Checks**
(Phases 2-4: lanes, pregate, evals, `Coverage:`, the plan checks, `Scope Check:`), **Decisions** (any
phase: each answered or auto-taken question, in its words), **Reviews** (Phases 3-5: the plan line,
start tokens, `Pre-Landing Review:`, `Gate edits:`, the reviewed tree), **Release** (Phases 5-7:
version, CHANGELOG, commits), **Documentation** (Step 14.5) and **Next steps** (every phase: the next act).
**Reviewers are the sections' own.** Every audit, specialist, Red Team, QA, fix-check, adversarial,
outside-voice and documentation brief, its severity and confidence rules and its gates come from its
section verbatim, with only its placeholders filled; this file
never shortens a reviewer's brief. A blocking reader's prompt is its `gstack-review-dispatch render`
file, unchanged; its findings reach `merged.jsonl` only via `collect`; `judge` refuses a drop or downgrade. Audit readers (Steps 7, 8, 9.2.1, 14.5) cannot block, so each runs on a
small model at low effort; their findings go to the PR body.
**Calls.** One pass with no fixes is 9 calls: Phases 1-8 and the report; at most 12 with a STOP's
section read or a fix-check, plus a keep-alive per 200 s waited. A fix repeats Phases 3-4.
**Budget: observe.** `gstack-ship-budget start --mode observe` records, never admits: each program ends
with `gstack-ship-budget note --step <last step> --reading R --credits C --record <rec>`, R and C read in that program
(Capy: your jam's `cost.tokens`, `cost.credits`). No check per step, no reservation, no meter-only
call, no handoff; under `--token-cap` a note past the cap prints `verdict=stop`, the one stop check.
A dispatching program takes `BEFORE` (R and C) as its readers start and passes
`--dispatched-at <R> --dispatched-credits <C> --readers <n>` with the reading after the last settles.
**Waits.** No call waits past 200 s: a program returns what still runs 200 s after its first line; the next
call resumes the poll. Lanes, pregate and `finish` run in background. Never end the turn while
readers run (each wakes it). A small waiting child saves nothing. Past 100 minutes, stop. Returns:
≤32 KB per program; split longer reads at headings, each byte once, before first use.
**One program per pass.** Each review pass, Step 11 and the Step 14.5 audit is one program, and the
parent makes no other call while it runs: (1) `gstack-review-dispatch pass`: `gstack-review-plan --base <base>`
with the pass's flags, then its staged manifest (Step 14.5 has one reader, `docs`); (2) `gstack-review-log --start
<skill>` once per row the step logs (Step 14.5 takes none); (3) `BEFORE`; (4) `sent` (`BRIEF_MISMATCH` voids it), then one
subagent per reader on its rendered file;
(5) a poll until every reader settles (status `done` or `failed`, or a final summary; a fresh `idle`
has not run); (6) `note` with the reading pair; a later batch (the Red Team,
given the specialists' collected lines) repeats (3)-(6); (7) the collect: return only each reader's
final output and status, via `collect`; it never walks the dispatch steps call by call.
## 1. Load: Step 0
The install check and this file.
## 2. Preflight, tests, evals and reads: Steps 0.9, 1, 2, 3, 4, 5, 6, 6.5, 10
`gstack-ship-budget start --record <rec> --mode observe [--token-cap <n>] --reading R --credits C`, then
`gstack-ship-preflight --base <base> --lane <label>=<command>...` (the test commands AGENTS.md or
CLAUDE.md names). `CARRY: carried` ends the run on its `GSTACK_RESULT:`
line. A lane passes on `tests_ran: N` with exit 0; `tests_ran: 0` is ZERO-RUN, a failed lane; `unknown`
is `count unavailable`. In-branch failures stop the ship; after a repair rerun with `--tests-only`.
`requires-remote` needs `gstack-pregate clear` before Step 18. When prompts, templates, judges or eval
harness changed, start the eval selector and pre-merge command (detached past 30 min); else
record `evals: none affected`. Steps 6.5 and 10 run only if `gstack-greptile-early detect` finds
Greptile. Then `gstack-ship-preflight --audit --base <base> --out <run dir>` writes the diff once
(`CONTEXT:`) and the TODOS.md items naming touched paths (`TODOS:`), and prints the coverage map, the
plan candidates and `READER: coverage=<needed|none> plan=<needed|none>`. Programs read
`sections/review-army.md`, `sections/adversarial.md`, `sections/documentation.md`, the todos and commits
files, and `sections/test-coverage.md` or `sections/plan-completion.md` only when its reader is `needed`.
Never read TODOS.md or the full diff into the parent. A `PERSIST:` hint never replaces Step 9.
## 3. Audits and review: Steps 7, 8, 9, 9.1, 9.2, 9.2.1
One program: the audit readers `READER:` names (Step 7 from `sections/test-coverage.md`, Step 8 from
`sections/plan-completion.md`, each run as written; Step 7 may write tests, so it settles first), Step 9.2.1's QA reader (that step of
`sections/review-army.md` as its brief) and the pass (above): Step 9's plan and start, Step 9.1's
specialists and Step 9.2's Red Team as written. `Coverage:` and Step 8's line come from `--audit` when no
reader ran.
## 4. Judgment: Steps 8.1, 8.2, 9.3, 9.4 and Step 11
Steps 8.1 and 8.2 (`Scope Check:`) on the todos and commits files, then the core checklist, Steps
9.3, 9.4 and the repeat decision as written (`gstack-review-plan` included;
`JUDGMENT: ok` before any fix), fixes and persistence in
one program. Prints `Pre-Landing Review:`, `Gate edits:`. `NEXT: stop` stops; `full` or
`scoped`: one program runs the failing test, fix, `--tests-only` and Phase 3, each gated; `done`: the same program runs Step 11 from
`sections/adversarial.md` as written (above), only the voices the last full-pass plan lists (neither
prints `ADVERSARIAL: skipped (review plan)`).
## 5. Voices, bind and version: Steps 11, 11.5, 12
Judge the voices; missing outside coverage is `unavailable`, never clean; queued fixes rerun Phases
3-4. Then `gstack-review-dispatch verify` (`VERIFY: clean`) and `gstack-review-read`: the final Step 9 row and Step 11 native row (or `CURRENT` freshness
after a planned skip) agree on `wtree`, `start_wtree`, `end_wtree`; save that reviewed tree. Then
`gstack-ship-release version --base <base> [--bump micro|patch] --why '<line>'`; MINOR, MAJOR, `BUMP_ANSWER_REQUIRED`:
approvals; `VERSION: skipped|kept`: no write.
## 6. Notes and documentation: Steps 13, 14, 14.5
Step 13: one user-facing entry from the commits file, where `NEXT:` says;
`gstack-prose-lint <it> --base origin/<base> --gate` until `PROSE_LINT: ok`. Step 14: TODOS.md deferrals and
completions, edited from the todos file. Step 14.5, every ship: read `sections/documentation.md` and run its audit as written, as
one program (above), then `gstack-ship-receipt docs-caps --base <base>`; print `Documentation:`.
One re-audit at most.
## 7. Release: Steps 15, 16, 17
Commit in bisectable chunks, then `gstack-ship-release finish --base <base> --reviewed-tree <t>
--docs-post <post> --lane ... [--build <cmd>] --trailer '<t>'`: `ROUTE:`, `DOCS:`, `EVIDENCE:` (FRESH;
STALE or MISSING reruns once), `PREGATE:`; print them, the last `Gate edits:` and each `tests_ran`. Then
`gstack-ship-release push --branch <branch> [--gate-open <n>]`: `REDACT_PREPUSH:`, `SEALED:`, `PUSH:`
(pushed or ALREADY_PUSHED). Unattended, push defers the pre-push offer; else its STOP runs Step 17's guard block (`HOOK_STATE:`, `HOOKS_IN_GIT_DIR:`, `PREPUSH_PROMPTED:`). Never force-push.
## 8. Publish: Steps 18, 19, 19-C, 20, 21, 22
- Step 18: the open-PR lookup; a title file starting `v<NEW_VERSION> `. `UNATTENDED_SHIP:` with no open PR at HEAD takes Step 18-H.
- Step 19 body: the receipt block, then the sections `sections/pr-body.md` lists (Pre-Landing Review: `REVIEW_LOOP:`, `Gate edits:`, deferred, notes), led under `CAPY_PR: on` (Step 19-C) by What changed, Why, Blast radius and Approvals (`gstack-approvals render`). `gstack-prose-lint <top> --sections 'Why,Summary,Blast radius' --gate`; `gstack-issue-links`; `gstack-review-scope summary --since "$REVIEW_SINCE" && gstack-ship-receipt write --pr <n> --base <base> --gate @<f> --pregate <f> --issues @<f> --review-loop @<f> --docs @<f> --body <body>`; `gstack-post pr-body` and `pr-title` (a new PR via the host's PR tool; a draft while a gate finding is `open`). `SHIP_RECEIPT:` opens your report.
- Step 20: the ship metrics row via `gstack-review-log`.
- Step 22: `gstack-ship-budget close --reading R --credits C` (`BUDGET_FINAL:` and `BUDGET_TIMELINE:` carry tokens and credits; put both in the report), then `gstack-ship-receipt result --pr <n>`: `GSTACK_RESULT: skill=ship status=complete run=<dir>`. Under a merge queue, `gstack-ship-queue ready --pr <n> [--screen|--no-screen]` at the pushed head; paste its output.
## Where each STOP sends you (paths under `<root>/ship/`)
{{SHIP_DRIVER_STOPS}}