Most advice on spec-driven development gets one thing backwards. It treats the hard part as writing the spec. It isn't. The hard part is keeping the spec true after the first real implementation surprise.

That's why the backlash is partly right. A lot of spec-first workflows really are waterfall with markdown. You get a polished doc, a burst of agent output, then three hours later the code and the plan no longer match. At that point the spec isn't guidance. It's debris.

For a solo builder, that failure hurts more. You don't have a product manager correcting scope, a staff engineer catching architectural drift, or a team keeping docs current. If you're using Cursor, Claude Code, Codex, or Gemini, stale specs get turned into fresh mistakes. Fast.

The useful split isn't spec-driven vs no specs. It's living specs vs frozen specs.

Here's the short version.

Dimension Living spec Frozen spec
Role Working source of truth Kickoff artifact
State after coding starts Updated with discoveries Left behind
Relationship to code Tracks reality Drifts from reality
Best use case Multi-step work, agent-assisted work, architecture changes Tiny tasks you'll finish before context shifts
Failure mode Some upkeep overhead Misdirection, rework, confusion
What it feels like Lightweight steering Waterfall with markdown

If you only remember one line, remember this: living specs update as the code changes. Frozen specs start lying the moment the work diverges.

Table of Contents

The Spec-Driven Backlash is Right About One Thing

The backlash isn't wrong. If you write a spec, bless it as truth, and then code against it without updating it, you've rebuilt waterfall in a nicer file format.

Simon Willison has pushed on this from the practical side. Birgitta Böckeler's taxonomy is useful here too. The difference isn't whether a spec exists before coding. The difference is whether the spec stays mutable during implementation. Addy Osmani's six-section format can work well. It can also become ceremony if nobody touches it after kickoff.

A frustrated developer looking at a stack of smoking, dusty requirement specification binders on their office desk.

The phrase waterfall with markdown lands because people have felt it. They write a beautiful document, hand it to an agent, and then spend the rest of the task compensating for all the things the document didn't predict. That critique is fair. The answer isn't "stop using specs." The answer is "stop freezing them."

A useful analogy comes from outside software. A study in Human Reproduction found that a dynamic, adaptable protocol for IVF cycles resulted in higher cumulative success rates than a rigid, frozen-all plan, which supports a broader point about plans that can adapt to real-time feedback versus plans locked up front (Human Reproduction cohort study). Different field, same lesson. If the environment changes while you execute, rigid plans underperform.

Practical rule: If the spec can't change after implementation starts, it isn't helping you think. It's forcing you to pretend you learned nothing.

For solo builders, this is the main dividing line between useful SDD and process theater. A living spec is just a doc that stays connected to reality. A frozen spec is technical debt wearing product language.

If you want the broader argument about when specs speed you up and when they become drag, read Tekk's take on when specs slow you down and when they help.

The Frozen Spec Trap Why Most Specs Become Useless

Most specs don't fail at the writing stage. They fail in the hours after the first commit.

The pattern is predictable. You start with clean intent. Then implementation exposes edge cases, hidden dependencies, naming conflicts, or a UI flow that only makes sense once you touch the code. The code changes. The conversations change. The spec doesn't.

An infographic illustrating the four stages of the Frozen Spec Trap in software development team projects.

The drift starts earlier than people think

A frozen spec usually dies in four moves:

  1. Kickoff optimism. The doc feels complete enough to start.
  2. Reality intrudes. You discover constraints that weren't obvious at planning time.
  3. Conversation leaves the doc. Decisions move to chat, commit messages, scratch notes, and your head.
  4. The file becomes unsafe to trust. You stop reading it because it's easier than sorting truth from history.

That's the trap. An outdated spec isn't neutral. It actively misleads your future self.

One reason this happens is the substrate itself. In community threads about AI-first workflows, developers keep circling the same complaint: markdown by itself doesn't enforce truth. A .md file can sit beside the code and still rot without notice. The thread on /r/VibeCodeDevs about managing context captures that pain well. The doc exists, but nothing compels sync.

The symptoms are obvious if you look

You can usually spot a frozen-spec workflow fast:

  • The PR or commit doesn't mention the spec. Work happened, but the source doc didn't move.
  • Open questions live somewhere else. Slack, Discord, notes app, terminal history.
  • Status is implied, not stated. Nobody knows whether the spec is proposed, active, outdated, or dead.
  • You hesitate before trusting the document. That hesitation is the signal.

A similar frustration shows up in developer discussions about standardizing AI use. The problem isn't only "how do we write specs?" It's "how do we stop them turning into stale ceremony the moment the task gets real?" The answer is usually not more template. It's tighter update mechanics.

If you want a parallel take from an AI documentation workflow angle, Halo AI's piece on how AI helps keep docs honest is worth reading because it focuses on the operational problem, not the aesthetic one.

Frozen specs don't usually explode. They decay. That's why teams tolerate them for too long.

The worst part is that frozen specs feel responsible. They look like rigor. But for a solo founder shipping under time pressure, they waste time twice. Once when you write them. Again when you work around them.

Anatomy of a Living Spec

A living spec isn't a philosophical posture. It's a document with a few built-in mechanisms that make drift visible and revision normal.

Birgitta Böckeler's framing around spec-anchored work is useful here. The spec is central, but not sacred. It remains editable because implementation teaches you things. Addy Osmani's spec guidance is also useful, especially the idea that the doc needs enough structure to survive revisions instead of collapsing into prose.

An infographic titled Anatomy of a Living Spec explaining four key components for dynamic project documentation.

The minimum metadata that keeps a spec alive

You don't need a giant framework. You need metadata that answers basic operational questions.

Use frontmatter like this:


---
title: Billing retry flow rewrite
status: active
version: 1.2.0
created: 2026-06-12
updated: 2026-06-12
owner: founder
supersedes: ./billing-retry-flow-v1.1.0.md
superseded_by:
review_trigger:
  - schema change
  - prompt change
  - new edge case found in implementation
related_code:
  - app/services/billing/retry.ts
  - app/api/webhooks/stripe.ts

---

The important fields are simple:

  • status tells you whether the file is still in play.
  • version gives you a history that matches decisions, not just commits.
  • supersedes / superseded_by stops old docs from hanging around like landmines.
  • review_trigger tells you when the doc must be revisited.

Without those fields, you're relying on memory. Memory is where solo workflows break.

A living spec should answer three questions in seconds: Is this current? What replaced it? What code does it touch?

If you want a complementary guide on writing more effective specification documents, AIDictation has a practical piece on effective specification documents that pairs well with this living-spec approach.

The document shape that actually works

A good living spec doesn't need to be long. It needs to be updateable.

This shape works well for solo builders:

Section What goes in it Why it matters
TL;DR The task in plain English Keeps you from drowning in implementation detail
Scope boundaries What's in and out Stops creep
Assumptions and risks Unknowns, dependencies, gotchas Makes revision expected
Subtasks Ordered steps Gives agents and humans a sequence
Acceptance criteria Observable done states Prevents hand-wavy completion
Change log What changed during implementation Keeps history attached to the spec

A few habits make this work:

  • Update at transition points. Don't wait until the end. Update when scope changes, when you hit a blocker, or when you choose a different path.
  • Write decisions, not diaries. "Switched to webhook-first retry because cron path conflicts with existing idempotency logic" is useful. A stream-of-consciousness recap isn't.
  • Deprecate aggressively. If a spec no longer reflects the path, mark it deprecated or superseded. Don't leave it half-true.

A living spec is less like a contract and more like an ADR attached to active work. That's why the ADR discussions in AI coding communities resonate. They preserve decisions without pretending the first version was final.

Workflows and Tooling for Living Specs

The mechanics matter more than the ideology. If your workflow doesn't force reality back into the spec, the spec will drift no matter how good your template looks.

Some solo builders can do this with plain markdown and discipline. Others need a structured loop so the document doesn't get abandoned when the coding gets messy. Both approaches can work.

A six-step diagram illustrating the automated workflow for managing, validating, and updating living technical specifications.

Manual workflow if you want zero ceremony

The lightest workable setup lives in your repo.

Keep a /specs folder. One file per active initiative. The rule is simple: if code changed in a way that affects intent, scope, acceptance criteria, or architecture, the spec changes in the same work session.

A manual loop looks like this:

  • Start with status: proposed. Write the smallest useful spec before touching code.
  • Flip to active when implementation begins. That small status change matters. It marks the file as a live operational document.
  • Append a short change note when reality shifts. Scope cut, renamed component, schema adjustment, dependency discovered.
  • Close with completed, deprecated, or superseded. Never leave the terminal state ambiguous.

This is enough for many indie projects. It works best when one person owns the whole task and the task finishes before context evaporates.

Structured workflow if discipline alone keeps failing

If your markdown folder turns into a graveyard, add a workflow layer.

GitHub's Spec Kit is one option. OpenSpec is another useful reference because it makes the lifecycle explicit with Propose / Apply / Archive. That structure does something important. It treats supersession as normal instead of as a sign that the original spec failed.

Here's a practical spectrum:

Approach Good fit Weakness
Plain markdown in repo You're disciplined and work alone Easy to forget updates
Template plus repo conventions You want consistency without much tooling Still relies on habit
Spec workflow frameworks like OpenSpec You want explicit lifecycle states Slightly more setup
Codebase-aware planning tools You want the spec tied closely to repo reality You must still review and revise

The right choice is the smallest system you'll keep current.

One useful pattern is a review cadence tied to events, not calendar guilt. Review the spec when one of these happens:

  • A prompt changes direction. The agent needed a new instruction because the original plan was wrong or incomplete.
  • A file touch expands. The work spills into areas outside the original scope boundary.
  • An acceptance criterion becomes impossible or irrelevant.
  • You discover a design decision worth preserving.

That event-driven review works better for solo builders than "update docs every Friday." Friday rituals get skipped. Work-triggered updates don't.

If you're trying to make this fit an agent workflow instead of a traditional team process, Tekk's guide to an AI agent workflow is a useful companion because it centers the handoff and revision loop around actual implementation.

Why AI Coding Agents Demand Living Specs

AI coding agents are literal in the worst possible way. They don't know which parts of your stale spec to distrust. They assume the map you hand them still matches the territory.

That makes frozen specs much more dangerous in agent-driven development than in manual coding. A human developer can notice the doc is old and compensate. An agent will often execute the wrong thing cleanly.

Agents follow the map you hand them

At this stage, living specs stop being "nice process" and become operational necessity.

A study of 600 rejected AI-generated pull requests found that alignment loss during execution caused more failures than an initially flawed task description, which is a strong signal that drift during implementation is the bigger risk in multi-step AI workflows (Augment Code on living specs vs static specs).

That finding matches what builders see in practice. The first prompt is often good enough. The failure happens later, when the codebase evolves mid-task and the original spec doesn't.

The agent isn't confused. It's obedient to outdated instructions.

That's why big-task prompting often feels expensive and weirdly brittle. You're not only paying for generation. You're paying for repeated attempts against stale context.

For a broader take on how AI-assisted development changes planning, Tekk's article on codebase-aware AI planning gets at the same issue from the planning side.

Where frozen specs break agent workflows

The failure pattern usually looks like this:

  • The spec says a component will own the logic.
  • The implementation reveals that the logic belongs in a service layer instead.
  • You adjust the code but not the spec.
  • The next agent pass adds work back into the wrong place because the document still says so.

Or this:

  • The acceptance criteria were written before you saw the actual edge case.
  • You discover the edge case in testing.
  • You patch around it in code.
  • The next run "fixes" your patch because the agent still thinks the old acceptance criteria are canonical.

If you're building mobile or cross-platform products with code generation in the mix, AppLighter's piece on boost React Native productivity with AI is useful context because it shows how much output quality depends on the clarity and recency of the guidance you provide.

Living specs solve this by narrowing the gap between planning and execution. Not perfectly. But enough that the agent keeps pulling in the current direction instead of reviving dead decisions.

A Decision Framework for Solo Builders

You don't need a living spec for every task. For some work, that would be overkill. The trick is knowing when "just jot a note and go" is fine and when that shortcut will cost you later.

Screenshot from https://tekk.coach

When a frozen spec is fine

A frozen spec is acceptable when all of these are true:

  • The task is tiny. You expect to finish before context shifts.
  • The blast radius is small. One small bug, one isolated component, one obvious fix.
  • There are no meaningful architectural choices. You're not deciding patterns, boundaries, or data contracts.
  • You won't need the doc later. The note is just a temporary launchpad.

In that case, a short static brief is fine. Write the task, do it, discard the note.

When a living spec is non-negotiable

Once the task stops being trivial, the cost calculation flips.

Use a living spec when the work has any of these traits:

Signal Why it matters
Multi-step implementation Drift compounds between passes
Multiple files or layers touched The plan changes as dependencies surface
Architecture or schema changes You need durable decision history
AI agent involvement Stale instructions get executed literally
Work likely to pause and resume Future-you needs a truthful state snapshot
Scope uncertainty The spec must absorb discoveries, not deny them

For builders who want tooling around this, Tekk.coach fits the living-spec model. It connects to a GitHub repo, asks structured follow-up questions, and produces a spec you manually hand to Cursor, Claude Code, Codex, or Gemini. Its async CTO loop runs one tick per workspace and emits at most one proposal or question per tick, which makes it more like an ongoing planning check than an orchestration layer. That's useful if you want codebase-aware specs without pretending the first draft should stay frozen.

If the task can surprise you, the spec must be allowed to change.

That's the whole decision rule.

How to Start with Living Specs Tomorrow

Don't start with a framework. Start with one habit.

For your next non-trivial task, create a markdown file in your repo and add this at the top:


---
title: [task name]
status: proposed
updated: 2026-06-12

---

When you begin coding, change proposed to active.

When implementation teaches you something important, add a short note under a ## Change log heading. Not every thought. Just the decisions that changed the shape of the work. If you abandon the plan, mark it deprecated. If a new file replaces it, add superseded_by.

That's enough to build the muscle.

If you want one more useful rule, borrow from ADR habits discussed in AI coding communities. Treat every material decision as something worth recording where the work already lives. Not in chat. Not in your head. In the file the next agent run will read.

A minimal starter template:


---
title: Add invoice retry guard
status: active
version: 0.1.0

---

## TL;DR
Prevent duplicate retries when webhook and manual retry overlap.

## Scope
In: retry guard, idempotency check
Out: full billing refactor

## Acceptance criteria
- Duplicate retry attempt is ignored
- Existing success path still works

## Change log
- Moved guard from controller to service after implementation exposed shared call path

Do that for one week and you'll feel the difference. The doc stops being ceremony and starts acting like memory you can trust.


Connect your GitHub repo. Describe the problem. Get a structured spec. Ship. Tekk.coach is built for solo builders who need codebase-aware specs they can keep alive while working.

Part of the Spec-Driven Development pillar — a 52-page honest playbook on shipping with AI coding agents.