Repository navigation
Closed
Copy link
Labels
priority: highSignificant impact, or blocks an imminent release; staff this cycle.Significant impact, or blocks an imminent release; staff this cycle.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.A maintainer confirmed the item is real and in scope; ready to be worked.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.Refactors, migrations, contract changes; cross-cutting and hard to reverse.
Description
Refs: #12284
Owner: Automation Lanes.
Summary
ci-status enforces holds in seven places. docs/contracts/loop-lane/README.md:460 calls do-not-merge "the only cross-lane hold". A sample of failed pr-require-checks runs from 2026-11-01 shows holds, not code, behind 17 of 24 red PR runs and 10 of 12 red merge groups. Source: audit comment, gates #6, #7, #8 and #17.
Holds against our own actors that do the same job as do-not-merge (all at cb8429f):
human-merge-hold:.github/workflows/pr-require-checks.yml:5686.- The lanes App body hold or member veto, read by the verdict reader inside ci-status:
:6247. This was 6 of 12 sampled red merge groups. The code comment at:4029-4051quotes about 860 calls and 6-11 min for a cold read in the queue. - The pr-unblock
failurecommit status::6186;docs/conventions/pr-pipeline/README.md:2863-2869. This was 6 of 24 sampled red PR runs. A cleared head waits for the half-hourly reconcile re-run. needs-humanused as a general park by pr-unblock escalation routes, outside cost and critical security.
Proposal:
- Each writer adds
do-not-merge, and ci-status reads that label alone for these cases. - Keep the person-only holds for critical security, cost and trust paths:
:5122,:5445for review-lane holds, and:5551.
Done when
-
human-merge-hold, the lanes App body or veto hold and the pr-unblock stop status each applydo-not-merge, and their separate ci-status steps are removed. - pr-unblock escalation routes other than CRITICAL security or cost stop adding
needs-human. - The review-lane critical-security and cost holds, and the trusted-person lift checks, are unchanged.
-
loop-lane/README.md:460andpr-pipeline/README.md"Review-lane holds" describe the result. - Red ci-status runs caused by holds are re-sampled and reported here.
Metadata
Metadata
Assignees
Labels
priority: highSignificant impact, or blocks an imminent release; staff this cycle.Significant impact, or blocks an imminent release; staff this cycle.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.A maintainer confirmed the item is real and in scope; ready to be worked.work-class: structuralRefactors, migrations, contract changes; cross-cutting and hard to reverse.Refactors, migrations, contract changes; cross-cutting and hard to reverse.
Type
Fields
Work status
ready
Activity
github-actions commentedon Nov 2, 2026
Proposed work class: work-class: structural
Basis: automated intake triage; the lanes App applied this class.
Size: Large
Complexity: High
Uncertainty: Knowable
Flags: none
Blocked by: none
Understood: make
do-not-mergethe single hold that ci-status reads for our own actors' holds (human-merge-hold, the lanes App body/veto hold, the pr-unblock failure status). Stop pr-unblock routes from parking onneeds-humanoutside cost and critical security. Keep the person-only security, cost and trust-path holds unchanged, update the two docs, and re-sample red runs.This touches several ci-status steps, the writers and docs, so it likely needs splitting. The last done-when item (re-sampling red runs over time) needs a later measurement.
Related, not a duplicate: #12449 (reading merge-queue holds once and dequeuing on a hold label). Parent audit: #12284.
Automated triage, applied by the lanes App.
melodic-automation-lanes commentedon Nov 2, 2026
Not admitted to the issue lane yet: Size large: the split into sub-issues at intake is pending (owner Q93).
melodic-automation-lanes commentedon Nov 2, 2026
Split at intake (owner Q93). This issue is Size Large, so its done-when is split into 4 sub-issues, each holding its task-list lines as written.
Automated split by the lanes App. Admission waits on this issue while a sub-issue is open; work-unblock closes it as completed once every sub-issue is closed as completed by a merge or a listed human and its done-when is covered.
kyle-sexton commentedon Nov 2, 2026
Status: one builder PR (Automation Lanes). Written by the issue-triage session.
A sub-issue exists here only when it ships as its own PR. So size-split parts 1, 3 and 4 are folded back into this issue and closed as carried:
Part 2, #12452, stays a sub-issue. It changes only
.github/scripts/pr-unblock/escalation-routes.json, ships and verifies on its own in the issue lane, and carries done-when line 2. It is narrowed to the own-actor routes: the intent and design question routes keepneeds-human.This issue is the PR unit for lines 1, 3 and 4, with line 5 after merge. Line 1 removes ci-status steps in
.github/workflows/pr-require-checks.yml(about:5677-5696,:6187,:6247), which the issue lane cannot push, so the Automation Lanes session builds it by hand. It moves tostatus: confirmed.#12449 (dequeue on a hold label) is now blocked by this issue, because both remove the same ci-status hold steps.
kyle-sexton commentedon Nov 2, 2026
Status: part 2 folded in too; builder notes. Written by the issue-triage session.
#12452 (part 2) is folded into this issue as well. Its criterion is done-when line 2, word for word. The issue-lane run on it (41504526015) stopped on design questions, and those questions sit inside this issue's one change, so the Automation Lanes builder settles them together:
do-not-mergein place ofneeds-human, with the reason marker in the same write.needs-humanstays on the intent and design question routes and on CRITICAL security or cost routes.feedback-dispatch.mjs:23anddispatch.mjs:75skip any PR carryingdo-not-merge. Aneeds-humanescalation, by contrast, lets address-feedback resume when a trusted person answers on the thread (gate-source.mjs;feedback-dispatch.mjs:33-35). The change must keep a resume path for the rerouted holds.feedback-round-cap,feedback-uncertainandfeedback-disputedin.github/scripts/pr-unblock/escalation-routes.jsoneach mix a CRITICAL or unrated security finding with other causes. Splitting them needs new reasons emitted byadjudicate-feedback.mjsandaddress-feedback.mjs, or a stated rule for which reasons count as security.docs/contracts/loop-lane/README.md:327(intent and design findings go to the human-gated label) stays as it is.kyle-sexton commentedon Nov 2, 2026
Owner decision (Q3): match each hold label to the PR's condition. Posted by the issue-triage session. The question was asked of the owner in that session on 2026-11-02, and the owner answered there.
Question (verbatim): "Q3 (revised): which label goes on routine stuck-agent PRs in #12446?" with recommendation (a): "match each label to its condition. Vetoes keep
do-not-merge. Lane stops and stuck review findings getneeds-session, which already exists.needs-humanstays only for intent, design, security and cost.human-merge-holdis removed."Owner's answer (verbatim): "Go with recommendations."
What this changes in this issue's direction, for the Automation Lanes builder:
do-not-merge, which the repo describes as "Hard merge gate: do not merge while applied."human-merge-holdis removed, not moved to another label. It is a person-approval hold against our own actors.needs-sessionon, notneeds-humanordo-not-merge. No hold label is needed to block the merge: the main-branch ruleset already setsrequired_review_thread_resolution: true, so an open thread blocks it.needs-sessiononly routes the PR to a session.needs-session, as it does today under the human-gated label (.github/scripts/pr-unblock/feedback-dispatch.mjs:33-35,gate-source.mjs).needs-humanstays for intent, design, CRITICAL security and cost findings only (docs/contracts/loop-lane/README.md:326-328).do-not-merge") and line 2 are read through this decision: the stop status and the escalation routes applyneeds-sessioninstead.kyle-sexton commentedon Nov 3, 2026
kyle-sexton commentedon Nov 3, 2026
Close-out check for #12446: three of the five items are met, so this stays open. Read at
origin/mainde80b21.Item 1: partial.
human-merge-holdis gone (only changelog mentions remain). The lanes App body hold appliesdo-not-merge(report-outcome.mjs:185,:2364). The pr-unblock stop status step is gone. A member's veto comment does not apply the label:merge-holds.mjs:1649says it "still holds, since nothing labels it". The step atpr-require-checks.yml:6140stays, because it also carries the kill switch, hold-path and verifier holds, and it still runs the verdict reader (:6428). Its name still says "its body or a member holds", and:6509still says "no body hold".pr-feedback-dispatch.ymlstill re-runs ci-status for a status it no longer reads (:575,:581).Item 2: met.
escalation-routes.json:19,21,29carryneeds-session. The nineholdroutes are security, intent, design and dependency (:32-37,:41,:42,:45). A session's answer restarting address-feedback underneeds-sessionwas not observed in a run.Item 3: met. The cost-hold, human-gated and hold-lift steps have identical non-comment bodies before #12522 and now (
pr-require-checks.yml:5169,:5492,:5598).Item 4: partial.
loop-lane/README.md:460-462and the pr-pipeline "Review-lane holds" section describe the result.loop-lane/README.md:470-471still says a comment is never a hold and no gate reads them, which contradicts:461-462.pr-pipeline/README.md:3952still says ci-status "enforces holds in seven places".Item 5: met by this comment.
Window: failed
pr-require-checksruns created after 2026-11-03T01:46:51Z, listed at 04:58:48Z (3 h 12 min). Every failed run was read: 55 pull_request (of 214) and 22 merge_group (of 78). Method as in the #12284 audit, reading failed steps andci-statusannotations. A run can count in more than one row, as in the audit. The audit covered a full day, this about 3 hours, and this window includes a lanes kill-switch stretch and an API rate-limit stretch.do-not-mergeneeds-humando-not-merge:6140step: body hold or veto by cause:6140step: verdict reader, no artifact listing:6140step: verdict reader refusal:6140step: lanes kill switchpr-verify-failed, label after enqueuepr-verify-failed, label on before enqueueThe holds this issue removed caused no red run in this window: 0 pr-unblock status, 0
human-merge-hold, 0 body hold, 0 veto. On pull requests, holds fell from 71% to 25% of red runs, and all 14 are the intendeddo-not-mergelabel.Merge groups did not improve. By the audit's step classification, every one of the 22 red groups failed in a hold step, against 10 of 12. The red rate was 22 of 78 (28%), against 24 of 363 (6.6%) on 2026-11-01, from 7 PRs. The audit's "body hold or member veto" row was counted by step: its two example runs (41348597754, 41324239904) are verdict-reader refusals, so removing body-hold reading could not lower it.
Separate from this issue: 11 groups fail at
pr-require-checks.yml:6444with "the verdict reader read no artifact listing" (first: 41573330717). The first was 18 minutes after #12558 turned on FAIL index mode. #12717 is open for it.Agent choice on the veto, not an owner answer. A member's veto comment stays read in the merge-holds step and adds no labeling write. Basis: 0 of 22 red groups came from a veto; a member can already apply
do-not-mergedirectly, and #12522's body records the comment read as how it built to Q3; a lanes App write on each veto comment would add a mechanism with no measured need. This reads done-when 1 through the owner's Q3 answer, as #12522 did.What remains: rename the
:6140step and its verdict text, drop thererun-ci-statusre-run for pr-unblock statuses, and fixloop-lane/README.md:470-471andpr-pipeline/README.md:3952. This session is taking that.docs(pr-pipeline): correct the stale hold text and audit citations
kyle-sexton commentedon Nov 3, 2026
Re-sample, window A (2026-11-03 01:46:51Z to 08:51Z): holds behind 4 of 25 red PR runs and 11 of 12 red merge groups, vs 17 of 24 and 10 of 12 on 2026-11-01.
This extends the close-out comment, which read every failed run from 01:46:51Z to 04:58:48Z. This one is a seeded sample over the whole window. It runs past #12717 (06:53Z), and it separates the review-lane outage.
What ran
pr-require-checksruns, with each cause read from the failing job, its step and its failure annotation text.12446. The draw israndom.Random(12446).sampleover each window's failed runs, sorted by id.failure, bycreated_at:pull_request(25 sampled) and 30merge_group(12 sampled).pull_request(10 sampled) and 1merge_group(1 sampled). The B pull_request sample was drawn from the 46 runs known at draw time. 41638442524 was still in progress in the cache and failed later.actions/runs/{id}/attempts/{n}/jobsandcheck-runs/{id}/annotations..work/coordinator/resample-12446-runs.json(local).Why ci-status is red
In this comment, "hold" means a hold label, a hold status, or the lanes App hold step. Review lanes not yet complete are reported but not counted as a hold. The baseline's rows sum to more than its run count, so which rows made up its 17 holds is UNVERIFIED. Its
do-not-merge, pr-unblock andneeds-humanrows add up to exactly 17.do-not-mergelabelfailurestatus on the headneeds-humanlabelpr-verify-failedlabel or a pr-verify reader refusal (baseline: hold label added after enqueue)failure-class=partial(new)failure-class=timeout(new; review-lane outage)Notes:
pr-verify-failedis a separate label fromdo-not-merge. It caused 5 of the 12 sampled window-A merge-group failures.failure-class=timeoutwas created at 08:19:01Z (41602368018). Every review failure from then until 09:30Z is that class.fallback=credit-stop. Linking these timeouts to the credit stop is UNVERIFIED. Either way, none of them is a hold.What changed on main since the baseline
These are the hold-step changes in
pr-require-checks.ymlfromgit log --since=2026-11-01 -- .github/workflows/pr-require-checks.yml:human-merge-holdand pr-unblock status steps.do-not-merge. A member's veto is still read from the comment.needs-humantoneeds-session.needs-humanand body-hold rows are 0.Done-when item 5 (red ci-status runs caused by holds are re-sampled and reported here) is met. The close-out comment first met it for 01:46Z to 04:58Z, and this comment confirms it over the full window A:
do-not-merge.pr-verify-failedqueue hold and a reader defect that is already fixed.