diff --git a/CHANGELOG.md b/CHANGELOG.md index a384bf8cb..75353b886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [1.91.337.0] - 2026-10-30 + +### Changed +- **Plan first has two narrow fix exemptions.** An S1 emergency (a broken install or upgrade, a red main, a security bug) and a fix from a problem list that was already diagnosed and audited can be built without an `/autoplan` run. Every other fix, a one-line bug fix included, gets a one-round, eng-only plan. `docs/captain.md` § Plan before build says how, and `captain/SKILL.md`, `captain/templates/CREW.md` rule 24 and the Capy skill's SKILL.md list the same exemptions. + ## [1.91.336.0] - 2026-10-30 **A repository can now assign its version when a PR merges instead of inside the PR: PRs carry unversioned CHANGELOG fragments and `gstack-ship-queue land` stamps, pushes and merges.** Today every PR picks a version before it merges, so each merge makes the next PR's version stale and its lane redoes the stamp (a median 14.5 minutes from stamp commit to merge over 30 slots, Oct 27-29; the queue froze on hand-made stamps in #3422 and #3487). With `changelog_fragments` on, two PRs cut from one base cannot collide, and nobody stamps by hand. gstack's own policy does not turn it on in this release (docs/ship-policy.md#changelog-fragments). diff --git a/VERSION b/VERSION index 6346b9d6a..5ee95b078 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.91.336.0 +1.91.337.0 diff --git a/agents-digest/gstack-AGENTS.md b/agents-digest/gstack-AGENTS.md index 51d51d4f1..156adc522 100644 --- a/agents-digest/gstack-AGENTS.md +++ b/agents-digest/gstack-AGENTS.md @@ -1,4 +1,4 @@ -# gstack digest v1.91.336.0 — regenerate/re-copy after upgrading gstack +# gstack digest v1.91.337.0 — regenerate/re-copy after upgrading gstack Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed for agent hosts without a full skill install. The full skills add workflows, diff --git a/captain/SKILL.md b/captain/SKILL.md index 6a1f0f270..2655c6345 100644 --- a/captain/SKILL.md +++ b/captain/SKILL.md @@ -355,7 +355,9 @@ a plan; relay it whole. Template: `captain/templates/plan-ask.md`. 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 +slot stamps, CHANGELOG resolves, cap re-pins under a grant, S1 emergencies (broken install +or upgrade, red main, a security bug) and fixes from an already-diagnosed, audited problem +list are exempt; every other fix gets a one-round, eng-only plan. The brief a controller hands a lane, with its `Plan: required | approved | exempt` line, is `captain/templates/brief.md`; the rule is `docs/captain.md` (Plan before build). diff --git a/captain/SKILL.md.tmpl b/captain/SKILL.md.tmpl index 87ed80e88..2664b3d3c 100644 --- a/captain/SKILL.md.tmpl +++ b/captain/SKILL.md.tmpl @@ -283,7 +283,9 @@ a plan; relay it whole. Template: `captain/templates/plan-ask.md`. 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 +slot stamps, CHANGELOG resolves, cap re-pins under a grant, S1 emergencies (broken install +or upgrade, red main, a security bug) and fixes from an already-diagnosed, audited problem +list are exempt; every other fix gets a one-round, eng-only plan. The brief a controller hands a lane, with its `Plan: required | approved | exempt` line, is `captain/templates/brief.md`; the rule is `docs/captain.md` (Plan before build). diff --git a/captain/templates/CREW.md b/captain/templates/CREW.md index e6bdf2806..311750b23 100644 --- a/captain/templates/CREW.md +++ b/captain/templates/CREW.md @@ -133,7 +133,9 @@ Homes are paths in the gstack checkout the lane checked at session start. 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 lanes, the daily flaky pass's repairs, slot stamps, CHANGELOG-only resolves, cap - re-pins under a written grant. Home: `docs/captain.md` (Plan before build), + re-pins under a written grant, S1 emergencies (broken install or upgrade, red main, + a security bug) and fixes from an already-diagnosed, audited problem list; every + other fix gets a one-round, eng-only plan. Home: `docs/captain.md` (Plan before build), `captain/templates/brief.md`. ## Crew-specific rules diff --git a/captain/templates/brief.md b/captain/templates/brief.md index 1f6b0decb..efb283815 100644 --- a/captain/templates/brief.md +++ b/captain/templates/brief.md @@ -17,8 +17,11 @@ Spend cap: set, run dir under ~/.capy/work). Write the plan with its ## ELI5, ## Before → after, ## Why it matters, ## What caused this work, ## Big decisions and ## Implementation plan sections, then run gstack-autoplan next --out --plan - sized to this brief (a one-file fix: --no-ui --no-dx --max-rounds 1 --estimate-usd - --spend-cap ). At the gate send me the output of + sized to this brief (a fix: --no-ui --no-dx --max-rounds 1 --estimate-usd + --spend-cap , then close the CEO phase before dispatching its voices with + gstack-autoplan close --out --phase ceo --deferred "eng-only fix plan" + --by agent:). + At the gate send me the output of gstack-owner-brief render --captain --out 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 diff --git a/capy/skill/gstack/SKILL.md b/capy/skill/gstack/SKILL.md index 2e74284b9..da5b50ef9 100644 --- a/capy/skill/gstack/SKILL.md +++ b/capy/skill/gstack/SKILL.md @@ -53,7 +53,7 @@ Every Capy thread that uses gstack follows these for new work, under a Captain o - **/ship before ready.** Run /ship at the final pushed head before a PR is called ready; `SHIP_RECEIPT: pr= 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. -Exempt from the plan step: read-only work, the daily flaky pass's repairs, slot stamps, CHANGELOG-only resolves and cap re-pins under a written grant. +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. Every other fix gets a one-round, eng-only plan. ## Working under a Captain diff --git a/docs/captain.md b/docs/captain.md index 9dc3697c5..d450b184c 100644 --- a/docs/captain.md +++ b/docs/captain.md @@ -134,7 +134,7 @@ alone is not an ask. 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 +scope has them, and a fix the exemptions below don't cover 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 @@ -178,7 +178,13 @@ The brief's done line names the row. A plan approval is not a READY field; the **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 -cap re-pinned under the controller's written grant need no plan. A crew may add exemptions +cap re-pinned under the controller's written grant need no plan. Two kinds of fix are exempt +too: an S1 emergency (a broken install or upgrade, a red main, a security bug), and a fix +from a problem list that was already diagnosed and audited, where that list is the plan. +Every other fix, a one-line bug fix included, gets a one-round, eng-only plan: the short +run above, with the CEO phase closed before its voices are dispatched +(`gstack-autoplan close --out --phase ceo --deferred "eng-only fix plan" --by agent:`). +A crew may add exemptions in its rules file with the owner's words and date; it does not remove these. The brief says which applies, `Plan: required | approved: | exempt: `, so an already-approved plan is not planned twice and exempt work does not wait on an ask. diff --git a/package.json b/package.json index d2b9bee45..f74d0b97e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.91.336", + "version": "1.91.337", "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.", "license": "MIT", "type": "module", diff --git a/test/captain-skill.test.ts b/test/captain-skill.test.ts index 895db459f..47309ab79 100644 --- a/test/captain-skill.test.ts +++ b/test/captain-skill.test.ts @@ -81,6 +81,17 @@ describe('/captain skill', () => { expect(read('captain/templates/automation-flaky-pass.md')).toContain('never merge'); }); + test('every copy of the plan-first exemptions names the two fix exemptions and the eng-only plan for every other fix', () => { + for (const rel of ['docs/captain.md', 'captain/SKILL.md', 'captain/templates/CREW.md', 'capy/skill/gstack/SKILL.md']) { + const text = read(rel).replace(/\s+/g, ' '); + expect(text, rel).toMatch(/S1 emergenc(?:y|ies) \(a? ?broken install or upgrade, a? ?red main, a security bug\)/); + expect(text, rel).toMatch(/already[- ]diagnosed,? (?:and )?audited problem list|problem list that was already diagnosed and audited/); + expect(text, rel).toContain('one-round, eng-only plan'); + } + expect(read('docs/captain.md')).toContain('gstack-autoplan close --out --phase ceo --deferred'); + expect(read('captain/templates/brief.md').replace(/\s+/g, ' ')).toContain('gstack-autoplan close --out --phase ceo --deferred'); + }); + test('is generic: parameters, not one crew\'s codes, names or repository', () => { const files = ['captain/SKILL.md.tmpl', 'docs/captain.md', ...TEMPLATES.map(t => 'captain/templates/' + t)]; for (const f of files) {