# Code review process, 30 days (2026-08-30 to 09-29), PropFlow-Technologies/propflowai

Sources: 600-PR sample of 5,437 merged (scratchpad/pr-latency/sample.jsonl, recounted fresh); 253 classified findings in 40 multi-round PRs (findings40_classified.jsonl); live REST counts for claude-code-review.yml on 09-22 and 09-29; 12 failed run logs on 09-29; prior ci-waste-audit-30d.md. ~20 API calls this stage.

## How it works (from the workflow files)
- claude-code-review.yml: every PR push. Sizes a tier on substantive lines (tiny 30 turns / medium 60 / large 100 / huge 150 / mega 300). ALL tiers run Opus 5.5; large+ run xhigh effort. Posts 🟢/🟡/🔴. A 🔴 is encoded as a FAILED required check ("Encode verdict in check status").
- decide-review-mode.sh: light path for test/doc-only follow-up pushes; whack-a-mole flag from round 3.
- Side machinery: review-execution-repin, claude-review-recheck, check-override, rerun-on-infra-failure, verdict-watchdog, auto-merge-all (audit: ~85k runs/30d sample, ~40% of all Actions runs).
- review:self: local copy of deterministic gates (body shape, ratchets, size 1,000-line ceiling).

## Numbers (HARD = counted from data)
| Measure | Value | Basis |
|---|---|---|
| PRs merged | 5,437 | HARD |
| Bot verdict rounds per PR | median 2, p90 5, 23 of 600 PRs got 8+ | HARD (600 sample) |
| Verdict mix (1,557 rounds) | 🟢 783 (50%), 🟡 445 (29%), 🔴 329 (21%) | HARD |
| PRs with at least one 🔴 | 185 of 600 (31%) | HARD |
| PRs ending on 🟢 | 473 of 580 reviewed (82%) | HARD |
| What follows a 🔴 | 🟢 46% (152), another 🔴 36% (120), 🟡 15% (48), merged on it 3% | HARD |
| Review runs per day | 530 (09-22), 1,266 (09-29) | HARD, live |
| Run outcome 09-29 | success 920, failure 272, cancelled 19, skipped 53 | HARD |
| Run outcome 09-22 | success 326, failure 189, cancelled 7, skipped 8 | HARD |
| Wall time per review run | median 9.7 min, mean 11.2 min (success) | HARD, 100 runs |
| Review machine-minutes | ~13k min/day on 09-29 (est.: 1,212 runs x ~11 min); 30-day total unknown | ESTIMATE |
| Claude tokens / dollars | not logged anywhere I could reach | NOT AVAILABLE |
| 🔴 real correctness bugs | 49 of 114 (43%) in 40 multi-round PRs | HARD, biased to 3+ round PRs |
| Other 🔴 | test gap 28, stale repeat 17, other 9, style 7, gate 4 | HARD |
| 🔴 that re-argued an earlier finding | 17 of 114 (15%); 120 of 329 🔴 were followed by another 🔴 | HARD |
| 🟡 followed by another push | 78% (347 of 445) | HARD |
| Rounds after a 🟢 | 310 | HARD |
| Rounds vs hours | 3+ rounds = 38% of PRs, 68% of open hours (1,571 h of 2,303 h) | HARD |
| Size vs 🔴 | under 100 lines: 8 🔴; over 1,000 lines: 132 🔴 (40%) | HARD |

Correction to the earlier audit: "27% of review runs produced no verdict" was wrong. In 12 sampled 09-29 failures, 9 were the verdict-encoding step (a 🔴 working as designed) and 3 were the "relevance" classifier. Most "failures" are red verdicts.

## Ladder vs reality
| Rule | Reality |
|---|---|
| 🟡 never holds a merge, arm and stop | 78% of 🟡 still get another push |
| A 🟢 is a merge, not a cleanup invite | 310 rounds came after a 🟢 |
| Freeze after round 1: only fix BLOCKING | 57% of blockers are not correctness bugs, so "blocking" is over-used |
| "Round count is NOT a stopping condition" (repo manual) vs Fede's 09-17/09-28 rule | Two texts still disagree; sessions obey the older one |
| Size gate 1,000 lines | 13% of PRs still exceed it; >600 lines is where 🔴 cluster |
| Every PR, every push, full Opus review | 82% of PRs are 🟢-final; tiny PRs (under 100 lines) average 1 round and 0.03 🔴 per PR |

## Mistakes
1. Bot calls non-bugs 🔴 (57%), and a 🔴 is a red required check, so style/test-gap points block merges.
2. Bot repeats itself (15% of 🔴, 38% of 🟡 are repeats of earlier findings).
3. Authors push after 🟡 and 🟢 (78% and 310 rounds) against the written rule.
4. Every push re-reviews from scratch on Opus 5.5 even for one-line fixes; xhigh on large+ with 0 turn-cap hits (budgets are 3-5x use).
5. Six helper workflows exist to keep the review check alive (re-pin, recheck, override, infra-rerun, watchdog, auto-merge): fragility tax.
6. Contradictory written rules on review rounds.

## Opportunities (estimates labeled)
| # | Change | Why | Est. effect |
|---|---|---|---|
| 1 | 🔴 only for a reproduced correctness or safety defect; all else 🟡 + bot-filed follow-up | 57% of 🔴 aren't bugs | about 1 round off each 3+ round PR; 400-600 PR-hours per 600 PRs (est.) |
| 2 | One verdict per PR head after round 1: bot never re-raises a prior finding, never re-reviews after 🟢/🟡 unless new files touched | 15% repeat 🔴, 310 post-🟢 rounds | est. 10-15% fewer review runs |
| 3 | Tiered review: under ~100 substantive lines and green review:self get Sonnet/low effort or deterministic-only | small PRs get 1 round, ~no bugs | est. cut model spend on about 22% of PRs (under 100 lines = 122 of 600) |
| 4 | Drop xhigh and cut turn budgets to ~2x observed | 0 cap hits | cost only, no latency change |
| 5 | Size gate 1,000 to 400 lines | >600 lines carries 60%+ of 🔴 | est. 100-200 h per 600 PRs |
| 6 | Merge queue plus one review orchestrator replacing the 6 helper workflows | fan-out is ~40% of runs | large, touches the merge guard |
| 7 | Log tokens and dollars per review run in the verdict footer | cost is unmeasurable today | enables all of the above |
