--- key: process.parallel-session-claim title: 2026-07-21 — Claim with `in-progress` before working; claiming is not collision safety (#542) status: active since: '2026-07-21' supersedes: none superseded-by: none rule: 'Before starting an issue, check for an existing claim four ways — open PRs referencing it, remote branches naming it, recent comments (a claim can precede the label), and a fresh `git fetch origin main` — then claim with the `in-progress` label plus a comment. A claim prevents duplicate PICKUP, not duplicate WORK. Re-fetch `origin/main` before every push, not only at branch time.' signals: 'parallel sessions · in-progress label · claim race · duplicate implementation · stale base · branch reverts merged work · dependency notes · shared surfaces · lore pruning · paths: `docs/handoffs/chicorytv-issue-queue.md` · issues: #542, #649, #666' mechanics: '`in-progress` label on the Gitea issue. The tiny read→claim race window is accepted; the later claimant backs off. Runner topology: two runners (ci-runner VM 127 + bumblebee-runner), 4 slots total.' --- The critical nuance is what a claim does *not* buy. Two sessions on non-overlapping issues can still collide in the same files. Before touching a shared surface, read the issue's dependency notes ("#234 after #231", "coordinate with #215"). When editing the standing lore/handoff doc, prune covered and stale bullets rather than appending — it is not append-only, and git keeps the history. `git pull --rebase` before committing it, since it is the single most contended file across parallel sessions. ## The label is not the check (ersatztv#649, 2026-07-26) #649 was implemented **twice, in parallel, to completion**. One session had labelled it `in-progress` and was three commits and four review rounds deep when a reviewer noticed `origin/main` had moved ten commits: the other session had already merged the same work as PR #666. The duplicate branch was discarded — pushing it would have reverted #666 *and* #667, showing the merged work as deletions because its diff was computed against a stale base. Two distinct failures, both now covered by the kickoff's step 3: 1. **The claim was made, and was insufficient.** The other session was presumably already underway when the label went on. A label answers "has anyone announced this?", not "is anyone doing this?" The cheap proxies for the second question are an open PR whose body says `fixes #N`, a remote branch with the number in it, and a claiming *comment* that predates the label — which is exactly the `CLAIM?` flag `scripts/select-queue.sh` already raises and deliberately does not resolve. 2. **The base went stale and nothing re-checked it.** `origin/main` was read once, at branch time, and not again across many hours. The tell is a `git diff origin/main` that shows deletions you did not make. Re-fetch before every push; rebase (never merge main in) when it has moved. Neither session did anything wrong at the moment of claiming. The lesson is that the *duration* of a session is the risk: the longer a branch lives, the more the "I checked at the start" evidence decays. Worth noting what worked: the duplicate effort was not wasted. The merged implementation was better in one respect (it exports `ETV_GITEA_URL` as well as `GITEA_BASE_URL`, because `pr-changed-files.sh` reads the former at higher precedence), and the discarded branch's test coverage was salvaged onto the merged code as an additive tests-only PR. When you discover a collision, diff the two implementations before throwing yours away — the loser usually contains something the winner lacks.