feat: run review phases in parallel or in sequence behind the phases input - #79
Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ewRequestError Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…l completion Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d phase runs Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
umm-actually re-reviewed at 2 new finding(s) posted (15 tracked finding(s) across all runs). Context notes
umm-actually · deepseek/deepseek-v4-flash-0731 |
The phases input (combined/parallel/sequential) determines whether the review makes 1 or 3 model calls but was missing from the startup settings log that records every other action input. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- config.ts: `value ? value : default` → `value || default` - comment-mapping.ts: extract chained ternaries (findingsLine, incompleteNote) into helpers with early returns - README.md: step 4 and roadmap reference the phases input table instead of re-explaining all three modes Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…phases check run Two coverage gaps found during test audit: - describeError (newly exported from logger.ts) had no direct tests for either branch — add tests for Error formatting and non-Error stringification - resolveCheckRunCompletion's zero-findings path with incomplete phases was untested — the check run title and summary carry the incomplete suffix even when no findings were posted Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ly real findings between stages Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
@CodeRabbit review |
|
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e sequential abort path end to end Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
New prior-findings note mis-states the merge and teaches later phases to suppress distinct same-line defects
The new sentence in the prior-findings note ('a later report on the same lines is merged into the earlier one') is factually wrong — overflow: an overlapping lower-or-equal-severity later finding is dropped by a later report on merger rule (or the equal-severity entry kept in merge-phase-findings), it is not merged — and its practical effect is to instruct a later phase that reporting on territory an earlier phase already touched is futile. The stated principle elsewhere in this PR's own prompt text is that a genuinely different defect at the same location is still a finding. A model reading this new clause will self-suppress precisely that distinct finding before the merge ever runs, so the run silently loses a real defect at model time rather than at merge time. Failure scenario: phases: sequential where correctness-security reports a high-severity null-deref at src/foo.ts:42. subtle-bugs traces the same diff and — per the pass-scope principle — identifies a genuinely different missing-bounds-check defect also at line 42. Reading 'a later report on the same lines is merged into the earlier one', subtle-bugs judges its report futile and omits it. The run posts only the first finding; the second real defect is never reported. Replacing the misleading claim with accurate merge semantics (higher severity wins, distinct defects still reported) avoids this. The fix for the phrasing: say reports on the same lines are collapsed keeping the higher-severity one, and a genuinely distinct defect at the same location is still a finding — report it. Suggested fixReword to: 'A later report on the same lines is collapsed with the earlier one, keeping the higher-severity finding; a genuinely distinct defect at the same location is still a finding — report it.' Remove the false 'merged into the earlier one' claim, which teaches suppression. This also keeps the prompt consistent with the pass-scope principle the PR adds for sequential mode.umm-actually · deepseek/deepseek-v4-flash-0731 |
…-findings note Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Regarding the beyond-diff finding on the prior-findings note (the "merged into the earlier one" wording): the precision half is applied in 170b16f. The note now says "when a later report overlaps one of these lines, only the higher-severity finding of the two is kept", which is what the merge does. The other half, promising that a distinct defect at the same location is still reported, is declined on purpose: the cross-phase merge is category-agnostic by design, so that promise would contradict the code (the previous finding on this PR flagged exactly that contradiction), and a later phase told to report on collapsed territory would spend output tokens on findings that cannot post. The collapse is counted in the job summary as Duplicates (cross-phase). 🔍 ship-check · pr-monitor · claude-fable-5-1 |
|
@umm review The self-review on 170b16f failed on two consecutive 900-second provider timeouts (both attempts, no response from DeepSeek), which is a provider failure rather than anything in the PR; the commit under review changed one line of prompt text. Re-running once. This run also exercised the new every-phase-failed path live: the check run concluded failure with both billed timeout attempts in its cost table. 🔍 ship-check · pr-monitor · claude-fable-5-1 |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
README.md conflict: main's PR #83 replaced the verbose Status section with a slim Roadmap heading; the branch had added phased-review to the Status list. Resolved by keeping main's Roadmap — the Status list was intentionally dropped. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge conflicts in AGENTS.md (review/ module list) and README.md (how-it-works steps 4-6) — combined phased-review additions from this branch with content-dedup additions from main. Fix: all-phases-failed cost summary now derives modelUsed from the billed attempts instead of hardcoding "none" — the summary header and table rows no longer contradict each other. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The current wording at prompt.ts:218 is "when a later report overlaps one of these lines, only the higher-severity finding of the two is kept" — this accurately describes the behavior (lower-severity overlapping finding is dropped via the pre-sorted reduce in selectFindings). The quoted wording "a later report on the same lines is merged into the earlier one" does not appear in the current code. 🔍 ship-check · pr-monitor · claude-opus-4-6 |
…, later phases complete
Why
Every review is one model call carrying all four dimensions, and that call is the whole wall clock of a review: 8m00s of an 8m28s job on this repo's own self-review, 3m29s of a ~4m job on a consumer's docs PR. Everything else in the pipeline takes about two seconds. Splitting the call was the candidate latency lever, and one 900s timeout on the single call loses the whole review. The live A/B below shows what splitting actually buys on the model in use.
What
phasesinput gainsparallelandsequential. The dimensions split into three focused phases: correctness + security (+ CI workflow checks), code quality + test quality, subtle bug patterns.parallelruns them at once;sequentialruns them in order, each phase seeing the earlier findings through the existingprior_findingsprompt section.combinedstays the default and is unchanged. An empty value means the default, so a workflow can wire an unset repo variable.review/run-stages.ts, pure): a stage's phases run concurrently, stages run in order. One phase failing does not discard its siblings. When no phase completes the dispatcher throws an error carrying every phase's outcome, so the failure check-run summary can still render the billed attempts. An auth/credit abort stops later stages instead of making doomed requests, and those phases are reported as not attempted.review/merge-phase-findings.ts, pure): findings two phases reported on overlapping lines of one file collapse to the higher severity (earlier phase wins ties), category-agnostic, because two phases on the same lines are almost always one defect under two labels. A candidate overlapping several kept findings must outrank all of them and then evicts all of them. Only cross-phase pairs compare, so a one-phase run passes through unchanged. Runs after the non-finding and unknown-file filters so a non-finding can never out-rank a real finding. Non-findings are also dropped before findings are threaded to a later stage.(1 of 3 phases incomplete)and the summary carries the reason; the job summary lists completed and incomplete phases and aDuplicates (cross-phase)row. The conclusion stayssuccess: the review ran and posted what it found.ReviewRequestErrorthrown by the client; a run where every phase fails renders them into the failure summary.model_usedjoins the routed models when phases were served by different ones.prior_findingsnote states the merge rule so a later phase is not told to report what the merge would collapse.action.yml, README (input, output, how it works, status), AGENTS.md tree line;self_review.ymlwiresUMM_PHASESso this repo can A/B the modes.Tests
parallel,sequential, partial failure, all-failed with and without billed attempts, sequential abort, and mixed routed models, cost table phase column, status comment and job summary wording, emptyphasesconfig.npm test,npm run lint,npm run buildgreen.Live A/B
Same PR, DeepSeek v4 flash via OpenRouter, 80K context budget. Per-phase order is correctness-security / conventions-tests / subtle-bugs. Runs cancelled by a later push still logged their phases.
What the numbers say:
parallelorsequentialruns, and five of those were valid and fixed.Default stays
combined. On this modelparallelis a depth setting, not a speed one; the speed premise holds only for a provider whose per-call latency is dominated by prefill or queueing rather than by output tokens. Worth re-measuring when the primary model changes.🤖 Generated with Claude Code