Skip to main content
← Perspectives

Perspectives · Engineering

A Practical Approach to Spec-Based Development with Claude

How structured specifications become the interface between human intent and AI implementation — and what it takes to make that interface trustworthy at scale.

Andrew Montgomery

Andrew Montgomery

CTO and COO, Kairoi

October 2026 · 12 min read

The Problem Nobody Warned You About

AI coding assistants are remarkably capable at generating code. They’re also remarkably capable at generating the wrong code with complete confidence. The failure mode isn’t that the AI can’t write a service layer or a database migration — it’s that it doesn’t know your service layer conventions, your migration naming scheme, or why your team made specific architectural choices six months ago.

This problem compounds in a polyglot monorepo. When your codebase spans Java, TypeScript, Go, and .NET — each with their own frameworks, testing patterns, and deployment conventions — the AI needs more than a prompt. It needs a briefing.

Most teams address this by writing longer prompts, pasting more context, or iterating through rounds of “no, not like that.” This works for small tasks. It falls apart when you’re building features that span multiple modules, require phased implementation across days, and involve design decisions that need to survive across conversation sessions.

We needed something more durable than a prompt and more actionable than a wiki page.


Two Phases, Two Modes

Before describing the workflow itself, it’s worth naming something that’s easy to get wrong: not all AI collaboration looks the same, and conflating the two modes is one of the more common ways this workflow breaks down.

The first phase is exploratory. You’re in a conversational interface — ideating on product direction, stress-testing architectural options, building throwaway prototypes to validate assumptions. This phase tolerates ambiguity. You’re asking “what should this be?” and “does this approach hold up?” The output isn’t code — it’s clarity. Design decisions get surfaced and challenged. Scope gets drawn. Tradeoffs get articulated. Prototypes get built and discarded.

The second phase is disciplined. You’re working with a coding assistant against a grounded spec, executing phase by phase, with validation gates between phases. Ambiguity is the enemy here. The spec is frozen. The AI is operating as an implementer, not a thought partner.

The spec is what makes the handoff between these phases reliable. Without it, insights from the exploratory phase live in a conversation that the implementation tool can’t read. With it, the product judgment, the design decisions, and the architectural choices survive the transition — encoded in a form that any tool, any team member, or any future AI session can act on.

This also suggests a discipline worth maintaining: keep the modes separate. Using a conversational interface for disciplined implementation tends to produce context rot and convention drift. Using a coding assistant for open-ended design exploration tends to produce premature commitment to implementation details. Each tool is well-suited to one phase; using them for the other is where things quietly go wrong.


Specs as the Interface Layer

The core idea is simple:

Structured specification documents become the programming language for AI collaboration.

Instead of describing what you want in a chat message and hoping the AI infers the rest, you produce a set of documents that are precise enough to implement against, rich enough to capture architectural intent, and portable enough to carry context across sessions, tools, and team members.

We use a three-document system for every feature:

  • Summary — the “what and why.” Product vision, success criteria, key capabilities. Written for someone who needs to understand the feature without reading code. This is where human judgment about what to build gets captured.
  • Spec — the “how.” Technical specification with numbered requirements (FR-1, FR-2…), data models with actual SQL, API contracts with request/response examples, and design decisions with rationale and tradeoffs. This is the blueprint.
  • Plan — the “when and in what order.” Phased implementation with task breakdowns, validation criteria per phase, and status tracking. Each phase is scoped so that it can be implemented and verified independently.

These documents live in the repository alongside the code, organized in lifecycle directories: planned/ for features in design, in-progress/ for active implementation, complete/ for shipped work. The spec is the ticket, the design doc, and the implementation guide — one artifact that serves all three purposes.


The Pre-Flight Audit: Grounding Before You Design

One of the most important steps in this workflow isn’t writing a spec. It’s verifying that your assumptions about the current codebase are accurate before you write one.

Before any spec work begins, we ask the AI to evaluate current project state: audit the relevant modules, surface gaps and risks, identify work that may already be done, and flag dependencies that might affect the design. The result shapes everything that follows.

This pre-flight audit does two distinct things simultaneously.

It discovers existing work. In an active codebase, the assumption that you’re designing from a blank slate is almost never true. The audit might reveal that 40% of a proposed feature already exists in some form — that a service you were planning to build was partially implemented in a prior spec, or that a data model you’re designing already has three of the five columns you need. When that happens, the spec gets scoped down before it’s written. You’re completing existing work rather than duplicating it.

It surfaces risks before commitment. The audit might reveal that a foundational dependency doesn’t exist yet, or that a prior spec introduced a constraint that affects the new design, or that a module you were planning to extend is currently in a state of active refactoring. Discovering that before you’ve designed around it is dramatically cheaper than discovering it mid-implementation. Sometimes the gaps are large enough to spawn a new spec that becomes a prerequisite. Other times they condense the spec significantly.

The result is that specs aren’t drafted against assumed reality — they’re drafted against verified reality. That changes the confidence level of everything that follows.

One honest qualification: the audit step has a skill component that can’t be fully proceduralized. The audit is only as good as the instincts of the person initiating it. A senior developer who’s been in the codebase for a year will know to say “before we design anything here, I want to verify the state of this abstraction because we touched it six months ago and I’m not sure what phase it’s in.” A developer newer to the codebase might scope it too narrowly and miss a dependency risk.

This is actually fine — and important to name explicitly. The workflow doesn’t eliminate the need for experienced engineers. It amplifies them. The senior developer’s pattern recognition about where to look becomes dramatically more powerful when the AI can execute a deep audit against those instincts in minutes rather than hours. But the instincts still have to come from somewhere. Onboarding into this workflow isn’t just learning the spec format — it’s developing the judgment to ask the right pre-flight questions.


How It Works in Practice

A typical feature moves through this pipeline:

Step 1 — Human writes the idea

This is a rough document — product intent, user stories, scope boundaries. It doesn’t need to be precise. It needs to be honest about what the feature should accomplish and why.

Step 2 — Pre-flight audit

Before any spec work begins, the AI evaluates current project state against the proposed idea. Gaps and risks are identified. Scope is adjusted. Any prerequisite work that needs to happen first gets surfaced and sequenced.

Step 3 — AI generates the spec trilogy

Given the refined idea and access to the codebase, the AI produces the summary, spec, and plan. Critically, it grounds the spec in the actual codebase — referencing real module names, real patterns from completed features, real pagination conventions. The spec isn’t theoretical; it’s written against the system as it exists today.

Step 4 — Human reviews and refines

This is where the real design happens. The AI proposes; the human validates. Requirements get sharpened. Edge cases get surfaced. Scope gets cut. The spec is a conversation artifact, not an AI monologue.

Step 5 — AI implements phase by phase

The plan breaks implementation into independently verifiable chunks. Each phase gets dispatched to a fresh context window with the accumulated learnings from prior phases. A shared learnings file acts as the memory bridge, preventing the “context rot” that happens when AI assistants lose track of earlier decisions in long sessions.

Step 6 — Layered verification at each checkpoint

Verification isn’t a single gate — it’s a tiered stack, where each layer catches what the others can’t.

Phase-level validation handles structural correctness: does the implementation match what the spec required for this phase? Explicit criteria — “schema is correct, entities map to tables, queries execute” or “all endpoints return 200 for valid requests, 403 for unauthorized” — make this tractable. The AI runs the build, runs the tests, reports results.

Agentic test harness / multi-turn evals handle behavioral correctness for AI-native components. Scripted conversation flows run against assistants, evaluators, scorers, and processors to verify they’re handling edge cases correctly. This matters because the things being tested have probabilistic behavior — deterministic tests can’t fully surface drift in how an AI component handles an edge case it’s encountered before.

Human-in-the-loop user testing handles experiential correctness — the last mile that automated verification can’t reach. Automated systems can verify that the feature works. They can’t verify that it feels right to the people who use it.

The result is that features which might take days of manual coding can be designed in hours and implemented in a single focused session — with a documentation trail that traditional development rarely produces.


The Institutional Memory Problem

The specs don’t just guide implementation. They encode institutional knowledge.

In a polyglot monorepo, every stack has conventions that are non-obvious and critical. The Java layer uses a specific pagination pattern that differs from the framework default. The TypeScript frontend consumes API responses in snake_case without transformation. The Go services follow a particular directory convention. The permission system uses a specific annotation-and-check pattern where the evaluation order matters.

We capture these conventions in persistent context files at each directory level. When the AI starts working in a module, it reads the local context file first — learning the gotchas, the naming conventions, the testing patterns, and the things that will break the build if done wrong.

Custom skills encode workflows: how to scaffold a new feature package, how to log a known issue, how to audit an app for wiring drift after a merge. These skills call the AI with the right context, the right constraints, and the right output format. They’re not prompts — they’re procedures that the AI follows.

The combination of specs, context files, and skills means that a new conversation session can pick up where the last one left off. The AI doesn’t need to rediscover conventions or re-learn architectural decisions. It reads the documents and operates within the established framework.


Part of a Larger Movement

It’s worth stepping back and acknowledging that this isn’t an isolated invention. The broader AI development community has been converging on the same structural insights from different directions — under different names, with different tooling, but with a remarkably consistent underlying shape.

What the industry now calls “agent harnesses” — the system and infrastructure around an AI model that determines whether it actually works in production — has produced a recognizable taxonomy of artifacts. AGENTS.md has emerged as something close to a universal standard, stewarded under the Linux Foundation, describing how an agent should behave inside a project: which commands to run, what to avoid, how to verify work. Claude Code has CLAUDE.md. Cursor has .cursorrules. AWS Kiro has steering files. GitHub’s Spec Kit formalizes a sequential workflow where spec.md, plan.md, and tasks.md are first-class artifacts that agents read and write.

Our three-document system maps cleanly onto this emerging taxonomy:

ConcernSpec KitKiroOur system
What to buildspec.mdrequirements.mdSummary
How to build itplan.mddesign.mdSpec
Work breakdowntasks.mdtasks.mdPlan
Project invariantsconstitution.mdsteering filesContext files + AGENTS.md

We didn’t design against this taxonomy — we arrived at it independently through practice. That convergence matters. It means the structural instincts behind this workflow aren’t idiosyncratic; they reflect something real about what it takes to make AI collaboration work reliably at scale.

What does appear to be less formalized in the broader community: the pre-flight audit before spec work begins, and the retirement model for handling spec drift post-completion. Those are contributions worth naming explicitly.


What’s Working

Consistency scales

When every feature goes through the same spec process, the codebase develops a rhythm. New modules look like existing modules. API contracts follow established patterns. Test structures are predictable. This consistency is hard to maintain manually across multiple developers and multiple stacks — but when the spec enforces it, it happens naturally.

Design decisions survive

Every spec has a Design Decisions section with rationale and tradeoffs. When someone asks “why did we do it this way?” months later, the answer is in the spec, not in someone’s memory or buried in a Slack thread.

Parallelization becomes easy

Because specs are self-contained, multiple features can be in-flight simultaneously. The spec is the coordination mechanism. Two developers (or two AI sessions) working on different specs don’t need to synchronize beyond normal merge discipline.

The AI gets better over time

Not because the model improves, but because the institutional context accumulates. Each completed spec becomes a pattern that future specs can reference. Each context file gets refined as new gotchas are discovered. Each skill gets tuned based on real usage. The system learns, even though the underlying model doesn’t.

Error locatability

When the AI gets something wrong — and it will — the spec makes the error findable. You can point to “FR-3.2 says the endpoint should return paginated results, but the implementation returns an unbounded list.” This is dramatically easier than debugging a vibes-based disagreement about what you asked for in a chat message.

Evals as living conformance checks

The agentic test harness extends spec conformance into runtime. When an eval breaks, it’s not just a test failure — it’s a signal that the AI component’s behavior has drifted from the intended design.


What’s Hard

The pre-flight audit requires judgment, not just process

You can document the procedure; you can’t fully systematize the wisdom about where to look. Teams need to invest in developing that judgment, not just in following the format.

Upfront cost is real

Writing a spec before touching code feels slow, especially for features where requirements only become clear through prototyping. The spec process is optimized for known problem spaces. For exploratory work, a spike-then-document approach may be more appropriate — and the pipeline needs to accommodate that without making it feel like a process violation.

Spec drift is the silent killer

After a feature ships, the code continues to evolve — but the spec doesn’t. Over time, completed specs can describe a system that no longer exists. If an AI assistant reads a stale spec and treats it as ground truth, it will make confident, well-structured, wrong decisions. This is worse than having no documentation at all, because the structured format inspires false trust.

AI confidence exceeds AI accuracy

A well-structured spec makes the AI very productive — but also confidently wrong in ways that are harder to catch because the output looks professional. The structured format can mask shallow understanding. Validation criteria are the main defense, but they require human judgment to verify.


Handling Spec Drift: The Retirement Model

We tried the obvious approach first: keep specs updated as code evolves. This doesn’t work. Nobody maintains documentation for features that are already shipped and working. The maintenance cost is pure overhead with no immediate payoff, so it never happens.

The insight was to reframe the problem.

A completed spec doesn’t need to stay accurate — it needs to be clearly marked when it becomes inaccurate.

Instead of updating stale specs, we retire them. A retired spec gets two additions: a header at the top marking it as historical (a clear signal to any reader, human or AI, that the codebase is the source of truth) and an epilogue at the bottom capturing what changed and why. Not a full rewrite — just enough context to understand the divergence.

Critically, the epilogue also notes what remains accurate. A retired spec isn’t worthless — the data model might still be broadly correct, or the design decisions might still apply. Calling out what’s trustworthy is as important as flagging what’s not.

The spec lifecycle becomes:

planned/ --> in-progress/ --> complete/
                                 |
                                 |-- [still accurate] -- no annotation needed
                                 |
                                 '-- [diverged]       -- retired with epilogue

The spec never moves out of complete/. It never gets deleted. It just gets annotated. Its value shifts from “how the system works” to “how the system got here” — and both are valuable, as long as you know which one you’re reading.


The Takeaway

Spec-based development with AI isn’t about writing more documentation. It’s about recognizing that the specification is the interface between human judgment and machine execution. The human decides what to build and why. The spec encodes that decision precisely enough that the AI can handle the how — faithfully, consistently, and at speed.

The approach works because it plays to each party’s strengths. Humans are good at product judgment, architectural vision, knowing when something feels wrong, and recognizing where to look when auditing an unfamiliar system state. AI is good at consistent execution, pattern adherence, and tireless attention to detail across large codebases. The spec is where those two capabilities meet.

It’s not free. The upfront cost of writing specs is real. The skill investment in developing audit judgment is real. The maintenance cost of skills and context files is real. The risk of stale documentation inspiring false confidence is real. But the alternative — ad hoc prompting, context loss between sessions, convention drift across a growing team — has costs too. They’re just less visible until they compound.

Six months from now, when someone needs to understand why the system works the way it does, the answer won’t be “I think we discussed that in a Slack thread” or “the person who knew that left.” It’ll be in the spec — or in the epilogue that explains why the spec no longer applies.

That’s the real value. Not faster code. Better institutional memory. And a team that gets more capable over time, not just faster.

More from Kairoi

This methodology shapes how we build for our clients.

The spec-based approach is the same methodology underlying Compass AI and every Kairoi engagement.

See Compass AI →

With your OK, we'll use Google Analytics cookies to see which pages people read and how they found us. We don't use them for ads. Privacy policy