diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c9cf61ee..69f654d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ ### Changed - **`captain/SKILL.md.tmpl`**: the approvals part carries a "Plan before build" paragraph pointing at the section and the brief, and the rules enumeration names the rule. -- **`capy/skill/gstack/captain.md` § 3**: the lane-side pointer, so a thread launched on Capy sees the first-act rule where it reads the plan-ask shape. +- **`capy/skill/gstack/SKILL.md` § Plan, approve, ship**: the short form every Capy thread follows, under a Captain or on its own (the owner, 2026-10-27: "Also incorporate the autoplan and eli5 and ship instructions for Capy-specific gstack usage"): /autoplan sized to the work before new functionality, the ELI5 with `rec` as the one-word default and a "do it" reply, the build only after the word and an `APPROVED` run, /ship at the final pushed head before a PR is called ready with the receipt naming that head, no merge without the owner's word, the review inside /ship and the autoplan sized to the change, and the exempt work. References are plain text, since the folder is copied to a Drive without the repository; the owner copies `capy/skill/gstack/` over the Drive skill folder to pick it up. +- **`capy/skill/gstack/captain.md` § 3**: the lane-side pointer, so a thread launched on Capy sees the first-act rule where it reads the plan-ask shape, linking to the SKILL.md section. - **`captain/templates/plan-ask.md`**: the record line names the autoplan path (`gstack-autoplan answer … --owner-reply`, then `gstack-approvals import --autoplan`) and keeps `gstack-approvals add` for plans that are not autoplan gates. - **`docs/captain.md` Setting it up, step 5**: lanes start with the brief. diff --git a/capy/skill/gstack/SKILL.md b/capy/skill/gstack/SKILL.md index 9eb16bebc..e5385dbcd 100644 --- a/capy/skill/gstack/SKILL.md +++ b/capy/skill/gstack/SKILL.md @@ -42,6 +42,17 @@ Run directories and scratch on Capy live under `~/.capy/work/` (`--out ~/. Capy checklist for `/autoplan`: drive `gstack-autoplan`, never a hand adaptation presented as a run. Relay `gstack-gate render /gate.json --all` with `rec` (every recommendation, plan changes included) as the one-word default; answer with `--by agent: --owner-reply ""`. Set `GSTACK_AUTOPLAN_CHECKPOINT_DIR` to a private project-user Drive folder; after machine replacement, `gstack-autoplan resume --out --from ` restores the newest valid checkpoint. +## Plan, approve, ship + +Every Capy thread that uses gstack, under a Captain or on its own, follows these for new work. The full rule for crews is `docs/captain.md`, section "Plan before build", in the gstack checkout; the lane side is section 3 of captain.md in this folder. + +- **Plan before build.** Before building new functionality (a new thread's scope, or scope taken on part-way), run `/autoplan` on it as the first act, sized to the work: the scope flags and `--max-rounds` size the run, and a one-file fix gets `--no-ui --no-dx --max-rounds 1` with a small `--spend-cap`, never no run. Drive `gstack-autoplan` as "Unattended runs" above says. +- **ELI5, then the word.** Send the plan and its gate to the person, or to the Captain when there is one, in plain language someone outside the project can follow (what, why now, what changes, cost, your pick): `gstack-owner-brief render --captain --out `, with `rec` (every recommendation taken) as the one-word default and a "do it" reply that takes every recommendation at full scope. Build only after their word is answered into the run (`gstack-autoplan answer … --owner-reply ""`), accepted plan changes are incorporated, and the run reports `APPROVED`; then `gstack-approvals import --autoplan `. +- **/ship before ready.** Run /ship on the branch at the final pushed head before a PR is called ready; `SHIP_RECEIPT: pr= head=` must name that exact head, and a later push needs a new /ship. The review inside /ship, like the autoplan, is sized to the change (`docs/review-policy.md`). +- **No merge without the owner's word.** A thread never merges on its own. Under a Captain the controller merges on the owner's recorded standing approval; a thread with no Captain asks the person. + +Exempt from the plan step: read-only work (triage, research, measurement, a review voice), the daily flaky pass's repairs, slot stamps, CHANGELOG-only resolves and cap re-pins under a written grant. + ## Working under a Captain When you work for a Capy Captain (a crew thread) or straight for a person, gstack's decisions reach them through you. Every workflow started with the `GSTACK_LAUNCH` line prints `CAPY: on` and a `capy-asks` block that repeats these rules. The full guide, with worked examples and copy-paste templates, is [captain.md](captain.md) in this folder. diff --git a/capy/skill/gstack/captain.md b/capy/skill/gstack/captain.md index 01d3b60ef..d403cbe55 100644 --- a/capy/skill/gstack/captain.md +++ b/capy/skill/gstack/captain.md @@ -72,9 +72,10 @@ gstack-approvals render # the ## Approvals se Under a Captain, a thread that builds something plans before any product code. A `/autoplan` run on its brief, sized to the work, is its first act, the gate goes up in the shape below, and the build starts only -when the answer is in the run and it reports `APPROVED` (`docs/captain.md`, Plan before build, which also -lists the exempt work: read-only threads, flaky-pass repairs, slot stamps, CHANGELOG resolves, cap re-pins -under a grant). +when the answer is in the run and it reports `APPROVED`. The short form every Capy thread follows, with the +exempt work (read-only threads, flaky-pass repairs, slot stamps, CHANGELOG resolves, cap re-pins under a +grant), is the "Plan, approve, ship" section of SKILL.md in this folder; the rule in full is `docs/captain.md`, +Plan before build. Every plan or gate you bring for approval has these parts, in this order, written so someone outside the project can follow it: diff --git a/test/captain-skill.test.ts b/test/captain-skill.test.ts index 08757b54b..1c74375aa 100644 --- a/test/captain-skill.test.ts +++ b/test/captain-skill.test.ts @@ -70,6 +70,11 @@ describe('/captain skill', () => { expect(brief).toMatch(/^1\. Plan[^]*?^2\. Build after the word[^]*?^3\. Ship[^]*?^Done when:/m); expect(brief).toContain('gstack-approvals import --autoplan'); expect(flat).toContain('**Plan before build.**'); + const capySkill = read('capy/skill/gstack/SKILL.md'); + expect(capySkill).toMatch(/^## Plan, approve, ship$/m); + expect(capySkill).toMatch(/## Plan, approve, ship[^]*?reports `APPROVED`[^]*?Exempt from the plan step[^]*?## Working under a Captain/); + expect(capySkill).not.toMatch(/## Plan, approve, ship[^]*?\]\((?:\.\.\/)?docs\//); + expect(read('capy/skill/gstack/captain.md')).toContain('"Plan, approve, ship" section of SKILL.md'); expect(read('captain/templates/plan-ask.md')).toContain('**do it**'); expect(read('captain/templates/plan-ask.md')).toContain('gstack-approvals import --autoplan'); expect(read('captain/templates/automation-flaky-pass.md')).toContain('never merge');