NoteOct 20266 min
Spec Driven Development and How to Build One for Multi Repo Native Engineering
How I kept AI coding agents aligned across iOS, Android, and the rest of the repos.
Over the last few years of building software, and with how fast agentic engineering is growing, something new and pretty costly has shown up, and that is context.
Context costs you time and money, both at once. Let me break each one down.
Context costs you time
If you're in software engineering, you know by now that AI models have a context window, and it gets used up pretty quickly. Once it's full, you either wait for it to reset or start over in a new session, and the new session knows nothing about what you just did.
Context costs you money
Now that these models can handle complex tasks, they eat up tokens real fast. They also create context at that same speed. That means token usage gets really high inside one session, and every time you spin up a new agent, it has to read the whole thing again just to get an idea of what's going on. That's a lot of tokens to waste on unstructured context.
This gets way worse when you're working across multiple repos, for example, a product with native iOS and Android apps.
Where this hit me
During my internship, I was working across four repositories: an iOS app, an Android app, a backend, and firmware for a hardware device. My loop always looked like this:
- Build a feature on iOS.
- Test it end to end.
- Open a different session and repeat the same inputs to the AI agent to build the same feature on Android.
The agent would ask the same questions again when we were building a plan for a feature, or I wouldn't explain the feature as well the second time. Then I'd spend more time editing the plan to get it to the right place. Same feature, paid for twice, and the two apps slowly drifting apart.
Attempt 1: a Notion wiki (didn't work)
My first fix was a Notion wiki. It had one home page listing every repo and what it owned, a section per codebase (firmware, backend, iOS), and dated pages explaining why we picked X over Y.
It was nice for people to read. It did nothing for the agents. Here's why:
- It wasn't the source of truth. The docs inside each repo still won if they disagreed with Notion. So every fact had two homes, and Notion was always the one that went stale first.
- The agents never read it. My agents work inside a repo. A wiki sitting outside the repos just isn't part of what they look at before making a change.
- It said why, not what. Good for decision history, but there were no exact rules or values I could check the code against.
- It wasn't versioned with the code. No way to say "this page is true as of this commit," and changing it didn't go through review like code does.
- It was split by codebase, not by feature. That's literally how the two apps drifted in the first place. Android didn't even have a section lol.
Attempt 2: a docs folder (better, still not it)
Next, I started keeping plans and specs as .md files in a docs folder inside the repo. Over time, I had a whole folder of documents for agents to read, but it wasn't built efficiently. Details got duplicated across repos, and agents still ended up reading the codebase most of the time anyway.
So I started looking into whether the industry already had a better answer for this, and landed on Spec Driven Development (SDD).
So what is Spec Driven Development?
The way I think about it, SDD is basically an encyclopedia for the product you're building: what each feature does, what it doesn't do, its limits, and the decisions behind it. Agents read the spec first, then build from it.
There are already a few frameworks out there, from big companies to open-source projects:
- Kiro
- GitHub Spec Kit
- OpenSpec
Rather than just picking one or going with whatever the internet recommends, I did some research on each of them. And one thing stood out: most of them are built to sit inside the repo itself, kind of like how .claude or .agentfolders get created. At a higher level, that's a real problem when your product lives in four repos. To be fair, OpenSpec has since added a beta feature for keeping specs in a repo of their own, so the industry is clearly heading this way too.
So the plan was to take the good parts of each one and blend them together. But first, here's what I didn't like about each.
What I didn't like about each one
Kiro is a pretty solid system to work with, but it's built to tie you down to its own framework. It started as its own Integrated Development Environment (IDE), with tools to write specs, explore features, bugs, and releases, then let your agents execute them. There's a Kiro CLI now too, but the specs still live in Kiro's own format and workflow. With how fast agentic engineering is moving, I don't think it's smart to tie our codebases to a closed framework. Especially in native mobile. You and I both know we need Xcode for iOS: building, installing on dev iPhones, and a bunch of other stuff. Same with Android Studio, because you need it for live preview instead of building and installing every single time you change something.
GitHub Spec Kit felt like a much bigger framework. It's very bulky, with too many .md files, and it's pretty loosely coupled. Structure is good, but we end up wasting tokens reading files we don't need just to search. Most of it could live in one file.
OpenSpec felt the most straightforward to me. Its drawbacks only really show when you compare it to the others. For example, it doesn't have separate flows for different goals, whereas Spec Kit has three: feature investments, bugs and releases, and feature specs.
What I built instead
I started with OpenSpec as the baseline, installed it, and made it its own repository with version control on GitHub. That way it's isolated from every code repo, and the team can add to it, change it, and treat it as the main spec for the product.
The big principle: specs should describe the product, not just one codebase. Spec-driven development is done per product, not per repo. The spec repo says what the product should do, and each code repo keeps its own implementation details.
The goal wasn't to recreate every feature of these tools. It was to build a smaller workflow around the problems we actually ran into.
Then I pulled in what I liked from everything else:
| From | We take |
|---|---|
| Spec Kit | Constitution · assess flow, from its assess extension (go / needs-clarification / kill) · bug stage rules, from its bug extension (assess doesn't edit code, fix doesn't grow in scope, test doesn't edit code to pass) · converge check |
| Kiro | EARS rules · bugfix current / expected / unchanged · quick path for small work · requirements-first vs. design-first |
| OpenSpec | Living specs + deltas + archive · named rules with scenarios · explore · validate (made strict) · the shared spec repo model |
| Our own | Notes per part (iOS / Android / firmware / backend) · validation with BLOCKED for hardware · parity matrix · the "same bug on the other platform?" check |
So that's the why. Context costs you time and money, and it gets way worse when one product lives across multiple repos. A Notion wiki was nice for people but invisible to the agents. A docs folder inside the repo got closer, but it duplicated details and still left agents digging through the codebase.
Spec-driven development fixed the core problem: one shared place that describes the product, not just one codebase. None of the existing frameworks fit a multi-repo native setup on their own, so I took OpenSpec as the baseline, kept it in its own repo, and pulled in the best parts of Spec Kit and Kiro, plus a few things only our project needed.
On the next part I will show how the repo is built within and how the structure works.