Specs are the new source code when AI writes the implementation

When implementation becomes cheap, ambiguity becomes the most expensive part of software. Specs are no longer documentation after the fact — they are the execution environment for AI agents that generate, test, and maintain code at machine speed.

Engineering9 min read
AI automationSoftware architectureProduct managementSpecificationsDeveloper experience
Share

AI coding agents generate implementation faster than most teams can clarify what they want built. The bottleneck has moved. It is no longer typing speed, framework knowledge, or even algorithmic expertise. It is the ability to express intent precisely enough that a machine produces correct behavior on the first pass — and predictable behavior on every subsequent pass. Code is no longer the scarce resource. Clarity is. Specs are the new source code because they are the artifact that determines what the system actually does, while generated code is increasingly a derived, disposable representation of that intent.

This shift is not incremental. It rewires how product managers define requirements, how engineers spend their time, how teams measure quality, and where accountability lives when something breaks. The organizations treating specs as living, enforceable contracts are shipping faster and regressing less than the ones still treating them as coordination artifacts written for humans and forgotten by machines.

AI makes weak specs more expensive, not less

Every ambiguous requirement that used to produce one confused pull request now produces five confident, contradictory implementations in the time it took to write the ticket. An agent does not stop to ask clarifying questions. It fills gaps with plausible assumptions, generates code that compiles and passes the tests it wrote for itself, and moves on. The ambiguity does not surface until integration, review, or production — when the cost of correction is highest.

A vague spec like "build a billing dashboard" generates a system with assumptions baked into every layer: which user role sees which data, whether amounts are gross or net, how deleted subscriptions appear in aggregates, what happens when the data source is unavailable, whether the component streams or polls. Each assumption is a potential defect. Each defect is invisible until a human with domain knowledge inspects the output — which defeats the purpose of using an agent to save time.

The economics have inverted. When implementation was expensive, an imprecise spec cost extra engineering hours to interpret. Now that implementation is cheap, an imprecise spec costs the rework of discarding generated code that satisfies the letter of the requirement but violates its intent. The cheaper code generation becomes, the more expensive ambiguity grows.

The old PRD was a coordination artifact — the new spec is an execution contract

Traditional product requirement documents served a human purpose: aligning stakeholders, recording decisions, and giving engineers enough context to make judgment calls during implementation. They were read once, partially, and then superseded by conversations in Slack, comments in Figma, and decisions made mid-sprint that never made it back into the document.

That workflow cannot survive agentic development. An agent reads the spec literally. It has no access to the Slack thread where the PM clarified that "active users" means "logged in within 30 days, excluding internal accounts." It has no memory of the standup where the designer said the empty state should show an onboarding prompt rather than a blank screen. It generates what the spec says, not what the team meant.

The new spec is an execution contract — a versioned, enforceable artifact that the agent treats as authoritative. It defines:

  • Intent: what outcome the system should produce, for whom, under what conditions.
  • Constraints: performance budgets, security boundaries, compliance requirements, accessibility standards.
  • Interfaces: input shapes, output formats, error responses, API contracts.
  • Invariants: rules that must never be violated regardless of implementation path (e.g., "an invoice total is never negative," "a deleted user's data is never returned to another user's session").
  • Examples: concrete input-output pairs that serve as both documentation and test cases.
  • Failure modes: what happens when dependencies are unavailable, data is malformed, or rate limits are hit.

When any of these elements are missing, the agent fills the gap with its own judgment — which is statistically plausible but not necessarily correct for the specific domain.

Acceptance criteria should become executable tests

The strongest form of a spec is one where the acceptance criteria are not prose descriptions a human interprets — they are executable assertions the system validates continuously. This is not new in principle. Behavior-Driven Development (BDD) attempted this two decades ago. What changed is that AI agents can now consume structured acceptance criteria and generate both the implementation and the verification in a single pass.

The practical shift:

  • Before: PM writes "the dashboard should load in under 2 seconds." Engineer interprets this as a p95 target measured at the client, or maybe at the API, or maybe just in development. Nobody checks after launch.
  • After: the spec states latency_p95_ms: 2000, measurement_point: client_first_contentful_paint, environment: production. The agent generates the implementation, the performance test, and the monitoring alert. The constraint is enforceable from the first deployment.

This pattern extends to every type of requirement. Permission models become role-access matrices the agent implements as RLS policies and tests as integration assertions. Data validation rules become schema constraints the agent generates alongside the form components. Empty states become enumerated UI variants the agent renders for each combination of data availability.

The eval rubrics that product managers write for AI systems follow the same principle: the definition of "correct behavior" is the specification, and the specification is executable. The distinction between requirement and test dissolves.

Constraints matter more than instructions

Instructions tell an agent what to build. Constraints tell it what must never break. In a world of generated code, constraints are more durable than instructions because they survive regeneration — the agent can rewrite the implementation entirely, but the invariants hold.

A spec built around instructions:

"Build a refund workflow that sends a confirmation email and updates the ledger."

A spec built around constraints:

"The refund workflow must: (1) never process a refund exceeding the original charge amount, (2) produce an idempotent ledger entry keyed on refund_id, (3) emit an audit event before any state mutation, (4) complete within 5 seconds at p99, (5) degrade gracefully if the email service is unavailable — the refund proceeds, the email is retried asynchronously."

The instruction-based spec gives the agent freedom to build a system that works in the happy path. The constraint-based spec gives the agent a contract that works in production — including the failure cases, race conditions, and edge states that instructions routinely omit.

This is why refactoring before AI automation matters as a prerequisite: the constraints must exist as enforceable rules in the system before the agent can respect them. A constraint that lives only in tribal knowledge is invisible to the agent and will be violated.

The spec checklist: what an agent-ready specification includes

Not every spec needs formal verification. But every spec that drives agent-generated code needs these seven elements to produce reliable output:

  1. Intent — one sentence describing the outcome the system produces for the end user. Not the implementation, not the technical approach — the outcome.
  2. Constraints — non-functional requirements encoded as measurable thresholds: latency budgets, error rate ceilings, cost caps, security boundaries.
  3. Interfaces — typed input and output contracts. Request schemas, response shapes, event payloads. The agent cannot generate correct integration code without knowing what the system speaks.
  4. Invariants — domain rules that must hold under all circumstances. These survive implementation rewrites and serve as regression anchors.
  5. Examples — concrete scenarios with specific inputs and expected outputs. These double as test cases and disambiguation for edge conditions.
  6. Failure modes — what the system does when dependencies fail, data is invalid, or resources are exhausted. If the spec does not define degradation behavior, the agent will not implement it.
  7. Test expectations — the verification strategy. Unit, integration, performance, security. What is tested, how, and what thresholds constitute a pass.

A spec missing any of these elements is incomplete for agent-driven development. The agent will still generate code — it will generate code that looks right but behaves unpredictably at the boundaries the spec did not cover.

How detailed should an AI-ready spec be?

The level of spec rigor depends on the blast radius of the feature and the domain complexity involved.

Does every feature need a full spec before AI can generate code?

Low-risk, well-understood features — a new filter on a list view, a copy change, a CRUD endpoint for an internal tool — need minimal specification. The domain is narrow, the failure modes are obvious, and the cost of regeneration is low. High-risk features — anything touching billing, permissions, data integrity, or cross-service orchestration — need full constraint-based specs because the cost of an incorrect assumption compounds with every downstream dependency.

What format should an agent-ready spec use?

Markdown in the repository, versioned alongside the code. The format matters less than the structure: intent, constraints, interfaces, invariants, examples, failure modes, test expectations. Some teams use structured YAML or JSON schemas for machine-readable fields (latency budgets, role matrices). Others keep everything in prose with executable test cases in companion files. The key constraint is that the spec must be checkable — a human or a machine can verify whether the implementation satisfies it.

Who writes the spec — the PM or the engineer?

Both. The PM defines intent, constraints, and invariants — what the system must do and what it must never do. The engineer adds interfaces, failure modes, and test expectations — how the system integrates and how correctness is verified. The spec is a collaboration artifact, not a handoff document. When both perspectives are missing, the agent operates with one eye closed.

The opposing view: agents can discover requirements while building

A recognized argument in the field holds that requiring complete specs before implementation reintroduces waterfall-era delays into an agile workflow. Modern agents can generate exploratory implementations, surface edge cases the team had not considered, and iteratively refine both the spec and the code in a tight feedback loop. Demanding complete specs upfront assumes the team knows all the requirements in advance — which is rarely true for novel features.

This view is correct about discovery. Agents are excellent at exposing the implications of a requirement by generating a candidate implementation that reveals gaps. The error is in conflating exploration with production. An exploratory implementation generated without constraints is a prototype — useful for learning, dangerous if shipped. The spec does not need to be complete before the agent starts; it needs to be enforced before the agent's output enters the system. Discovery and enforcement are different phases, not competing philosophies.

Key takeaways

  • When implementation becomes cheap, ambiguity becomes the most expensive part of software. The bottleneck moved from typing code to specifying intent.
  • Specs are no longer coordination documents for humans. They are execution contracts for agents — the artifact that determines what the system actually does.
  • Constraints are more durable than instructions. An agent can rewrite the implementation entirely; the invariants must hold regardless.
  • A complete agent-ready spec includes intent, constraints, interfaces, invariants, examples, failure modes, and test expectations.
  • The spec is a collaboration between PM (intent, constraints, invariants) and engineering (interfaces, failure modes, test expectations). Neither perspective alone is sufficient.
  • Discovery and enforcement are different phases. Agents can explore without specs; they cannot ship without them.

Conclusion

The organizations shipping the fastest with AI agents are not the ones with the best prompts. They are the ones whose specifications are precise enough that the generated code satisfies intent on the first pass and maintains correctness across regeneration cycles. The spec has moved from a coordination artifact that humans glance at during kickoff to the execution environment that agents treat as authoritative. This changes who does what on a product team: product managers become spec authors whose output directly determines system behavior, and engineers become constraint architects whose job is making those specs enforceable. The question for every team adopting agentic development is not "which AI model should generate the code" — it is "who owns the spec, and is it precise enough to produce the right system?"

Related articles

Command Palette

Search for a command to run...