diff --git a/bin/gstack-install-verdict.sh b/bin/gstack-install-verdict.sh index 23661ed4b..7477dd56d 100644 --- a/bin/gstack-install-verdict.sh +++ b/bin/gstack-install-verdict.sh @@ -131,7 +131,10 @@ gstack_install_admission() { src=$(gstack_source_root "$bin") || src="" project=$(gstack_install_project "$src") file=$(gstack_install_verdict_path "${_GH:-$HOME/.gstack}" "$src" "$project") - { [ -f "$file" ] && ! gstack_doctor_install_profile "$(gstack_install_verdict_field "$file" for)"; } || [ ! -f "${GSTACK_INSTALL_VERDICT:-}" ] || file="$GSTACK_INSTALL_VERDICT" + case "$(gstack_install_verdict_field "$file" schema_version 2>/dev/null)" in + 1|2) if gstack_doctor_install_profile "$(gstack_install_verdict_field "$file" for)" && [ -f "${GSTACK_INSTALL_VERDICT:-}" ]; then file="$GSTACK_INSTALL_VERDICT"; fi ;; + esac + [ -f "$file" ] || [ ! -f "${GSTACK_INSTALL_VERDICT:-}" ] || file="$GSTACK_INSTALL_VERDICT" [ -f "$file" ] || file=$(gstack_install_verdict_legacy_path "${_GH:-$HOME/.gstack}" "$src") code=INSTALL_UNVERIFIED fix="run the Capy skill installer (scripts/install.sh --for $skill) on this machine, then launch with the GSTACK_LAUNCH line it prints" diff --git a/docs/capy-install.md b/docs/capy-install.md index 1aa27b2dc..53326df6d 100644 --- a/docs/capy-install.md +++ b/docs/capy-install.md @@ -42,7 +42,10 @@ no host profile, so a workflow started there is refused (`INSTALL: fail verdict — … (review-voice certifies only the read-only helpers); fix: run GSTACK_CAPY_ROOT= bash /capy/skill/gstack/scripts/install.sh --for …`). A review-voice check never replaces an ok verdict that a fuller -install wrote for the same HEAD and project. The reverse is an in-place +install wrote for the same HEAD and project. Nor does one run from another +project shadow the session's own verdict: when the verdict for the current +project is a review-voice one, admission reads the session's launched +`GSTACK_INSTALL_VERDICT` instead (GST-1161). The reverse is an in-place upgrade: a reviewer later asked to run a workflow runs the same installer `--for `, which reuses the checkout (`upgrading the review-voice install in place to --for (same checkout ...; no second clone)`), diff --git a/test/install-verdict.test.ts b/test/install-verdict.test.ts index efeb1122f..98aa8ed14 100644 --- a/test/install-verdict.test.ts +++ b/test/install-verdict.test.ts @@ -146,6 +146,10 @@ describe('install verdict keyed by (checkout, project): both twins', () => { const alone = both('autoplan', proj, { GSTACK_STATE_ROOT: sr }); expect(alone).toMatchObject({ refuse: true, status: 'verdict', code: 'INSTALL_UNVERIFIED' }); expect(alone.detail).toContain('certified for=review-voice'); + const gone = both('autoplan', proj, { GSTACK_STATE_ROOT: sr, GSTACK_INSTALL_VERDICT: path.join(sr, 'gone.json') }); + expect(gone.detail).toContain('certified for=review-voice'); + writeVerdict(sr, { project: proj, schema_version: 3, for: 'review-voice' }); + expect(both('autoplan', proj, env).detail).toContain('unsupported schema_version'); }); test('a running Bun other than the recorded one refuses with BUN_RESOLUTION_DRIFT and names both', () => {