feat(tasks): task_decompose splits a goal into a dependency-linked graph in one approval

The freestyle analyst can now break a large goal with dependency seams or
independent review/handoff points into a parent epic + DEPENDS_ON-linked children
in a single T2 approval, instead of N separate task_create calls. Parent
DEPENDS_ON every child (completes last); each child IMPLEMENTS parent. Resolves
depends_on by ref or index; rejects cycles, unresolved refs, missing title/goal,
and empty batches; same batch dedup + force_reason convention as task_create.

A session works one active task, so multi-task work is multi-session by
construction: the analyst names the single ready task this run works, the architect
threads only that one, and siblings are claimed by later runs via task_ready
(claim-driven; no scheduler, /tasks/next stays rejected).

Doctrine: analyst_freestyle.md picks one-task-vs-decompose and names the ready
task; architect_freestyle.md threads only that one; plus the L0 policy line.
freestyle_planning.toml analyst gains task_decompose (pinned by
FreestylePlanningWorkflowTest).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 10:39:03 +00:00
parent 67384691e0
commit 21e01da3ac
8 changed files with 446 additions and 15 deletions
@@ -4,10 +4,20 @@ given a directory path), `ls`, `grep`, `cat`, `find`.
Before deriving requirements, check for existing work: `task_search` for related, duplicate, or
blocking tasks and `task_context` to load any the goal names. Fold what you find into the
analysis rather than re-deriving it; flag a duplicate instead of restating it. If a task already
covers this work, name its id (e.g. `auth-142`) in the analysis; if none does and the work
warrants tracking (per the task policy), `task_create` one and name its id — either way later
stages thread it through the plan.
analysis rather than re-deriving it; flag a duplicate instead of restating it.
Then frame the work as a task (per the task policy):
- If a task already covers this work, name its id (e.g. `auth-142`) in the analysis.
- If the goal is a single coherent unit one run can carry to review, `task_create` one and name its
id.
- If the goal has **dependency seams** (a thing that must land before another) or **independent
review/handoff points** (a piece worth shipping or reviewing on its own), `task_decompose` it into
a parent epic + `DEPENDS_ON`-linked children — one approval for the whole graph. A session works
one task at a time, so the children are claimed by *later* runs as they unblock; don't over-split.
- After decomposing, **name in the analysis the single task this run will work** — the one already
ready (no unmet dependency, e.g. the scaffold). Leave the blocked siblings for future runs.
Either way later stages thread the named task through the plan; the rest wait to be claimed.
Emit the `analysis` artifact (JSON, schema provided):
- `summary`: the goal in your own words.
@@ -63,15 +63,17 @@ Emit a JSON object that validates against the `execution_plan` schema:
(`["file_read", "file_write", "file_edit", "ShellTool"]`). Do not invent names beyond
this set.
- **Task tracking — only if the `analysis` references a task** (an id like `auth-142` that
the analyst found or opened with `task_create`; if none is referenced there is no task to
track). When one is referenced, thread it through the plan so the work stays tracked:
the analyst found, opened with `task_create`, or named as the ready task of a
`task_decompose` graph; if none is referenced there is no task to track). Thread **only that
one task** — this run works a single task; any sibling tasks the analyst decomposed are for
later runs to claim, so do not plan or reference them here. When one is referenced:
- Give the stage that does the work `task_context` and `task_update`, and have its
`prompt` `task_update action=claim` the task before starting and
`action=submit_for_review` when its output is ready.
- Give the final or review stage `task_context` and `task_update`, and have its `prompt`
`task_update action=complete` the task once the work is accepted.
- If the `analysis` references no task, omit the task tools entirely. Do not create a
new task here — creation is out of scope for the plan.
- If the `analysis` references no task, omit the task tools entirely. Do not create or
decompose tasks here — task creation is out of scope for the plan.
- Keep stages small and single-responsibility. Prefer more stages over large monolithic
prompts.