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>
Live repro: architect emitted a verify stage with kind=analysis and a
verdict-equals edge. The kind schema doubles as the LLM response format,
so 'verdict' was never emitted and the workflow failed at its final hop
at runtime. The compiler now requires artifact_field_equals fields to be
declared by the producing stage's kind schema, failing the plan at lock
time with a pointer at review_report. Architect prompt rule added;
reachability check extracted alongside the new validation.
Live repro: the architect wired all three stages straight to 'done'
instead of chaining them, so phase 2 legitimately completed after
stage 1 of 3 — a silently truncated plan reported as success. The
compiler now walks the edge graph from start and fails compilation
when any declared stage is unreachable, surfacing the broken topology
as ExecutionPlanRejected at lock time instead. Architect prompt edge
rules rewritten to demand explicit chaining (the old wording was
garbled).
ExecutionPlanCompiler treated the plan's single 'produces' string as a
registry kind id, while the architect prompt described it as a unique
artifact id referenced by needs/edges — the model followed the prompt,
invented descriptive ids (files_created), and every freestyle plan
failed to compile. Collapsing both onto one string is also unsound:
two stages producing the same kind would collide on slot name and make
artifact_validated edge conditions ambiguous.
Plan stages now carry an optional 'kind' selecting the registered kind
(mirroring TOML's produces = { name, kind }); 'produces' stays the
unique slot name. Missing 'kind' falls back to the old produces-as-kind
reading so existing plans still compile. Vocabulary entry, architect
prompt, and execution_plan schemas updated to match.
Add docs/schemas/execution_plan.json (goal/stages/edges), the
architect_freestyle prompt that instructs emitting the execution pipeline as
JSON, and register the execution_plan llm-emitted kind in both
artifacts.config.toml and sample-config.toml. Validated via
ExecutionPlanSchemaValidationTest (minimal plan passes; missing stages rejected).