Skip to content

The Merge Gate Has No Answer for a Reviewer That Declined to Review #1298

Open

Description

@ptr727

Filed from ptr727/HomeAutomation-Config, where several pull requests merged with a documented coverage gap on their final head. Each decision was defensible and stated at the time rather than glossed over, but the judgement was re-derived per pull request because nothing says what the gate requires when a reviewer is absent. Tracked downstream as ptr727/HomeAutomation-Config#156.

What the gate does and does not cover

GOVERNANCE.md "PR Review Etiquette" and its Merge Gate answer what to do with a finding. They do not answer what to do with a reviewer that produced none because it declined to run.

Two distinct shapes appeared in one session:

A quota skip that reports success. Once a plan's hourly review allowance is exhausted, the reviewer's status check reports success with a description saying it is rate limited. That is a genuinely fresh check run explicitly declining to review, and it is trivially misread as a pass. scripts/pr_review.py already surfaces it correctly, which is the only reason it was caught: the check row says pass while review_on_head says no.

A reviewer that simply stops. A second reviewer, on a trial nearing expiry, reviewed one head and never re-reviewed across four subsequent pushes. It also re-reported a finding from its first round that had since been fixed, measured against a title it had not re-read. Silence and satisfaction are indistinguishable without checking which head was covered.

Why this needs a rule rather than judgement

The quota is exhausted precisely when several pull requests are driven concurrently, which is exactly when the operator is least able to give each merge individual thought. Four concurrent pull requests reliably exhausted a ten-per-hour allowance within the hour.

The tooling is not the gap. review_on_head, coverage, and the surfaced rate-limit description already separate "reviewed this head" from "reviewed something earlier" from "declined". What is missing is what the gate does with each answer.

What to decide

  • Whether a single reviewer covering the head at full coverage satisfies the gate when a second is rate limited, and whether that depends on what the unreviewed delta contains. In practice the defensible cases were those where the delta after the last real review was prose, or was itself the fix for a finding that reviewer had raised.
  • Whether concurrency should be bounded by the review budget rather than only by file ownership. This is an orchestration rule as much as a review rule, and it belongs alongside the delegation guidance.
  • How a reviewer's permanent departure is recorded, so its later absence is not read as approval by a session that never saw it working.

A separate, concrete tooling bug found alongside

scripts/pr_review.py --match fails to select a thread whose body contains typographic quotes, which one reviewer uses routinely in its finding titles. The workaround is to pick an ASCII-only substring, but the failure mode is a NO_MATCH that reads identically to "the thread is already resolved", which the helper's own message acknowledges. Filed separately.

Activity

  1. added
    decisionA question waiting on the maintainer, alone or beside whatever else the issue carries
    on Sep 5, 2026
  2. ptr727 commented on Sep 7, 2026

    @ptr727
    OwnerAuthor

    Maintainer decision, 2026-09-07: a single reviewer covering the head at full coverage satisfies the
    Merge Gate, with the unreviewed delta constrained.

    The gate passes where one reviewer reports full coverage of the current head and the delta since the
    last real review is either prose, or is itself the fix for a finding that reviewer raised. Anything
    else in the delta still owes a covering review. This writes down what was already being judged
    defensible case by case, so it stops being re-derived per pull request.

    Not decided here, and still open on this issue: whether concurrency should additionally be bounded by
    the review budget rather than only by file ownership, and how a reviewer's permanent departure is
    recorded so its later silence is not read as approval. Those are separable and neither blocks
    implementing the rule above.

  3. ptr727 commented on Sep 18, 2026

    @ptr727
    OwnerAuthor

    Decision (ptr727, 2026-09-18): one reviewer covering the head at full coverage satisfies the Merge Gate, provided the delta since the last real review is prose or is itself the fix for a finding that reviewer raised.

    That is the condition the defensible cases actually met, so the rule is written from what was done rather than invented over it. A delta carrying anything else, new code, a new workflow condition, a changed contract, does not qualify, and the gate is unmet until a reviewer covers it.

    What this leaves for whoever writes it up:

    • The rule belongs in GOVERNANCE.md "PR Review Etiquette" beside the Merge Gate, since it is a gate item rather than a finding disposition, and pr-review-conduct packages it.
    • scripts/pr_review.py already separates "reviewed this head", "reviewed something earlier" and "declined", so the tooling needs nothing new to state the condition. What it may need is to say which of the two qualifying shapes a delta is, since that is the part a session has to judge.
    • A quota skip reporting a success status check is the trap worth naming explicitly in the text: the check row says pass while review_on_head says no, and only the second is the answer.

    The other two questions this issue raised are not settled by the above and stay open on it: whether concurrency should be bounded by the review budget as well as by file ownership, and how a reviewer's permanent departure gets recorded so its later silence is not read as approval.

  4. removed
    decisionA question waiting on the maintainer, alone or beside whatever else the issue carries
    on Sep 18, 2026
  5. ptr727 commented on Nov 1, 2026

    @ptr727
    OwnerAuthor

    Decision triage split the undecided item out of this issue into #3741, which carries the decision label. Everything else here stays as ordinary work an agent can do without the maintainer.

  6. ptr727 commented on Nov 1, 2026

    @ptr727
    OwnerAuthor

    Maintainer answer to the split decision #3741 (decision triage, 2026-11-01): Option 1: no budget-derived limit. Keep the file-ownership grouping and the four-worker cap, and stop on an exhausted allowance as the skill already does.

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