Repository navigation
v1.91.307.0 ship: proportional review depth (light, standard, full) with depth-checked receipts - #3567
Conversation
…wed tree after a rebase A base merge whose only product-side change is a registered output the pregate regen check proved fresh now carries the receipt. A rebased head carries when its tree is one the receipt covers and its product patch-id against the current base matches (RECEIPT_CARRY_TREE_MISMATCH otherwise). Docs: merge main into a reviewed branch, never rebase it. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
The regen check deletes each touched output in its scratch worktree before the command runs and records the ones recreated byte-identically as proven. gstack-ship-receipt carry exempts only those paths, and only when the check ran origin/<base>'s registry at the commit the carry reads. A file under an output glob that the generator never writes stays product (pre-landing review, #3564 pass 1). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…tured review-loop exception (#3559) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
The regen verdict comes from the unmodified run again, so a generator that reads its own registered output (gen-skill-docs and qa/templates/functional-report-template.md) passes as before; the proof is a second run with the touched outputs deleted, and its failure only means not proven. The carry ignores a proven path with glob syntax, since it uses the paths as pathspec globs (pre-landing review, #3564 pass 2). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…x line Documentation audit for #3564 (/document-release, audit ship3564-docs-1). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…7-review-depth Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> # Conflicts: # docs/ship-policy.md
… checks) - carry refuses a --head other than the checked-out HEAD, a receipt with gstack_version but no review_depth, and an owner exception that no longer stands; a dirty or foreign checkout makes the write-time gate scan unavailable (full) - the queue binds a gate scan only to the full bound commit and recomputes the scope signals with gstack-diff-scope <base> --head <sha>, the same range the writer uses - the queue checks the review-loop exception's fix-check ancestry - a package.json version line counts as stamp-only only when it is a bare version key - docs and help name what review_depth is and which registry the queue reads Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
… field Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…'s depth field" This reverts commit e9ec264.
E2E Evals: ✅ PASS (flaky: 3 case(s) passed on their one rerun)125 executed, 0 reused rule/judge records | 0 manual accepted (unscored; no score-cache credit) | $32.08 rule/judge cost | reconcile exit: 0 Profile: pr / mode Full gate restored by:
Derived dependents (scripts/pr-dependencies.ts):
Rule and judge shards
Fail-closed reconciliationSliced lane: planner → duration-packed executors → fail-closed report. Behavior cases run a pre-registered 3-trial panel (PASS at 2/3 with no contract violation); a PASS 2/3 is shown with its failed trial, never as a clean pass. Reused results retain their original provenance and expiry. Flaky: failed once, passed on its one rerun (rule 16)Each failed and passed on its rerun in run 40805543956 at the attempts named above. Logged for the daily flaky-fix pass in this run's Dispatched narrow screen (gstack-ship-queue ready --screen) of merge commit |
|
😎 This pull request was merged. |
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ts; land checks the depth-checked receipt (#3567) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…; regenerate the doctor anchors Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ts; land checks the depth-checked receipt (#3567) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…; regenerate the doctor anchors Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ts; land checks the depth-checked receipt (#3567) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…; regenerate the doctor anchors Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ts; land checks the depth-checked receipt (#3567) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…; regenerate the doctor anchors Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ts; land checks the depth-checked receipt (#3567) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…; regenerate the doctor anchors Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…ts; land checks the depth-checked receipt (#3567) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…; regenerate the doctor anchors Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Stacked on #3564 (receipt carry rules). Review that one first; this PR's diff is against its branch.
What changed
A 12-line code fix now gets light depth: one batched specialist plus the native adversarial pass, and the plan prints the depth and gate scan the receipt records.
Before/after as text: A 12-line code fix now gets light depth: one batched specialist plus the native adversarial pass, and the plan prints the depth and gate scan the receipt records
lib/review-depth.ts, newlib/review-collect.ts,bin/gstack-review-plan, the review-army and adversarial sections). The depth depends on runtime lines: code-class lines minus docs, tests, and outputs registered with a command in the base commit's.gstack/generated.json.DIFF_CMDpathspecs.--depth-flooronly raises. EveryDEPTH_ERROR:carries its input, the sanitized cause and the repair.writeaddsgstack_versionandreview_depth: depth, class, runtime lines, rules hash, base and registry commits, the gate scan and reasons. They are computed at the checked-out head from the committed range, and--headmust be HEAD; tracked edits in the checkout make the gate scan unavailable, which records full. TheSHIP_RECEIPT:line printsdepth=<d>afterartifacts_consumed.readyandtrain buildrecompute the depth the head needs from the same committed range and refuse a lower receipt withQUEUE_RECEIPT_DEPTH_RAISED. TheREVIEW_DEPTH:line prints the receipt's depth, the required depth, runtime lines, class, reasons and inputs. A gate scan counts only when it names the full bound commit; otherwise the head needs full.--headis not the checked-out HEAD, when the receipt recordsgstack_versionwithoutreview_depth, or when an owner exception no longer stands.review_loop_exception(write --review-loop-exception) records an accepted stop after a fix-check edit under frozen scope: who, when, via, why, and the fix-check's head and findings. It needsreview_loop.fix_checksof 1 or more and a fix-check head that is the receipt head or its ancestor, and the body must carry the printed line word for word (REVIEW_LOOP_EXCEPTION_INVALID). The queue checks this exception and the docs exception the same way, including the fix-check ancestry (QUEUE_RECEIPT_EXCEPTION_INVALID).gstack-diff-scope <base> --head <sha>reads the committed range only, the scope the writer and the queue share..gstack/ship-policy.jsonmin_gstack_versiongoes from 1.91.146.0 to 1.91.299.0.Fixes #3559
Why
"A 12-line fix paid for the same reviewer fan-out as a change to the merge gate." The plan (GSTA-147, approved by Garry: "rec" on gate_rev 2) sizes the review to what the diff can break, while gate code, security paths, published numbers and every classifier failure keep the full review.
Light-depth backtest (D5): INCONCLUSIVE, so light keeps the adversarial pass.
The bar was at least 15 light-eligible PRs with attributable findings and 0 blockers lost. Only 5 were attributable, so light at runtime > 0 dispatches the native adversarial pass beside the batched specialist (reason "backtest inconclusive (GSTA-147 D5)").
Blast radius
The change touches /ship's review dispatch, every receipt write and the queue's acceptance of receipts. Depth only lowers the fan-out on non-gate diffs of 50 or fewer runtime lines, and receipts with neither new field (every receipt written before this release) are accepted as legacy, so in-flight PRs keep moving (script ran:
test/ship-receipt-depth.test.tscovers the legacy case, and the whole free tier passed on the frozen head). Each write runs gstack-diff-scope and the gate scan once, about 0.4 s.These resolutions differ from the plan:
review_depth.gate_scan, notreview_loop.gate_scan, becausereview_loopcomes from the review-scope summary.writecomputes the depth itself. Step 9 plans on the uncommitted tree before Step 15 commits, so its scan names an older head.RECEIPT_CARRY_REFUSED, not a newRECEIPT_CARRY_DEPTH_RAISEDcode.min_gstack_versionrises to the newest released version, not to this PR's own version. That version is allocated at the slot stamp, and the policy file is not a stamp path. A one-line follow-up after the stamp can raise it.readyhas no--jsonmode, so the diagnostics are text only.Approvals
Source: gstack-approvals record for gsta147-review-depth (display only; not an approval citation).
The #3559 amendment came from GStack Minder's relay of Garry's plan approval; the lane never merges.
Summary
Proportional review depth for /ship (light, standard, full), receipts that record the depth bound to the head they describe, and a queue that refuses a receipt below what the head needs. The pre-landing review tightened that binding, so the queue and the writer now read the same committed range, a gate scan binds only to the full commit, and carry refuses the cases the queue would refuse.
Test Coverage
Step 7 audit (audit-only): 25 of 28 paths tested.
Tests: 92 → 124 (+32 new) across the seven touched test files.
Coverage: 89% of paths tested (86% at two stars or better), with 3 gaps and 1 weakly covered path.
Test value: the audit-only run recorded no per-card counts; 1 path weakly covered.
Gaps left as proposed tests: a
test/ship-queue-train.test.tsrow that builds a train with a light receipt on a standard head; the rules-only equal-tree acceptance; a bounded recompute time for a five-PR train (filed in TODOS.md).Tests ran: remote_gate 23668 (pregate, whole free tier on one Ubicloud VM)
Pre-Landing Review
Pass 1 (full, gate class: 6 specialists, Red Team, native adversarial, outside voice on openai/gpt-6.1-sol) found 14: 7 fixed in 4ad8a6b, including 2 blocking (the queue bound a gate scan by prefix and recomputed scope without the writer's range) and a reproduced CRITICAL (a carry
--headother than the checkout recorded a working-tree gate scan). Pass 2 on the fix range (one batched specialist over six checklists plus Red Team) found 2 notes and nothing at the floor.REVIEW_LOOP: passes=2 blocking_found=2 deferred=0 noted=9 fixed=7 scope=frozen dispatches=9
Gate edits: 19 listed, 14 read, 0 findings — 0 kept, 0 restored, 0 open
Outside review: completed (openai/gpt-6.1-sol, pass 1); its carry finding matched the testing specialist's and was fixed.
Review notes
bin/gstack-ship-receipt:603(state-machines, pass 2): after a carry across rewritten history, a later linear carry checks the old fix-check ancestry and refuses a receipt the queue accepts. Fails closed (a needless /ship rerun).bin/gstack-diff-scope:87(simplification, advisory): the first clause of the--headtest is redundant.bin/gstack-review-plan:120(security): control characters in a path can reachDIFF_CMD.lib/review-collect.ts:129(adversarial):collectLivefollows a FIFO or symlink in the working tree.lib/ship-receipt-depth.ts:121(adversarial): legacy acceptance has no expiry.bin/gstack-ship-receipt:208(Red Team):review_depthis the depth the head needs, recomputed at write, not the depth the review ran.deeper()is dead atbin/gstack-ship-receipt:605;Collected.mergeBaseis unused; thedepthOfCommitInputfloor is unused.Exploratory QA
Not run as a separate charter: the change is CLI and library behaviour, exercised through the fixture repositories in
test/ship-receipt-depth.test.ts,test/review-plan-cli.test.tsandtest/diff-scope.test.ts, plus the before/after review plan above, captured on a scratch repository.Design Review
No frontend files changed — design review skipped.
Eval Results
Not run locally.
eval:selectfalls back to the full PR profile (143 behaviors) becausetest/size-ledger/ship/gsta147-review-depth.jsonis an unknown dependency, beyond the lane's $10 focused cap; the paid coverage for this PR is the train gate (gstack/full-gate), still outstanding.Greptile Review
No Greptile comments.
Plan Completion
Step 8 audit: 21 of 33 DONE, 7 CHANGED, 3 PARTIAL, 2 NOT DONE (plan: captain-gstack-minder/plans/GSTA-147/plan.md, PR 2).
carry.coversderived from the depth (until then a carried light receipt'scoversis the fixed list); a bounded recompute-time test for a five-PR train.QUEUE_RECEIPT_DEPTH_RAISEDprints neither both rule hashes nor runtime lines at both heads; the rules-only equal-tree acceptance with a note is not implemented and has no test.Issues
Fixes #3559
Verification Results
Plan obligations run at review: the depth matrix, fail-closed errors, write, carry and queue refusals and the review-loop exception PASS in their focused tests; the five-PR recompute bound is NOT RUN (deferred above).
TODOS
No TODO items completed in this PR. Added a P1 section for the two deferred plan items.
Documentation
Status: updated. Factual edits to docs/ship-policy.md and docs/troubleshooting.md; no blockers.
Scope: the committed range 3b90122..45d9835 (40 files; nothing staged, unstaged or untracked): review depth (lib/review-depth.ts, lib/review-collect.ts, bin/gstack-review-plan), receipt fields gstack_version, review_depth and review_loop_exception (bin/gstack-ship-receipt, lib/ship-receipt-depth.ts), the queue checks QUEUE_RECEIPT_DEPTH_RAISED and QUEUE_RECEIPT_EXCEPTION_INVALID, and
gstack-diff-scope <base> --head <sha>. Docs that name these commands were audited.Documentation health:
ready, /ship-before-READY andtrain buildrefusal lists name the two new queue codes;verify --trainnarrowed to QUEUE_RECEIPT_MISSING/STALE, since it does not recompute depth; the carry depth and exception refusals name RECEIPT_CARRY_REFUSED)write --headnot being the checked-out HEAD; QUEUE_RECEIPT_DEPTH_RAISED names the base ref per command; QUEUE_RECEIPT_EXCEPTION_INVALID adds the fix-check ancestor rule; RECEIPT_CARRY_REFUSED adds the depth and owner-exception refusals)Documentation Debt
gstack-diff-scope <base> --head <sha>: reference only (bin header, ship-policy.md, CHANGELOG); no how-to..gstack/generated.jsonas a review-depth input: explained in review-policy.md, but pregate.md's generated-v1 section does not point to it (reference cross-link).Diagram drift: none (no architecture diagram names the review or receipt machinery).
Test plan
gstack-pregate --stage tests --remote --spend-cap 2 --timeout 2700 --allow-repo-commands: PREGATE_REMOTE tree=2b975190e0b1 tests=23668 failed=0 spent=0.08; PREGATE_VERIFY ok (macOS and Windows lanes cleared)bun test test/approval-classes.test.ts test/gstack-ship-receipt.test.ts test/ship-receipt-depth.test.ts: 37 pass, 0 fail for the first two after the summary-line fix; ship-receipt-depth 6 passbun run typecheck: clean🤖 Generated with Claude Code