Repository navigation
pr-pipeline: review-lane hold follow-ups from the #9361 security review #9369
Copy link
Copy link
Open
Labels
priority: mediumReal value, no hard deadline; normal backlog flow.Real value, no hard deadline; normal backlog flow.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.status: readyTriaged, unblocked, and fully specified; eligible to pick up.Triaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.A briefed fix or small feature; blast radius bounded by the brief, tests exist.
Description
Refs: #9276
Follow-ups from the security review of #9361 (review-lane holds in ci-status). Each was rated MEDIUM or LOW and left out of that PR on purpose.
Medium
- Review runs are matched to a PR by head SHA only. ci-status's "Require both review lanes on this head" step, and
pr-feedback-dispatch.yml'srerun-ci-status, take the newestpull_requestrun of each caller on the head SHA. A second PR on the same SHA, with a different base, has its own review, and that review can count for this PR. Fix: give both callers arun-namecarrying the PR number, and filter ondisplay_title. Alternatively, also require this PR's ownclaude-lane-review-completemarker for the head. - The kill switch's pass can fail open and outlive the switch. A lane passes when its
Report the kill switchstep ran, and that step also runs whencheck-kill-switchfails closed on an unreadable variable. A head that passed while the switch was on stays green after it clears.pr-merge.ymldoes not readCLAUDE_REVIEW_DISABLED, so a review-only stop leaves agent PRs merging with no AI review. OD-8 chose no merge freeze. Options: pass a stopped lane only on PRs a trusted person authored, or make pr-merge refuse lane merges while a review switch is on, and re-run ci-status on open heads when the switch clears. - The gate runs from the PR's own copy of
pr-require-checks.yml.hold-pathsdoes not list the gate's own files:pr-require-checks.yml, both review callers,pr-feedback-dispatch.ymlandpr-merge.yml.- The merge-group run re-checks labels only, not the review-lane requirement or who lifted a hold.
- Options: add the workflow files to
hold-paths(owner decision Q48 set the current list), and move the lift and review checks into default-branch code, such as the pr-merge prefilter or aworkflow_runjob posting a status.
Low
- An exempt author's PR skips the review wait after a pushed fix. fix-ci can push to a release-App PR, which is exempt from the review requirement by author id. Agent-written commits can then merge before their review finishes. Fix: exempt only when every commit is the exempt App's own, or keep exempt-author PRs out of fix-ci.
- The hold label name can diverge. ci-status reads the human-gated label from the base
.work-item-tracker.json, while both callers hardcodehold-label: needs-human. Renaming the tracker label would let review holds stop holding. Fix: fail ci-status on the literalneeds-humanas well, or feed the callers the tracker value. - The rerun listener is unproven live.
rerun-ci-statusruns from main, so feat(pr-pipeline): turn on review-lane holds and require both review lanes in ci-status #9361's own CI could not exercise it. Confirm it on the first PR after merge.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
priority: mediumReal value, no hard deadline; normal backlog flow.Real value, no hard deadline; normal backlog flow.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.status: readyTriaged, unblocked, and fully specified; eligible to pick up.Triaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.A briefed fix or small feature; blast radius bounded by the brief, tests exist.
Type
Fields
No fields configured for Task.
Activity
github-actions commentedon Oct 23, 2026
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
#9369 (comment)
The decision settles every open question: per-PR run-name matching (item 1), kill-switch pass only when read as on and a trusted person authored the PR (2), no change to hold-paths (3), exemption only when all commits are exempt (4), and a literal needs-human check (5). Item 6 is confirmed later from run history; an unattended run can't do that, so the other items are triaged as usual. No duplicates found.
Automated triage, applied by the lanes App.
kyle-sexton commentedon Oct 26, 2026
Decision recorded. The owner answered in the Refinement and Issue Triage sessions (2026-10-25), deciding the open items below on the facts:
No owner ledger (
.work/*/interview-checklist.md,.work/gh-monitor-owner-decisions/) names this issue. No ledger entry for OD-8 or for a Q48 abouthold-pathswas found; the Q48 rows in.work/*/interview-checklist.mdare on other subjects. Every item below tightens a gate or leaves it as is; none widens one. The review rated each MEDIUM or LOW.Decided: Give both review callers a
run-namecarrying the PR number, and have both readers keep only runs whosedisplay_titlenames this PR. Both readers still pick byhead_shaalone: ci-status (.github/workflows/pr-require-checks.yml:4217,:4297-4299) andrerun-ci-status(.github/workflows/pr-feedback-dispatch.yml:335,:472-481). The pr-unblock dispatchers already match runs bydisplay_title(.github/scripts/pr-unblock/fix-docs-dispatch.mjs:210), so this reuses that pattern.Decided: A lane stopped by a kill switch passes only on a PR a trusted person authored, and only when the switch was read as on, not when
check-kill-switchfailed closed on an unreadable variable. Today a stop counts on the report step's notice (pr-require-checks.yml:4212-4213), and the report step runs wheneverproceedis not true (.github/workflows/pr-review-hosted.yml:125,:151-157). Of the body's two options this is the narrower one: pr-merge is unchanged and a person's PRs still merge; only agent-authored PRs wait for a review, which is the gap the body names ("a review-only stop leaves agent PRs merging with no AI review"). The pr-merge-refuses option also stops merges of PRs a person wrote, so it is not taken. OD-8's own text was not found in this repository or.work/; the body reports it chose no merge freeze, and neither part of this decision freezes pr-merge.Decided: No change.
hold-paths"never holds by itself" (pr-review-hosted.yml:197); adding files to it only adds review scrutiny. A rewritten gate reaches a merge only through a PR pr-merge lists, which is a lanes App, trusted-actor or Dependabot PR (.github/workflows/pr-merge.yml:620-627), and a lane patch cannot touch.github/workflows/**: every patch row refusesgithub-workflows(.github/actions/resolve-config/patch-rules.json:3,:14,:24,:35,:54,:64).Decided: ci-status exempts a PR from the review requirement by author only when every commit on it is authored by an exempt account. Today the check reads only the PR author's id (
pr-require-checks.yml:4230,:4248). This keeps fix-ci working on those PRs and makes the review wait once an agent commit lands. The review lanes do run after such a push: they skip a[bot]sender only when its id is not inallowed-bot-sender-ids, which holds the lanes App (pr-review-hosted.yml:16-18,:183), so the wait ends.Decided: ci-status also fails on the literal
needs-humanlabel, besides the tracker's human-gated label. The callers hardcodehold-label: needs-human(pr-review-hosted.yml:199), and ci-status reads the tracker value (pr-require-checks.yml:4023-4034). A workflowwith:cannot read the tracker file, so the literal check is the smaller change.Decided: Check it from run history, as a criterion below. Basis: the body says
rerun-ci-statusruns from main, so the PR that added it could not exercise it.Build: host session (every item but 6 edits
.github/workflows/**, which lane patches refuse,.github/actions/resolve-config/patch-rules.json:64).Acceptance criteria:
run-namewith the PR number, and ci-status's review-lane step andrerun-ci-statuscount only runs whosedisplay_titlenames this PR; a test shows a second PR's review on the same head SHA is not counted.needs-humanlabel even when the tracker names a different human-gated label; a test covers it.pr-feedback-dispatch.ymlrun whosererun-ci-statusjob re-ran ci-status on a PR after a review run completed.Builder: the Automation Lanes session builds this from the owner's machine, because the fix edits
.github/workflows, which the lanes App cannot push.agent-readystays off so the issue lane does not race the build.kyle-sexton commentedon Oct 26, 2026
Released for re-triage under the owner's 2026-10-26 rule: a person is involved only for "1. A change in original intent/vision 2. Something comes up during implementation ... that alters intent/vision or the primary design 3. If there is a HIGH/CRITICAL security issue". None applies here, so the hold label came off and intake triage runs again now.
To hold this issue again, add
needs-human(orstatus: needs-decision) and name which of the three applies.melodic-automation-lanes commentedon Oct 26, 2026
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: Tighten the review-lane gate so reviews are matched per PR, kill-switch stops and author exemptions pass only on safe cases, and the needs-human label always holds, per the owner's recorded decision on items 1, 2, 4 and 5.
Acceptance criteria
Dependencies
Related work
Sources read
Automated refinement by the lanes App. Intake triages the issue again with it.