captain docs: the lane sleeps while /ship runs; READY duty owners (GST-1573) (#4055)

* captain docs: the lane sleeps while /ship runs; READY duty owners (GST-1573)

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

* captain docs: the Capy skill's /ship-subagent bullet matches; --pregate, base-red and catch-up read (GST-1573)

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

* fix: pre-landing review fixes

Trim the Capy skill's 'Sleep while /ship runs' bullet back under the eagerPerInvocation.capy/skill/gstack context-budget ceiling (5372 > 5315 tok failed test/context-budget-ratchet.test.ts in Free Tests run 42169300422).

Review-Finding: capy/skill/gstack/SKILL.md:58:testing reader=core
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>
This commit is contained in:
Garry Tanandcapy-ai[bot] authored and GitHub committed 2026-11-06 06:09:08 +00:00
1 parent 8d712d63dd
commit 45c849c289
4 files changed
+36 -9

No files matched your search

+7 -1
View File
@@ -32,7 +32,13 @@ Spend cap: <focused paid runs per PR, from SPEND>
3. Ship. CHANGELOG entry under [Unreleased]; GUARD_CHECKS, pregate and /ship at the final
head; one unstamped READY block (captain/templates/READY.md) to me; the PR body carries
gstack-approvals render. Never merge; stamp only on my slot call.
The lane subscribes to the PR, then stops its /ship subagent at READY (docs/captain.md, the lane's /ship sequence).
After dispatching /ship, end your turn; wake only on /ship's completion, holding no PR
watch meanwhile (cancel one you hold; a red check during /ship waits for it to finish).
/ship owns the receipt and the PREGATE line. On that wake you subscribe to the PR, read
its checks and comments once, stop the /ship subagent, run gstack-ship-queue ready
--pr <n> --pregate <pregate.json> --screen|--no-screen at the pin (its notes on origin),
audit your decision trail, write Attention and send READY; after READY, handle PR events
as usual (docs/captain.md, the lane's /ship sequence).
Done when: the READY block is sent at a frozen head, reports/<thread code>.md is written,
and its Approvals table carries the plan approval row (the owner's words, the date) or the
+1 -1
View File
@@ -55,7 +55,7 @@ Every Capy thread that uses gstack follows these for new work, under a Captain o
- **Plan first.** Run `/autoplan` on new functionality right after the install check. The lean run (the Capy default) is one reviewer over plan and draft code; `--full` adds every phase.
- **ELI5, then the word.** Send the plan and gate to the person, or the Captain, in plain language: `gstack-owner-brief render --captain --out <run dir> --captain-name "<Captain name>"`, its choices as lettered lines in the ask format (`docs/captain.md`) and "do it" taking every recommendation at full scope. Build only after their word is answered into the run and it reports `APPROVED`; then `gstack-approvals import --autoplan <run dir> --by "<owner>"`.
- **/ship before ready.** Run /ship at the final pushed head before a PR is called ready; `SHIP_RECEIPT: pr=<n> head=<head>` must name that head, and a later push needs a new /ship. The review inside /ship, like the autoplan, is sized to the change.
- **Stop a finished /ship subagent.** When a /ship subagent opens its PR, the parent subscribes to that PR with Capy's subscribe tool and keeps that one subscription until the PR merges or closes, re-subscribing if the watch expires, then cancels it. Once the subscription is in place and READY arrives, the parent stops the subagent and owns the PR from then on, slot stamp, re-READY and receipt carry included. A stopped /ship subagent woken by a check, review or merge notice, not by its parent, reports one line naming what woke it, its pin and the PR head (`gh pr view <n> --json headRefOid --jq .headRefOid`) and ends the turn without acting, whether or not the head moved. A message from its parent is an instruction it carries out.
- **Sleep while /ship runs, then stop it.** After dispatching /ship the parent ends its turn with no PR watch until /ship completes (a re-READY drops a held watch first). On that wake it subscribes to the PR (renewed on expiry, cancelled at merge or close), reads its checks and comments once, stops the subagent, runs `gstack-ship-queue ready` and owns the PR thereafter: slot stamp, re-READY, receipt carry (`docs/captain.md`, the lane's /ship sequence). A stopped /ship subagent woken by a check, review or merge notice, not its parent, reports what woke it, its pin and the PR head (`gh pr view <n> --json headRefOid --jq .headRefOid`) in one line and ends the turn without acting, even if the head moved. A message from its parent is an instruction it carries out.
- **No merge without the owner's word.** A thread never merges on its own; under a Captain the controller merges on a recorded standing approval, and a thread with no Captain asks the person.
Exempt from the plan step: read-only work, the daily flaky pass's repairs, slot stamps, CHANGELOG-only resolves, cap re-pins under a written grant, S1 emergencies (a broken install or upgrade, a red main, a security bug) and fixes from an already-diagnosed, audited problem list. Other bug fixes skip plan review (`--kind fix`, R65) but carry a repro on current main or a failing test written first; features get the lean run (`--kind feature`).
@@ -0,0 +1,3 @@
### Changed
- **Captain docs: a lane sleeps while /ship runs.** `docs/captain.md` (the lane's /ship sequence), `captain/templates/brief.md` and the Capy gstack skill's "Sleep while /ship runs" bullet now say that after dispatching /ship, the lane ends its turn and wakes only when /ship completes, holding no pull request watch meanwhile; that one wake relays READY, and after READY the lane handles pull request events as before. Each READY duty has a named owner so `train build` never refuses a pin with `QUEUE_NOT_READY` for a step nobody ran: /ship owns the ship receipt and the pregate record behind the `PREGATE:` line; the lane owns `gstack-ship-queue ready --screen|--no-screen` and its notes, the decision-trail audit and the `Attention` section. The tradeoff is that a red check that lands while /ship runs waits for /ship to finish instead of being fixed in parallel.
+25 -7
View File
@@ -277,7 +277,8 @@ never refuses or stales a READY for it, and the lane reruns neither `ready` nor
### The lane's /ship sequence before READY
Every READY follows a /ship run on the branch at the head being READY'd, re-READYs after
a push included. The sequence that works unattended on Capy:
a push included. The sequence that works unattended on Capy (steps 3 to 8 run inside
/ship; steps 1, 2, 9 and 10 are the lane's):
1. Install for ship (`bash scripts/install.sh --for ship` from the project directory; a
planning-only install does not admit /ship).
@@ -304,15 +305,32 @@ a push included. The sequence that works unattended on Capy:
`/ship --resume <record>`; no READY goes out on the conditional receipt,
except on a train with `gates` ([Merge trains for other repos](#merge-trains-for-other-repos)).
9. READY: `gstack-ship-queue ready --pr <n> --pregate <pregate.json> --screen|--no-screen`;
send the printed block.
send the printed block. The lane runs this on /ship's completion wake, below.
10. After the slot call, the stamp commit keeps the pin's receipt; re-READY with the same
receipt, no second /ship.
When /ship runs in a subagent, the parent subscribes to the pull request's check and
review notices as soon as the subagent opens it, and stops the /ship subagent only once
that subscription is in place and its READY arrives. From then on the parent owns the pull
request: red checks, human review, the slot stamp and re-READY of step 10, and any receipt
carry. It does that work itself or sends it to the subagent as an explicit instruction. On
When /ship runs in a subagent, the lane sleeps while it runs. After dispatching /ship, the
lane ends its turn and wakes only on /ship's completion: one wake to relay READY, because the
controller hears READY from the lane, never from its subagent. So the lane holds no pull request watch of its own
while /ship runs: /ship opens the pull request, and on a re-READY the lane cancels the watch
it already holds before it dispatches. Every READY duty has one owner, so `train build`
never refuses the pin with `QUEUE_NOT_READY` for a step nobody ran:
| READY duty | Owner |
|---|---|
| The ship receipt (`SHIP_RECEIPT:`) and the pregate record behind the `PREGATE:` line (steps 4, 7 and 8) | /ship |
| `gstack-ship-queue ready --pr <n> --pregate <pregate.json> --screen\|--no-screen` at the pin, with its notes pushed to origin `refs/notes/gstack-trains` (step 9; /ship runs on the lane's machine, or the lane copies its `pregate.json` over first) | the lane |
| The decision-trail audit and the READY's `Attention` section, when the crew keeps a trail ([unattended.md](unattended.md#the-decision-trail)) | the lane |
On the completion wake the lane subscribes to the pull request's check and review notices,
reads its checks and comments once (a notice that landed while /ship ran went to /ship, or to nobody on a re-READY),
stops the /ship subagent, runs `ready`, audits its trail, writes `Attention` and sends the
READY. A completion that ends `SHIP_PAUSED: base-red` follows step 8 instead: the lane
registers the base-red wait, tells the controller, and sends no READY. From then on the lane handles the pull request's events as before: red checks, human
review, the slot stamp and re-READY of step 10, and any receipt carry. It does that work
itself or sends it to the subagent as an explicit instruction. The tradeoff: a red check
that lands while /ship runs waits for /ship to finish instead of being fixed in parallel.
In exchange, the lane stops re-reading its whole context on every notice during /ship. On
Capy the mechanics are in [the gstack skill](../capy/skill/gstack/SKILL.md#plan-approve-ship).
When the base moves under a reviewed branch, merge it in; never rebase. A merge that