diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cef95b96..ebe24d15e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.91.99.0] - 2026-10-13 + +**A Bun pin mismatch on Capy now names the one command that fixes it, and the skill says to run it.** After gbrain pinned Bun 1.4.3 in CI, a session-start check on a gbrain checkout ended `gstack: fail pins` with a fix line that offered two choices and no command, and the skill's repair step only covered `revision` and `runtime`, so an agent following the skill left the machine failing. The same bootstrapper run without `--check` already installs the pinned Bun (a verified 1.4.3 in about 4 s) and ends `gstack: ok`. + +### What this means for you + +- **The `pins` row's fix is the exact command on Capy.** Under the Drive bootstrapper, `FAIL pins … (PROJECT_PIN_MISMATCH)` now says `fix: bash /scripts/install.sh [--for ] (installs the project's pinned Bun when it is a verified version: 1.4.2 1.4.3; otherwise it names the conflict), or change the pin in `. Outside Capy the fix text is unchanged. +- **The Capy skill's repair step covers `pins`.** Step 2 runs the same command without `--check` when the trailer names `revision`, `runtime` or `pins`. A pin gstack has no verified archive for stops with `RUNTIME_PIN_CONFLICT` naming the pin to raise. The owner copies `capy/skill/gstack/` to the Drive skill folder as before; `scripts/install.sh` is unchanged. + +### For contributors + +- `test/gstack-doctor.test.ts` checks the Capy fix line (with and without `--for`) and that the non-Capy text does not name the wrapper; it fails before the change. + ## [1.91.98.0] - 2026-10-13 **A lane's plan obligations now meet the repo's own gates before it reports done. Paid gates get a price before approval, a restamp is proved stamp-only by machine, and sealed eval output can't ride a push into a public repo.** @@ -20,6 +33,7 @@ - New: `lib/pregate/checks/guards.ts`, `lib/pregate/regate.ts`, `lib/pregate/runtime.ts`, `lib/sealed-guard.ts`; docs `docs/eval-calls.md`, `docs/pregate.md#regate` and `#gbrain-worked-configs`. - New result codes with troubleshooting anchors include `EVAL_GATE_UNPRICED`, `PREGATE_GUARD_FAILED`, `SEALED_OUTPUT_REFUSED` and `MIGRATION_COLLISION`. - Pregate and ship-policy validators still refuse unknown keys, so a repo should commit `guards`, `sealed`, `price_file`, `stamp_files`, `stamp_patterns`, `restamp_command` or `migrations` only after its machines run this release. + ## [1.91.97.0] - 2026-10-13 **An unattended `/autoplan` run on Capy now closes in its own run directory. Reviews done by Capy subagents bind with one command, a revised plan is reviewed in the same run, and the gate asks fewer, better questions.** diff --git a/VERSION b/VERSION index 0a3f874a1..c2ce38c56 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.91.98.0 +1.91.99.0 diff --git a/agents-digest/gstack-AGENTS.md b/agents-digest/gstack-AGENTS.md index 6f0e18552..1d59dbb9e 100644 --- a/agents-digest/gstack-AGENTS.md +++ b/agents-digest/gstack-AGENTS.md @@ -1,4 +1,4 @@ -# gstack digest v1.91.98.0 — regenerate/re-copy after upgrading gstack +# gstack digest v1.91.99.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/bin/gstack-doctor-check.sh b/bin/gstack-doctor-check.sh index 617946137..b028323b8 100644 --- a/bin/gstack-doctor-check.sh +++ b/bin/gstack-doctor-check.sh @@ -297,6 +297,7 @@ _dc_check_pins() { return fi local fix="install the pinned version for this platform (bin/gstack-capy-install installs gstack's verified Bun alongside when a pin names it), or change the pin in $project" note="" + [ -n "${GSTACK_CAPY_WRAPPER_PATH:-}" ] && fix="bash $GSTACK_CAPY_WRAPPER_PATH${CHECK_FOR:+ --for $CHECK_FOR} (installs the project's pinned Bun when it is a verified version: $GSTACK_BUN_VERIFIED; otherwise it names the conflict), or change the pin in $project" if [ -n "$_dc_ln_dir" ] && [ "$_dc_ln_ver" != "$_dc_bun" ] \ && bun "$BIN/gstack-runtime-pins.ts" --project "$project" --bun "$_dc_ln_ver" ${node:+--node "$node"} /dev/null | grep -q '^PINS_VERDICT: pass'; then note="; bun $_dc_ln_ver found at $_dc_ln_dir (not on PATH) satisfies them" fix="$_dc_ln_fix" diff --git a/capy/skill/gstack/SKILL.md b/capy/skill/gstack/SKILL.md index 55a13c4d5..397dba50c 100644 --- a/capy/skill/gstack/SKILL.md +++ b/capy/skill/gstack/SKILL.md @@ -10,7 +10,7 @@ description: Install and use gstack in Capy and Claude Code. Load at session sta Resolve `scripts/install.sh` relative to this SKILL.md, not the working repository. It is a frozen bootstrapper: it prints `gstack-capy-skill: wrapper ()` first, learns the supported minimum from gstack's remote, and hands over to the checkout's own wrapper (`bin/gstack-capy-session`). 1. At session start run `bash scripts/install.sh --check`, adding `--for ` when you know the workflow (`--for autoplan`, `--for review`, `--for qa`). It prints one `PASS|FAIL|SKIP ` row per component, a `GSTACK_LAUNCH:` line, and exactly one trailer as the last line: `gstack: ok for=` (exit 0) or `gstack: fail …` (exit 1). Read the exit status and grep `^gstack: ` directly; never pipe the check through `tail`, `head` or `grep` alone. `--check` never moves the checkout. -2. If the trailer is `gstack: fail revision …` or `gstack: fail runtime …` and a checkout exists, run the same command without `--check` (900-second timeout). A clean, unpinned checkout below the supported minimum is fast-forwarded (`gstack-capy-skill: upgraded -> `), reinstalled and rechecked in one locked step; about 1 s when nothing changed. A pinned (`--revision`, detached), dirty or diverged checkout is never moved: the trailer names the cause and the exact commands. `GSTACK_CAPY_AUTO_UPGRADE=0` disables the fast-forward. +2. If the trailer names `revision`, `runtime` or `pins` (`gstack: fail revision …`, `gstack: fail runtime,pins`, `gstack: fail pins`) and a checkout exists, run the same command without `--check` (900-second timeout). For `pins` it installs the project's pinned Bun when the pin names a verified version (about 4 s), or stops with `RUNTIME_PIN_CONFLICT` naming the pin to raise. A clean, unpinned checkout below the supported minimum is fast-forwarded (`gstack-capy-skill: upgraded -> `), reinstalled and rechecked in one locked step; about 1 s when nothing changed. A pinned (`--revision`, detached), dirty or diverged checkout is never moved: the trailer names the cause and the exact commands. `GSTACK_CAPY_AUTO_UPGRADE=0` disables the fast-forward. 3. If the trailer is `gstack: fail not-installed …` and this session runs no gstack workflow, record that line and continue; nothing is installed. Install right before the first workflow with `bash scripts/install.sh --for ` (about 30 s cold: clone, the SHA-256-verified Bun 1.4.2, both host profiles without Chromium). 4. Any other `FAIL` row carries a `fix:` command and a reason code with a troubleshooting anchor; run the fix, then `--check` again. `SKIP codex-cli (optional; …)`, `SKIP browser (lazy; …)` and `SKIP pins (planning-only; …)` are not failures. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index fe26c07f3..fc1e2c026 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -1117,7 +1117,11 @@ fails. The row is `SKIP pins (no bun to evaluate the project pins)` when Bun is absent, never silent. **Fix.** Install the pinned version for this platform (the row names each -constraint with its source), or change the project's pin. +constraint with its source), or change the project's pin. On Capy the row's +fix is the exact bootstrapper command, `bash /scripts/install.sh` +(the same command without `--check`): it installs the pinned Bun when the pin +names a verified version and ends `gstack: ok`, or stops with +`RUNTIME_PIN_CONFLICT` naming the pin to raise. ### `FAIL revision — installed (requested ) (REVISION_UNMET; ...)` diff --git a/lib/result-codes.ts b/lib/result-codes.ts index 16bcf8001..4e7f5d0ea 100644 --- a/lib/result-codes.ts +++ b/lib/result-codes.ts @@ -128,7 +128,7 @@ export const RESULT_CODES = { PROJECT_PIN_MISMATCH: { anchor: 'doctor-project-pin-mismatch', summary: 'the running Bun or Node is outside a version the target project pins (package.json engines, .tool-versions, .nvmrc, .bun-version or a CI workflow)', - fix: 'install the pinned version for this platform, or change the pin in the project', + fix: 'install the pinned version for this platform (on Capy: run the gstack skill\'s `scripts/install.sh` without --check), or change the pin in the project', }, REVISION_UNMET: { anchor: 'doctor-revision-unmet', diff --git a/package.json b/package.json index 726b20b28..bd7e4804c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.91.98", + "version": "1.91.99", "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/gstack-doctor.test.ts b/test/gstack-doctor.test.ts index 6abfdacb3..fa1528c09 100644 --- a/test/gstack-doctor.test.ts +++ b/test/gstack-doctor.test.ts @@ -606,6 +606,22 @@ describe('gstack-doctor --check', () => { expect(missing.rows.pins.status).toBe('SKIP'); }); + test('project pins on Capy: the PROJECT_PIN_MISMATCH fix is the exact bootstrapper command, which installs a verified pinned Bun', () => { + const f = makeFixture(); + const project = path.join(f.base, 'project'); + write(path.join(project, 'package.json'), '{\n "engines": {\n "bun": ">=1.4.2"\n }\n}\n'); + const wrapper = '/drive/skills/gstack/scripts/install.sh'; + const capy = row(f, ['--project', project], { STUB_BUN_VERSION: '1.3.14', GSTACK_CAPY_WRAPPER_PATH: wrapper }); + expect(capy.rows.pins.status).toBe('FAIL'); + expect(capy.rows.pins.rest).toContain(`fix: bash ${wrapper} (installs the project's pinned Bun when it is a verified version: 1.4.2 1.4.3; otherwise it names the conflict), or change the pin in ${project}`); + expect(capy.rows.pins.rest).toContain('(PROJECT_PIN_MISMATCH; '); + const forSkill = row(f, ['--project', project, '--for', 'review'], { STUB_BUN_VERSION: '1.3.14', GSTACK_CAPY_WRAPPER_PATH: wrapper }); + expect(forSkill.rows.pins.rest).toContain(`fix: bash ${wrapper} --for review (installs`); + const plain = row(f, ['--project', project], { STUB_BUN_VERSION: '1.3.14' }); + expect(plain.rows.pins.rest).toContain('fix: install the pinned version for this platform'); + expect(plain.rows.pins.rest).not.toContain(wrapper); + }); + test('--revision: a matching VERSION passes, an unmet revision is never ok', () => { const f = makeFixture(); const ok = row(f, ['--revision', VERSION]);