Objective
Add a per-team lock or deduplication mechanism to prevent multiple concurrent advance_dag calls for the same team from racing each other.
Motivation
When multiple tasks in the same team complete in rapid succession, the NATS listener will trigger multiple advance_dag("team-X") calls concurrently. Since advance_dag fetches tasks, finds ready ones, and claims them in a non-atomic sequence, two concurrent calls could both see the same pending task as ready and both attempt to claim it. While ProjectAgamemnon's PUT endpoint may reject the second claim, this creates unnecessary API calls and noisy error logs.
Deliverables
Success Criteria
Priority
HIGH -- Race conditions in task claiming are the most likely source of production bugs in the current architecture
Updated per ADR-006 — ai-maestro references replaced with current architecture terminology.
Objective
Add a per-team lock or deduplication mechanism to prevent multiple concurrent
advance_dagcalls for the same team from racing each other.Motivation
When multiple tasks in the same team complete in rapid succession, the NATS listener will trigger multiple
advance_dag("team-X")calls concurrently. Sinceadvance_dagfetches tasks, finds ready ones, and claims them in a non-atomic sequence, two concurrent calls could both see the same pending task as ready and both attempt to claim it. While ProjectAgamemnon's PUT endpoint may reject the second claim, this creates unnecessary API calls and noisy error logs.Deliverables
dict[str, asyncio.Lock]inTaskClaimerkeyed byteam_idadvance_dagand release it on completionSuccess Criteria
advance_dagcall executes per team at any given timeasync withfor safety)Priority
HIGH -- Race conditions in task claiming are the most likely source of production bugs in the current architecture
Updated per ADR-006 — ai-maestro references replaced with current architecture terminology.