diff --git a/SKILL.md b/SKILL.md index e638724fb..a03f92690 100644 --- a/SKILL.md +++ b/SKILL.md @@ -214,7 +214,7 @@ quality gates that produce better results than answering inline. - User asks to update docs after shipping → invoke `/document-release` - User asks to write docs from scratch, generate documentation, "document this feature/module" → invoke `/document-generate` - User asks for a weekly retro, what did we ship, "how'd we do" → invoke `/retro` -- User asks to run a crew of agents, coordinate lanes, build a merge train, call a slot, validate a READY block, write the crew digest, "captain", "crew" → invoke `/captain` +- User asks to run a crew of agents, coordinate lanes, build a merge train, call a slot, validate a READY block, write the crew digest, "set up a captain", "run the crew" → invoke `/captain` Generic “second opinion”, “outside review”, or “cross-model review” requests use `/codex` (namespaced: `/gstack-codex`). This selection follows the **claude harness**, independently of model configuration. Explicit provider requests take precedence: Codex means `/codex`; Claude Code means `/claude-code`. Never silently substitute another provider. If that provider is the current harness, report that no outside invocation ran and suggest the other wrapper only as a separate user choice. Wrapper availability: Claude Code installs only /codex; Codex installs only /claude-code; other harnesses install both. Repair stale installations with `setup --host claude`. There is no /claude compatibility alias. - User asks for safety mode, careful mode → invoke `/careful` or `/guard` - User asks to restrict edits to a directory → invoke `/freeze` or `/unfreeze` diff --git a/SKILL.md.tmpl b/SKILL.md.tmpl index 8c8d4d245..0c7baa07f 100644 --- a/SKILL.md.tmpl +++ b/SKILL.md.tmpl @@ -90,7 +90,7 @@ quality gates that produce better results than answering inline. - User asks to update docs after shipping → invoke `/document-release` - User asks to write docs from scratch, generate documentation, "document this feature/module" → invoke `/document-generate` - User asks for a weekly retro, what did we ship, "how'd we do" → invoke `/retro` -- User asks to run a crew of agents, coordinate lanes, build a merge train, call a slot, validate a READY block, write the crew digest, "captain", "crew" → invoke `/captain` +- User asks to run a crew of agents, coordinate lanes, build a merge train, call a slot, validate a READY block, write the crew digest, "set up a captain", "run the crew" → invoke `/captain` {{OUTSIDE_VOICE_ROUTING}} - User asks for safety mode, careful mode → invoke `/careful` or `/guard` - User asks to restrict edits to a directory → invoke `/freeze` or `/unfreeze` diff --git a/captain/SKILL.md b/captain/SKILL.md index ee05bcff3..c7d01295b 100644 --- a/captain/SKILL.md +++ b/captain/SKILL.md @@ -373,8 +373,9 @@ the top of the digest needs. - The controller merges; a lane never merges, enables auto-merge, or uses a merge queue the controller does not drive. A lane's job ends at an unstamped READY. - The controller never commits to a lane's branch. It calls slots; the lane stamps. -- Nothing merges outside a train except a one-PR `--urgent` train. Every merge outside a - train costs a backstop gate. +- Nothing merges outside a train; a single PR takes a one-PR `--urgent` train, and a + repair under a freeze takes `train build --repair`. Every merge outside a train costs a + backstop gate. - The owner's decisions arrive through the controller, in the owner's exact words, and are recorded before the work they approve starts. - Paid evidence is read, never rejudged: no thresholds, trial counts, case kinds or @@ -430,7 +431,7 @@ and adds the lines the tool cannot know. Validate every field before the pin goe | `ci` | every `REQUIRED_CHECKS` name green at the pin, with counts (`passed=… failed=0 pending=0`) | a pending or failed required check, or a run on another head | | `PREGATE` | `pass` for the pin's tree, remote lanes cleared with that head's own CI runs | `incomplete`, or a pass for another tree | | `gate` | the paid evidence the lane offers: its own focused cases (named, with results), or the screen it asks for | "ran the cheap tier" offered as merge evidence | -| `SHIP_RECEIPT` | `pr= head=` written by /ship at the pin | `none`, or a receipt head that is not the pin | +| `SHIP_RECEIPT` | `pr= head=` written by /ship at the pin | `none`, `invalid`, or a receipt head that is not the pin | | `screen` | `--no-screen` with the focused cases that passed, or `--screen` with the reason | no choice, or `--no-screen` with no cases named | | `READY_RECEIPT` | the receipt path the tool wrote (local and on the notes ref) | missing | | flaky cases | each one already in the ledger, with both runs | a rerun that is not logged, or a second failure called a flake | diff --git a/captain/SKILL.md.tmpl b/captain/SKILL.md.tmpl index dbc006c7c..3cda72b68 100644 --- a/captain/SKILL.md.tmpl +++ b/captain/SKILL.md.tmpl @@ -51,8 +51,9 @@ the top of the digest needs. - The controller merges; a lane never merges, enables auto-merge, or uses a merge queue the controller does not drive. A lane's job ends at an unstamped READY. - The controller never commits to a lane's branch. It calls slots; the lane stamps. -- Nothing merges outside a train except a one-PR `--urgent` train. Every merge outside a - train costs a backstop gate. +- Nothing merges outside a train; a single PR takes a one-PR `--urgent` train, and a + repair under a freeze takes `train build --repair`. Every merge outside a train costs a + backstop gate. - The owner's decisions arrive through the controller, in the owner's exact words, and are recorded before the work they approve starts. - Paid evidence is read, never rejudged: no thresholds, trial counts, case kinds or @@ -108,7 +109,7 @@ and adds the lines the tool cannot know. Validate every field before the pin goe | `ci` | every `REQUIRED_CHECKS` name green at the pin, with counts (`passed=… failed=0 pending=0`) | a pending or failed required check, or a run on another head | | `PREGATE` | `pass` for the pin's tree, remote lanes cleared with that head's own CI runs | `incomplete`, or a pass for another tree | | `gate` | the paid evidence the lane offers: its own focused cases (named, with results), or the screen it asks for | "ran the cheap tier" offered as merge evidence | -| `SHIP_RECEIPT` | `pr= head=` written by /ship at the pin | `none`, or a receipt head that is not the pin | +| `SHIP_RECEIPT` | `pr= head=` written by /ship at the pin | `none`, `invalid`, or a receipt head that is not the pin | | `screen` | `--no-screen` with the focused cases that passed, or `--screen` with the reason | no choice, or `--no-screen` with no cases named | | `READY_RECEIPT` | the receipt path the tool wrote (local and on the notes ref) | missing | | flaky cases | each one already in the ledger, with both runs | a rerun that is not logged, or a second failure called a flake | diff --git a/captain/templates/CREW.md b/captain/templates/CREW.md index a34251db0..7dd18a7ba 100644 --- a/captain/templates/CREW.md +++ b/captain/templates/CREW.md @@ -69,7 +69,8 @@ Parameters: `REPO=` · `BASE=
` · `REQUIRED_CHECKS= | | | | | -READY block sent: · SHIP_RECEIPT: pr= head= · screen: +READY block sent: · SHIP_RECEIPT: pr= head= · screen: ## Needs diff --git a/docs/captain.md b/docs/captain.md index f3fd05ec3..48af8f671 100644 --- a/docs/captain.md +++ b/docs/captain.md @@ -32,7 +32,9 @@ by a daily pass; nothing is retried into green. slots, relays asks to the owner in the three shapes, runs the flaky pass, and decides everything that needs no access, credentials, spend over cap or a cited approval. - **A lane** (a crew thread) owns named files, builds on its own branch and machine, - runs /ship, sends one READY block, stamps on call, writes one report, and never merges. + runs /ship, sends one READY block, stamps on call (merging the base into its pin only + as part of that stamp commit, or when the controller names a real-code conflict), + writes one report, and never merges a PR. - **The controller never commits to a lane's branch**, and a lane never pushes to another lane's. One committer per shared tree. @@ -133,7 +135,8 @@ loop, per train: A red train: `train bisect` on the red cases over every prefix. An attributed PR leaves the train and goes back to its lane; red on the base branch itself is fixed forward -through an urgent one-PR train; all prefixes green earns exactly one unchanged rebuild; +through an urgent one-PR train (or `train build --repair` while the queue is frozen, which +refuses `--urgent`); all prefixes green earns exactly one unchanged rebuild; anything else goes to a repair lane. An infra-only census earns one re-dispatch. A backstop gate runs on every push to the base branch and freezes the queue when it finds a tree no green train covered; one repair PR at its exact head clears the freeze. @@ -143,14 +146,16 @@ stamp on the bare pin leaves the PR conflicting on the CHANGELOG. The lane merge into its pin first (expect a CHANGELOG-only conflict; resolve it with `mergeChangelogs` from `lib/changelog-check.ts`, the `bun -e` one-liner in [ship-policy.md](ship-policy.md#run-a-merge-train), never by hand, and grep for conflict -markers before stamping), then restamps, then commits only the merge and the stamp files. In practice slot 1 needs the same merge whenever the base moved -after the pin was taken. A stamp commit with one extra byte freezes the queue for every +markers before stamping), then restamps, then commits only the merge and the stamp +files. In practice slot 1 needs the same merge whenever the base moved after the pin was +taken. A stamp commit with one extra byte freezes the queue for every lane behind it. Options the controller writes into CREW.md rather than inheriting: squash versus merge commits; lane stamps versus controller stamps; gate-ahead (slot i+1 gates on slot i's -head while i merges); the severe race (a slot called for several severe PRs, first -complete READY wins); whether a READY also carries a gate run id and tree hash. +head while i merges); the severe race (several severe lanes told at once that the next +urgent train is theirs, first complete READY takes it; never a race for a slot inside a +built train); whether a READY also carries a gate run id and tree hash. ## Approvals: three shapes diff --git a/lib/gate-list.ts b/lib/gate-list.ts index 15c0d8397..086abdaf7 100644 --- a/lib/gate-list.ts +++ b/lib/gate-list.ts @@ -6,7 +6,7 @@ * grammar: `rec` (every item takes its recommendation, plan changes * included), `