fix: pre-landing review fixes — import --by takes the owner alone, the controller checks the row against its relay, brief.md spells the full answer command and carries the run dir, first act after the install check (GSTA-130)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-27 21:41:15 +00:00
1 parent 7458f2e287
commit ead576d45c
9 files changed
+39 -31

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@
### 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/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.
- **`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, pointing at 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.
+1 -1
View File
@@ -352,7 +352,7 @@ with one line saying what it covers. `gstack-owner-brief render --captain` print
a plan; relay it whole. Template: `captain/templates/plan-ask.md`.
**Plan before build.** A lane that builds something runs a sized `/autoplan` on its brief as
its first act and sends the controller the plan ask above; the controller relays it, and the
its first act after the session-start check and sends the controller the plan ask above; the controller relays it, and the
lane builds only after the owner's word is answered into the run and it reports `APPROVED`.
New scope taken on part-way gets its own plan. Read-only lanes, the flaky pass's repairs,
slot stamps, CHANGELOG resolves and cap re-pins under a grant are exempt. The brief a
+1 -1
View File
@@ -280,7 +280,7 @@ with one line saying what it covers. `gstack-owner-brief render --captain` print
a plan; relay it whole. Template: `captain/templates/plan-ask.md`.
**Plan before build.** A lane that builds something runs a sized `/autoplan` on its brief as
its first act and sends the controller the plan ask above; the controller relays it, and the
its first act after the session-start check and sends the controller the plan ask above; the controller relays it, and the
lane builds only after the owner's word is answered into the run and it reports `APPROVED`.
New scope taken on part-way gets its own plan. Read-only lanes, the flaky pass's repairs,
slot stamps, CHANGELOG resolves and cap re-pins under a grant are exempt. The brief a
+1 -1
View File
@@ -127,7 +127,7 @@ Homes are paths in the gstack checkout the lane checked at session start.
`/ship` and `/review` skills.
24. **Plan before build.** If you build something, a `/autoplan` run on your brief, sized
to the work, is your first act; send `CONTROLLER` the plan and its gate in plain
to the work, is your first act after the session-start check; send `CONTROLLER` the plan and its gate in plain
language with the recommended reply named; build only after the owner's word is
answered into the run and it reports `APPROVED`; record it with `gstack-approvals
import --autoplan`. New scope taken on part-way gets the same. Exempt: read-only
+18 -14
View File
@@ -9,21 +9,23 @@ is filled by the controller; `Plan:` says whether the lane plans first
Lane: <thread code> · Controller: <CONTROLLER> · Rules: <drive>/CREW.md · Base: <BASE>
Owns: <the files and directories this lane may edit; everything else is routed through the controller>
Do not touch: <files other live lanes own, each with its lane>
Plan: required | approved: <autoplan run id> | exempt: <reason from the exemption list>
Plan: required | approved: <autoplan run dir, or its checkpoint dir> | exempt: <reason from the exemption list>
Spend cap: <focused paid runs per PR, from SPEND>
1. Plan (when Plan: required). Install for autoplan, write the plan with its
## Before → after, ## Why it matters, ## What caused this work, ## Big decisions and
## Implementation plan sections, and run
gstack-autoplan next --out <run dir> --plan <plan.md> <scope flags> sized to this brief
(a one-file fix: --no-ui --no-dx --max-rounds 1 --spend-cap <small>). At the gate send
me the output of gstack-owner-brief render --captain --out <run dir> whole, as a
needs-you report. Build nothing yet.
1. Plan (when Plan: required). After the session-start install check, install for autoplan
and follow autoplan/DRIVER.md "On Capy" (launch file sourced, GSTACK_AUTOPLAN_CHECKPOINT_DIR
set, run dir under ~/.capy/work). Write the plan with its ## Before → after,
## Why it matters, ## What caused this work, ## Big decisions and ## Implementation plan
sections, then run gstack-autoplan next --out <run dir> --plan <plan.md> <scope flags>
sized to this brief (a one-file fix: --no-ui --no-dx --max-rounds 1 --estimate-usd <n>
--spend-cap <small>). At the gate send me the output of
gstack-owner-brief render --captain --out <run dir> whole, as a needs-you report.
Build nothing yet.
2. Build after the word. I bring the owner's exact words back. Answer them into the run
(gstack-autoplan answer … --by agent:<your thread> --owner-reply "<their words>"),
incorporate every accepted plan change (revise), finish every reopened phase, and start
product edits only when the run reports APPROVED. Then
gstack-approvals import --autoplan <run dir> --by "<owner> (via <controller>)".
(gstack-autoplan answer --out <run dir> --gate-rev <n> --reply <tokens> --rec-hash <h>
--by agent:<your thread> --owner-reply "<their words>"), incorporate every accepted plan
change (revise), finish every reopened phase, and start product edits only when the run
reports APPROVED. Then gstack-approvals import --autoplan <run dir> --by "<owner>".
New scope you take on part-way goes back to step 1 with its own plan.
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
@@ -34,5 +36,7 @@ and its Approvals table carries the plan approval row (the owner's words, the da
Plan: exempt reason.
```
A lane whose brief says `approved: <run>` starts at step 2 with that run; a lane whose brief
says `exempt:` starts at step 3. A brief with no `Plan:` line reads as `Plan: required`.
A lane whose brief says `approved: <dir>` starts at step 2 with that run (restore it with
`gstack-autoplan resume --out <new dir> --from <dir>` when it lives on another machine); a
lane whose brief says `exempt:` starts at step 3. A brief with no `Plan:` line reads as
`Plan: required`.
+1 -1
View File
@@ -30,5 +30,5 @@ named: docs, trains, cleanups>, and carry them through to done with no further a
When the answer comes back, record it before the work starts. For an autoplan gate:
`gstack-autoplan answer --out <run dir> --gate-rev <n> --reply <tokens> --by agent:<thread> --owner-reply "<exact words>"`,
then `gstack-approvals import --autoplan <run dir> --by "<owner> (via <controller>)"`. For any
then `gstack-approvals import --autoplan <run dir> --by "<owner>"` (the tool records the relayer). For any
other plan: `gstack-approvals add --ask "<what>" --words "<exact words>" --by "<owner> (via <controller>)" --scope "<what it covers>"`.
+2 -2
View File
@@ -46,8 +46,8 @@ Capy checklist for `/autoplan`: drive `gstack-autoplan`, never a hand adaptation
Every Capy thread that uses gstack follows these for new work, under a Captain or on its own. The rule in full is `docs/captain.md`, "Plan before build"; the lane side is section 3 of captain.md in this folder.
- **Plan first.** Before building new functionality, run `/autoplan` on it as the first act, sized to the work (scope flags and `--max-rounds`; a one-file fix gets `--no-ui --no-dx --max-rounds 1` and a small `--spend-cap`, never no run).
- **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>`, with `rec` 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 and it reports `APPROVED`; then `gstack-approvals import --autoplan <run dir>`.
- **Plan first.** Before building new functionality, run `/autoplan` on it as the first act after the install check, sized to the work (scope flags and `--max-rounds`; a one-file fix gets `--no-ui --no-dx --max-rounds 1` with `--estimate-usd` and a small `--spend-cap`, never no run).
- **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>`, with `rec` 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 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.
- **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.
+12 -9
View File
@@ -124,10 +124,11 @@ alone is not an ask.
## Plan before build
A lane that builds something plans first. Its first act, before any product code, is a
`/autoplan` run on its brief, sized to the work. The phases run in order, CEO, then design,
then DX, then eng, with design and DX only when the scope has them, and a one-file fix
gets a short run (`--no-ui --no-dx --max-rounds 1` and a small `--spend-cap`), not no run. On Capy the
A lane that builds something plans first. Its first act after the session-start install
check, before any product code, is a `/autoplan` run on its brief, sized to the work. The
phases run in order, CEO, then design, then DX, then eng, with design and DX only when the
scope has them, and a one-file fix gets a short run (`--no-ui --no-dx --max-rounds 1`, with
`--estimate-usd` set so a small `--spend-cap` still seats its attempts), not no run. On Capy the
unattended loop is `autoplan/DRIVER.md` in the gstack checkout. New functionality a lane
takes on part-way, scope its brief did not name, gets its own plan and its own ask before
the lane builds it. In the rules file this is rule 24 of the
@@ -157,11 +158,13 @@ finished, and the run reports `APPROVED` (`status=complete` after `export`). An
gate that still prints `PLAN_AMEND_PENDING` or `REOPENED:` is not a completed plan, and an
imported approval row alone is not completion.
**The record.** `gstack-approvals import --autoplan <run dir> --by "<owner> (via <controller>)"`
writes the approval row (date, the ask, the owner's exact words, who relayed them, what it
covers); `gstack-approvals render` puts it in the report and the PR body, where the
controller reads it before training the PR (shape A). The brief's done line names the row.
A plan approval is not a READY field; the [READY contract](#the-ready-contract) is unchanged.
**The record.** `gstack-approvals import --autoplan <run dir> --by "<owner>"` writes the
approval row (date, the ask, the owner's exact words, the lane that answered as relayer,
what it covers); `gstack-approvals render` puts it in the report and the PR body. Before
training the PR the controller compares that row's words and `gate_rev` with the ask it
relayed and the reply it carried back; a row that does not match is not READY (shape A).
The brief's done line names the row. A plan approval is not a READY field; the
[READY contract](#the-ready-contract) is unchanged.
**Exemptions.** Read-only lanes (triage, research, measurement, a review voice), the daily
flaky pass's repairs, slot stamps, CHANGELOG-only conflict resolves and a size or budget
+2 -1
View File
@@ -66,7 +66,8 @@ describe('/captain skill', () => {
for (const h of ['## Lane discipline', '## Plan before build', '## Contributions from outside the crew']) expect(doc).toContain(h);
expect(doc).toMatch(/## Plan before build[^]*?reports `APPROVED`[^]*?## Contributions from outside the crew/);
const brief = read('captain/templates/brief.md');
expect(brief).toContain('Plan: required | approved: <autoplan run id> | exempt: <reason');
expect(brief).toContain('Plan: required | approved: <autoplan run dir, or its checkpoint dir> | exempt: <reason');
expect(brief).toContain('gstack-autoplan answer --out <run dir> --gate-rev <n> --reply <tokens>');
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.**');