Development record
abcd drain reads the issue ledger of the checkout it runs in and never checks whether that checkout is behind origin's default branch: from a primary checkout 185 commits behind main, the dry run listed 162 eligible issues from the stale ledger, many since fixed or changed, and a run would judge, reserve and work from that list.
abcd drain reads the issue ledger of the checkout it runs in and never checks whether that checkout is behind origin's default branch: from a primary checkout 185 commits behind main, the dry run listed 162 eligible issues from the stale ledger, many since fixed or changed, and a run would judge, reserve and work from that list.
Reproduced in a lab with three accounts on one origin (2026-10-16): with one account's checkout a commit behind after another resolved the head issue on origin, the behind account's dry run still listed it eligible, its drain reserved it (reserve makes no check that the record is resolved on origin's default branch, and the new reservation reads released at once), and opened a lane cut from origin's main, where the brief refused because the issue is already resolved there, advising to land the issue first. Every later move of that drain then answered "drive" the stalled lane (iss-2610161015368630). A drain never updates its own checkout, so on a busy day each drain falls further behind and this is reached within hours.
A fuller remedy: plan from the origin default branch's tree fetched at the start of each move, as the lane's brief already reads its base, and have a fresh reservation over a record finished on origin's default branch refuse or hand back (grounds: a queue consumer reads the row it locks, as SELECT ... FOR UPDATE SKIP LOCKED).
Grounds
- pursued: a behind checkout's drain neither reserves, judges nor opens a lane for an issue resolved on origin; shown wrong if a drain on a stale checkout reserves an issue already resolved on origin's default branch
Frontmatter
| id | iss-2610160957404827 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | critical |
.abcd/work/issues/resolved/iss-2610160957404827-abcd-drain-reads-the-issue-ledger-of-the.md
open on GitHub ↗ · commit history ↗
References1
- itd-2610161016394967Drains on several accounts share the workrelated
mentions5
- dcn-26101610403502562026-10-16 — A drain plans from origin's default branch (facilitator-on-delegation, drain-many-accounts): each drain move fetches origin inside the drain's lock before it reads anything, and takes one snapshot of the ledger from origin's default branch, which the plan, the lane's start check, the judgement's remedy digest and the reservation footprint all read; a fetch that fails, a default branch the fetch could not read, or a missing origin/HEAD means the move cannot plan and enters the drain's outage wait, never planning from what the checkout last saw; the dry run plans from the last fetched view and says how old it is, so it still writes nothing; a checkout behind origin is warned about, not refused, because the lane is cut from origin anyway; and any reservation of a record finished on origin's default branch backs off, with or without a tip (grounds: a queue consumer reads the row it locks, as SELECT ... FOR UPDATE SKIP LOCKED; iss-2610160957404827, iss-2610161015448977).
- dcn-26101611351222942026-10-16 — Reserving a record being reopened on a branch backs off until the reopen is merged (facilitator-on-delegation, drain-many-accounts): the finished-record back-off reads only origin's default branch, so while that branch holds an issue resolved or wontfix, or an intent shipped or superseded, a branch that moves it back to open cannot reserve it, and no flag gets past the back-off; the reopen is merged first, and the record is reserved once origin's default branch holds it open again; accepted because the default branch is the one view every account shares, and an exception for one branch would let a checkout reserve work that origin still calls done (spc-2610161044461448 step 1; iss-2610160957404827).
- iss-2610161015368630A lane that refuses at a step without handing back (a conflicting pull request at arming, the land fence, or a brief refused because the issue is already resolved at the base) is read by laneOutcome as in progress, so every later drain move answers "drive" that lane and the drain opens nothing more; implement step --discard and --release act only on held lanes, so only removing the run directory by hand frees it.
- itd-2609091034175565Before an agent starts on an item, it reserves it on the shared remote, and everyone who works on the project sees the reservation
- spc-2610161044461448drain-many-accounts