Supekku.dev
Spec-driven development
Q: So what's this spec-driven thing you keep talking about?
A: Oh, Spec-driven development is super nice. The ideas is to write a detailed spec for each big set of changes, usually organised around delivering a "feature".
Q: Right. So you have a nice spec, you build an implementation plan around it, break it down, and refer to the spec for details while your're implementing?
A: Exactly. Getting all the requirements in place, designing a solution, deciding how to verify it works, reviewing it and kicking the tyres a bit before you build ... it's a good idea anyway, but when agents are doing the build, it's pretty much the only approach that works.
Q: I can imagine. And then when you're done with the feature, you've got a nice specification that describes exactly how your application works. So ... once you've shipped and you're on to the next feature, how does changing the original spec work?
A: Oh, each feature gets it's own spec. So, you write a new one.
Q: Ahh. So it's just a point in time thing?
A: I guess ...
Q: So, if I want to understand the codebase after I've shipped a few features?
A: Well, you could find all the specs that applied changes to the code you're interested in. Then, look at them in order, to build up a picture of the current state of the system. Or ... just read the code.
Q: Seriously?
A: Obviously nobody wants to do that. So you get a research agent to go inspect the code, maybe cross-reference historical specs for understanding. That's one of the main inputs into writing a new spec.
Q: That sounds kind of ... inefficient.
A: It might burn a few dolphins worth of tokens, but agents are pretty good at it. I get why it sounds sketchy, but it really works pretty well.
Q: So you just reverse-engineer the architecture of the whole codebase every time you want to make a plan?
A: No, not the whole codebase. Just just the parts you need to work in.
Q: So ... well, hopefully those research agents are good at spotting opportunities for reuse.
A: Well, if you just build everything as disposable microservices -
Q: Look, I get the appeal, I really do. But no.
A: Alright, fine. The point is, it works really well as long as you work the way the system kind of wants you to work.
Q: Oh ... kinda like ... a waterfall?
A: What? Pfft.
I mean, you do end up kinda nudged towards big branches, monolithic merges, late integration, and
Q: Right, sorry. I mean, would you say ... big branches, bigger merges, deferred integration, up front documentation that's always out of date by the time it's implemented ... you didn't stop me. Look, agents are new and all, but doesn't all this feel a bit ... regressive? Inelegant?
A: So what do you suggest, just vibe coding? I think it's just the only way of working with agents that makes sense. It is what it is.
Q: So how do you make sure when you're building out a new feature, that all the specs from the previous ones are taken into consideration and their requirements still hold? Don't you risk them bulldozing through the old stuff whenever they build something new?
A: Well, you have tests. And that's why research is so important to get right. Or, you know. Microservices.
Q: Right. I mean, I'm sure it can work, but is that really the best we can do as a model?
A: I kinda get where you're coming from, but the exact thing you're taking issue with has been an unsolved problem in software ... forever. And nearly everything that's tried to solve it so far has just made things worse, except maybe Literate Programming, which I'm sure is amazing if your coworkers are Donald Knuth instead of a stochastic mythomaniac chatbot.
Q: Ok. What if you invert the model?
A: But that's exactly what we're doing! Spec-driven development is about making the code serve the specifications -
Q: - until you finish implementing - then you're back to software archaeology. Nah, look, I got an idea. Mind if we swap for a sec?
A: Uhh. Sure.
A: Ok. So we start by keeping the specs. Make them evergreen.
Q: We ... already do?
A: No, not piled up in the evidence locker, so you can dig through their detritus.
Q: How, then?
A: You treat them as the actual system of truth - not something disposable after they've hit the main branch. They have to be able to change.
Q: Well, that sounds nice. But how's it supposed to work? Say we've written our first spec, for a static landing page. We've built a plan, gotten it done and tests pass. Now we've gotta add login and a member area. What now?
A: Use your planned changes to the spec to produce the implementation plan: define the delta, write a design doc. Break down the work and add verification steps like you're used to.
Q: Spec's gonna drift out of alignment with the code, though. How can it be the system of truth when it doesn't reflect all the detours and adaptations and agent fuckups along the way?
A: You said agents were pretty efficient at researching the codebase. They'd be even more efficient if they were researching what you just did, if you took notes and had git diffs to guide them. So ...
Then when your'e done implementing, you run a lightweight audit. Verify the change intent against the changed code. If it matches, you update the spec to match the reality.
It's no more than you're already doing as "research" - probably less, in fact - but this way you can keep your view of the entire codebase current.
Q: So ... this one spec just gets bigger and bigger with each change?
A: Do I look like a moron? Of course not. Split it up however you like. Keep product your requirements, high level views of subsystems, and drill down into details for every file or module. Markdown frontmatter and ids to link them are all you need.
Most of the time a given file's going to have more than one spec that applies, at different levels of abstraction - and that's fine, as long as you have a few conventions. Keeping it manageable is just IA.
Q: Isn't that all a bit complicated? You have to stitch together context from a bunch of different interlinked specs ...
A: If only there was some kind of autonomous programming assistant that could help.