AI Should Join the Team, Not Replace the Development Process
In my previous article, I explored something that has been bothering me about emerging models for AI-driven software development. AI can make implementation extraordinarily cheap. Specification-driven development can make intent explicit, while agentic systems can take on increasingly complex engineering work. All of this is useful.
The problem appears when we conclude that the natural end state is to separate human thinking from machine implementation: humans specify what should exist, while an AI production system turns that specification into software.
That may be efficient, but I don't think it is the only future available to us. Another possibility is to make AI a member of the development team.
The vocabulary behind the model
A few terms are useful before describing the alternative.
Spec-Driven Development (SDD)
An approach in which structured specifications make intent, constraints and expected behaviour explicit enough for AI to participate deeply in implementation. In the model explored here, the specification is not considered complete before coding starts. It evolves as implementation and experimentation produce new knowledge.
Agent
An AI system capable of pursuing a task through multiple steps: inspecting information, using tools, changing code, running tests and adapting to what it discovers.
Harness
The environment around the AI that determines what it knows, what it can do and what constraints it operates under. It connects the AI model to code, tools, specifications and the engineering knowledge relevant to the task.
Hub
A relatively small shared context that helps the AI navigate the larger engineering landscape. The hub should contain genuinely global knowledge and, importantly, tell the AI where to find more specialised knowledge. It is a map and common memory, not an attempt to contain everything the organisation knows.
Spoke
A spoke is a scoped body of persistent engineering knowledge, not a specialised AI agent, tool or capability. It is usually stored as information files close to the code or domain where the knowledge belongs.
For example, a microservice may have a spoke containing its local domain concepts, architectural constraints, interfaces, known implementation traps and accumulated lessons. A spoke can also contain knowledge whose scope legitimately crosses repository or bounded-context boundaries, such as an ADR or an implementation plan spanning several services.
The defining characteristic of a spoke is therefore the scope of the knowledge it contains, not the kind of AI work it supports. A spoke is part of the AI's distributed memory. It is not a worker that performs a specialised function.
The purpose is the same as decomposition in software architecture: knowledge should live at the narrowest scope where it remains coherent and useful, unless there is a good reason to share it more broadly.
Bounded AI context
The principle that an AI should receive the knowledge relevant to the problem it is working on rather than automatically receiving everything available. The hub helps locate the appropriate spokes, and the spokes provide richer local or cross-cutting context when needed.
The distinction underlying the rest of this article is therefore simple: the AI should be able to navigate the organisation's knowledge without requiring all of it to be centralised.
Two ideas that appear to contradict each other
Agile development and specification-driven AI development begin from quite different assumptions. Agile is fundamentally about learning under uncertainty. We understand part of the problem, build something, observe what happens and change our understanding.
Its loop looks roughly like:
Understand → Build → Observe → Learn → Adapt
Its weakness is familiar to anyone who has worked in a software organisation for long enough. Much of what we learn disappears. Important reasoning lives in conversations, whiteboards, chat threads, pull requests and people's heads. Six months later somebody asks why an architectural decision was made, and the most accurate answer available is often: "I think there was a reason."
Specification-driven AI development attacks that weakness almost exactly. It rewards explicit intent, constraints and context because knowledge has to become accessible to the machine.
Its natural loop tends towards:
Understand → Specify → Generate → Verify
That is extraordinarily efficient, but it has the weakness I explored in the previous article: it can separate the people responsible for software from the process through which the software comes into existence.
I don't think we need to choose between these two models.
A synthesis rather than a compromise
A useful philosophical idea comes in here. Two apparently conflicting positions don't always have to end with one defeating the other, or with a compromise halfway between them. Sometimes the contradiction can produce something new that preserves important properties of both.
That is how I have started thinking about Agile and AI-native specification-driven development.
From Agile I want to keep empiricism, collaboration, working software, autonomy and the idea that implementation is part of learning. From specification-driven development I want explicit intent, persistent knowledge, reproducibility and the enormous leverage AI provides.
What I don't particularly want to preserve from traditional Agile is disappearing knowledge and unnecessary manual work. Likewise, I don't want Big Design Up Front, black-box implementation or developers gradually becoming operators of a software-producing machine.
The result is not halfway between the two. It changes the role of AI.
Put AI inside the feedback loop
Instead of giving AI a finished specification and receiving software, I want AI involved while we are discovering what the specification should be.
A development loop might look something like this:
Understand together → Capture current intent → Build and experiment with AI → Interact with the implementation → Observe → Learn together → Update code, specification and AI memory
Then we go around again. The important thing is that no handover point exists where human thinking ends and machine production begins.
The specification describes our current understanding. It can be incomplete because we know implementation will teach us something. AI helps us implement it quickly, and humans and AI inspect what happened. We test assumptions against running software, discover things we hadn't considered, and change our understanding. The specification changes with it.
The spec is no longer a contract handed to a factory. It becomes a living record of what we have learned.
Keep the code in the conversation
This also means that humans do not leave the code behind. I don't particularly care whether a developer physically types a line of code. That distinction is already becoming less meaningful and will probably become almost irrelevant.
I care whether developers think through the implementation.
They should still investigate code, debug unexpected behaviour, question design choices, experiment, refactor and understand important implementation decisions. AI can participate in all of those activities. Sometimes the developer should ask the AI to explain something, sometimes the developer should explain something to the AI, and sometimes two developers and an AI should explore a problem together.
The objective is not human authorship of code. It is human understanding of the system for which humans remain responsible.
The hub can still be useful
This also changes how I think about hub-and-spoke architectures. I don't want to throw the hub away. I want to make sure it does not become the place where everything eventually ends up.
A useful analogy is the software architecture itself. In a microservice architecture, we do not want every service to contain the knowledge and logic of every other service. We have services and bounded contexts in the first place to keep complexity local.
Why should the architecture of our AI's knowledge be fundamentally different?
If a service owns a particular domain responsibility, much of the knowledge required to work on that service should live with it. In practice, this can be surprisingly simple: information files stored in the same repository as the code, containing domain concepts, constraints, important implementation knowledge and things the team and AI have learned while working there.
These become the service's local spoke.
The hub then needs enough information to understand the larger landscape and know where relevant knowledge lives. When work concerns a particular service, the AI follows the hub to that service's spoke rather than carrying the detailed knowledge of every service all the time.
The distinction matters: the hub should know that knowledge exists without necessarily containing it.
That gives us something closer to distributed engineering memory than a central AI brain.
Knowledge should have an architecture too
If we have learned anything from distributed software architecture, it is that making everything globally available is rarely a good long-term strategy. Locality matters. Boundaries matter. The same should apply to the information we maintain for AI.
Most detailed knowledge should therefore remain close to the software it describes. A service repository can contain not only code but the AI-accessible memory needed to work responsibly with that code: domain terminology, local architectural decisions, constraints, interfaces, known traps and lessons from previous work.
Not all knowledge fits neatly inside one service. An ADR may deliberately describe a decision affecting several bounded contexts. A larger change may need a temporary implementation plan spanning several repositories. Security, observability or organisational engineering principles may legitimately be broader still.
Those can also be spokes, as long as their scope is clear.
The important distinction, then, is not simply global versus local. It is scope.
Store knowledge at the narrowest scope where it remains coherent and useful. A service-specific fact belongs with the service. A cross-service architectural decision belongs at the level where that decision applies. Only genuinely shared knowledge belongs in the hub.
This also gives the AI a natural way to assemble task context. It begins with a relatively small common understanding, identifies which parts of the system are involved, follows the relevant spokes and constructs the context it needs:
Hub → Discover scope → Load relevant spokes → Work with code → Learn → Update the appropriate memory
The AI does not need an ever-growing universal context. It needs the ability to find the right context.
We already learned not to solve software complexity by putting all behaviour into one deployable unit. We should be cautious about solving AI context by putting all knowledge into one cognitive unit.
Memory should be a product of the work
This distributed memory also changes what development produces.
Suppose a developer and AI spend an hour debugging unexpected behaviour in a service. They discover that an apparently strange implementation exists because of a subtle constraint in another system.
Traditionally, this knowledge may end with the developer. Perhaps it appears in a pull request or comment. Perhaps somebody writes documentation. Perhaps six months later someone removes the strange implementation because they don't know why it exists.
With persistent scoped memory, the work can produce two durable outputs: the corrected software and an updated spoke containing what was learned.
The repository remembers something the team learned.
The same applies to larger work. A cross-service implementation plan can evolve while the work proceeds. An ADR can gain context from what happened when a decision met reality. Local domain knowledge can improve as developers and AI discover exceptions.
The hub does not have to absorb all of this. It needs to help future work find it.
This is where persistent AI context becomes genuinely interesting to me. It is not simply information we prepare so that AI can write better code. It is a mechanism for retaining engineering learning that we have historically been very bad at preserving.
Capabilities are different from spokes
There is another distinction worth making. Implementation, testing, security analysis, architecture analysis and documentation are useful AI capabilities, but they are not spokes in this model.
They belong to the harness: what the AI can do.
A spoke is not a specialised agent that performs one of those activities. It is the scoped knowledge that an agent may use while performing them. For example, a security-analysis capability might use a service's local spoke, relevant security guidance from another spoke and the hub's global constraints. The capability performs the analysis; the spokes provide the knowledge that makes the analysis relevant to the system.
The separation is useful:
Harness — What can the AI do?
Hub — What must it know globally, and where can it find more?
Spokes — What scoped engineering knowledge persists?
Task context — What knowledge has been assembled for this particular problem?
Code — What actually exists and behaves in the running system?
Keeping those concepts separate helps avoid turning the hub into both a knowledge store, workflow engine, architecture model and agent coordinator.
AI should strengthen conversations, not eliminate them
This matters socially. One danger of very capable personal AI assistants is that they remove the need to ask another human being for help. That is wonderfully efficient locally and potentially destructive collectively.
Perhaps we should therefore deliberately create situations where AI participates in human collaboration. Imagine an architecture discussion with three engineers and an AI. The AI can retrieve previous decisions, inspect relevant spokes, search the code, prototype alternatives and challenge assumptions while the humans contribute experience, disagreement, intuition and domain understanding.
At the end, the team has learned something. The AI can then help capture what was learned in the appropriate persistent memory. The next conversation starts from a better position.
In that model, AI is not replacing collective intelligence. It is helping the organisation retain and amplify it.
Junior developers change the optimisation problem
The same principle applies to learning. If the objective is simply to complete a small programming task as quickly as possible, assigning it to AI is increasingly the rational choice.
But completing the task was never its only output. Sometimes the other output was a developer who now understood the system slightly better.
That means we need to recognise that engineering work can produce several things simultaneously:
Software + Knowledge + Engineers + Teams
Different tasks may deliberately optimise for different combinations of those outcomes.
A junior developer working with AI may take longer than simply letting an autonomous agent solve the problem. That can still be the better organisational decision if the developer learns how the system works, how to debug it and how to judge alternative solutions.
AI could be an extraordinary tutor and pair programmer. It can explain unfamiliar code without impatience, retrieve relevant historical context, generate experiments and challenge an assumption. But that only helps if the human remains inside the learning loop.
Human agency as an architectural property
This leads to a principle I increasingly think should be explicit in AI-native development: human agency is a design constraint.
That does not mean humans must perform tasks machines can do better. Quite the opposite. We should automate repetitive translation, boilerplate implementation, mechanical verification, documentation maintenance and other work where human participation adds little value.
But we should be careful not to classify every human interaction that slows production as waste.
Discussion is slower than asking an AI, exploration is slower than following a complete specification, and teaching a junior developer is slower than letting an agent implement the feature. Trying an idea that turns out to be wrong is also slower than generating the correct solution immediately.
Yet those activities create understanding, judgement, relationships and organisational capability. Efficiency and effectiveness are not always the same thing.
The optimisation target should therefore not be to minimise human involvement. It should be to minimise unnecessary human labour while maximising useful human judgement, learning and collaboration.
Cheap implementation should make us more Agile
Another consequence I find particularly exciting. For most of software history, experiments have been expensive. We therefore spent considerable effort trying to avoid implementing the wrong thing.
AI changes the economics.
If an implementation that previously required three days now takes thirty minutes, uncertainty becomes less threatening. We can try two approaches: generate a prototype and show it to somebody, or implement an architectural idea far enough to discover whether it actually works before debating it for three meetings.
This suggests a very different equation from specification-first automation:
AI capability ↑ → Experiment cost ↓ → Feedback frequency ↑
AI may therefore allow us to practise the empirical ideals of Agile more aggressively than we ever could before. That seems much more interesting to me than using AI primarily to speed up the implementation phase of a predetermined process.
The team remains the brain
This gives me a different mental model for AI-native development. The AI is not merely a tool; that understates what increasingly capable agents can contribute. But it is not the engineering organisation's brain either.
The team remains the brain. The AI becomes a participant with an extraordinary distributed memory and an expanding set of capabilities.
Its memory contains what it has learned while working with us, organised according to the parts of the system where that knowledge belongs. Its harness gives it powerful capabilities. The specification records our evolving intent, while the code remains something we interact with rather than an opaque product delivered back to us.
Humans remain in the process not because machines can't replace individual activities, but because the process has purposes beyond producing the next piece of software.
It also needs to produce understanding, engineers and teams.
From shepherd to colleague
In the previous article, I used the image of developers becoming shepherds managing a flock of AI agents, and my concern that a sufficiently prescriptive process could turn the metaphor around: the process becomes the shepherd and the developers become part of the flock.
I now think there is a better metaphor. Perhaps we don't need either shepherds or sheep. AI can join the team.
Not anthropomorphically; an AI is obviously not a colleague in the human sense. But functionally, we can design the development process so that AI participates in exploration, implementation and learning rather than sitting behind a specification boundary.
The objective of AI-native software development should not be to remove humans from the development loop. It should be to make that loop dramatically more capable.
If we manage that, the result might preserve something I value deeply about software engineering while still embracing what AI makes possible: people thinking together, discovering things they did not know when they started, creating systems they actually understand, and leaving behind a memory of what they learned.
A note on the experiment behind these articles
These two articles are themselves a small experiment in the model I am describing. I did not begin with a specification for two articles; I began with a concern.
I discussed it with AI, added observations, rejected interpretations, introduced Marx, industrialisation and Agile, changed my mind about parts of the problem, and eventually arrived at the idea of a synthesis.
The hub-and-spokes idea changed in exactly this way. An early version treated spokes as specialised AI workers or capabilities. Thinking further about our experience with microservices made that feel wrong. The more useful interpretation was scoped memory: knowledge kept close to the domain and code where it belongs, with the hub providing navigation rather than omniscience.
So we changed the model, and then changed the article.
The AI contributed structure, counterarguments, terminology and connections. I contributed experience, judgement and direction. Neither the initial prompt nor the first response contained the argument you have just read. Our "specification", if we want to call it that, emerged from the work.
That is a small example, but perhaps it captures the distinction I am trying to make. The AI did not receive my finished thinking and implement it. The thinking developed while we worked together.
And when the thinking changed, our specification did too.
That is the kind of AI-assisted engineering process I want to explore.
Comments
Post a Comment