mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-01 14:34:42 +01:00
Two blocking findings from /ship's own pass 1, both reproduced in the QA smoke before the fix: gstack-ship-receipt carry hashed the product diff with git patch-id --stable, which strips whitespace, so a space moved in a reviewed shell line carried as "no product change"; and it classed package.json and every lockfile as release metadata, so a dependency swap carried too. The patch-id is now --verbatim, package.json and VERSION are metadata only while the change is a version stamp (lib/pregate/stamp-only.ts), lockfiles are product unless the policy names them, the test globs name code extensions, a dirty working tree refuses before anything is compared, and a receipt carried twice keeps the reviewed head as carry.from. gstack-review-scope: an unresolvable base is POLICY_SOURCE_UNAVAILABLE instead of a silent working-tree read; --range-base is validated; git runs with core.quotePath=false; range_base is null on pass 1; a blocking finding with no path is fix; category "testing" is a test finding below the floor; defer searches once, files nothing on a failed search and exits 0 unfiled; summary refuses zero matching passes and the receipt write is chained to it with &&; a finding the diff causes elsewhere names the changed line in `cause` and classify follows it. Review-loop budget wording (ideas from tstack's sol-loop and pstack's interrogate, rewritten; NOTICE.md): the blocker / should / nit glossary and two stop rules in Step 9.4, the checklist and docs/review-policy.md; a lead-judgment stage in the finding merge both /review and /ship render. The core read diffs $RANGE_BASE from pass 2 on. Caps and pins re-measured with reasons. Step 7 coverage audit: four tests added in existing files, the --review-loop case moved to its own test (the shared test tripped bun's 5 s default). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>