Two agents can both be “available” and still be a bad match for the same task. If each reads a backlog row and starts work without an atomic claim, they may both edit the same files, both spend model time, and produce two deliveries that a reviewer must reconcile. The fix is a state transition, not a longer prompt.
The minimal state diagram
OPEN --claim(runner, revision)--> CLAIMED
CLAIMED --release(runner)-------> OPEN
CLAIMED --deliver(evidence)-----> DELIVERED
DELIVERED --request changes-----> CLAIMED
DELIVERED --accept(reviewer)---> DONE
Only one runner owns CLAIMED at a time. DELIVERED means evidence is ready for review; it does not mean the change has merged or deployed. A second agent reading an old OPEN snapshot must lose its claim attempt when the record's revision has changed.
Here is an original task template for a small engineering team:
task: "Add an empty state to the billing history view"
scope:
files: ["src/BillingHistory.tsx", "src/BillingHistory.test.tsx"]
excluded: ["billing API", "payment settings"]
access: "runner has repository access through their own account"
acceptance:
- "No invoices: show the approved empty-state copy"
- "Invoices present: preserve current list and pagination"
- "Keyboard focus remains in a sensible order"
evidence:
- "diff or branch"
- "commands and actual test output"
- "real screenshots at 390px and 1280px"
reviewer: "named frontend maintainer"
The preparer supplies the scope, approved copy, and reviewer. The runner can execute only with their own authorized tools. The reviewer judges whether the delivered evidence meets the acceptance criteria. If the runner cannot access the repo, the task stays unclaimed; sharing another person's token is not a workaround.
The handoff in practice
Imagine agents A and B both poll at 09:00. Each sees revision 18. A submits claim(task, A, expectedRevision=18) and the server records revision 19. B submits the same transition with revision 18 and receives a stale-revision response. B rereads the task, sees A as the runner, and selects another item. This is a compare-and-swap pattern; it requires the task store to enforce the transition atomically. A spreadsheet status cell edited by hand does not provide the same guarantee.
A then changes the empty state and attaches a branch, a real test log, and screenshots. The task moves to DELIVERED. The reviewer notices that the empty state disappears when the network request fails, which was outside the original happy-path proof but within the UI's expected behavior. They request a fix. A revises the change and resubmits. Only the reviewer moves the task to DONE after checking it. That review may still be separate from merge and release.
This kind of shared AI execution capacity is useful only when the ownership boundary is explicit. The Wagglet workflow guide gives context for separating a request, a prepared task, delivery, and acceptance. The state diagram above is a portable design example; it is not a claim that every backlog tool implements exactly these transitions.
Failure cases to keep visible
Claim timeouts need a deliberate policy. Do not silently reclaim a task just because a runner was quiet for ten minutes; the runner may have work in progress. A human can inspect the attempt and release or reassign it. Retries need idempotency so a network timeout cannot create duplicate deliveries. A reviewer also needs authority to reject thin evidence instead of accepting a polished summary.
If you keep those rules in the task system, two agents can look at the same queue safely. They will still make mistakes in the work itself. The claim transition only removes one avoidable class of waste.
AI disclosure: This article was prepared with AI assistance. The example state machine is an illustrative design, not a report of a shipped implementation.
Top comments (0)