Repository navigation
perf(source-control): keep the lane room's unverified answer through a same demotion - #10741
Conversation
…a same demotion The lane room refused a post-merge answer past the two-minute unverified age, then kept it only when nothing it was read from moved. Its demotion test was the coarse probe, which trips on any edit to an issue the lane opened, so such an edit ran a full post-merge check. The unverified keep now re-reads the demotion when the probe trips, after the runs check, and keeps the answer when it reads the same, as the demotion-changed keep already does. A different demotion or a failed read still recomputes. The lane-room report gains postMerge (answer, reason, moved), so the enable-auto-merge log line shows whether the answer was reused, kept or recomputed, and why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orts Name the merge job's settle and the idle-tick reuse in the changelog: they take the same unverified keep through a demotion that reads the same. 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. |
|
claude-review reviewed No findings. I read the full diff ( What I checked:
Spend: none that bills. The change makes the lane room run fewer full post-merge checks and adds a log field. The PR says |
|
claude-security-review reviewed No security issues found in this PR (4 files). The only trusted-path file is critical-findings: 0 What changed. Does the keep weaken a merge hold? I checked this and found it does not.
Other checks.
|
Refs: #9646
Summary
The lane-room read in pr-merge's
enable-auto-mergejob can run a full post-merge check of its own instead of reusing the answer post-merge-dispatch already computed. Of 15 room reads measured on 2026-10-28, 8 took 83-104 s and 7 took 10-20 s. 8 of the 9 slow reads came from runs whose post-merge check exited 5, meaning at least one lane merge was still unverified. The fast reads all exited 0.The reason is that an answer with an unverified merge is reusable on age alone for only
SHARED_UNVERIFIED_MAX_AGE(2 minutes). The gap from post-merge-dispatch to the room read measured about 2m07s, so every exit-5 answer is refused asunverified-stale. It is then kept only when_moved(formerly_still_current) finds nothing it was read from has moved. When something has moved, the room recomputes.This PR:
Refs:and notCloses: whether that gap caused the measured slow reads is UNVERIFIED. During several slow windows, main moved and the verifying runs were in flight, and those are correct recomputes. The newpostMerge.movedfield will show which clause trips on the next runs. Run 40754482922 was slow with exit 0, so it was notunverified-stale; anew-mergerefusal is likely (a release commit landed 8 s aftercomputedAt), but that is UNVERIFIED.Fix
LaneRoom.report()gainspostMerge:answer(reused,kept,recomputedorrefused),reason(theshared_refusalreason, orcode-changed, behind any answer exceptreused) andmoved.movedapplies when anunverified-staleanswer is not kept, and nameshead-moved,config-moved,demotion-changed,runs-movedorunreadable.settle_sharedfills the field through a new optionaloutcomeargument.enable-auto-merge.mjs'sreadRoompasses extra keys through, so its existinglane room:log line prints the field with no.mjschange._demotion_changedprobe. That probe trips on any edit to an issue the lane opened.settle_shared's owndemotion-changedkeep already accepts a freshread_demotionthat equals the shared demotion._moved(..., reread_demotion=True)now does the same, after the head, config and runs checks pass. A demotion that differs, or a demotion read that fails, still refuses: fail closed. This rule is shared bysettle_shared's three callers: the lane room, the merge job'ssettle, and post-merge-dispatch's idle-tick reuse. The merge gate's own keep inassessis unchanged.pr-merge.ymlandenable-auto-merge.mjsare unchanged.Verification
Fail before the source change (new tests on the old code):
KeyError: 'postMerge'(report field)AssertionError: Lists differ: [(datetime...)] != [](the room ran a full check for an unverified answer whose demotion reads the same)AssertionError: Tuples differ: (None, 'post-merge answer unverified-stale') != (SharedPostMerge(...), None)(settle_sharedrefused the same case)Pass after:
python3 -m unittest tests.test_babysit_lane_room: 61 tests OKpython3 -m unittest discover -s testsinbabysit-prs/scripts: 3380 tests OK (5 skipped)scripts/run-plugin-tests.sh --suites-fromthe 53plugins/source-control/suites: all passed, with 5 platform skipsnode --test .github/scripts/pr-merge/enable-auto-merge.test.mjs .github/scripts/pr-merge/merge-holds.test.mjs: 197 passscripts/validate-plugins.sh --only source-control: passedscripts/run-ruff.sh checkon the changed Python: cleanRelated
🤖 Generated with Claude Code