Skip to content

pr-pipeline: clear a feedback-not-landed escalation once the head moves and no lane thread is open #10074

Description

@kyle-sexton

Problem

clear-escalations.mjs clears a pr-unblock escalation once its reason no longer holds, but its CHECKS table (.github/scripts/pr-merge/clear-escalations.mjs:120-132) covers only workflow-staged, unresolved-conflict, protected-path-conflict and feedback-protected-path. A feedback-not-landed escalation stays labeled after the cause is gone.

Example: #9965 escalated feedback-not-landed at resume key e5183af3; the head moved to 898665b3 with no unresolved review thread left, and ci-status stayed red only on the needs-human label until a person removed it.

Owner decision (2026-10-25)

A stop is worth a person only for security, intent, or a real charge. feedback-not-landed is none of those once the head has moved.

Fix

Add a feedback-not-landed entry to CHECKS in clear-escalations.mjs: the reason no longer holds when the head differs from the escalation's resume key and no review thread the lane replied to is left unresolved. Reuse the existing clearing path; add no second mechanism.

Done when

  • clear-escalations.test.mjs covers: head moved and no open lane thread clears; head unchanged keeps; an open lane thread keeps.

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: Small
    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 three implementation answers below for the feedback-not-landed clear check?
    [quote truncated; the full decision is at the link]

    #10074 (comment)

    This decision settles the open questions: the resume key is passed into the check, lane threads are found by paging reviewThreads, and the rule that a person who spoke keeps the label stays. Nothing is left to ask. The work is a bounded change to the clear-escalations script plus its tests.

    Automated triage, applied by the lanes App.

  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    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: Add a feedback-not-landed entry to CHECKS in clear-escalations.mjs that clears when the PR head differs from the escalation's resume key and no review thread the lane replied to is unresolved, with three tests.

    Related work

    Open questions

    1. CHECKS functions get only github, repo, pull and mainSha, not the escalation's resume key. May verdict() pass the escalation's resume key into the CHECKS call?
      RECOMMENDED: Yes: parse the key from line 2 of each feedback-not-landed escalation with RESUME_KEY and pass it in; keep the label if any such key equals the current head. Basis: .github/scripts/pr-merge/clear-escalations.mjs:253 and .github/scripts/pr-unblock/gate-source.mjs:21,85
    2. How is a review thread the lane replied to identified? The script reads no review threads today and CHECKS has no GraphQL access.
      RECOMMENDED: Page reviewThreads over GraphQL and treat a thread as a lane thread when any comment is authored by the lanes bot login (pass bot into CHECKS); any unresolved one, or a truncated listing, keeps the label. Basis: .github/scripts/pr-unblock/address-feedback.mjs:596-616
    3. The module header says a person commenting or reviewing since the label keeps it. Does the owner decision override that for feedback-not-landed?
      RECOMMENDED: No: keep the existing person-spoke rule, so the new check only runs after it passes. Basis: .github/scripts/pr-merge/clear-escalations.mjs:24-27,226-229

    Sources read

    • .github/scripts/pr-merge/clear-escalations.mjs:119-138: CHECKS covers only workflow-staged, unresolved-conflict, protected-path-conflict, feedback-protected-path
    • .github/scripts/pr-merge/clear-escalations.mjs:208-211: a reason not in CHECKS keeps the label as a person's decision
    • .github/scripts/pr-unblock/report-escalation.sh:13: the resume key is the gated head SHA
    • .github/scripts/pr-unblock/publish-feedback.mjs:500,552,582: where feedback-not-landed is raised
    • .github/scripts/pr-merge/clear-escalations.test.mjs: existing test file

    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 three implementation answers below for the feedback-not-landed clear check?

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

    A stop is worth a person only for security, intent, or a real charge. feedback-not-landed is none of those once the head has moved.

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

    1. CHECKS functions get only github, repo, pull and mainSha, not the escalation's resume key. May verdict() pass the resume key in?
      Decided: Yes. Parse the key from each feedback-not-landed escalation's resume-key line and pass it in; keep the label if any key equals the current head. Basis: origin/main .github/scripts/pr-merge/clear-escalations.mjs:253 (the CHECKS call) and .github/scripts/pr-unblock/gate-source.mjs:21,82-86 (RESUME_KEY on line 2 of each escalation). Intake's answer kept.
    2. How is "a review thread the lane replied to" found? clear-escalations reads no review threads today.
      Decided: Page reviewThreads over GraphQL as address-feedback does, and count a thread as the lane's when any comment is by the lanes bot login. Any unresolved one, or a listing that may be cut short, keeps the label. Basis: .github/scripts/pr-unblock/address-feedback.mjs:614-622,737-742; clear-escalations.mjs:35-36 (a cut-short listing counts as the reason holding). Intake's answer kept.
    3. Does the owner decision override the rule that a person commenting or reviewing since the label keeps it?
      Decided: No. Keep the person-spoke rule; the new check runs only after it passes. A person speaking is an intent signal, which the owner decision still counts. Basis: clear-escalations.mjs:24-27,224-229. Intake's answer kept.

    Acceptance criteria:

    • clear-escalations.test.mjs covers: head moved and no open lane thread clears; head unchanged keeps; an open lane thread keeps. (Converted from the body's Done when, wording unchanged.)
    • clear-escalations.mjs has a feedback-not-landed entry in CHECKS and adds no second clearing mechanism.
    • A thread listing that may be cut short keeps the label, with a test case.
    • A person who commented or reviewed since the label went on still keeps it for feedback-not-landed, with a test case.
  9. added
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    on Oct 29, 2026
  10. added
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    and removed
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    on Oct 29, 2026
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

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.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 Bug.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions