Repository navigation
fix(pr-unblock): route a lane-answered open thread to the session queue - #11796
Conversation
A thread address-feedback answered UNCERTAIN, VALID-defer or INCORRECT stays open; the next round drops it and escalates feedback-untaken-threads, a failing status with no queue label, so the PR waits on the owner. feedback-untaken-threads and feedback-unadjudicated now add needs-session, and the select job skips awaiting-session instead of escalating again while this head's address-feedback stop already sits in that queue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ain-needs-session
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed Security review: no security issues foundI read every hunk of all 10 changed files. Two of them are on trusted paths: Merge holds: this change does not weaken any
Can the skip be triggered by spoofing?No.
A comment from an outsider can't satisfy the author check. Adding labels requires triage access or higher. Even a forged match would only stop the lane from escalating again; the failing status from the earlier stop would still hold the merge. Other checks
critical-findings: 0 |
|
claude-review reviewed Code review: no findingsThe PR adds What I checked against the surrounding code (read only; I could not run anything):
Unverified: I did not run the test results in the PR description (879 pass / 1 fail, 916 ok, and so on). They are the author's claims. The one failing test the author reports ( Other checks:
|
No related issue: lane defect measured in a census of 1528 PRs (2026-10-25..11-01)
Summary
When address-feedback answers a review thread
UNCERTAIN,VALID-deferorINCORRECTandleaves it open, the next round drops that thread (
threadAuthors: the lane's own reply is thelast comment) and keeps none.
selectthen escalatesfeedback-untaken-threads. That reason, andfeedback-unadjudicated, routedfailwith no label, so the stop landed in no queue and the PRwaited until the owner answered by hand.
Census (1528/1528 PRs updated 2026-10-25..11-01): 11 PRs carried 19
feedback-untaken-threadsstatuses caused by an
UNCERTAIN-last thread (#10583, #10802, #10868, #10900, #11072, #11457,#11519, #11520, #11697, #11733, #11752). Across the window, 25 of 45 current-form
UNCERTAINthreads got an owner reply after the lane's. The count is a lower bound: a commit keeps only the
newest status per context.
Fix
escalation-routes.json:feedback-untaken-threadsandfeedback-unadjudicatednow name"label": "needs-session", likefeedback-protected-pathandci-fix-escalated. Eachwhysays a session builder takes it.
report-escalation.shalready adds that label before thelane-stopped comment, and
clear-escalations.mjsalready lifts it (SESSION_LABELSis derivedfrom the table).
address-feedback.mjsselect: an unresolved thread the lane does not take skips the newawaiting-sessionreason instead of escalating again, whensessionQueuedholds. That needsthe PR to carry the label and the lanes App's address-feedback lane-stopped comment to name
this head with a reason routed to that label. The check reads
pull.labelsandissueComments, whichselectalready fetches, so it adds no API call.gated(awaiting-human) and owner-PR (not-applicable) branches, and onlywhen a thread is untaken. A head with no unresolved thread still skips
stop-resolvedwithresolved: true, so a session that resolves the thread clears the failing status.needs-sessionadded by anotheractivity (for example
ci-fix-escalated) does not silence this stop. On a new head (nostatus there, so
clear-escalationsmay lift the label), the lane escalates again andre-queues the PR.
pr-pipeline.schema.json$defs/skip-reasonaddsawaiting-session, sincedecide.mjsposts only enum members. The README's "Outputs and skips" section describes it.
docs/conventions/pr-pipeline/README.md#activities, theneeds-sessionline indocs/contracts/loop-lane/README.md,pr-run-activity.md, and achangelog fragment.
Verification
address-feedback.mjsandescalation-routes.jsonand ran the new tests against them. The route test failed (
actual: ['fail', undefined],expected
['fail', 'needs-session']). The stand-down test failed (actual: ['escalate', undefined, 'feedback-untaken-threads', undefined], expected['skip', 'awaiting-session', ...]).address-feedback.test.mjs:the lanes App, a stop reason that names no queue label, and another activity's queued stop.
stop-resolvedwithresolved: true.needs-humanstill wins (awaiting-human).report-check-run.test.mjspostsawaiting-sessionas neutral underthe schema's enum.
report-escalation.test.shnow has both reasons in its exactSESSION_REASONSset.node --testruns:clear-escalations, clear-escalations-stale-hold, report-check-run, decide and
maintenance-monitor-signals collect: 879 pass, 1 fail at first. The failure was
feedback-dispatch's
ownerAdoption reads the base adoption section, caused by a missingnpm ciin.github/actions/resolve-config/(ajvnot found), not by main. At heada6d2263 with dependencies installed: feedback-dispatch and address-feedback 373 pass,
0 fail; origin/main passes the same file 191/191.
bash report-escalation.test.sh: 916 ok, exit 0.scripts/check-affected.sh --tests: 12 passed, 4 skipped. It left the 77 selected suitesto CI.
label,needs-session(
.github/scripts/pr-unblock/report-escalation.sh:286-287). The human-gated label goes ononly in the hold branch (
report-escalation.sh:325-326), and neither reason routeshold(
escalation-routes.json:18,:23).(
report-escalation.sh:269-283).address-feedback.mjs:1064-1065) and writes nolabel or comment.
report-escalation.shandclear-escalations.mjsread the route and label from it, and the morning brief counts queuelabels and
work-items:escalationmarkers, not lane-stopped reasons. So the label makesthese session-builder stops everywhere they are read.
Related
awaiting-sessionleaves the monitoring lane'sstalled lane stopsignal unchanged(
maintenance-monitor-signals/collect.mjs): aSkipped:check is not an attempt, so aqueued stop older than two hours is still listed, as
feedback-untaken-threadswas before.plugins/source-control/skills/**is unchanged.🤖 Generated with Claude Code