bc-uxrix: A merge-bead that becomes a card leaves the only list the sweep reads - #779
Open
mordam wants to merge 3 commits into
Open
bc-uxrix: A merge-bead that becomes a card leaves the only list the sweep reads#779mordam wants to merge 3 commits into
mordam wants to merge 3 commits into
Conversation
`bd.listAgent` runs `--exclude-label human` and `raiseMergeCard` puts `human` on, so a merge-bead left the only list the sweep read the moment it became a card. Two things went quiet: `cardedFor` could only ever return `[]`, so the take-a-card-back loop of bc-91srt had never run in the daemon; and `strandedPrs` built its cover set from the same rows, so every card was reported as a pull request nothing was about. Adds `Bd.listCards` — a second read narrowed by assignee to this queue's own cards — and hands both halves to the reclaim and the strand report. Carves a reviewer's veto out of the reclaim per Adam's 2026-08-24 answer, without which making cards visible would merge a refused pull request unattended. Raises the strand scan off `pr.list`'s silent default of 40 and says when the ceiling is hit. `fakeBd.listAgent` in test/mergequeue.mjs now applies the same exclusion the real one does, so the five reclaim tests fail honestly if the second read is ever removed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
|
A beadcause worker opened this and does not merge its own work. It is on the merge queue as bc-zaqxb. |
Owner
Author
|
The beadcause merge queue tried to merge this and could not: it has been tried 3 times and stopped at the same place each time. nothing ran on this commit at all — zero checks were reported for it, so there is nothing here that says this passed. Tried 3 times — that was the last. It is Adam's call now — see bc-zaqxb. |
…ity-uxrix # Conflicts: # test/mergequeue.mjs
Contributor
|
beadcause-resolver: stood down — the worktree for worktree-card-visibility-uxrix is already locked by another resolver ("resolver pid 8202 #779", a live claude process started 16:12 ADT), so I did not touch the tree. Branch left as-is; still CONFLICTING with main. |
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Gives the merge queue a second read of the tracker so it can see the cards it raised itself, and carves a reviewer's veto out of the reclaim so that visibility cannot merge a refused pull request.
Bd.listAgentrunsbd list --exclude-label human— for a good reason of its own — andraiseMergeCardhands a pull request over by puttinghumanon. Those two facts together meant a merge-bead left the only list the sweep ever read at the exact moment it became a card. Nothing failed; two things went quiet.cardedForselects rows carryinghumanand notmerge-queue, so fed a listhumanhad been filtered out of it could only ever return nothing — the whole take-a-card-back mechanism of bc-91srt had never executed once in the daemon. AndstrandedPrsbuilds its cover set from the same rows, so every card came back as a pull request nothing was about, which is the#N is open and no merge-bead is about itline the log has repeated once per tick per card. Both are measured rather than reasoned: replaying the real reads against the live workspace today gives cardedFor 0 from listAgent alone against 21 from both, and strandedPrs 22 false strands against zero.So
Bd.listCards(ws, assignee)is the other half, narrowed by assignee so it is this queue's own cards rather than the inbox read twice, andsweepMergeQueuehands both halves to the reclaim and the strand report whilequeueForkeeps the queued half alone — putting a card intoqueuedwould re-merge every handover. A card list that cannot be read suppresses both consumers rather than running them on a set known to be short.The veto carve-out had to land in the same change and is Adam's answer on the bead of 2026-08-24: the reclaim is for cards the queue gave up on, not cards a reviewer gave up on. A vetoed card carries both a reviewer's refusal and, underneath it in a different block of the same field, the queue's own stale "waiting on a review" sentence — which is the only reason it was selectable. Without the carve-out, waking
cardedForup would have taken #655 (green, clean, explicitly refused) back and merged it unattended, becausegateVerdictdoes not consult the review gate at all andreviewRequiredPerWorkspace.beadcauseis currentlyfalse. The predicate isreviewEscalation, already inlib/mergebead.jsand already whatlib/mergeraise.jsescalates on; run against the live cards it fires on exactly bc-0k5bf (#661) and bc-45rd5 (#655) and nothing else. Achangesverdict mid-loop is deliberately not carved out, and there is a test either way.Third, the strand report stops truncating itself in silence: it took
pr.list's default of 40 without saying so, andghsorts newest first, so on 2026-08-24 thirty-five of seventy-five open pull requests could not be reported however stuck they were — and they were the oldest.STRAND_SCAN_MAXis 200, the query costs the same either way, and hitting it is logged. Honest caveat: the repo has 35 open pull requests today, so this half is not currently observable in production and is pinned by a test instead. I also widened the directory set the report sweeps to include repos known only through a card, which the bead did not ask for but is the same "a card is a merge-bead too" rule — without it, a workspace whose merge-beads had all been carded reported nothing at all.The test change is the part I would look at hardest.
fakeBd.listAgentin test/mergequeue.mjs now applies the same--exclude-label humanthe real one does, which is what makes the five existing reclaim tests fail honestly if the second read is ever removed; they had been passing against a wiring that could not deliver them a row. A new test deletesbd.listCardsand asserts nothing is reclaimed, so the dependency is falsifiable rather than implied.lib/inmain.jscarried a comment assertinglistAgentis the queue's only read — amended rather than deleted, because its own exclusion is still right: an inmain flag leavesmerge-queueon, so such a bead is still unmergeable and still unreclaimable, it is merely counted as cover now.Tests: affected: 227 suites for 7 changed files, all passed (node bin/b7e-shipgate). Plus a read-only replay of the real read against the live workspace: cardedFor(listAgent only)=0 vs cardedFor(both)=21, strandedPrs 22 false strands -> 0.
Worth knowing: The first tick after this merges takes 12 cards back onto the queue. Measured by replaying cardedFor -> pr.view -> gateVerdict against live state: of 21 selected, 1 is already MERGED, 8 stay cards on their own gate, 12 say merge. That is bc-91srt working for the first time and it is intended, but nobody has ever watched it run. Merges are still paced by MERGES_PER_TICK=2 and each card is re-asked at most once per RECLAIM_COOLDOWN_MS, so it is a label swap on 12 beads rather than 12 merges in a minute. There is deliberately no per-tick cap on the reclaim itself; if 12 at once proves too many, the shape of that fix is a MERGES_PER_TICK sibling in the reclaim loop.
Left undone: No cap on reclaims per tick (see the risk). queueFor is still fed the queued half only, on purpose. The blind spot strandedPrs already names - a workspace with no merge-bead of any kind, so no checkout is resolvable - is narrowed but not closed: a card now names a directory, so only a repo with neither a queued bead nor a card is invisible.
Files changed — 8 files · +474 −15 · against `main`
Opened by a beadcause worker session on bc-uxrix — A merge-bead that becomes a card leaves the only list the sweep reads, so cardedFor can never reclaim one and strandedPrs calls every card a strand. It merges itself once the checks report; merging is what closes the bead. If this is still open, something stopped that, and the reason is on bc-uxrix and in Adam's inbox.
bead: bc-uxrix