Root cause
sdd-review and sdd-validate (both post as the App bot) re-scan the entire PR diff (head vs base) on every trigger — there is no incremental memory of what was already reviewed.
sdd-review.md §3: "Review the pull request diff across three concerns." §4 partitions a >200-line diff by concern, but the scope is always the full diff — never "only the commits since my last review."
sdd-validate.md: re-runs the full gate set against the current head each time (proof artifacts re-executed, full changed-files-scope check, credentials).
Every push therefore re-reviews unchanged code and can surface new findings on lines nobody touched this iteration. The #247 unresolved-thread aggregation prevents duplicating an open thread, but nothing records that a region of the diff already passed — so each run starts from the whole diff again.
Impact (observed in a consumer pilot run)
On a multi-PR feature cascade, every push re-triggered a full re-review:
Fix
Make the review incremental, keyed to a last-reviewed commit:
- Persist a
last-reviewed-sha per PR (a hidden marker comment, or reuse the #247 directive state).
- On each run, scope the diff to
last-reviewed-sha..head (the commits added since the last review) for raising new findings, instead of re-scanning base..head.
- Still honor the full unresolved-thread set (
#247) for context and resolution, and still allow a full re-scan when explicitly requested (e.g. @coderabbitai full review-style, or a first review with no marker).
- Apply the same to
sdd-validate's changed-files-scope and proof re-execution: re-evaluate only what the new commits touched, plus the standing gate state, rather than re-deriving every gate from scratch.
- Advance
last-reviewed-sha to head after a run completes.
Acceptance
- A push that changes one file does not produce review comments on unrelated, unchanged files.
- A finding the bot already passed on (in a prior reviewed range) is not re-raised on a later push that did not touch that code.
- A full re-scan is still available on demand and on the first review.
last-reviewed-sha advances per run; a force-push / rebase resets it to a full review (the base changed).
References
Root cause
sdd-reviewandsdd-validate(both post as the App bot) re-scan the entire PR diff (head vs base) on every trigger — there is no incremental memory of what was already reviewed.sdd-review.md§3: "Review the pull request diff across three concerns." §4 partitions a >200-line diff by concern, but the scope is always the full diff — never "only the commits since my last review."sdd-validate.md: re-runs the full gate set against the current head each time (proof artifacts re-executed, full changed-files-scope check, credentials).Every push therefore re-reviews unchanged code and can surface new findings on lines nobody touched this iteration. The
#247unresolved-thread aggregation prevents duplicating an open thread, but nothing records that a region of the diff already passed — so each run starts from the whole diff again.Impact (observed in a consumer pilot run)
On a multi-PR feature cascade, every push re-triggered a full re-review:
needs-humanon each push.The only stable state is 0 unresolved threads + green CI, because a fresh run re-scans everything; "wait it out" does not converge. This is a steady throughput drain and a churn source feeding the auto-revise. Siblings: Auto-revise must resolve each addressed review thread with an inline resolution note (valid+sha / invalid+reason) #311 (reasoned thread close-out), A human-issued /revise is gated behind needs-human and silently no-ops until the label is cleared #313 (revise gating).
Fix
Make the review incremental, keyed to a last-reviewed commit:
last-reviewed-shaper PR (a hidden marker comment, or reuse the#247directive state).last-reviewed-sha..head(the commits added since the last review) for raising new findings, instead of re-scanningbase..head.#247) for context and resolution, and still allow a full re-scan when explicitly requested (e.g.@coderabbitai full review-style, or a first review with no marker).sdd-validate's changed-files-scope and proof re-execution: re-evaluate only what the new commits touched, plus the standing gate state, rather than re-deriving every gate from scratch.last-reviewed-shatoheadafter a run completes.Acceptance
last-reviewed-shaadvances per run; a force-push / rebase resets it to a full review (the base changed).References
sdd-review.md§3-4 (full-diff, concern-partitioned),sdd-validate.md(full gate re-run)#247(unresolved-thread directive — the state to key off)