Зачем это нужно
После урока про размер задачи может возникнуть естественный вопрос: если мы дробим feature на много маленьких tasks, как не потерять общую картину?
Ответ - dependency graph. Tasks лучше представлять не только списком, но и графом зависимостей. Тогда видно:
- что нужно сделать сначала;
- какие tasks можно выполнять независимо;
- где находятся integration points;
- какие проверки должны закрывать ветви графа;
- какой порядок безопасен для single-agent execution.
В этом модуле мы используем dependency graph для планирования одного агента. Позже та же модель станет основой для parallel agents и worktrees.
Основная идея
Плоский список задач скрывает зависимости.
Плоский список:
T1. Add repository
T2. Add API
T3. Add service
T4. Add UI
T5. Add E2E
T6. Add integration tests
Проблема: непонятно, что от чего зависит. API зависит от service? UI зависит от API contract? E2E зависит от UI и backend? Integration tests должны появиться до UI или после?
Dependency graph делает порядок явным.
DB/Repository -> Service -> API -> UI -> E2E
\-> Integration Tests
Task graph помогает агенту двигаться по feature маленькими шагами, не теряя структуру.
Ключевые термины
| Термин | Значение |
|---|---|
| Dependency Graph | Граф задач и зависимостей между ними. |
| DAG | Directed Acyclic Graph: направленный граф без циклов. |
| Node | Отдельная task или milestone в графе. |
| Edge | Зависимость: task B требует результата task A. |
| Parallel-ready Task | Задача, которую можно выполнять независимо от других ветвей. |
| Integration Point | Место, где результаты нескольких tasks объединяются. |
| Critical Path | Самая длинная или блокирующая цепочка зависимостей. |
| Topological Order | Порядок выполнения tasks, который соблюдает зависимости. |
Почему нужен DAG
DAG - это удобная модель, потому что feature work обычно имеет directed dependencies:
Repository must exist before service uses it.
Service must exist before controller calls it.
API contract must exist before UI integrates with it.
UI and API must exist before E2E test passes.
Циклы в task graph указывают на проблему decomposition.
Плохо:
T1 depends on T2
T2 depends on T3
T3 depends on T1
Такой graph нельзя безопасно выполнить. Нужно пересмотреть boundaries: возможно, нужна foundation task, interface contract или design clarification.
Схема Password Reset DAG
Этот graph показывает:
- spec и ADR должны быть готовы до implementation;
- repository блокирует service;
- service блокирует API;
- UI зависит от API contract;
- E2E зависит от backend и UI;
- integration tests закрывают backend ветвь до E2E.
Dependency types
Не все зависимости одинаковы.
| Тип зависимости | Пример | Что делать |
|---|---|---|
| Technical | Service зависит от repository | Выполнить upstream task сначала |
| Contract | UI зависит от API response shape | Зафиксировать contract до UI |
| Data | Endpoint зависит от migration/model | Сначала data task |
| Architecture | Implementation зависит от ADR | Утвердить ADR до code |
| Verification | E2E зависит от backend + UI | Запланировать после integration |
| Knowledge | Agent не знает existing patterns | Добавить discovery task |
Хороший task graph показывает не только порядок, но и причину зависимости.
Parallel-ready branches
Даже в single-agent курсе полезно видеть независимые ветви. Это помогает:
- планировать порядок;
- не смешивать unrelated diffs;
- готовиться к будущему multi-agent workflow;
- понимать, где возможны merge conflicts.
Пример:
After API contract is approved:
Backend integration tests
Frontend form implementation
Documentation update
могут быть частично независимыми, если contract стабилен.
Но parallel-ready не означает "можно запускать без coordination". Нужно проверить:
- не меняют ли tasks одни и те же файлы;
- не зависят ли они от одного unstable contract;
- есть ли integration point;
- понятно ли, кто resolves conflicts.
Integration tasks
Integration task - это отдельный узел графа, а не случайный финальный шаг.
Пример:
T8 API integration tests
T11 E2E happy path
T12 Acceptance checklist
Integration task проверяет, что результаты отдельных ветвей действительно работают вместе.
Без integration tasks можно получить:
- repository tests pass;
- service tests pass;
- UI renders;
- но полный password reset flow не работает.
Поэтому graph должен содержать не только build tasks, но и verification/integration tasks.
Как читать task graph
Для single-agent execution используйте topological order:
1. Выполнить tasks без dependencies.
2. Проверить их.
3. Разблокировать downstream tasks.
4. Выполнить следующую группу.
5. После ветвления выполнить integration tasks.
Пример order:
T1 Spec approved
T2 ADR token storage
T3 Repository
T4 Service
T5 Request API
T6 Confirm API
T7 Email integration
T8 API integration tests
T9 Request UI
T10 Confirm UI
T11 E2E
Если task падает, downstream tasks не должны начинаться до исправления или replanning.
Task graph format
В tasks.md можно хранить graph в двух формах.
Таблица
| Task | Depends on | Output | Verification |
|---|---|---|---|
| T3 Repository | T2 | ResetTokenRepository | unit tests |
| T4 Service | T3 | PasswordResetService | service tests |
| T5 Request API | T4 | POST request endpoint | controller tests |
| T8 Integration tests | T5, T6, T7 | API flow verified | integration tests |
Mermaid
```mermaid
flowchart TD
T3[Repository] --> T4[Service]
T4 --> T5[Request API]
T4 --> T6[Confirm API]
T5 --> T8[Integration tests]
T6 --> T8
```
В реальном файле удобно иметь обе формы: таблица лучше для деталей, diagram лучше для обзора.
Практика: нарисовать DAG
Создайте или дополните:
specs/password-reset/tasks.md
Добавьте:
# Password Reset Task Graph
## Task table
## Mermaid DAG
## Critical path
## Parallel-ready tasks
## Integration points
## Risks
Минимальные требования:
- минимум 8 tasks;
- у каждой task есть
depends on; - минимум 2 integration tasks;
- минимум 2 parallel-ready tasks;
- указан critical path;
- есть Mermaid diagram.
Пример risks в task graph
Risk:
UI task зависит от нестабильного API response.
Mitigation:
Сначала зафиксировать API contract в spec/design
и добавить controller tests.
Risk:
Repository и service tasks меняют один и тот же test helper.
Mitigation:
Выделить helper setup в отдельную task или выполнять последовательно.
Task graph нужен не только для порядка, но и для раннего обнаружения таких рисков.
Типичные ошибки
Ошибка 1. Хранить только плоский список
Плоский список скрывает dependencies. Агент может начать downstream task слишком рано.
Ошибка 2. Не добавлять integration tasks
Без integration nodes graph проверяет части, но не систему.
Ошибка 3. Считать parallel-ready все tasks в разных папках
Разные папки не гарантируют независимость. Contract, shared helpers и data model могут связывать tasks.
Ошибка 4. Не обновлять graph после изменений
Если во время работы появилась новая dependency, tasks.md нужно обновить. Иначе graph становится ложной картой.
Ошибка 5. Делать graph слишком детальным
Если каждый import становится node, graph перестает помогать. Node должен быть meaningful task или verification point.
Критерии готовности
После урока студент должен уметь:
- объяснить, зачем task graph лучше плоского списка;
- описать DAG, node, edge, integration point и critical path;
- построить Mermaid DAG для feature;
- определить parallel-ready tasks;
- указать integration tasks;
- выбрать безопасный topological order для single-agent execution.
Краткое резюме
Dependency graph сохраняет общую картину после декомпозиции. Он показывает, какие tasks зависят друг от друга, где находятся integration points и какой порядок выполнения безопасен.
В single-agent workflow graph помогает не начать задачу слишком рано. В будущих multi-agent workflow он станет основой для распределения независимых ветвей по разным агентам и worktrees.
Вопросы для самопроверки
- Почему плоский список tasks недостаточен для сложной feature?
- Что означает DAG и почему циклы в task graph опасны?
- Чем integration task отличается от обычной implementation task?
- Как определить parallel-ready tasks?
- Почему UI task часто зависит от API contract?
Что дальше
Модуль IV завершает переход от approved spec и architecture constraints к task graph. В следующем модуле мы перейдем к Context Engineering: научимся давать агенту не весь проект сразу, а правильный слой контекста для конкретной task.