feat(tasks): analyst opens the task; freestyle threads it into implementation
Two coupled gaps from tracing a real run: 1. Freestyle implements in phase 2 via stages compiled from the architect's execution_plan (ExecutionPlanCompiler sets allowedTools = stage.tools), so the static allow-lists never reach it and architect_freestyle.md banned every tool but the file four. Teach the architect to thread an analysis-referenced task through the plan: implementing stages get task_context/task_update and claim + submit_for_review; the final/review stage completes it. No task referenced → no task tools, and the plan never creates one. 2. Give the analyst task_create so the work is framed as a tracked item up front (role_pipeline + freestyle). "Read-only" for the analyst means it writes no files; a task is an event-log entry, not a file write — task_create is T2, so opening one is approval-gated. The analyst names the new id in the analysis so the implementer claims it and the reviewer completes it; the implementer now creates only as a fallback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
id = "freestyle_planning"
|
||||
start = "analyst"
|
||||
|
||||
# analyst is read-only, so it gets only the read-only task tools: task_search to find related
|
||||
# or duplicate work and task_context to ground the analysis in an existing task.
|
||||
# analyst writes no files, but it owns task framing: task_search/task_context (read-only) find
|
||||
# existing work, and task_create (T2, approval-gated — a task is an event-log entry, not a file
|
||||
# write) opens a task for this work and names its id in the analysis, so the architect can thread
|
||||
# it into the plan's implementation stages.
|
||||
[[stages]]
|
||||
id = "analyst"
|
||||
prompt = "prompts/analyst_freestyle.md"
|
||||
produces = [{ name = "analysis", kind = "analysis" }]
|
||||
allowed_tools = ["file_read", "ShellTool", "task_search", "task_context"]
|
||||
allowed_tools = ["file_read", "ShellTool", "task_search", "task_context", "task_create"]
|
||||
token_budget = 16384
|
||||
max_retries = 2
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@ Steps:
|
||||
code. Identify the files, modules, and subsystems involved. Do not modify anything.
|
||||
3. Check for existing work: `task_search` for related, duplicate, or blocking tasks, and
|
||||
`task_context` to load any the request names. Fold what you find into the analysis rather
|
||||
than re-deriving it; flag a duplicate instead of restating it.
|
||||
than re-deriving it; flag a duplicate instead of restating it. If this work warrants tracking
|
||||
(per the task policy) and no task covers it, `task_create` one and name its id in the analysis
|
||||
so the implementer claims it and the reviewer completes it.
|
||||
4. Derive concrete, checkable requirements and acceptance criteria.
|
||||
|
||||
The decision history above (steering, approvals, prior verdicts) is ground truth — honour it.
|
||||
|
||||
@@ -4,7 +4,10 @@ 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.
|
||||
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.
|
||||
|
||||
Emit the `analysis` artifact (JSON, schema provided):
|
||||
- `summary`: the goal in your own words.
|
||||
|
||||
@@ -57,9 +57,21 @@ Emit a JSON object that validates against the `execution_plan` schema:
|
||||
llm-emitted kind.
|
||||
- Declare `needs`: every upstream artifact id the stage's prompt references. Every id in
|
||||
`needs` must be `produces`d by a strictly earlier stage.
|
||||
- Include `tools` only for stages that write or edit files:
|
||||
`["file_read", "file_write", "file_edit", "ShellTool"]`. Do not invent tool names
|
||||
beyond this set.
|
||||
- Include `tools` per stage as it needs them, using only names from this set:
|
||||
`file_read`, `file_write`, `file_edit`, `ShellTool`, `task_context`, `task_update`,
|
||||
`task_search`. Stages that write or edit files take the file set
|
||||
(`["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:
|
||||
- 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.
|
||||
- Keep stages small and single-responsibility. Prefer more stages over large monolithic
|
||||
prompts.
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ You receive the `impl_plan` artifact (above). Execute it using the tools availab
|
||||
(`file_read`, `file_write`, `file_edit`, and shell). File writes land in the bound workspace.
|
||||
|
||||
Steps:
|
||||
1. If this work is tracked as a task — or warrants it per the task policy in the context above —
|
||||
`task_context` to load it and `task_update action=claim` before you start; `task_create` one
|
||||
if none exists. Skip this for a self-contained change.
|
||||
1. If the analysis opened or referenced a task, `task_context` to load it and `task_update
|
||||
action=claim` before you start (`task_create` one only if the work warrants tracking and none
|
||||
exists). Skip this for a self-contained change.
|
||||
2. Work through the plan `steps` in order. Read before you edit.
|
||||
3. Make the change with `file_write` / `file_edit`. Keep new code consistent with the
|
||||
surrounding style, naming, and patterns.
|
||||
|
||||
@@ -24,16 +24,17 @@
|
||||
id = "role_pipeline"
|
||||
start = "analyst"
|
||||
|
||||
# 1. Understand the request and the relevant code. Read-only.
|
||||
# ground_references: every workspace-relative file path the analysis names is checked
|
||||
# for existence; a hallucinated path fails the stage and retries with the misses fed back.
|
||||
# task_search/task_context (read-only) let it find related or duplicate tasks and load
|
||||
# their context, so the analysis is grounded in existing work rather than re-derived.
|
||||
# 1. Understand the request and the relevant code — writes no files (ground_references checks
|
||||
# every workspace path the analysis names; a hallucinated path fails the stage and retries).
|
||||
# It also owns task framing: task_search/task_context (read-only) find existing work, and
|
||||
# task_create (T2, approval-gated — a task is an event-log entry, not a file write) opens a
|
||||
# task for this work up front, named in the analysis so the implementer claims it and the
|
||||
# reviewer completes it.
|
||||
[[stages]]
|
||||
id = "analyst"
|
||||
prompt = "prompts/analyst.md"
|
||||
produces = [{ name = "analysis", kind = "analysis" }]
|
||||
allowed_tools = ["file_read", "ShellTool", "task_search", "task_context"]
|
||||
allowed_tools = ["file_read", "ShellTool", "task_search", "task_context", "task_create"]
|
||||
ground_references = true
|
||||
token_budget = 16384
|
||||
max_retries = 2
|
||||
|
||||
Reference in New Issue
Block a user