Task Graph
Tasks, dependencies, and the directed acyclic graph that connects them.
Task Graph
Every Piyaz project is a directed acyclic graph (DAG) of tasks connected by edges. Tasks are nodes; edges define how work relates and what must happen in what order.
Task Lifecycle
Tasks move through four statuses, each with a distinct color in the UI:
draft → planned → in_progress → done| Status | Color | Meaning |
|---|---|---|
| draft | Gray (#9ca3af) | Idea captured. Needs description and acceptance criteria before planning. |
| planned | Blue (#55b3ff) | Has an implementation plan. Ready to be claimed when dependencies are met. |
| in_progress | Amber (#ffbc33) | Claimed by an agent or person. Work is underway. |
| done | Green (#5fc992) | Complete. Execution record, decisions, and files should be recorded. |
Edge Types
Two edge types define relationships between tasks:
depends_on (blue, #55b3ff)
A depends_on edge from A to B means A cannot start until B is done. This is a hard ordering constraint. Piyaz uses these edges to compute ready tasks, blocked tasks, and the critical path.
A ──depends_on──▶ B
(A needs B done first)Use depends_on when: removing the target task would make the source task impossible to implement. The source needs the target's code, APIs, data, or decisions.
relates_to (violet, #a78bfa)
A relates_to edge from A to B means A and B share context but neither blocks the other. These edges appear in context views and help agents understand related work, but they don't affect scheduling.
A ──relates_to──▶ B
(A and B share context)Use relates_to when: the tasks inform each other but can proceed independently. Removing the target would make the source harder but not impossible.
When in doubt: removing the target makes the source impossible? Use depends_on. Just harder? Use relates_to.
Edge Notes
Every edge has a note field explaining why the relationship exists. Edge notes propagate into agent context for downstream tasks, so an agent implementing a dependent task knows not just that a dependency exists but why it matters.
Good edge notes answer: "What does the source task need from the target task?"
Graph Analysis
Piyaz provides 5 analysis types that query the task graph. Each is available programmatically via the piyaz_analyze MCP tool.
Consider this example graph:
[Define API schema] (done)
│
depends_on
│
▼
[Build REST endpoints] (planned)
│
depends_on
│
▼
[Add auth middleware] (draft, has description + criteria)
│
depends_on
│
▼
[Write integration tests] (draft, no criteria yet)
[Update docs] ──relates_to──▶ [Build REST endpoints]Here's what each analysis returns for this graph:
Ready
Tasks where all depends_on targets have status done and the task itself is planned. These are the tasks that can be worked on right now.
Example result: Build REST endpoints -- it's planned and its only dependency (Define API schema) is done.
Blocked
Tasks with at least one depends_on target that isn't done. The response includes which specific tasks are blocking and their current statuses.
Example result: Add auth middleware is blocked by Build REST endpoints (planned). Write integration tests is blocked by Add auth middleware (draft).
Plannable
Draft tasks that have a description and at least one acceptance criterion. These tasks have enough specification to write an implementation plan but haven't been planned yet.
Example result: Add auth middleware -- it's draft with a description and acceptance criteria. Write integration tests would not appear because it lacks criteria. See lib/graph/traversal.ts:293 for the filtering logic.
Critical Path
The longest chain of depends_on edges in the project. This is the bottleneck -- shortening the critical path is the fastest way to accelerate the project. Computed via a recursive CTE that walks from root tasks (tasks with no outgoing depends_on edges) and tracks the longest path. See lib/graph/traversal.ts:414 for the implementation.
Example result: Define API schema → Build REST endpoints → Add auth middleware → Write integration tests (depth 4). Update docs is not on the critical path because relates_to edges don't count.
Downstream
All tasks that transitively depend on a given task, following depends_on edges in reverse. Use this for impact analysis: before changing a completed task's output, check what downstream work might be affected.
Example result: Calling downstream on Define API schema returns Build REST endpoints (depth 1), Add auth middleware (depth 2), Write integration tests (depth 3).
Constraints
The graph enforces several invariants (see lib/graph/mutations.ts:createEdge for validation logic):
- No self-edges -- a task cannot depend on itself.
- No duplicate edges -- each (source, target, type) triple is unique (enforced by a database unique index).
- No cross-project edges -- both tasks must belong to the same project.
- No cycles -- adding a
depends_onedge that would create a cycle is rejected. Piyaz walks the dependency chain from the target to check if the source would be reached. - Cascade deletion -- deleting a task removes all its edges automatically via database foreign key cascades.