Back to series

Spec-Driven AI-Assisted Development · Article 3

From Spec to Working Software

5 min read

A practical workflow for turning specs into working software through small implementation slices, checks, context management, and write-back.

The Spec Is Not the Work

The previous article ended with a simple point: a spec gives the work memory before implementation starts.

But a spec doesn't build the product.

At some point, the agent has to change files, write code, run checks, and respond to what breaks.

This is where the workflow matters.

If we give the agent the whole spec and say "build it, make no mistakes!", we are back to the same problem in a different shape. The agent has too much to hold, too many decisions to sequence, and too many ways to drift.

The spec is the source of truth.

The workflow is how we turn that source of truth into working software.

Teach the Agent the Workflow

The agent won't automatically know that I want requirements.md, design.md, and tasks.md.

I need to make that workflow explicit.

One way is to use a project instruction file, like AGENTS.md, CLAUDE.md, or the equivalent file for the AI tool I am using.

Another way is to create reusable commands or skills:

/add-spec
/update-spec
/implement-spec

The goal is not to add ceremony.

The goal is to avoid explaining the same workflow over and over in each prompt.

When the workflow is written down, the agent knows where decisions should go, when the spec should be updated, and when implementation can start.

I won't go deep into the setup files and reusable skills here. Article 5 will cover the practical template: project instructions, spec files, and commands like /add-spec, /update-spec, and /implement-spec.

Start With One Slice

A spec can describe the whole feature, but the agent shouldn't implement the whole feature at once.

I prefer to start with one slice.

A slice is a small piece of working behavior that can be built, checked, and reviewed on its own.

For the training-request app, "build Office Management space" is too large.

A better slice is:

Show Office Management a queue of submitted requests, with filters and a detail panel.

That slice is still useful. It touches the product workflow, backend contract, UI state, and verification.

But it is small enough to inspect.

Make the Slice Prove Itself

After the agent implements the slice, I don't want to continue immediately to the next feature.

First, the slice has to prove that it works.

For the Office Management queue, that means checking the important behavior:

  • Office Management can see submitted requests.
  • The filters return the right requests.
  • Selecting a request shows the correct detail.
  • Status and assignee changes are saved.
  • Draft requests stay out of the Office Management queue.

These checks don't need to be perfect at the beginning.

But they need to exist before the next slice starts.

Otherwise the agent keeps building on behavior that we have not verified.

Let the Checks Push Back

This is where backpressure starts to matter.

I don't mean a complicated AI harness yet.

Verification rule: If the current slice doesn't pass its checks, the agent doesn't move to the next slice.

For example:

  • If the filters are wrong, fix the filters.
  • If the status update isn't saved, fix the status update.
  • If the spec was unclear, update the spec before continuing.

This keeps the workflow honest.

The agent can still move fast, but the checks decide when it's allowed to move forward.

Keep the Context Small

When the work gets larger, context becomes part of the workflow.

In the mega-prompt experiment, the agent kept implementing for a while, and the conversation was compressed more than once.

Which means the agent was carrying a lot of work in one long thread.

For each slice, I want the active context to stay small:

  • the relevant spec lines
  • the current task
  • the expected behavior
  • the checks that must pass
  • the decision that was made if something changed

Practical rule: I try to keep the active context around 30% to 40% when possible. This is a working heuristic, not a universal threshold.

Research note: Performance can degrade as context grows, even before the advertised limit is reached. Where that degradation begins depends on the model and the task. Sources: Liu et al., TACL 2024 · Du et al., EMNLP 2025

Keeping the context small is also cheaper.

With API-based agents, the cost is direct because input and output tokens are billed.

With subscription-based tools, the cost is less visible, but it still exists. Bigger contexts consume quota faster, hit usage limits earlier, and can make the workflow slower.

Large context windows are useful, but they are not free.

If the slice becomes too large, I split it again.

A smaller context makes it easier to see what the agent is doing, what it changed, and whether it is still following the spec.

Write Back What Changed

When the agent finishes a slice, the useful information shouldn't stay only in the conversation.

If we learned something during implementation, it should go back into the spec or the task list.

For example:

  • If a business rule became clearer, update requirements.md.
  • If an architecture choice was made, update design.md.
  • If a task is done, mark it in tasks.md.
  • If a check failed, keep it visible until it passes.

This is what keeps the spec alive.

The conversation can be compressed, closed, or forgotten, but the files stay.

What This Changes

The agent is still writing code.

But the work is no longer one long request.

Each slice has context, checks, and a place to write back what changed.

If the agent can implement more of the code, what does the engineer still own?