id = "freestyle_planning"
start = "discovery"

# discovery runs before the analyst: it vets the request against the real repo and either clears
# it to plan or parks on a batched list of operator questions (grounds contradictions too, e.g. a
# request naming an endpoint the server doesn't expose). Read-only; owns clarification exclusively.
[[stages]]
id = "discovery"
prompt = "prompts/discovery.md"
produces = [{ name = "discovery", kind = "discovery" }]
allowed_tools = ["file_read", "list_dir", "shell"]
token_budget = 16384
max_retries = 2

# analyst writes no files, but it owns task framing: task_search/task_context (read-only) find
# existing work; task_create (T2, approval-gated — a task is an event-log entry, not a file write)
# opens a single task; task_decompose (T2, one approval for the whole graph) splits a goal with
# dependency seams into parent + DEPENDS_ON-linked children. Either way the analysis names the task
# id the run will work, so the architect threads it into the plan's implementation stages.
[[stages]]
id = "analyst"
prompt = "prompts/analyst_freestyle.md"
produces = [{ name = "analysis", kind = "analysis" }]
allowed_tools = ["file_read", "list_dir", "shell", "task_search", "task_context", "task_create", "task_decompose"]
token_budget = 16384
max_retries = 2

[[stages]]
id = "architect"
requires_approval = true
inject_artifact_kinds = true
prompt = "prompts/architect_freestyle.md"
needs = ["analysis"]
produces = [{ name = "execution_plan", kind = "execution_plan" }]
token_budget = 16384
max_retries = 2

[[transitions]]
id = "discovery-to-analyst"
from = "discovery"
to = "analyst"
condition_type = "artifact_validated"
condition_artifact_id = "discovery"

[[transitions]]
id = "analyst-to-architect"
from = "analyst"
to = "architect"
condition_type = "artifact_validated"
condition_artifact_id = "analysis"

[[transitions]]
id = "architect-to-done"
from = "architect"
to = "done"
condition_type = "artifact_validated"
condition_artifact_id = "execution_plan"
