Manage blockers & prevent cycle deadlock
Guides show HOW. Conceptual model: Tenancy. Tool details: MCP, routes: REST reference.
Why blockers exist
A task isn't just work — it has preconditions. task_dependencies(task_id, blocker_task_id) encodes "this task waits on that one". Because blockers are data, blocked is derived — never maintained by hand.
The mechanics
- A task waits on any number of blockers.
- Blockers stay inside the same project (cross-project blockers →
400). - A task cannot block itself (
400). - Cycles are rejected transitively with
409— the service checks the whole chain before accepting an edge, so deadlock by construction is impossible.
Recipe: order work with blockers
# make task B wait on task A
curl -X POST https://pm.blarass.com/v1/tasks/<task-b-uuid>/blockers \
-H "Authorization: Bearer <key>" -H "Content-Type: application/json" \
-d '{"blocker_task_id":"<task-a-uuid>"}'
# check state
curl https://pm.blarass.com/v1/tasks/<task-b-uuid> -H "Authorization: Bearer <key>"
# → blocked: true while task A isn't doneReading blocked
task.blocked is true iff any blocker isn't done. When the last blocker completes, blocked flips false automatically — no bookkeeping. Both REST /tasks/:id and MCP get_task return it.
Cycle-prevention recipe (for agents)
When your agent plans sequential work, it should:
- Create all tasks first (no dependencies yet).
- Add blockers in dependency order (earliest-blocking first).
- Treat
409 cycleas a signal to reorder the plan, not to force-write a dependency graph that doesn't exist.
Related: Tasks reference · Progress reports