Skip to content

Review rounds are spent debating prose in comments instead of fixing code #1631

Open

Description

@ptr727

ProjectTemplate's issue count has not gone down after weeks of near constant burndown, see #1311 that is growing the count nor reducing it (yes it is entirely possible that the baseline position does have lots of defects per the current rules and we are simply discovering them and documenting them, then we need to evaluate the ROI of those rules if it enforcing them simply burns time and money vs. fixing real bugs.). Every Pr round I observe spends 90+% of the time debating prose and wording in comments vs. just fixing code. Real bugs are caught at the last moment after all prose arguments have been settled.

E.g. Nine findings across three review passes, every one against the comment I wrote, none against the key. Deleting the comment ended it. I've saved that: config changes ship bare, the measurement goes in the commit and PR body where it's reviewed once, and an issue reference never goes in a carried file. In this case the no prose in comments is a known rule, the no issue pointers in comments is also a known rule, yet this was the offered solution at round 10.

The result is that huge amounts of time is being wasted, huge amounts of tokens are being wasted, and huge amounts of github copilot and actions credits are being wasted.

Analyze all (ptr727 fleet) the recent (two weeks) PR's and determine how many review rounds violated a known rule and then determine why the rule was not followed, and calculate the time spent landing a PR, the average round count, and estimate how much time could have been saved if the rules were followed from the start.

Final step is determining what to do to prevent this, e.g. delete all prose and comment related rules so that it never violates, have a 0-agent comment rule where only humans are allowed to write comments, linter checks only and all rules are encoded in python code and PR agents only review code no prose, remove all governance rules in prose and only use skills, do periodic sweeps to keep the fleet in sync vs. enforcing conformity in real-edit-time, etc.

Activity

  1. ptr727 commented on Sep 15, 2026

    @ptr727
    OwnerAuthor

    Step 1: two weeks of fleet review rounds, measured, and the decision

    Method: every PR merged 2026-09-01 to 2026-09-15 in the 25 registry repos, fetched by GraphQL with reviews, review threads, and Copilot's collapsed suppressed findings; every thread first-comment and suppressed item classified by target (what it is about) and status (why it exists relative to the rules) in 50-item batches with five hand-labelled sentinels each (sentinel agreement 93% target, 98% status; a blind 72-item re-classification agreed 94% on target, 89% on status, 97% on prose-versus-not). Rounds are head commits that received a bot review. Local review passes, token counts, and dollars come from the Claude Code session transcripts on the machine that drove 235 of the 321 feature and promotion PRs, priced at list API rates. The scripts are scratch and land later as the weekly metric under #1324.

    Window 2026-09-01 to 2026-09-15, merged PRs across the 25 registry repos: 542 = 254 feature + 67 promotion (develop->main) + 221 Dependabot. 21 promotions are byte-identical re-reviews of one feature PR. Findings: 1437 (1125 threads + 312 Copilot suppressed), 1437 classified, 0 unclassified.

    1. Scope by repository

    Repo PRs feature promotion dependabot findings linked to a local session
    ProjectTemplate 144 101 35 8 558 135
    Financial-Modeling 69 57 10 2 488 0
    aiopurpleair 48 27 7 14 63 34
    HomeAutomation-Config 41 37 4 0 191 41
    LanguageTags 39 6 1 32 51 3
    PlexCleaner 35 1 0 34 11 5
    PhotoCleaner 32 0 0 32 0 0
    Utilities 30 5 2 23 40 7
    ESPHome-Config 26 6 6 14 17 12
    ESPHome-NonRoot 20 14 0 6 0 0
    Blog 18 0 0 18 0 6
    NxWitness 16 0 0 16 0 0
    homeassistant-purpleair 16 0 0 16 0 0
    VSCode-Server-DotNetCore 6 0 0 6 0 0
    HomeAssistant-Config 2 0 2 0 18 2

    2. Review rounds

    A GitHub round is one head commit that received at least one bot review. A local round is one review subagent dispatched in a Claude session linked to the PR (visible only for PRs driven from this machine).

    Set PRs rounds median mean p90 max Σ rounds Σ extra rounds Σ Copilot reviews Σ bot reviews wall h median Σ wall h linked PRs local rounds median Σ local rounds
    feature 254 2.0 2.54 5 12 645 412 649 1074 0.51 660 178 2.28 804.3
    promotion 67 2 2.22 4 10 149 83 149 281 0.64 290 57 2.07 319.36
    dependabot 221 0 0.00 0 0 0 0 0 0 0.03 9 10 1.24 12.4

    Copilot reviews vs Copilot review requests disagree on 5 of 542 PRs, each a request Copilot never answered: ESPHome-Config#146, Financial-Modeling#280, Financial-Modeling#285, Financial-Modeling#227, Financial-Modeling#228.

    3. Findings, all classified (feature + promotion PRs)

    target \ status correctness prose-rule-no-gate gated-rule-missed-shape rule-opt-in-not-enabled no-rule-reviewer-taste finding-wrong total
    code-behavior 531 0 1 0 17 16 565
    test 87 0 0 0 15 2 104
    config-key 4 0 0 0 1 0 5
    comment-text 61 28 16 0 17 7 129
    doc-wording 24 20 7 22 58 3 134
    doc-content-contract 381 2 1 0 6 21 411
    workflow-yaml 33 2 1 0 1 8 45
    other 2 21 0 0 18 3 44
    total 1123 73 26 22 133 60 1437

    Introduced by the PR: 93% yes, 7% pre-existing, 0% unknown. Disposition: fixed 609, none 538, declined 120, deferred 110, false 60. Prose targets (comment-text + doc-wording): 18%. Prose targets or prose rules: 20%. Real defects (correctness): 78%.

    By bot: | bot | findings | correctness | prose target | finding-wrong |
    | --- | --- | --- | --- | --- |
    | copilot-pull-request-reviewer | 773 | 77% | 26% | 3% |
    | coderabbitai | 401 | 87% | 6% | 4% |
    | qodo-code-review | 262 | 69% | 14% | 7% |
    | qodo-free-for-open-source-projects | 1 | 100% | 0% | 0% |

    Classifier: 30 gold items hand-labelled, 5 seeded per 50-item batch as sentinels. Low-confidence labels: 302 of 1437.

    4. The known-rule findings (prose-rule-no-gate)

    rule findings introduced by the PR by Copilot by CodeRabbit by Qodo
    pr-title 21 21 0 0 21
    doc-tense-voice 15 15 8 0 7
    cmt-narrative 9 8 5 0 4
    carried-coord-ref 9 9 8 0 1
    cmt-grew 7 7 0 0 7
    doc-number-stale 6 6 4 2 0
    cmt-unneeded 4 4 1 0 3
    doc-link-toc 2 2 2 0 0

    Why the rule was not followed, one cause per finding:

    cause findings
    in-context-violated 47
    unknown (PR not driven from this machine) 16
    rule-ambiguous-or-disputed 8
    pre-existing 1
    not-in-context 1

    5. Cost, and what following the known rules from the start would have saved

    Extra rounds (every round after the first) on feature + promotion PRs: 495 rounds, 620 h of round-to-round wall clock, 844 bot reviews. Linked-session spend on these PRs: $15,188 (transcript tokens at list API rates, 235 PRs).

    A round is saveable when every finding of the previous round was on text the PR introduced and (strict) violated a known prose rule with no gate, or (wide) was any non-defect finding on a comment, wording, or a prose rule.

    definition rounds PRs wall h bot reviews USD in those intervals (linked PRs) Actions runs
    saveable-strict 6 (1% of extra rounds) 6 1.0 11 $98 (5 rounds priced) 18 (6 rounds counted)
    saveable-wide 30 (6% of extra rounds) 26 6.7 37 $533 (27 rounds priced) 87 (30 rounds counted)

    For scale: every extra GitHub round interval on linked PRs, saveable or not, holds $10,124 of session spend (345 intervals), against $15,208 linked to PRs in total, so most of a PR's spend lands after its first bot review. All 108 in-window sessions on this machine, main thread and subagents, price at $15,421 at list API rates (per-model rates taken from Claude Code's own cost record, applied to transcript token counts, since that record omits subagents). The 52 sessions with a duration record spent $7,236 over 384 session-hours, about $19 per session-hour; a fan-out session running many subagents at once burns an order of magnitude faster, which is the shape a metered API key sees.

    Local review rounds: every review subagent dispatched in an in-window session on this machine, identified by its dispatch description. 1172 of 1285 subagents were review passes, costing $3,328 in their own tokens. On the 235 linked feature + promotion PRs: 1123 review passes (median 2 per PR, a multi-PR session's passes split evenly) against 579 GitHub rounds, and $3,322 of the $15,188 linked spend went to the review subagents themselves, before the main thread's cost of reading and disposing of what they returned. Their per-finding classification is not recoverable from transcripts, so their prose share is not measured; the #1630 case (three passes, nine findings, all on one comment, $25 and 1.9 h for a two-line config change) is the measured instance.

    6. Prevention options, scored on this window

    option findings it removes of all non-Dependabot findings notes
    Delete the prose and comment rules 27 2% only findings that cite a rule; the bots do not read GOVERNANCE or CODESTYLE, so the rest of the prose findings stay
    Zero-agent-comment rule (a diff adding a comment line fails, human override by label) 117 8% removes every finding on an agent-written comment, including 54 classed correctness
    Linter-only: bots review code, not prose (path and instruction filters) 263 18% keeps doc-content-contract and correctness; CodeRabbit is already filtered this way on .md
    Governance only as skills 0 to 1 up to 0% bounded by the not-in-context count; in-context violations (47) are unaffected
    Periodic sweeps instead of edit-time conformity (drop the per-PR whole-unit pass) 1123 local review passes on linked PRs, $3,322 n/a removes the local pump the #1630 case shows; adds one sweep PR per unit per period
    Gate the top two violated rules in prose_lint (pr-title, doc-tense-voice) 36 3% pattern-reachable: an issue or PR number, a rule name, or a hub name inside a comment or carried file
    Enable sentence-length and sentence-split by default 22 2% already implemented, opt-in
    Stop re-reviewing byte-identical promotion PRs 24 findings, 20 rounds, 31 bot reviews 2% 21 promotions had the same file fingerprint as one feature PR

    7. Undercounts and unknowns

    • Local rounds and USD exist only for PRs driven from one machine (235 of 321 feature + promotion PRs). No fleet extrapolation is made.
    • 6 findings have no introduced flag (suppressed items on PRs whose diff was not fetched, or hunks without an anchor).
    • Qodo's reviews have empty bodies, so its rounds are counted from thread timestamps and its suppressed-equivalent findings are not counted.
    • CodeRabbit's outside-diff findings are not itemised. Actions minutes are not measured, run counts only.
    • A round that received no re-review (5 unanswered Copilot requests) is not a round here.

    8. What the numbers say, and the decision

    The thesis that 90% of review-round time is prose does not hold for the bot rounds. Fleet-wide, 78% of the 1,437 bot findings are real defects, 18% land on a comment or on wording, and 5% (73) are instances of a known prose rule that has no gate. Only 30 of the 495 extra GitHub rounds (6%) were caused solely by non-defect prose findings, and following every known prose rule from the start would have saved 6 to 30 rounds, 1 to 7 hours, 11 to 37 bot reviews, 18 to 87 Actions runs, and $98 to $533 over the two weeks.

    Where the rules were broken, they were broken with the rule in context. 47 of the 73 known-rule findings came from sessions that had loaded the style skill or read the style doc before writing the text; 1 had not. Restating, relocating, or deleting the rules therefore changes little: the agent knows the rule and writes the comment anyway. Only a mechanical gate or removing the surface (no agent-written comments) changes that.

    The cost is real, and it sits in the loop after the first review, most of it local. 82% of PR-linked session spend ($10.1k of $15.2k) lands after a PR's first bot review. 1,172 local review passes ran in the window (1.5 per push) and cost $3.3k in their own tokens before the main thread's disposal work, which is where a nine-findings-on-one-comment loop like #1630 spends its $25 and 1.9 hours. The local passes' findings are not classifiable from transcripts, so their prose share is not measured; the bots' share is, and it is not 90%.

    Recommendation, in order of measured effect per unit of change:

    1. Cap the local review at one diff pass per push and move the pre-push whole-unit canonical pass to a scheduled weekly sweep. This is the only lever aimed at the spend that is actually large. The bots then carry the second look, which the data says they do well.
    2. Add a zero-agent-comment gate to prose_lint: a diff that adds a comment line in code or config fails, overridable by a PR label. Removes 117 findings (8%), including every Set MD024 to Sibling Scope in the Carried Markdown Config #1630-class loop, mechanically.
    3. Three small mechanical gates: a PR-title check (21 findings, all Qodo), sentence-split and sentence-length on by default (22), and no re-review request on a promotion PR whose file fingerprint equals its feature PR's (20 rounds, 31 bot reviews).
    4. Tell Copilot and Qodo, as CodeRabbit already is told, not to report wording on Markdown. Removes up to 263 findings (18%) but 85 of them are real, so this is optional.

    Not recommended: deleting the prose rules (2% of findings cite one) and moving governance into skills only (bounded at 1 finding).

    Decision (ptr727, 2026-09-15): items 1 to 4, all of them. One local diff pass per push and the whole-unit canonical pass moved to a scheduled weekly sweep; a zero-agent-comment gate in prose_lint with a label override; a PR-title gate, sentence-split and sentence-length on by default, and no re-review request on a byte-identical promotion; and Copilot and Qodo told, as CodeRabbit already is, not to report wording on Markdown. Each lands as its own PR. #1312 is done in substance (#1330 committed the stop rule and two-round budget without naming it) and #1313 is partial (#1328 named it, and reports/canonical-review.json is still a tracked file that 53 commits touched in this window); item 1 supersedes both.

  2. ptr727 commented on Sep 17, 2026

    @ptr727
    OwnerAuthor

    Decision item 3, the sentence rules: dropped, both stay opt-in

    Decision (ptr727, 2026-09-16): sentence-split and sentence-length are not moved into DEFAULT_RULES. Both stay opt-in. The other two parts of item 3, the PR-title gate and the no-re-review-on-a-byte-identical-promotion skip, are unaffected and still stand.

    The scoring above counted this option's benefit (22 findings, 2%) and not its cost. Measured on this repository at 91e0fd2:

    violations files
    sentence-split 6550 123
    sentence-length 3155 94

    Existing text is not the exposure, since the gate is diff-scoped. What the cost actually is: replaying the last 12 commits on develop through the two rules, scoped to each commit's own diff, 7 of the 12 would have failed, the largest at 159 sentence-split plus 221 sentence-length on one change.

    commit sentence-split sentence-length
    91e0fd2 159 221
    dbbb28f 30 13
    e1559c9 71 19
    7a6fcdd 0 12
    bf3b629 0 21
    796c32e 0 21
    55c2485 54 90

    The cause is structural rather than a backlog that shrinks. sentence-split asks for one sentence per line, and every carried skill file is hard-wrapped at about 100 columns, so nearly every sentence in one wraps. Enabling it by default is therefore a decision to reflow 123 files to semantic line breaks, which is a house-style change nobody has taken. docs/fleet-map.md already records the prior call that promotion into DEFAULT_RULES waits "if and when the corpus converges", and on this measurement it has not.

    Reproduce either column with a detached worktree at the commit and python3 scripts/prose_lint.py . --diff <commit>^1 --check <rule>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions