Repository navigation
fix(outside-review): a check-results sign-off keeps the no-findings conclusion (#3469) - #4130
Merged
Merged
Conversation
…onclusion (#3469) A clean Codex review that ends with "Tests, lint, and build all pass." read VERDICT: unverified, so /ship and /review reported missing outside coverage. Closing check-results sentences are now skipped when the conclusion is read, fail-closed for code, failures, truncation and wrapped lines. (GST-1803) Co-authored-by: vilano93 <244097767+vilano93@users.noreply.github.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
|
😎 This pull request was merged. |
A clause after the whole-change scope ("No issues in the diff, while the change disables auth.") no longer reads as a no-findings conclusion: the scope phrase ends at a clause break and while/whereas count as contrast words.
Review-Finding: p1/specialist-batched#1 reader=red-team
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
Any clause joined after the whole-change scope (a comma, dash, parenthesis, or and/so/since/while...) keeps the no-findings statement from concluding the review; a list of change kinds stays one scope. The scope test is linear again. Review-Finding: p2/fix-check/fix-check#1 reader=fix-check Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
A double-hyphen or figure dash, brackets, a spaced slash, plus and despite after the whole-change scope also start a clause the scope does not cover. Granted fix-check under review_loop_exception a-2726c5b57840. Review-Finding: fc2/fix-check#1 reader=fix-check Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
…view no-findings conclusion Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Clean reviews that sign off with their checks now read clean; a clause after the scope still never does.
Before/after as text: Clean reviews that sign off with their checks now read clean; a clause after the scope still never does
lib/outside-review-result.ts:withoutClosingCheckResults()drops whole closing sentences that only report passing checks before the conclusion is read.NO_FINDINGSaccepts a whole-change subject ("The changes introduce no …") and up to two adjectives, and that form is always held to the whole-change scope rule. A clause joined after the whole-change scope ("and", "while", em dash, parenthesis) no longer concludes the review.test/outside-review-result.test.ts: a#3469block, written first and red on main (2 fail / 55 pass), with the two real tails from outside-review-result: a clean structured review is unverified when Codex adds a check-results sentence after its conclusion #3469 in-process and through the CLI, plus negative controls for findings, truncation, empty and check-only replies, a failing check, quoted code, wrapped lines, colon conditions and joined clauses.docs/troubleshooting.md#outside-review-verdict: the "No findings" rule names the new form, the sign-off rule and the joined-clause rule. No new reason code.changelog.d/gst-1803-outside-review-check-signoff.md: the changelog fragment.Why
#3469: "a clean Codex review is recorded as missing outside coverage". Codex's structured review often adds one sentence about the checks it ran after its conclusion, and since #3304 only the last sentence can conclude a review, so /ship and /review read reviews that ran and found nothing as unverified. Those reviews now read clean, and a reply that adds a contrast or a new claim after its scope still never does.
Blast radius
Only the no-findings conclusion of untagged structured and review replies changes; severity parsing,
Verdict:handling, execution evidence and every other gate are untouched, and the parser stays fail-closed because a check sentence is skipped only when it is a whole sentence with terminal punctuation, holds no code and is not the reply's only sentence (lib/outside-review-result.ts read, 57 focused tests ran, before/after repro above). The rewrite is pure string parsing with no network calls, file or environment reads, dependencies, workflows, install scripts or permission changes.Credit
Rewritten on current main from the design and tests in #3641 by @vilano93 (outside code, read as text only; never checked out or run). Fixes #3469.
Approvals
Approvals
Approved: yes (record r-33db30cefe39). The full approval record stays private: this repository is public or its visibility is unknown.
Plan: exempt: bug fix
Plan check: exempt bug fix
Summary
/ship and /review reported missing outside coverage when Codex signed off a clean review with a sentence about its checks (#3469). The conclusion reader now skips a closing check-results sentence, accepts a whole-change subject, and refuses any clause joined after the whole-change scope, which closed three fail-opens the review loop found along the way. Rewritten on current main from the design and tests in #3641 by @vilano93 (outside code, read as text only; never checked out or run).
Test Coverage
All new code paths have test coverage: the
#3469block was red on main (2 fail / 55 pass) and every review-loop fix added its failing case before the fix.Tests ran: outside-review 57
Tests ran: typecheck count unavailable
Pre-Landing Review
REVIEW_LOOP: passes=2 blocking_found=4 deferred=0 noted=14 fixed=3 scope=frozen fix_checks=3 dispatches=2 est_input_tokens=6766
I reviewed the parser.\nNo issues in the diff: the fallback path now swallows ENOENT. Tests pass.reads clean at 30276a0. Recorded as a note under the Captain's B1 ruling; follow-up GST-1808.test/outside-voice-preflight.test.ts:256flips the real~/.gstack/config.yamlcodex_reviews to disabled under the launch environment's GSTACK_STATE_ROOT; same on main.Ruled note: lib/outside-review-result.ts:185:adversarial-single-sentence at 30276a0 ruled by Captain GStack Minder (GSTA-36), 2026-11-07 at 2026-11-07T16:52:27.368Z: pre-existing fail-open on main (GST-1808): 'Recommendation: Ship because no issues in the diff, so the change disables auth.' reads clean at cefcb20 and HEAD (approval a-f6a069074b30)
Ruled note: lib/outside-review-result.ts:158:adversarial-exception-phrases at 30276a0 ruled by Captain GStack Minder (GSTA-36), 2026-11-07 at 2026-11-07T16:52:27.926Z: pre-existing fail-open on main (GST-1808): 'No issues in the diff with the exception of the auth change.' reads clean at base and HEAD (approval a-0db6fe19731a)
Ruled note: lib/outside-review-result.ts:185:adversarial-question at 30276a0 ruled by Captain GStack Minder (GSTA-36), 2026-11-07 at 2026-11-07T16:52:28.101Z: pre-existing fail-open on main (GST-1808): 'No issues in the diff?' reads clean at base and HEAD (approval a-fa3f0d17f584)
Ruled note: lib/outside-review-result.ts:164:outside-as-a-whole at 30276a0 ruled by Captain GStack Minder (GSTA-36), 2026-11-07 at 2026-11-07T16:52:28.323Z: fail-closed note: 'Reviewed the diff. / No actionable regressions were found in the change as a whole.' reads unverified (clean on main) (approval a-1b367343b7d3)
Gate edits: none detected (2 listed, 1 read; patterns: RH-1,RH-3,RH-4,RH-12,RH-13,RH-14,RH-15,RH-16; unlisted idioms: none)
Outside review: the Codex outside voice ran in pass 2 and returned findings (outside-voice#1, ruled a fail-closed note above).
Review notes
Below the blocking floor (advisory, informational, test-gap or wording items); recorded here and not fixed in this PR.
lib/outside-review-result.ts:181A semicolon-joined check sign-off ('... in the diff; tests pass.') now fails closed: the ';' stays on the qualifier.lib/outside-review-result.ts:161Some clean replies with a trailing tail after the scope ('across the diff, including tests', 'while the change is small') now fail closed.lib/outside-review-result.ts:161The new scope regex backtracks quadratically on a huge comma-free last sentence (220 KB: 15 s).lib/outside-review-result.ts:161Same as fix-check#1 at INFORMATIONAL: 'and', em dash and parenthesis joins read clean; changelog overstates.lib/outside-review-result.ts:161A comma-spliced sign-off ('No issues in the changes, all tests pass.') now fails closed.lib/outside-review-result.ts:161Overlapping quantifiers backtrack super-linearly on 100 KB qualifiers.lib/outside-review-result.ts:164Other joiners after the scope still read clean as on main: colon (the colon-explanation rule), ' / ', 'plus', 'despite', U+2012.lib/outside-review-result.ts:186The clause-break word list turns some clean whole-change scopes unverified ('between main and this branch', 'since main', 'as a whole', 'that this PR makes', 'or tests', a because-clause with 'and tests pass'). Fails closed.lib/outside-review-result.ts:163SCOPE_LIST_JOIN names committed but not uncommitted: 'across the committed and uncommitted changes' reads unverified. Fails closed.lib/outside-review-result.ts:161A scoped claim with no joiner ('No issues in the auth module of this change.') reads whole-change; same at main, 2580692 and a5b9dc7.lib/outside-review-result.ts:164More fail-open joiner spellings: U+2010/U+2212 between spaces, ellipsis, unspaced slash, one-sided hyphen, ' ~ ', 'with', 'now'.lib/outside-review-result.ts:163SCOPE_LIST_JOIN does not cover ' / ' or 'plus', so 'in the staged / unstaged changes' and 'in the commits plus staged changes' now read unverified (fail-closed).lib/outside-review-result.ts:164'--' and brackets inside scope text ('git diff --cached changes', 'fix--retry', '[PR feat: add multi-agent consensus eval runner with persistent reputation #123] changes') now read unverified (fail-closed).Exploratory QA
Functional surface (library and CLI verdict), report-only. Smoke probes 001-003 found the pass-1 red-team case (002/003); replays 004-006 pass after the fix. Captures 007-010 on the pass-2 tree pass, and 011 (unverified) and 012 (clean) at 30276a0 pass. No blocked or not-run charters.
Design Review
No frontend files changed — design review skipped.
Eval Results
No prompt-related files changed — evals skipped (PR profile: 0 probes, 0 judges).
Review bot comments
No review bot comments.
Scope Drift
Scope Check: CLEAN
Plan Completion
Plan: exempt: bug fix. No plan file bound.
Issues
Fixes #3469
Refs fc2/fix-check#1
Refs fix-check/fix-check#1
Refs p1/specialist-batched#1
Related: #3641 (@vilano93)
Verification Results
No Step 8.1 obligations (plan exempt: bug fix). Lanes: outside-review 57 pass, typecheck exit 0. CI free-tests run 42394725946/1 green at 6c0a420 (tree f81ecc346d35, 36101 tests); pregate requires-remote cleared by that run.
TODOS
No TODO items completed in this PR.
Documentation
Status: updated. One factual edit to docs/troubleshooting.md, and no blockers.
Scope: base cefcb20 to head 30276a0, 4 commits and 4 files: lib/outside-review-result.ts, test/outside-review-result.test.ts, docs/troubleshooting.md and changelog.d/gst-1803-outside-review-check-signoff.md. There were no staged, unstaged or untracked changes.
Documentation health:
Coverage debt: the no-findings rules in classifyOutsideReview have reference coverage only (docs/troubleshooting.md#outside-review-verdict). No new commands, flags or environment variables were added. Diagram drift: none.
Test plan
bun test test/outside-review-result.test.ts: 57 pass, 0 failbun run typecheck: exit 0free-tests.ymlrun 42394725946/1 at 6c0a420: green, 36101 tests🤖 Generated with Claude Code