DEV Community

Cover image for From Coding to Lead Agents
Heriberto Flores
Heriberto Flores

Posted on

From Coding to Lead Agents

A while ago my relationship with Claude Code was simple: I typed a request, read what came back, corrected it and typed again. It worked. It was also me doing all the coordination. I was the one remembering what had been decided three messages ago, noticing when the model drifted, and deciding when something was "done".

Today most of my prompts don't ask for code at all. They describe a process: which phases run, in what order, who does each one, what counts as evidence, and when to stop. The agent writes the code. I write the rules it works under.

I didn't get here in one jump. It happened in four stages, and each one started with something going wrong.

Stage 1: Prompting

It was late in the afternoon, two hours into one long conversation. Early on, the model and I had agreed on how a validation rule should work. Now, deep in the scrollback, it rewrote that same rule the old way, and it did it with total confidence. I scrolled up to find where we had decided it, and I realised something uncomfortable: the decision only existed in the chat, and I was the only one still remembering it.

That was the pattern back then. Ask for a feature, get a diff, point out what's wrong, repeat. The chat was the source of truth, and when the context got long, decisions quietly disappeared. Every fix polluted the next step: by the time I asked for tests, the model had already seen the implementation, so the tests matched the code, not the requirement. And "done" meant "the model said it's done". No evidence, just confidence.

None of this was the model's fault. I was asking a single context to be the analyst, the architect, the developer, the tester and the reviewer, all at once, while remembering everything.

Stage 2: Spec-driven development

The first real change was adopting spec-driven development with Spec Kit. It splits the work into explicit phases, each one producing a file: spec → clarify → plan → tasks → analyze → implement → verify.

The first time I cleared the context between two phases, it felt wrong, like throwing away work. Then I watched the plan phase read the approved spec.md and catch a requirement I had forgotten I'd written. That's when it clicked: each phase stays consistent with what is actually written down, not with the half-decisions piling up in a conversation. If it isn't in a file, it didn't happen.

The rule that surprised me most was that the implementer doesn't write the tests. Implementation writes product code only. Tests come later, in verify, written from the spec's acceptance examples by an agent that isn't allowed to read the product source. A context that has seen the implementation writes tests that confirm the implementation. A blind tester writes tests that confirm the requirement. That only works if the context is truly clean, so clearing it between implement and verify isn't a nice-to-have; it's the whole guarantee.

Bugs fit the same pipeline. A feature starts from requirements, so the spec is authored. A bug starts from a symptom, so the spec is discovered from what the code does and what was reported. Both produce the same spec.md, and the bug path is allowed to stop instead of guessing: when it can't reproduce the symptom with evidence, when nobody has defined the correct behaviour, or when the bug comes from something the codebase doesn't own. Teaching an agent when to stop turned out to be as valuable as teaching it what to do.

Stage 3: Becoming the orchestrator

SDD fixed the drift, but it created a new routine. Clear the context, run the next command, read the output, decide whether to continue, clear the context again. One day I counted how many times I had done that for a single feature and realised I was just a very attentive for-loop.

So I wrote the for-loop as a prompt. The main session stopped doing work and became an orchestrator:

## Orchestration rules

- Act only as an orchestrator; never do the work of a phase yourself.
- Run phases sequentially. For each phase, create a new, isolated subagent
  and ask it to read and follow that phase's skill.
- Before each phase, read the progress file. After it finishes, record the
  result before starting the next one.
- Each subagent reports in at most 10 lines: status, artifacts, blockers.
- If a phase fails or is blocked, record it, stop, and report why.
  Do not run later phases.
Enter fullscreen mode Exit fullscreen mode

Everything else in the prompt is about making that trustworthy. Each phase gets a fresh subagent with only the minimum it needs: the goal, the phase instructions, the relevant artifacts and the acceptance criteria. No transcripts, no "here's everything we discussed". Every subagent returns the same short report (PASS, FAIL or BLOCKED, plus artifacts, checks run and blockers), with one line I consider essential: PASS is only valid when the acceptance criteria were actually checked. The absence of reported errors is not evidence.

A progress file is the orchestrator's memory, updated after every step. The first time a session died halfway through a feature, a fresh one read that file and picked up exactly where the old one stopped. That's when I started trusting long flows.

After the phases pass, an independent subagent reviews the whole change. If it finds issues, new subagents fix them, tests run again, and a new review checks the result, for a maximum of three rounds. After that, the flow stops and reports. It never declares success on its own word, and specs can't be edited just to make a finding go away. Only when every exit condition holds does it commit, push and open a pull request. If it can't determine the target branch with certainty, it stops and asks. Do not guess the branch is literally in the prompt.

Stage 4: Planning for agents, not for humans

Once execution was agentic, the weak point moved upstream. I handed the orchestrator a plan I had written the way I'd write it for a teammate, with tasks like "refactor the module" and "fix the tests". The agents did exactly what each line said, and almost nothing I meant. A human fills the gaps with context. An agent in a fresh, isolated context has no context to fill them with.

So I wrote a second prompt whose only job is to produce plans an orchestrator can execute. Every task carries its own execution contract: the objective, the files to load, what may and may not change, dependencies, acceptance criteria, how to verify it, and a short handoff for whoever comes next. Alongside the plan comes a dependency map (what's sequential, what can run in parallel, where agents could collide on the same files) and a checkpoint so work can resume in a fresh context.

The test I use for a good plan: could another agent execute this task using only its specification and the referenced files, without the original investigation? If not, the task isn't done being planned.

What actually changed

Looking back, the code got better, but that's not the main difference. My job changed.

When I was prompting When I lead agents
I write requests I write processes
The chat holds the state Files hold the state
One context does everything Each role gets a fresh, minimal context
"Done" is the model's opinion "Done" is a list of verified conditions
I catch mistakes by reading everything Gates, limits and reviews catch them, and I review the artifacts
More agents feels like progress Delegate only what's needed for the goal

A few lessons I'd pass on:

  • Context is a resource you manage. Load only what's needed, persist the rest.
  • Teach agents to stop. An agent that halts and explains is worth more than one that guesses and keeps going.
  • Separate who builds from who checks. Blind tests and independent reviews only work when the checker hasn't seen the builder's reasoning.
  • Demand evidence, not confidence. Write it into the prompt. Agents will happily report success otherwise.
  • You're still accountable. I review the spec, the plan and the final diff. Leading agents doesn't mean leaving the room.

If I could tell myself one thing on day one, back in that two-hour chat, it would be this: stop trying to remember everything. Write it down, and build something that checks.

Your turn

Are you still in the long-chat phase, or have you started writing processes for your agents? I'd love to hear what guardrails you've found useful, or where agentic flows broke for you. Leave a comment.

Top comments (0)