Repository navigation
perf(pr-pipeline): record main-review stops and cut merge-job lane reads - #11084
Conversation
pr-review-main now records a designed stop (binary, too-large, long-line) as a neutral `verdict=none reason=<reason>` check run instead of failing the run. The binder reads it as no CRITICAL and no binding, naming the lane's unbound reason `main-review-stop:<reason>` inside the existing MED evidence-unbound cause. No person hold is added. For a lane-source pull request the merge job lists only the security lane's pull_request runs and reads the code lane's pr-review-main check runs on the head only. Refs: #10961 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…uts-and-main-review-stop
…uts-and-main-review-stop
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 No security issues found in PR #11084. I read the whole diff and PR context, and the consuming code in Trusted paths touched:
No critical-findings: 0 |
|
claude-review reviewed No blocking or advisory findings. I read the whole diff (all 12 files) and the PR context. I did not run any tests. The test results in the PR description are author-claimed and unverified by me. What I checked
Not counted as findings
Spend Manifests / closing issue
|
Refs: #10961
Summary
This ships part 1 of #10961 and two merge-job read cuts.
binary file, is over 300000 bytes, or has a line over 1800 bytes gets no verdict. The run stays
green, and each stop leaves one countable check run. The merge gate names the stop as the lane's
unbound reason. No person hold is added: the stop stays the same MED
evidence-unbound:<lane>lane cause as before, and only its reason changes.
evidence that
bind()never uses.Fix
.github/workflows/pr-review-main.yml(all three legs, identical edits):stop()helper. Onbinary,too-largeorlong-lineitlogs
::notice title=pr-review-main stop::reason=<r> lane=<lane> pr=<n>, writesstop=<r>,<lane>-stopand<lane>-headto the step outputs, and exits 0.failed
write-diff.py.steps.diff.outcome == 'success'now also needssteps.diff.outputs.stop == ''.claude-review-stop,claude-security-review-stop,claude-review-headandclaude-security-review-head.review-fallbackgains anoutputs:block holding only these.recordjob, "Record the stops", does not depend on the artifact download.For each lane it reads the leg that set the stop. It checks the reason against
^(too-large|binary|long-line)$and the head against a 40-hex SHA, and fails on anything else.It then posts the check run
pr-review-main: <lane>on that head with conclusionneutralandtitle
verdict=none reason=<r>.Binder (
plugins/source-control/skills/babysit-prs/scripts/):babysit_gh.py:MAIN_REVIEW_STOP_TITLEreads a stop title as("stop", reason). Any other title that doesnot read is still
None, which counts one CRITICAL.main_review_criticalcounts a stop as 0 CRITICAL.babysit_merge.py_main_reviews:head_recordskeeps only count tuples.head_stopsholds each lane's stops on the head.babysit_review_evidence.py_main_lane: when no verdict binds and the head has a stop, theunbound reason is
main-review-stop:<reason>. Otherwise it stayslane-source-changed.babysit_risk.pyis unchanged. The reason reaches the report through the existingevidence-unbound:<lane>detail,not bound: main-review-stop:too-large.Cut A (
babysit_merge._lane_evidence):needs_main_reviewis computed once, beforecollect_lane_runs, and passed into_main_reviews.bind()reads the code lane's runs nowhere, since
_unboundand_carried_blockingread only thesecurity lane.
Cut B (
babysit_gh.collect_main_review_counts):head_recordsuses only the head and itscarried count is checked only for
None.Fail-closed:
github-actions) only renames an unboundreason. It adds nothing a person reads and never binds a lane.
lane-source-changed.Metrics
Countable outcome event (part 1).
pr-review-main: <lane>, on the head. It is titledverdict=none reason=<too-large|binary|long-line>, its conclusion isneutral, and its app isgithub-actions. The checks API has no delete, so the count is durable.::notice title=pr-review-main stop::reason=<r> lane=<lane> pr=<n>.failureshould fall by the number of stops.Expected GITHUB_TOKEN reads saved per merge-job tick. These are estimates. They come from the
plan's figures, taken from the
babysit-gh-callslines of merge job run 40819274416, whichpredates #10743. The parent records the before and after measurements.
_lane_evidence)workflows/pr-review-hosted.yml/runslisting, plus about 3 reads per uncached claude-review run (actions/runs/{id},attempts/{n}/jobs,check-runs/{id}/annotations). In the sample, 2 of 10 candidates took this path, about 17 reads for the tick.collect_main_review_counts)Verification
New tests, each run on the old code first (
git restore --source=HEADon the source files only)and then on the new code:
.github/scripts/pr-review-main/workflow.test.mjs(node --test: 29 pass after; 4 fail before):a diff the review cannot read whole stops green and names its reason for the record job:runs the real "Write the diff" script under
bash -e -o pipefailwithgitandpython3stubs, in every leg. It covers a too-large stop, a long-line stop, a failed
write-diff.py(non-zero, no
stop=), and a whole diff (parts written, no stop).after a stop no later step of the leg runs, and each lane's stop leaves the leg.the record job posts each stop as a neutral verdict=none record, from a closed reason: runsthe step with a
ghstub. A malformed reason or head fails and posts nothing.a later leg runs only for the lanes the previous leg handed on: the fallback leg'soutputs:assertion is narrowed to the four stop outputs.tests/test_babysit_gh.py(stop title parse; stop counts 0 and an unknown reason counts 1; oneread per listed (sha, lane)): 3 fail before, pass after. The case of a stop on one head beside
critical=1on another passes before and after. It guards that the stop skip drops no otherhead's count.
tests/test_babysit_merge.py:_main_reviewsinput test fails before and passes after. It checks per-lane SHAs,head_stops, and thathead_recordsexcludes stops.LaneRunsReadTestschecks that a lane-source PR lists only the security lane's runs; it failsbefore and passes after. Its paired case, where any other PR lists every lane, passes both.
tests/test_babysit_review_evidence.py:main-review-stop:too-large, keeps the carried CRITICAL, and scores as MEDevidence-unboundwith no new person code. This fails before and passes after.bind()with security-only runs equalsbind()with both lanes' runs. Thispasses before and after.
Runs on the final tree:
pyteston the five touched or neighboring babysit test files: 812 passed.pytest tests/test_babysit_risk.py: 135 passed.node --testonworkflow.test.mjs,reconcile.test.mjsandenable-auto-merge.test.mjs:all pass.
actionlintandzizmor --offlineonpr-review-main.yml: clean.scripts/run-ruff.shformat and check: clean.scripts/check-changelog-fragments.sh --check: valid.CI runs the full suites.
Related
main-review-stop:<lane>HIGH person code, its prefix and itslane-causes-person-codespin) is dropped by owner direction. A stop is recorded and reported,and nothing waits on a person.
merge.diff-check.path-holds) is the base this branch was cut from. feat(pr-pipeline): lane-arm the merge gate's own code on a verified pr-merge attestation #10966 was closedunmerged, so nothing here depends on it.
🤖 Generated with Claude Code