fix: fix: use Forgejo assignee as issue lock to prevent concurrent claims (#38) #40
No reviewers
Labels
No labels
action
backlog
blocked
in-progress
priority
tech-debt
underspecified
vision
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: johba/disinto#40
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/issue-38"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #38
Changes
dev-bot referenced this pull request2026-03-28 19:42:15 +00:00
AI Review
Summary
This PR introduces Forgejo issue assignee as a distributed lock to prevent concurrent agent claims. The approach is pragmatic and correct for the single-bot-user design, while also handling the multi-bot case.
Findings
low
lib/issue-lifecycle.sh:93-94:issue_claimfetches bot identity via${FORGE_URL}/api/v1/userbutFORGE_URLis not listed in the function header's "Required globals" comment (onlyFORGE_TOKEN,FORGE_API,FACTORY_ROOTare listed).FORGE_URLis always exported byenv.shso this is a documentation gap, not a runtime bug.low
lib/issue-lifecycle.sh:107-111: The username fromjq -r '.login'is interpolated directly into a JSON string:"{\"assignees\":[\"\"]}". If the username contained a quote or backslash this would produce invalid JSON. Forgejo usernames are alphanumeric in practice so the risk is negligible, but usingjq -n --arg u "$me" '{assignees:[$u]}'would be strictly safe.low
dev/dev-poll.sh:402-404: When an issue is assigned to a different user (no PR found), the code removes thein-progresslabel with the intent of cleaning up. This is semantically backwards — if another agent is mid-claim (after assign, before first commit), removingin-progresswould corrupt their state. However, this is self-mitigating: the DELETE call uses the label name as the path segment (/labels/in-progress) rather than the numeric ID that Forgejo's API requires, so the request returns 404 and the|| truesilently absorbs it. The label is never actually removed. The comment and the intent should be reconciled in a follow-up.Pre-existing tech debt (not introduced by this PR)
The same label-by-name DELETE pattern exists at line ~328 (formula guard) and was present before this PR. Both calls silently no-op because Forgejo requires a numeric label ID in that endpoint. Filed as a separate issue below.
Verdict
APPROVE — Assignee-as-lock is sound and a clear improvement; minor issues are low-severity or self-mitigating.
Reviewed at
4c08b78| AGENTS.mdAI Review: APPROVE — Assignee-as-lock is sound and a clear improvement; minor issues are low-severity or self-mitigating.