← All articles

SpecDD for CTOs

·

AI-assisted development has reached the point where the question inside engineering leadership is no longer whether the tools are useful. They can write code, explain code, refactor code, generate tests, and chew through routine implementation work at a pace that would have seemed implausible not very long ago.

Once that is true, the harder question is what happens when you let that capability loose inside a real engineering organization. That is where the conversation becomes less comfortable, because the output is not only measured in lines of code or completed tickets, but in architectural drift, review burden, security assumptions, product nuance, platform constraints, and the amount of senior engineering attention required to keep the whole thing pointed in the right direction.

AI agents can produce a lot of code very quickly, including a lot of almost-right code very quickly, and almost-right code is not a productivity gain if your best people have to spend their afternoons correcting its assumptions.

For a CTO, the important part is not a developer workflow tweak, but a way to make engineering intent explicit and operational at the point where software is actually changed. It gives AI agents and humans the same local source of truth for what a part of the system is supposed to do, what it owns, what it must respect, and what would count as a correct implementation. That may sound modest, but modest is often what actually survives contact with an engineering organization.

The productivity spike has a shadow

Most organizations begin using AI coding tools in the same informal way. A developer asks for a test, a refactor, a small feature, or a migration script, the tool helps, and the team gradually starts trusting it with more consequential work. Eventually, someone asks whether this should be standardized, measured, subsidized, encouraged, or built into the delivery process, and that is usually when the leadership problem appears.

At small scale, AI mistakes are personal. A developer catches them, corrects them, and learns how to prompt around the tool’s weak spots. At organizational scale, the same mistakes become systemic: a dependency appears that the platform team has avoided for good reasons, an internal abstraction gets bypassed because the direct library call looks simpler, or behavior matches the ticket while contradicting a product rule that has lived in the heads of two senior engineers for three years.

There is also a quieter kind of drift that matters at leadership scale. An unchecked agent will often pull local implementation toward patterns it has seen elsewhere: the framework tutorial answer, the public-repository answer, the thing that looks like best practice in the average project. Some of those patterns are perfectly valid for other teams, but that does not make them valid for yours. Your architecture may have different boundaries, different operational constraints, different security assumptions, or a history that explains why the obvious implementation is not the right one. Without local context, the agent has no principled way to know the difference.

None of these failures are exotic. They are the normal failures of context-poor implementation, the same kind of failure human engineers make when they join a new codebase, move between teams, or work in a part of the system they do not know well. AI agents simply compress the feedback cycle, so a boundary that a human might gradually wander across over a few weeks can be crossed in the first patch.

The tempting response is to keep the blast radius small: let developers use AI individually, avoid making it a core part of delivery, and treat it as autocomplete with a better interface. That is understandable, but it leaves too much value on the table. The better response is to make the context layer strong enough that AI-assisted implementation can happen inside clear constraints, which is the layer SpecDD is designed to provide.

Your organization already has specifications

Most companies have far more specification work than they realize. It just does not live in a form that software agents, or often humans, can reliably use.

Some of it is in architecture documents that were accurate at the time they were written. Some lives in tickets, pull-request comments, incident reviews, Slack threads, onboarding conversations, old migration plans, and the memory of senior engineers who have been around long enough to know why the obvious solution is not the right one. Product behavior, platform boundaries, and security expectations often end up specified by precedent, folklore, and review habits rather than by anything an implementer can reliably find.

That arrangement is survivable when teams are small and stable, but it becomes expensive as the organization grows. AI agents make the cost visible because they do not participate in institutional memory. The meeting where a team decided never to call a vendor API from the request path is not in their context. Neither is the social signal around a service boundary, or the business meaning of a data field whose name looks obvious until you know the history behind it.

An AI agent works with what it can read now, which is why adding more AI on top of weak context can make engineering leadership feel less in control even when individual developers are moving faster. The organization has increased implementation capacity without increasing the clarity of the rules that implementation is supposed to follow.

SpecDD treats that as the central problem. Instead of assuming the answer is a larger prompt, a longer context window, or a more elaborate conversation with the model, it assumes that important intent should live in the repository, close to the code it governs, in a format that is clear enough for humans and structured enough for agents.

The small local contract

The basic idea is simple. Instead of maintaining one large architecture document, or a collection of high-level requirements that sit far away from implementation, SpecDD uses small specification files that live beside the code they describe.

A billing service has a local spec, a payment adapter has a local spec, and a reporting job has a local spec. Each one describes the responsibility of that part of the system and the boundaries around it, including what the component owns, what it is allowed to depend on, what behavior it must support, what it must avoid, and what work remains.

The goal is not to create paperwork, but to put the contract where it can be used. When a developer or an AI agent changes a part of the system, the relevant specification is nearby and versioned with the code. The team can review it with the implementation, evolve it as the design evolves, and use it as a shared surface for engineers, QA, product, and AI agents that need to understand the local rules without guessing.

For CTOs, this matters because it turns specification from a document artifact into an operational asset. The spec is not something written once for approval and then slowly abandoned, but part of how the team changes the system.

That distinction matters because a lot of engineering organizations have tried documentation drives, and they usually fail because documentation is treated as a separate deliverable from the software itself. SpecDD pulls the description of intent into the same surface area as implementation. If the code changes and the intent changes, the spec changes with it. If the code changes and the intent does not, the spec constrains the change.

The prompt stops being the contract

The informal AI workflow starts with a request: implement this endpoint, fix this bug, add this screen, write tests for this module. The agent reads some files, infers the surrounding patterns, and produces a patch. That is sometimes enough, but in a mature codebase, on work that touches important behavior, it often is not.

SpecDD shifts the workflow slightly upstream. Before implementation, the relevant specification is written or updated. That does not have to be a long process. For small changes, it may mean adding one rule, clarifying one boundary, or capturing one scenario. For larger features, it may mean sketching the local contracts before code exists. The important step is that the intended behavior and constraints become explicit before the agent starts making implementation decisions, after which the agent implements against the spec.

Compared with better prompting, this is a different operating model. A prompt is transient and belongs to a session, disappearing from the repository unless someone copies it somewhere, and even then it is rarely maintained. A local specification becomes part of the project history, where it can be reviewed, corrected, discussed, and reused by the next agent, the next developer, and the next version of the feature.

The Tasks section adds a useful governance handle here. Teams can phase AI-assisted work inside the same local contract, ask for one task at a time, review that slice, and keep progress visible without losing the connection to the behavior and boundaries the spec already defines.

The governance move here is not ceremonial governance, and it is not governance as a committee that slows delivery. It is a clear contract sitting close enough to implementation to change behavior.

This also changes code review. Reviewers are no longer forced to reconstruct intent from a ticket, a conversation, and a diff. They can compare the patch against the local contract. Did the implementation respect the boundary? Did it fulfill the expected behavior? Did the spec change because the design changed, or because the implementation wanted to make something easier?

Those are much better review questions than asking a tired staff engineer to remember the entire history of a module while scanning yet another AI-generated diff.

The payoff is less invisible work

The most immediate benefit is less accidental architecture erosion. Every CTO has seen the slow version of this: a shortcut becomes a pattern, the pattern becomes an unofficial API, and the unofficial API becomes a dependency that nobody wants to own. A year later, the team is paying interest on a decision that was never really made. AI can accelerate that cycle because it tends to prefer locally plausible solutions unless the project tells it otherwise.

Local specs make the “otherwise” visible, and they also reduce the amount of senior attention spent on repeat explanation. In many organizations, the same handful of people are asked to protect the same handful of architectural truths over and over. They do it in design review, code review, incident follow-up, planning, onboarding, and casual chat, which is a poor use of scarce judgment. If a rule is important enough to repeat, it is usually important enough to put where the work happens.

SpecDD is also useful for onboarding. New engineers do not need a complete mental model of the system before they can make a safe contribution. They need a reliable way to understand the part of the system they are touching, including the local constraints that are easy to miss by reading code alone. The same is true for engineers moving between teams or working in unfamiliar parts of the codebase during incidents and migrations.

For product and QA, the benefit is that behavior becomes easier to inspect. A well-written local spec can capture the business rule behind a feature without burying it inside implementation. That does not turn product managers into engineers, and it should not try to. It gives them a readable surface for checking whether the system is being asked to do the right thing before code is generated around the wrong assumption.

The AI benefit is the obvious one, but it is not isolated from the human benefit. Better agent context, clearer review surfaces, and a more durable memory for decisions all come from the same source: intent written where the work happens.

Start where the risk is already visible

SpecDD does not need to begin as a company-wide mandate, and in most organizations it probably should not.

The best starting points are the places where weak context is already costing you something. That might be a module that changes often and breaks often. It might be a legacy area where only one or two people understand the real rules. It might be a boundary between teams where ownership is routinely misunderstood. It might be the part of the system where AI-generated changes are useful but require too much review correction. Those are the places to start.

Write the local specs for that area. Capture the responsibility of the module, the boundaries it must respect, the business behavior that should not be guessed, and the implementation tasks that are already known. Use those specs in normal development by asking agents to read them before changing code, reviewing changes against them, and fixing either the code or the spec when they diverge. That is enough to learn whether the approach fits your organization.

The adoption path can stay incremental because SpecDD is local by design. A team does not need to specify the entire monolith before getting value from one important subsystem. A platform group does not need to rewrite every guideline before encoding the boundary rules that agents keep violating. A product engineering team does not need a full requirements process before capturing the handful of behaviors that should not be inferred from ticket titles and habit.

This matters politically as much as technically. Engineering process fails when it asks the whole organization to change shape before anyone sees value. SpecDD can start as a local improvement around a painful workflow and expand only where it proves useful.

The cost is real, which is why it works

There is no honest version of this argument where specifications are free. Someone has to write them, someone has to review them, and someone has to keep them aligned with the code. If a team treats SpecDD as decorative documentation, it will become decorative documentation, and the organization will get exactly as much value from it as that implies.

The discipline is the product, and although that may sound like a drawback, it is also why the approach works. The act of writing a useful local spec forces a team to make decisions that otherwise remain soft. What does this module own? Which dependency is acceptable here? What must never happen in this path? Which behavior is genuinely required, and which is an implementation habit? Where is the line between this service and the next one?

Those questions are going to be answered either way. The only choice is whether they are answered deliberately before implementation, or accidentally through code that becomes expensive to unwind.

From a CTO’s perspective, the trade-off should be evaluated against the real cost of the current workflow. How much time do senior engineers spend correcting intent in review? How much rework comes from misunderstood boundaries? How often does onboarding depend on oral history? How much AI output is thrown away because it was plausible but wrong? How much delivery risk is hidden inside decisions that are known but not written where an implementer can use them?

SpecDD costs time, and so does the absence of SpecDD. One of those costs leaves the organization with reusable context. The other leaves it with another corrected diff and the same problem waiting for the next session.

Moving the documents is not the same as fixing context

There is another trap worth naming, because it looks like the serious answer to the same problem. One version is the heavyweight specification program: large requirements documents, architecture sign-off, central templates, modeling tools, and process around keeping everything approved. There are domains where that level of formalism is appropriate, especially where regulation, safety, contracts, or auditability demand it. For ordinary product engineering, though, it often creates too much distance from delivery. The documents become too slow to update, too specialized for broad participation, and too detached from the code that is actually changing.

The lighter version is more common in AI tooling conversations: take the same Confluence-style documents, move them into the repository, shuffle the folders, maybe split them by feature, and assume the context problem is solved.

The problem is not solved. The documents are just arranged differently. If the material is still too broad, too stale, too detached from the code being changed, or too vague to constrain implementation, putting it in Git does not make it operational. It may be easier for an agent to read, but it is not necessarily easier for the agent to use correctly. A repository full of loosely organized markdown can become the same old documentation problem with better proximity and worse confidence. To put it bluntly, “this will not suffice”.

Repository documentation is not the enemy here. The problem is that location alone does not create usable context. The context has to be local, specific, structured, and connected to the implementation boundary it governs. A service spec should live near that service and say what the service owns, what it must do, what it must not do, and what counts as done, because a vague feature note three folders away cannot provide the same constraint.

SpecDD sits between the extremes. Ultra-formal frameworks often create too much friction to survive normal delivery, while casual repo-doc approaches often fail to change agent behavior because they do not encode enough local authority. The useful middle is lightweight enough to adopt incrementally, structured enough to guide implementation, and local enough that the relevant context is available where the work actually happens.

A root specs folder is still a weak center

There is a related pattern that deserves a little shade: specification frameworks that put a structured specs/ or docs/ folder at the root of the repository and treat that as the context architecture.

These approaches can work to a degree. A structured root folder is better than a stale wiki, and it is better than having no written intent at all. It gives teams a place to put requirements, decisions, diagrams, and feature notes. It can make an agent slightly less blind than a prompt-only workflow.

But it still solves the problem poorly.

The issue is not whether the folder is organized. It may be very organized. The issue is that the relevant context is still centralized away from the implementation boundary. The agent still has to decide which document matters, which part of that document applies to the file it is changing, whether the document is current, and whether a broad feature note should override the local code it is looking at. That is a lot of interpretation to ask from a system that already fails in exactly those interpretive gaps.

Root-folder specs also miss the best maintenance property of small local specs. A local spec changes when the code next to it changes. It is reviewed in the same diff, by the same people, against the same boundary. A root spec has to be remembered. Someone has to know it exists, find it, update it, and keep it aligned with implementation that may live several directories away. That sounds manageable during the first adoption push, and then six months later everyone is back to asking whether the document reflects the system or the system merely drifted away from the document.

They are also painful to maintain for the same reason large documentation systems are painful to maintain: ownership is blurry, updates are detached from the work, and broad documents become politically safer than precise ones. Developers will enjoy maintaining that root specs folder about as much as they enjoy updating your Confluence pages, because it feels like a separate chore instead of part of the change they are already making. The more general the document becomes, the less authority it has at the point of change. The more specific it becomes, the more likely it is to be in the wrong place.

SpecDD’s bet is different. The spec should be small enough to stay current, semi-formal enough to constrain an agent, and local enough that the person or agent changing the code cannot plausibly miss it. That is the part root-level spec folders do not give you, no matter how clean the directory tree looks.

Teach the method, not the memory

There is a deeper reason SpecDD works better as a framework than as a pile of context. It teaches the agent how to operate inside the project: how to find the relevant local contract, how to follow inherited constraints, how to respect ownership, how to treat Must not as a boundary, and how to keep code, tests, and specs aligned. That is different from dumping documents into memory and hoping the agent learns what matters.

The same is true for people. Onboarding a developer by sending them away to read documents for several weeks is a poor substitute for teaching them how the project works, where authority lives, which boundaries matter, and how to make a safe change in the part of the system they are touching. AI agents are not exempt from that problem. They also need a working method for applying context at the point of change, not just a larger stack of things to read.

A practical way to say yes

The reason CTOs should care about SpecDD is not that specification-driven development is a new idea, because it is not. The reason to care is that AI-assisted software development makes the old context problem much sharper. The implementation capacity of the team is increasing, but the organization’s ability to communicate intent to that capacity has not automatically increased with it.

That mismatch is where the risk lives, and SpecDD gives engineering leaders a practical way to say yes to AI without giving up control of the codebase. It does not require betting on a single vendor, adopting a heavyweight requirements process, or waiting for perfect tooling. It requires putting local, structured intent beside the software it governs and treating that intent as part of the engineering system.

Over time, this creates options. Specs can support better agent workflows, become inputs to validation tools, dependency checks, test generation, ownership analysis, and review automation, and help engineering teams preserve the reasoning behind the system as people move, priorities change, and models improve.

The immediate value is simpler than that. When someone changes an important part of the system, human or AI, the project should be able to tell them what matters there. It should not depend on a stale document three folders away, a meeting they did not attend, or the memory of someone who happens to be on vacation. The relevant intent should be right there, next to the code, in a form they can read and follow, because that is the operational promise of SpecDD: intent local enough to matter.

← All articles