Repository navigation
fix(pr-merge): clear a native gate's needs-human label once its cause is gone - #10198
Conversation
… is gone Under merge.lane-prs native, enable-auto-merge writes every lanes App PR's pr-merge needs-human label, and its holdReason then keeps the PR from being judged again, so the label stayed until a person removed it (#10090). clear-escalations now judges enable-auto-merge's own person refusal comment (refusalBody, byte for byte) again at the current head with the gate's reader, and removes the label as refusal-cleared only when nothing refuses or what refuses is a lane's (verifyClears lane). A person's refusal, a risk hold (security finding, trust gate, cost), an unread answer, a failed read, and a hold-path or cost-path refusal keep it. Labels a person set and other lanes' escalations are untouched, as before. At most three reads a run; the step gets the reader's Actions token and a 15-minute timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8107219b59
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8107219b59
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…lations # Conflicts: # .github/scripts/pr-merge/clear-escalations.mjs
…ep a hidden cause clear-escalations no longer clears a risk or issue-link label on a reader answer that refuses for another reason (a verdict refusal hides the risk score), and never clears a verifier label on an unreadable or missing verdict or an unreadable risk score. It re-judges enable-auto-merge's refusal only under merge.lane-prs native, only at the head the comment names (a moved head takes main's head-moved path), and not when the comment was edited. The sweep starts at an offset that moves with the run number, so labels past the three-read cap are read on a later run, and the clear step shares the gate step's run cache, listing and head-ref map. enable-auto-merge exports READER_HOLDS, the reason prefixes verifyHold writes, and tells a person that pr-merge takes a reader refusal's label off itself; a comment in the earlier wording still stands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
claude-security-review reviewed Incremental security review of the five files changed since 6433994. I found no security issues. critical-findings: 0 What I checked:
No manifest files changed. No instruction-surface deletions apply: the removed text is a code comment and a wording variant, and the narrowing code still enforces the rule. Spend: the clear step's timeout goes from 3 to 15 minutes and the merge job's from 30 to 45 minutes. This uses only subscription or prepaid runner time, so it is not a hold. |
|
claude-security-review holds this pull request for a person (critical-security) at clear-escalations.mjs (with the pr-merge.yml step that runs it) now removes the human-gated needs-human label on its own, from the gate reader's output. That narrows a merge hold, which this lane treats as CRITICAL. A person should confirm the narrowing is intended. claude-lane: claude-security-review |
|
claude-review reviewed Incremental review of the changes since 6433994. I found nothing to flag. I read the code and did not run the test suite. What changed. Under Checked, no issue:
Note, not counted as a finding. A person-class refusal whose cause goes away at the same head, for example an issue link added to the PR body, now needs a person to remove the label by hand. The PR states this as owner decision Q-CLEAR B. Spend. The change does not add a paid charge or any lane spend. The escalation clear step's timeout rises from 3 to 15 minutes, at most three reader runs per run, within existing Actions usage. |
…ue link The reader answers an ineligible link early, with verify:ineligible and no verdict, so a lane-class link answer no longer lifts a verifier label. The reader-refusal wording now says the same-head clear happens only under merge.lane-prs native, since enable-auto-merge also runs under gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A lane-class reader answer can hide a cause a person must clear: an unbound security review never reads its findings, a partial file listing never checks cost, trust or high paths, and a verdict that is not a pass never checks the spec's trust. A label whose recorded reason carries a PERSON_RISK code or a PERSON_REFUSALS verdict now comes off only when the reader refuses nothing; the lane-answer relaxation stays for recorded causes the lanes clear, such as #10090's evidence-unbound label. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
claude-security-review holds this pull request for a person (critical-security) at Trust-control change: clear-escalations.mjs (with enable-auto-merge.mjs and the pr-merge.yml clear step) now lets the pr-merge job remove a person-class needs-human label (security-finding, trust-gate, cost-review-required, high-path:**, verify:untrusted-spec, verify:repeated-fail) on its own, after one same-head reader read with no refusal. The next enable-auto-merge run can then arm auto-merge with no person having cleared the cause. This narrows a merge hold, so the review lane treats it as CRITICAL. claude-lane: claude-security-review |
…icit lane list clear-escalations now treats a recorded refusal as a lane's only when every "; "-separated risk code, or the verdict, is on LANE_CAUSES: the holding lane codes babysit_risk.py emits (files-incomplete, evidence-unbound:<lane>, the manifest review), the reader's unread score, and every verifier refusal but untrusted-spec and repeated-fail. Any other code, an unknown one or a configured high path included, and every issue link, comes off only when the reader refuses nothing. The check no longer reads enable-auto-merge's PERSON_RISK or PERSON_REFUSALS, so it fails closed whatever those lists become. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lations # Conflicts: # .github/workflows/pr-merge.yml
|
claude-security-review holds this pull request for a person (critical-security) at Trust-control change: claude-lane: claude-security-review |
… recorded one A label now lifts on a refusing answer only when every code recorded and every code refusing now is on LANE_CAUSES for its kind, and the reader got at least as far as the recorded cause (link, then verdict, then risk). The list is per kind with no branches: issue links have none, verdicts are FAIL, EARLIER_FAIL and SPEC_CHANGED (too-old recurs at the same head, ineligible always comes with a link answer, missing and unreadable are no answer), and risk codes are files-incomplete, evidence-unbound:<lane> and the manifest review. The reader's own unread link or score is no longer a lane cause, and a current high-path or other person code keeps a recorded lane label. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The merge job's 30-minute ceiling covered the gate's sweep alone; the escalation clear now takes up to 15 minutes for its three reader runs, so a long sweep followed by slow reads could hit the job timeout and cancel the closing steps. The ceiling is 45 and a workflow test checks it covers the gate's sizing plus the clear step's timeout. The clear-escalations test for kept answers now also asserts exit 0, so a null reader answer is kept as a verdict rather than caught as a per-PR error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Decision (owner, 2026-10-26): Q-CLEAR option B (strict). clear-escalations removes only lane-class needs-human labels on its own. A label whose recorded cause is person-class (security finding, trust gate, cost review, high-path, untrusted spec, repeated fail, too-old, files-capped) stays until a person removes it, so no HIGH/CRITICAL hold is narrowed. The change to B lands on this PR next; the security lane's two open CRITICAL threads are answered against it. |
Owner decision Q-CLEAR B: clear-escalations re-judges enable-auto-merge's
refusal at the same head only when the recorded cause is lane-class (every
code on LANE_CAUSES). A person-class recorded cause (issue link, security
finding, trust gate, cost, high path, untrusted spec, repeated fail, unknown
codes) is not read and not lifted, even when the reader finds nothing
refusing; a person removes the label, or head-moved clears it on a push.
enable-auto-merge's person refusal wording goes back to main's ("fix the
reason, then remove the label"): every label it sets is person-class, so the
same-head auto-removal promise no longer holds for any of them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No related issue: needs-human audit row P7 (owner rule 2026-10-26)
Head:
ecf1fda804. Owner Q-CLEAR B (strict, 2026-10-26).Summary
This repository runs
merge.lane-prs: native(docs/conventions/pr-pipeline.yaml). Under native, every pr-mergeneeds-humanlabel on a lanes App pull request comes fromenable-auto-merge.mjs(note(), throughverifyClearsandrefusalWrites). #9826 clears such a label once thehead moves (
head-moved). A label set before its cause became a lane's (for example theevidence-unboundrisk hold on#10090) stayed until a person removed it, even
though the lanes now clear that cause.
Fix
clear-escalations.mjsre-judges enable-auto-merge's own person refusal comment at the head it was raised at, but onlywhen all of these hold:
LANE_PRSisnativeand the PR is the lanes App's.refusalBody(true, …).;-separated code is onLANE_CAUSESfor its kind (owner Q-CLEAR B).Then the gate's reader runs (
pythonVerify, the sameevidencecall enable-auto-merge makes, rung cap passed as C3),and the label comes off as
refusal-clearedwhen nothing refuses, or when what refuses now is lane-class too and thereader got at least as far as the recorded cause (link, then verdict, then risk score).
Owner Q-CLEAR B: a person-class recorded cause is never read and never lifted at its head, even when the reader would
find nothing refusing. That covers an issue link (every one),
security-finding,trust-gate:*,cost-review-required,high-path:*,verify:untrusted-spec,verify:repeated-fail,verify:too-old,verify:ineligible, and any unknowncode. A person removes the label, or main's
head-movedclear does once the head moves (enable-auto-merge labels the newhead again if the cause still holds). Because person-class labels no longer depend on the reader's answer, they do not
depend on the fixed C3 rung or the
demoted=Falseread either.LANE_CAUSESis an explicit per-kind list, so it fails closed.babysit_risk.PERSON_CODES(#10249) is to become itssingle source.
verify:fail,verify:earlier-fail,verify:spec-changed, which a push clears.files-incomplete,evidence-unbound:<lane>,manifest-review-required. Codes match whole; onlyevidence-unbound:is a prefix.Reads are capped at
NATIVE_READS_PER_RUN(3) a run, starting atrotated(held, GITHUB_RUN_NUMBER), so labels past thecap are read on a later run. In
pr-merge.ymlthe clear step has a 15-minute timeout and gets the reader's Actions tokenplus the gate step's
BABYSIT_VERIFY_LISTING,BABYSIT_VERIFY_HEAD_REFSandBABYSIT_RUN_CACHE. The merge job'sceiling rises from 30 to 45 minutes to fit the clear's three reads of up to four minutes each beside the gate's budget
(
workflow.test.mjschecks it).In
enable-auto-merge.mjs,READER_HOLDSexports the reason prefixesverifyHoldwrites. The person refusal wordingstays main's ("fix the reason, then remove the label"): every label enable-auto-merge sets is person-class
(
verifyClears), so the same-head auto-removal wording an earlier round of this PR added is reverted.Changelog:
.changes/pr-pipeline/fix-clear-native-escalations-6e1b4a92.md. README: arefusal-clearedrow in theescalation-clear table.
Verification
At
ecf1fda804, withorigin/mainmerged at14fd4e5aa9(no rebase):a person-class label is never removed at its head, even when nothing refusesfails on the previous head'ssource (
6433994e), which read and lifted a person-class label when nothing refused.a lane-class label comes off at its head once nothing refusesanda lane-class label stays when the reader's answer no longer shows its causecover the lane side.node --test .github/scripts/pr-merge/*.test.mjs: 434 passed, 0 failed.actionlint .github/workflows/pr-merge.yml: clean.scripts/check-affected.sh --tests: 10 passed, 4 skipped.Related
evidence-unboundrisk label comesoff once a whole read names only lane causes.
refusal at an old head, person-class included.
🤖 Generated with Claude Code