Forgejo's assignees PATCH is last-write-wins, so two dev agents polling
concurrently could both observe .assignee == null at the pre-check, both
PATCH, and the loser would silently "succeed" and proceed to implement
the same issue — colliding at the PR/branch stage.
Re-read the assignee after the PATCH and bail out if it isn't self.
Label writes are moved AFTER this verification so a losing claim leaves
no stray in-progress label to roll back.
Adds tests/lib-issue-claim.bats covering the three paths:
- happy path (single agent, re-read confirms self)
- lost race (re-read shows another agent — returns 1, no labels added)
- pre-check skip (initial GET already shows another agent)
Prerequisite for the LLAMA_BOTS parametric refactor that will run N
dev containers against the same project.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add issue_is_dev_claimable() helper to lib/issue-lifecycle.sh that checks
whether an issue's labels are compatible with dev-agent ownership. Labels
like bug-report, vision, in-triage, prediction/*, action, and formula
indicate another agent owns the issue.
In dev-poll.sh, replace the vision-only skip with the new helper so that
ALL non-dev labels are excluded from stale detection. This prevents
dev-poll from relabeling bug-reports (or other agent-owned issues) as
blocked while they are being triaged.
Also removes the now-redundant formula/prediction guard block in the
orphan section, since issue_is_dev_claimable covers those labels.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 60-second grace period to stale in-progress detection in dev-poll.sh.
When a poller sees an in-progress issue with no assignee/PR/lock, it now
checks the timeline API for when the label was added. If <60s ago, it
skips stale detection to allow the claiming agent time to finish its
assign+label sequence.
Also documents the intentional assign-before-label ordering in
issue_claim() that minimizes the race window.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove ensure_blocked_label_id() from ci-helpers.sh; _ilc_ensure_label_id()
in issue-lifecycle.sh is the canonical, general implementation. Update the
stale comment that referenced the removed function.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>