Skip to content

pr-pipeline: re-run the review lanes on lane-source-changed instead of labeling needs-human #10076

Open

Description

@kyle-sexton

Problem

When review evidence unbinds as lane-source-changed (plugins/source-control/skills/babysit-prs/scripts/babysit_review_evidence.py:202), pr-merge holds the pull request on its risk score and labels it needs-human. A person can do nothing about it except ask for the reviews again.

Examples (escalation text: evidence-unbound:claude-review: not bound: lane-source-changed; evidence-unbound:claude-security-review: not bound: lane-source-changed): #9890, #9831, #9821, #9806, #9800.

Owner decision (2026-10-25)

A stop is worth a person only for security, intent, or a real charge. Re-running a review is Claude usage, which the cost rule (#9904) allows.

Fix

On an evidence-unbound reason whose cause is lane-source-changed, pr-merge dispatches both review lanes on the current head (once per head) and judges again when they report, instead of labeling. The unbinding rule stays as is: it is the security control that stops a head from forging its own review.

Done when

  • An unbound-by-lane-source PR gets fresh reviews dispatched and no needs-human label.
  • A second unbind on the same head escalates as today (no loop).

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 25, 2026
  2. github-actions commented on Oct 25, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Medium
    Complexity: Medium
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Decision recorded. The owner answered in the Refinement session (2026-10-25), deciding the open items below on the facts:

    go with whatever the facts/data/metrics + /discovery:research says and ensure we're aligned with SOLID, DRY/SSOT principles

    I should only ever be in the loop ONLY when necessary (intent/vision changed, something came up during implementation that impacts trajectory/alignment, OR a high security risk) - I've covered this all before

    Question asked: Accept the body's Fix as the design, with the dispatch, placement and mixed-cause answers below?
    [quote truncated; the full decision is at the link]

    #10076 (comment)

    This decision settles the open questions: dispatch mechanism and once-per-head marker, where the change lives, mixed-cause handling, and the design itself. Nothing is left to ask.

    I understood the request as follows. When both review lanes unbind as lane-source-changed, pr-merge dispatches fresh reviews once per head instead of labeling needs-human. A second unbind on the same head escalates as today. The unbinding rule stays unchanged.

    Automated triage, applied by the lanes App.

  3. added
    priority: highSignificant impact, or blocks an imminent release; staff this cycle.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 25, 2026
  4. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    status: needs-decisionAwaiting a human or maintainer judgment call.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Oct 25, 2026
  5. melodic-automation-lanes commented on Oct 25, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane: no trusted-human acceptance criteria: a listed human must put the confirmed - [ ] criteria in the body or post them as their own comment, or, on an issue a listed human filed, intake's newest refinement comment must hold them unedited. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).

  6. melodic-automation-lanes commented on Oct 25, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: the issue is at status: ready.

  7. melodic-automation-lanes commented on Oct 25, 2026

    @melodic-automation-lanes
    Contributor

    Refinement. A read-only run explored this repository, searched its issues and pull requests, and read the allowed docs to draft what follows. On an issue a listed human filed, it counts as the issue's spec once posted, while unedited; it is still model text, so check it.

    Intended outcome: When a PR's review evidence is unbound as lane-source-changed, pr-merge dispatches both review lanes once on the current head, re-judges when they report, and escalates with needs-human only if the same head unbinds again.

    Related work

    Open questions

    1. Which mechanism dispatches the two review lanes and records the once-per-head marker (workflow_dispatch, a re-requested check, or a marker comment as in clear-escalations.mjs)?
      RECOMMENDED: Dispatch via workflow_dispatch from the pr-merge scripts and record a head-keyed HTML marker comment, like the needs-human-cleared marker, so a second unbind on the same head finds it and escalates. Basis: judgment; .github/scripts/pr-merge/clear-escalations.mjs:90
    2. Where should the change live: the Python risk gate (babysit_risk.py, which builds the evidence-unbound reason) or the pr-merge .mjs scripts that apply the needs-human label?
      RECOMMENDED: Keep babysit_risk.py and babysit_review_evidence.py unchanged, so the unbinding rule stays as is. Detect the lane-source-changed cause in the pr-merge label path and skip the label there. Basis: plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:956
    3. If only one lane is unbound as lane-source-changed and the other has a different unbind cause, should pr-merge still dispatch?
      RECOMMENDED: Dispatch both lanes only when every unbound reason is lane-source-changed. Any other cause escalates as today. Basis: judgment
    4. The issue is labeled status: needs-decision, and no Decision recorded comment exists. Has the owner settled the design, or only the intent?
      RECOMMENDED: Treat the 2026-10-25 owner decision in the body as settling intent only; the owner should confirm the dispatch mechanism and the one-retry rule. Basis: judgment

    Sources read

    • plugins/source-control/skills/babysit-prs/scripts/babysit_review_evidence.py:202: raises Unbound("lane-source-changed")
    • plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:956: builds the evidence-unbound:<lane> Reason at Risk.MED
    • plugins/source-control/skills/babysit-prs/scripts/babysit_risk.py:971: the same reason with the unbind cause appended
    • /.github/scripts/pr-merge/clear-escalations.mjs:90: head-keyed marker comment pattern for needs-human

    Automated refinement by the lanes App. Answer with a comment whose first line is **Decision recorded.**.

  8. kyle-sexton commented on Oct 26, 2026

    @kyle-sexton
    MemberAuthor

    Decision recorded. The owner answered in the Refinement session (2026-10-25), deciding the open items below on the facts:

    go with whatever the facts/data/metrics + /discovery:research says and ensure we're aligned with SOLID, DRY/SSOT principles

    I should only ever be in the loop ONLY when necessary (intent/vision changed, something came up during implementation that impacts trajectory/alignment, OR a high security risk) - I've covered this all before

    Question asked: Accept the body's Fix as the design, with the dispatch, placement and mixed-cause answers below?

    The body's owner decision (2026-10-25) settles the intent:

    Re-running a review is Claude usage, which the cost rule (#9904) allows.

    Open items come from intake's refinement: #10076 (comment)

    1. Which mechanism dispatches the two review lanes and records once-per-head? This is a trust-boundary call: it adds a new trigger for the review lanes.
      Decided: workflow_dispatch from pr-merge, which already holds actions: write, and a head-keyed HTML marker comment like the needs-human-cleared marker, so a second unbind on the same head finds it and escalates. Basis: origin/main .github/workflows/pr-merge.yml:134; .github/scripts/pr-merge/clear-escalations.mjs:90. Intake's answer kept.
    2. Where does the change live?
      Decided: Leave babysit_review_evidence.py and its unbind rule unchanged. Skip the label in pr-merge's risk escalation, babysit_merge.py, which writes the <!-- babysit-merge-risk --> comment and the human-gated label, when every reason is evidence-unbound with cause lane-source-changed. Basis: plugins/source-control/skills/babysit-prs/scripts/babysit_merge.py:87; babysit_risk.py:956,971; babysit_review_evidence.py:213. Intake's answer corrected: it put the label path in the pr-merge .mjs scripts, but babysit_merge.py applies it.
    3. If one lane is unbound as lane-source-changed and the other for another cause, does pr-merge still dispatch?
      Decided: Dispatch only when every unbound reason is lane-source-changed; any other cause escalates as today. Basis: judgment. Intake's answer kept.
    4. Has the owner settled the design, or only the intent?
      Decided: The body's Fix is the owner-filed design (dispatch both lanes on the current head once per head, judge again, keep the unbind rule). Items 1 to 3 are implementation within it. Basis: the issue body's Fix section. Intake's answer corrected: it asked the owner to confirm what the body already states.

    Acceptance criteria:

    • An unbound-by-lane-source PR gets fresh reviews dispatched and no needs-human label. (Converted from the body's Done when, wording unchanged.)
    • A second unbind on the same head escalates as today (no loop). (Converted from the body's Done when, wording unchanged.)
    • babysit_review_evidence.py's unbinding rule is unchanged.
    • A PR with any unbind cause other than lane-source-changed escalates as today, with a test case.
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

    priority: highSignificant impact, or blocks an imminent release; staff this cycle.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions