PROJECT · 90 minutes
Capstone project: build the linear task-orchestration agent at the heart of Brandon's SDLC harness — spec in, steps planned and executed sequentially with shared context, status report out.
Every module in this path has been building toward one question: what does a reliable agentic system actually look like when you run it for real? This capstone answers that with the same pattern I use in my SDLC harness — a linear task-orchestration agent that runs on my Mac Mini, driven by a plain Markdown spec file.
The agent does four things, in strict order:
claude-sonnet-4-6 to decompose the spec into numbered steps.No parallel subtasks, no handoff between specialized agents, no orchestration framework. The simplicity is the point. Module 06 gives you the theory for why this works; this module gives you the working code.
Think of the agent like a contractor who reads a project brief, writes a numbered to-do list, works through it top-to-bottom while keeping notes on each completed item, and then files a completion report. The notes carry forward — every item on the list is informed by everything done before it. That is the shared-context principle made concrete.
Why "research agent"? The module title is inherited from the original path. The build you will complete here is more precisely a task-orchestration agent — the same pattern underpins research automation, code-generation pipelines, and anything else that needs a plan executed step-by-step with a running log.
The agent starts with a plain-text spec file. In the SDLC harness this is a Markdown task description; for this module any text file describing a task will work.
Copy this block, create a task-spec.md with any task description, and run it. The client
object is all you need — no additional SDK wrapping. This is your first runnable step, and
it verifies your ANTHROPIC_API_KEY before you write any more code.
Spec size matters. If the spec is thousands of tokens long, Claude's step list can drift or repeat itself. Keep specs focused on one task. Break large projects into multiple shorter specs rather than one enormous document.
Once the spec is loaded, the agent asks Claude to decompose it into a numbered list of steps. The prompt is deliberately minimal — we want a clean step list, not prose explanation.
The parser is simple: any line starting with a digit is a step. Production harnesses often ask for structured JSON output and parse that instead, but plain text is easier to inspect when you are getting the system running for the first time.
Before moving on, predict: what does response.content[0].text hold after the plan_steps
call above? The model's generated numbered step list — not a token count, not the system
prompt, not the raw HTTP response. Add print(raw) before the list comprehension and run it
against a real spec to confirm.
Planning is just a Claude call. There is no magic planner here — just a language model reading a spec and listing steps. The reliability comes from passing the full plan and all prior step results forward to every subsequent stage.
The agent needs to do things — read files, write files, run commands. In the Anthropic SDK, tools are defined as JSON schemas that describe what each tool accepts. Think of a tool definition like a job description you hand to a new contractor: a name, what the role does, and what information they need to start.
Tool descriptions do real work. A clear description lets the model select the right tool without any routing logic from you. If the model keeps choosing the wrong tool for a step, improve the description before reaching for conditional logic.
Now add the dispatch function that routes a tool-call block to its real implementation:
Two tools, one dispatch function, eleven lines. Module 03 showed you how to extend this
incrementally — adding a run_command tool follows exactly the same pattern. Start with the
minimum tools the task requires and add more only when you have evidence a capability is missing.
The execution loop is where the path's core thesis becomes code. Each step receives the full history of every completed step before it — not a summary, not a filtered view — so the model's decisions are always grounded in what already happened.
Notice that context["history"] grows with every call. Step 3 can see steps 1 and 2 in full
detail. That is what makes the outputs coherent — no step is working blind. When no tool_use
block appears, the model's text response is treated as the step result and appended to history
so that later steps still see it.
What would break if you ran all steps in parallel instead of sequentially?
Each step would start with an empty history. Step 3 could not know that step 1 already created the file it is supposed to read. Steps would conflict or duplicate work, and the final report would be incoherent — exactly the failure mode module 06 describes in the multi-agent trap. Sequential with shared context produces better output, even when parallel looks faster on paper.
Resist the urge to parallelize. Each step you parallelize is a step that cannot see what the others are doing. Sequential execution with shared context almost always produces more coherent results than parallel execution with isolated contexts.
When all steps finish, the agent asks Claude to turn the accumulated history into a human-readable status report, then writes it to disk.
The report summarizes what the agent actually did, not what it planned to do. If step 2 failed to find a file, the history captured that failure, and the report reflects reality. This honest audit trail is what makes the system trustworthy enough to use for real work.
Now assemble the four stages into a single run_task_agent function. Each stage calls a
function you have already seen — no new logic, just composition in order.
This is the complete agent. Four stages, six functions, one linear pass through the spec. The
SDLC harness I run on my Mac Mini follows this exact shape — the production version adds a
retry wrapper around execute_step and writes structured logs, but the core loop is identical.
What you just built is the real thing. A spec drives a Claude API call to generate a plan; each plan step calls a real Anthropic tool; the full history threads through every iteration; a final Claude call writes the report. Copy this into a project and point it at a real spec — it runs.
Module 06 will explain why this architecture is reliable: the relay-race principle (each step hands the baton — the full context — to the next runner), and why multi-agent systems fail when that handoff is broken. What you built here is the practical demonstration of the theory.
The exercise below extends the capstone with a human-confirmation gate before the report is written — the same checkpoint pattern from module 04, applied at the exact moment where a mistake would be hardest to undo.
Application-level questions on the task-orchestration agent, shared context, and tool dispatching.
1. After `plan_steps(spec)` returns, what does the list contain?
Correct Answer: B
plan_steps filters the response for lines starting with a digit and returns a list of those step strings. The list comprehension discards blank lines and non-step prose, leaving only the numbered step content.
2. In `execute_step`, why is `context['history']` passed to Claude on every call?
Correct Answer: B
Shared context is the core reliability mechanism. Each step's prompt includes the full history of prior steps so the model's decisions are grounded in what actually happened — not assumptions about what might have happened.
3. What does `execute_step` do when the response contains no `tool_use` block?
Correct Answer: C
The loop exits without calling dispatch_tool. The model's text response is treated as the step result, appended to context['history'], and returned. This handles steps that are better answered with prose than a tool call.
4. You run all steps in parallel, each starting with an empty `context['history']`. Which failure is most likely?
Correct Answer: C
With an empty history, step 3 cannot know that step 1 already created a file it is supposed to read. Steps make incompatible assumptions, produce conflicting output, and the final report is incoherent — the multi-agent trap applied to a single-agent context.
5. The `read_file` description is changed to 'A file utility'. The model starts choosing `write_file` for read-only steps. What is the most likely cause?
Correct Answer: B
The model reads tool descriptions to select the right tool. 'A file utility' gives no signal about what the tool does or when to use it. Clear, specific descriptions are the first lever for fixing tool-selection problems.
6. The exercise adds the human gate BEFORE `write_status_report`. Why not after?
Correct Answer: B
Once write_status_report writes to disk, the artifact exists and may propagate to other systems. A gate before the write is a true checkpoint. A gate after the write arrives too late to prevent the file from being committed.
7. If the model requests a tool named `run_command` and `dispatch_tool` has no case for it, what happens?
Correct Answer: D
The final `return f'Unknown tool: {name}'` handles the fallback. The agent logs this string in context['history'] and continues — a safe default that produces an error message rather than an exception that would abort the entire run.
8. Which argument to `client.messages.create` enables the model to issue tool calls?
Correct Answer: C
The Anthropic SDK uses `tools=[...]`. `functions` is an OpenAI convention. `capabilities` and `tool_definitions` are not valid Anthropic parameters. Passing the wrong key means the model never sees the tools and will not issue any tool_use blocks.