W
WisyLink
ProductPricingAPIBlogContact
All posts

WisyLink Blog

spec-driven-developmentexecutable-specificationssource-of-truthcode-generationintent-versioning

Spec-Driven Development: When the Spec Becomes the Product

Spec-driven development makes the executable specification the source of truth and code a regenerable projection. What changes when teams own intent, not lines.

Jun 16, 20268 min read
Spec-Driven Development: When the Spec Becomes the Product

Spec-driven development is the discipline of treating an executable specification as the primary artifact a team owns, with code generated as a downstream projection of that intent. When the specification carries enough precision to regenerate the implementation, the spec becomes the source of truth — the thing humans version, review, and argue over — while code settles into a derived, replaceable layer beneath it.

  • The specification becomes the durable artifact; code becomes a regenerable projection of it.
  • Review shifts upward, from diffs of implementation to diffs of intent.
  • Determinism of regeneration matters more than elegance of any single output.
  • Specifications accrue their own debt when intent drifts from what runs.
  • Versioning the spec changes what "a change" even means inside a system.
  • As systems grow, the seams between specifications strain before the code does.

Why the specification, not the code, becomes the source of truth

An executable specification refers to a description of intended behavior precise enough that a generator can produce a working implementation from it without further human authoring. The shift it introduces is quiet but structural. For decades the code was the artifact that survived; comments, design documents, and tickets decayed around it, and the running program remained the only honest record of what a system did. Spec-first inverts that relationship.

When intent is captured as something a machine can execute against, the specification stops being documentation and starts being the asset. Code is regenerated from it, and the implementation that exists at any moment is one of many valid projections. What survives across regenerations is the spec. That is the heart of the change: the most durable thing in the repository is no longer the most detailed thing.

This tends to reorganize ownership. The artifact a person defends in review is the statement of behavior, not the lines that satisfy it. A team that internalizes this stops treating generated code as precious and starts treating it as weather — present, consequential, and expected to change. The instinct to polish a function by hand fades, because the polish lives one regeneration away from being erased.

What changes when review moves from code to intent

Once the spec is the source of truth, the center of gravity in review moves with it. Reviewers stop reading implementation diffs line by line and start reading changes to the specification — additions to behavior, tightened constraints, removed assumptions. The implementation diff becomes an output to spot-check rather than the object of scrutiny.

This is harder than it sounds. A specification diff often looks small while the regenerated code beneath it changes substantially. A single sentence added to a behavioral clause can ripple through hundreds of generated lines. Reviewers learn to reason about the blast radius of an intent change without reading every projected line, which is a different skill than reading code, and one that takes time to build.

One tradeoff that surfaces is traceability. When a defect appears in generated code, the question is no longer "who wrote this line" but "which clause of the specification produced it." Teams that practice spec-first build the habit of tracing defects back to intent, then deciding whether the spec was wrong or the generator misread a correct spec. That second case is its own category of bug — a fidelity failure — and it has no equivalent in hand-written code.

How regeneration determinism shapes whether the spec can be trusted

For a specification to serve as source of truth, regeneration has to be predictable enough to rely on. If the same spec produces materially different implementations each time, the spec is not really the source of truth — the generator's mood is. So the discipline puts heavy weight on determinism: stable outputs, pinned generation behavior, and tests that bind the projection to the intent.

There is a spectrum here. Eager regeneration rebuilds the implementation on every meaningful spec change and treats the code as fully disposable. Lazy regeneration keeps a generated baseline and reprojects only the parts a change touches. Each has costs, and the choice tends to track the size of the system more than the preference of the team.

PropertyEager regenerationLazy regeneration
Code permanenceFully disposable; rebuilt wholesalePartially retained between changes
Drift riskLow; output always tracks the specHigher; stale regions can linger
Cost per changeHigh compute, low reasoningLow compute, higher reasoning
Failure modeWhole-system surprisesLocalized inconsistencies

Neither end is correct in the abstract. Small systems tolerate eager regeneration cheaply and benefit from its guarantee that output always tracks the spec. Large systems often cannot afford to reproject everything and drift toward lazy strategies, which reintroduces some of the divergence spec-first was meant to remove.

Where specifications accumulate their own kind of debt

Specification debt is the gap that opens when the written intent no longer matches what the running system actually needs. It is the spec-first analogue of legacy code, and it accrues in familiar ways. Clauses contradict each other. Edge cases get bolted on as exceptions rather than folded into the model. The specification grows by accretion until no single person holds its whole shape.

The failure is subtler than tangled code because a specification can read cleanly while encoding an incoherent intent. A well-formatted spec full of quiet contradictions still generates something — it just generates the wrong thing confidently. Reviewers can be lulled by prose that looks deliberate, and the generator will never object to a contradiction the way a compiler objects to a type error.

Specification drift
The slow divergence between stated intent and the behavior the system actually requires in practice.
Projection fidelity
The degree to which generated code faithfully realizes the specification without adding or dropping behavior.
Intent surface
The set of clauses and constraints a change must touch to alter system behavior deliberately.

Managing this debt means refactoring specifications the way teams once refactored code: consolidating clauses, removing dead constraints, and naming the model so its shape stays legible as it grows. The work is unglamorous and easy to defer, and deferring it is exactly how a clean spec turns opaque.

How a deliberate spec-first change tends to proceed

The order of operations in a mature spec-first workflow tends to follow a consistent shape, regardless of domain. The sequence keeps the specification authoritative and prevents the generated code from quietly becoming a second source of truth that competes with the spec. What matters is less the exact steps than the direction every step points: changes enter through intent and flow outward to implementation, never the reverse.

  1. State the behavioral change as an amendment to the specification, not as a code edit.
  2. Encode the new intent as constraints and examples a generator and a test suite can both read.
  3. Regenerate the affected projection and let the binding tests confirm fidelity.
  4. Inspect the diff of behavior, not the diff of lines, against the stated intent.
  5. Fold any surprises back into the spec so the next regeneration carries the lesson.

The discipline lives in step five. When a regeneration surprises you, the temptation is to patch the output by hand. Each hand-patch that does not return to the specification reopens the gap spec-first was meant to close, and the spec quietly stops being the truth. The patched line works today and lies tomorrow, the moment something triggers a fresh regeneration. Teams that hold the discipline treat a surprising projection as a signal that the intent was underspecified, and they spend the effort to say what they meant more precisely rather than overriding the output downstream.

Where the model strains as systems grow larger

At small scale, a single specification holds a whole system comfortably and regeneration is cheap. The strain appears at the seams. Large systems are not one specification but many, composed together, and the contracts between specifications become the fragile surface — exactly where ordinary architectures also fail, but now one level up, in the language of intent rather than interfaces.

Bounded composition, where each specification owns a clear interface and reprojects independently, tends to scale. Unbounded composition, where specifications reach into each other's assumptions, produces regenerations that are individually valid yet collectively inconsistent. The coupling moves from code to intent, and intent coupling is harder to see because nothing in any single spec looks wrong.

The other strain is human. A specification that grows beyond what one reader can hold becomes its own form of opaque legacy, and the promise that the spec is the readable, owned artifact erodes. Keeping specifications small enough to reason about becomes a first-order concern, not a stylistic preference, and the teams that ignore it rebuild the same fog they left behind. The discipline of decomposition that once governed code now governs intent, and it arrives with the same warning: a boundary drawn badly is more expensive to move than no boundary at all.

What the field is becoming as the spec hardens into the product

The trajectory points toward the specification being treated as the shipped product and the code as build output, much as compiled binaries were demoted decades ago. As that settles, the hard problems migrate upward. Versioning intent, diffing behavior, and reviewing constraints become the daily craft, while reading generated implementations becomes an occasional, diagnostic act reserved for when fidelity breaks. The tooling will follow the center of gravity, and the artifacts a team is proud of will be the clean, legible specifications rather than the clever code beneath them.

What gets harder is governance of meaning. When the spec is the product, the question of who is allowed to change which clause, and how a change to intent is validated before it reprojects, becomes the central discipline. Authority over a specification carries the weight that authority over a release branch once did, because a single edit can reshape behavior everywhere the spec projects.

The systems that hold up will be the ones that treat their specifications with the rigor once reserved for production code — versioned carefully, reviewed seriously, and kept small enough to remain honest. The pull in the other direction is real, since a spec that generates working software invites the assumption that it must be sound. That assumption is where the next decade of hard-won lessons will land, and the teams that resist it earliest will spend the least to learn them.

F.A.Q.

Frequently asked questions

What is spec-driven development?
Spec-driven development is a discipline in which an executable specification is the primary artifact a team owns, and the implementation is generated from it. The specification becomes the source of truth, while code is treated as a downstream projection that can be regenerated when intent changes.
How is an executable specification different from documentation?
Documentation describes a system after it is built and tends to decay as the code moves on. An executable specification is precise enough that a generator can produce a working implementation directly from it, so the specification stays authoritative rather than drifting into a stale record.
What is specification debt?
Specification debt is the gap that opens when the written intent no longer matches what the running system actually needs. It accrues as contradictory clauses and bolted-on exceptions, and unlike tangled code it can hide behind clean prose while still generating the wrong behavior confidently.
Does spec-first development scale to large systems?
It scales when each specification owns a clear interface and reprojects independently, which keeps coupling visible. It strains when specifications reach into one another's assumptions, because the resulting regenerations can each be valid yet collectively inconsistent, moving the coupling from code into intent.
Why does regeneration determinism matter so much?
If the same specification produces materially different implementations each time, the generator effectively becomes the source of truth instead of the spec. Stable, predictable regeneration bound by tests is what lets a team trust the specification as the durable artifact the system is built from.
Share
XLinkedInFacebook
On this page
  1. Specification as source of truth
  2. Review moves to intent
  3. Regeneration determinism and trust
  4. When specifications accrue debt
  5. Ordering a spec-first change
  6. Where the model strains at scale
  7. Spec hardening into the product

Documentation

  • Overview
  • API
  • CLI
  • GitHub
  • npm

Blog

  • Explore the blog
  • Proving the Origin of Machine-Generated Media
  • From Prompt to World: When Generated Output Becomes Space
  • Spec-Driven Development: When the Spec Becomes the Product
  • The 70% Problem: Why Generated Software Needs a Human Last Mile

Legal

  • Privacy
  • Terms
  • Company

Product

  • Capabilities
  • Pricing
  • Contact
  • Engineering
WisyLink © 2026·
Built with ❤️ by our team