We brought in spec-driven development. Then we took it out.
In October 2025 I brought spec-driven development into the platform team I work on. A year later we retired it, and kept the parts that had earned their place. Both were the right call at the time, and the gap between them is the most useful thing I learned last year about working with AI agents.
Why we needed it
At the end of 2025 the models were good at writing code and bad at knowing what to write. Give one a feature description and it would happily produce something that compiled, passed its own tests, and broke three architectural rules we cared about. Business logic in the wrong layer. Hand-rolled field mapping where a spread would do. Queries that skipped the data access layer.
So the question was how to get the rules in front of the model before it started typing. SpecKit, GitHub’s spec-driven toolkit, was the obvious place to start. Requirements first, then a spec, then a plan, then tasks, then code. I took it and customised it for our monorepo.
By the time I was finished it had nine constitutional principles, about twenty-six specialised agents, and a chain of slash commands. Planning fanned out to seven specialist agents, one per concern, and an orchestrator stitched their output into a plan. The agents were written to refuse. If you asked for something that broke the constitution, the repository agent would say no and offer the compliant version instead.
The constitution caught things early that would otherwise have shown up in review. I gave two lunch-and-learns on it in November, one on the method and one on a spike we had run through it end to end.
What the first version taught us
The second of those talks had a slide I’d titled "The Reality Check", with the team’s honest feedback on it. Too many commands. Specs too verbose. Feels rigid. Takes longer than just doing it. Most of the team were using parts of it rather than the whole thing, and when they hit a snag it was easier to go back to coding normally.
None of that was a surprise and none of it was anyone’s fault. We’d built a system that was impressive to look at and hard to live in. It ran in both Codex and Claude Code, and it wasn’t great in either. The agents and rules duplicated things that belonged in the codebase’s own documentation. And the shape of the work never really matched the shape of the pipeline. Real features go epic, discovery, design, phases, carry-forward. SpecKit wanted spec, plan, tasks, implement.
So we decided, as a team, to replace it rather than keep explaining it.
Specflow
In March 2026 I built the replacement, which we called Specflow. The idea was to keep what had actually earned its place and drop the rest.
What stayed: a written statement of intent before implementation, the constitutional rules, and a planning step for anything consequential. What changed: everything moved into skills instead of agents and slash commands. There was a layer skill each for data, repositories, services, queues and the frontend, and they were useful for ordinary bug fixes as well as for the workflow, so maintaining them paid off every day. There were three lanes, tiny, lite and full, so a one-line fix didn’t have to pretend it was a feature.
This one was used, and used well. For about six months it was how the team shipped.
The models moved
What changed wasn’t the process. It was the models, and the order matters, so here it is honestly. In the first half of August I went and looked at what was actually happening before suggesting anything. Out of roughly a hundred merged PRs, not one had gone through the full pipeline. Three quarters had declared the lite lane, which in practice meant a structured issue, the layer skills, an independent review and evidence on the PR. The spec documents were duplicating the issue. The task ledger was duplicating GitHub. The approval after every intermediate document was a gate that nobody needed any more.
That was already true on the models we had in August. Then September brought GPT-6 Astra and Opus 5.5, and the gap got wider. Those models didn’t need a durable plan to implement a well-described feature. They needed a clear statement of what was wanted, the rules of the codebase, and a way of proving the result. Give them a good GitHub issue and the layer skills, and the plan they’d write for themselves was about as good as the one the pipeline produced, and it would be gone by the time the PR merged, which was fine. The August numbers said the pipeline was unused; the September models said it wasn’t coming back. I’m not claiming an experiment here. It was an observation followed by a decision.
I asked a model that hadn’t been involved in building any of it for a second opinion, and it came back with the same split I’d arrived at. The pipeline part of spec-driven development had stopped earning its place. The contract part hadn’t. Someone still has to own the intent, decide who can approve what, write down what done means, and prove it.
What we kept
In September I proposed retiring Specflow for new work, and in October the team agreed and the cleanup merged. The process went. The skills stayed, and they’re the part that matters.
Those layer skills are still in the repo today and they’re never finished. Every time a model changes, we check them against it: which examples it misreads, where the source has drifted from the guidance, where a rule is giving false confidence. They get rewritten to fit the model we actually have, not the one we had in March. What survives of the old Definition of Done is small enough to say in a sentence: an agreed outcome, proof proportionate to the change, the supporting changes that go with it, honest ownership of anything left, and a truthful handoff.
We didn’t put a smaller process in the same spot. The point of removing one is not to replace it.
What I’d take from it
Process for agents has a shelf life, and it’s shorter than process for people. The constitution was worth having because the models of late 2025 needed it. The plan documents were worth having for about six months. The skills have outlasted both, because they encode what the codebase needs rather than what a given model needs.
The thing I’d do again is look at the real PRs before deciding. Counting is what let us take it out without an argument.
I’m fairly sure what we kept will need trimming again in another six months. That’s the job now. Knowing when a process has stopped earning its place, and being willing to say so.