Repository navigation
fix(pr-merge): read the post-merge answer afresh in lane_room on any reuse refusal - #10154
Conversation
…reuse refusal lane_room read the run's shared post-merge answer again only when shared_refusal returned unverified-stale. Every other refusal (stale, future, demotion-changed, new-merge, binding) made the room unreadable, so enable-auto-merge left every lane pull request unarmed and disarmed the armed ones. The gate itself reads afresh on any refusal. Run 40255059710 hit this on demotion-changed: issue #10149, filed by the lanes App after the answer was computed and then labeled by triage, has updated_at != created_at, which _demotion_changed counts. The room now recomputes on any refusal when it has post_merge, keeping the cheap _still_current path for unverified-stale only. 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 I found nothing to block or flag in this pull request. I read the whole diff and the PR context, and I read
|
|
claude-security-review reviewed No security issues found in PR #10154 (head 2354cbd). critical-findings: 0 I read the whole diff (7 files) and the PR context. What changed: any Why this does not fail open:
Residual note (not a finding): a recompute costs a full post-merge check, about 5 minutes in the cited run, against the 8-minute Spend: this runs one extra post-merge check inside the existing lane run, which draws only on existing CI usage. It is not a cost hold. |
No related issue: found while diagnosing the merge-lane stall in pr-merge run 40255059710.
Summary
No lane pull request merged after 23:46Z on 2026-10-25. Scheduled pr-merge run 40255059710 logged
lane room: {"refusal":null,"unreadable":"post-merge answer demotion-changed",...}. It left 12 lane pull requests unarmed and disarmed #10100 and #10116.babysit_merge_policy.lane_roomread the run's shared post-merge answer again only whenshared_refusalreturnedunverified-stale. Every other refusal (stale, a futurecomputedAt,demotion-changed,new-merge:#<n>, binding) made the room unreadable. The gate (assess) reads afresh on any refusal, as theshared_refusaldocstring says.What triggered it: the answer was computed at 01:36:59Z. #10149 was opened by
melodic-automation-lanes[bot]at 01:40:01Z, and triage then labeled and commented on it (01:40:26Z to 01:42:28Z)._demotion_changedcounts any issue the agent identity opened whoseupdated_atdiffers fromcreated_at, so it returned True. The issue's body has no demotion marker.Fix
lane_room: whenpost_mergeis given, anyshared_refusalresult now goes through_recompute_shared, the same full read theunverified-stalepath already used. That read includesread_demotion, so a real demotion still holds the rung off. The cheap_still_currentkeep-path is still limited tounverified-stale, so astaleanswer is never kept unchanged. The recompute uses the room's own self logins (none), as the room binds them.post_merge, or a recompute that raises or comes back unreadable, the room staysunreadableas before._demotion_changedis unchanged. It is a lane safety control, and narrowing it is the owner's decision. One effect of this PR: whenever the issue lane files an issue and triage touches it shortly before a room read, the room pays one full post-merge check. Run 40255059710's post-merge step took 4m56s (01:36:59Z to 01:41:55Z), insideLANE_ROOM_TIMEOUT_MS(8 minutes).enable-auto-merge.mjsheader anddocs/conventions/pr-pipeline/README.mdto match. Added changelog fragments for source-control and pr-pipeline.Verification
test_babysit_lane_room.pyencoded fix(pr-merge): recompute an unverified-stale post-merge answer in lane_room and annotate room holds #9602's narrower behavior:test_an_answer_the_gate_would_not_reuse_is_unreadableandtest_a_lane_merge_the_answer_does_not_count_is_unreadable. Both asserted that no recompute ran. They are rewritten to assert the recompute. fix(pr-merge): recompute an unverified-stale post-merge answer in lane_room and annotate room holds #9602's body only says "every other refusal behaves as before"; it gives no reason those refusals had to stay unreadable.babysit_merge_policy.py: 6 fail (stale, future, demotion-changed, new-merge, cheap path not taken for stale, fresh demotion holds rung off). With this change all 27 lane-room tests pass.test_an_unusable_answer_with_no_fresh_read_is_unreadablecovers no check, a check that raises, and an unreadable check. It passes both before and after, since that behavior is kept.enable-auto-merge.test.mjsandworkflow.test.mjs: 133 pass, 0 fail. Ruff check is clean on the changed files. The pre-pushcheck-affectedpassed.Related
unverified-stalerecompute this change extends.🤖 Generated with Claude Code