Spec-Driven Development for Teams: The Shared-Spec Workflow
How a spec stops being personal discipline and becomes the contract your team ships from: shared specs in git, spec review by pull request, gates on a board, and why the bottleneck moves from writing code to integrating it.
Solo, the spec is discipline against your own drift. In a team, it becomes the contract everyone reads instead of reading each other’s minds. Same document, a bigger job.
People who search for Spec-Driven Development in a team have usually already used it alone. They read the case study, tried it on a feature, watched an agent build the right thing from a good spec, and now they want to bring it to the people they work with. The question underneath is whether the method survives contact with a second developer, a reviewer, and a shared codebase.
It does. But one thing changes, and missing it is how you end up with process theater: a folder of specs nobody reads and a ritual nobody believes. Solo, the spec is your discipline against your own drift and the agent’s. In a team, the spec picks up a second job. It becomes a contract, between people and between squads. The document is the same. The job is bigger.
This is the practical companion to the solo case study and to how to write a spec. It covers what actually changes when a spec has more than one reader: versioning it as a shared contract, reviewing it by pull request, keeping the conventions in the tool instead of in heads, putting the gate on a board, and the reason the whole workflow earns its keep, which is that the bottleneck moves from writing code to integrating it.
What changes when the spec has more than one reader
Solo, the spec does one job. It is the only memory the agent gets, and it is the discipline that stops you from drifting off what you actually meant. In a team it keeps that job and picks up two more.
The three jobs of a team spec
| The spec sits between | What it carries | Solo or team |
|---|---|---|
| Human and agent | The only memory the agent gets. Limits its drift. | Both |
| Human and human | What a teammate reads instead of reading your mind. | Team only |
| Squad and squad | The contract at the boundary where two teams integrate. | Team only |
The failure mode is treating a team spec like a solo spec with more authors. You keep writing private notes, add a shared folder, and call it a practice. The notes still assume everything that lives in your head. A teammate opens the file, hits the first implicit rule, and guesses, which is the exact problem specs exist to kill.
Version the spec, or you do not have a team practice
Git is what turns a spec from private memory into a shared contract. The spec lives in the repo, next to the code it governs, versioned alongside it. One source of truth, one history, one place to look.
That much you might already do solo. The move that makes it a team practice is the one nobody writes about: the spec enters review before the code exists.
A code review after implementation catches typos in a decision that was already wrong. A spec review catches the wrong decision before a single line encodes it. So the requirements land as a pull request, a reviewer reads them, and only when they approve does the .status flip to requirements:approved and design begin. Same for design. Same for tasks.
Keep the canon in the tool, not in heads
Solo, your conventions live in you. The Smart Kid bar, the EARS grammar, the habit of writing an explicit negative scope: you apply them without thinking because they are yours. In a team, if those live only in heads, every developer’s SDD drifts in its own direction and you end up with five dialects of spec that read nothing alike.
The fix is to put the canon where the tool reads it, not where a person remembers it. Shared steering files hold the product context and the rules. Skills carry the format and the bar into every developer’s agent. The three-layer context system that a solo developer keeps for themselves becomes the thing the whole team shares.
The shared canon, versioned for everyone
- .ai/
- steering/
- product.md// what we are building and who for
- tech-stack.md// the stack and the rules that bind the agent
- conventions.mdthe bar// spec format, gates, code rules, shared by everyone
- sdd/specs/012-login-otp/
- .statusgate// stage:state, the machine-readable gate
- requirements.md// the WHAT, reviewed by PR before design
- design.md// the HOW
- tasks.md// the HOW MUCH
This is also how onboarding changes. A new developer reads the spec corpus and the steering files, not a wiki page and a shoulder-tap. The specs are the orientation material, because they are the record of every decision and why it was made. The bar travels in the tool, so a person who joined yesterday writes a spec that reads like a person who has been there two years.
Who owns the spec
Solo, you are all four roles at once: you write the requirements, decide the design, cut the tasks, and review the result. In a team those separate, and the moment they do, ownership becomes a real question.
Map it to the roles SDD already names. Whoever writes the requirements owns the WHAT. An architect, human or agent, owns the design. A reviewer owns the gate. None of this is heavy. It is the same people who already review code, doing it one step earlier, on the document instead of the diff.
The question that actually matters is what happens when two developers want different things. Without SDD, they find out at the merge, or later, in production, after both built their version. With SDD, the disagreement surfaces in the requirements pull request, in comments, before either of them writes code.
Where a disagreement surfaces, and what it costs
| Where the conflict shows up | What it costs to resolve |
|---|---|
| In the requirements PR (SDD) | A comment thread, before any code exists. |
| In code review, after implementation | One rewrite of a feature that already works. |
| At integration, between two squads | Two implementations that do not fit together. |
| In production | An incident, and then all of the above. |
Put the gate on a board
The .status file is the gate. It is machine-readable and it lives per spec. Solo, you read it yourself and that is enough. In a team, a gate that only lives in a file nobody opens is a gate that gets skipped, because most people cannot see it.
So you make it visible. A board where each column is an SDD stage. A card is a feature. The card moves when its gate is approved, and the approve is the move.
How a feature moves across the board
Input
A new feature enters the backlog
- PRDWrite and approve the WHAT
requirements.md opens as a pull request. A reviewer approves it. The .status flips to requirements:approved. Nothing downstream starts until it does.
- SPECDesign against the approved WHAT
design.md maps every requirement to a decision. It is approved the same way, by review, in git, before any task is cut.
- TASKSCut the work into gates
tasks.md breaks the design into 2 to 4 hour units, each independently testable, each approved before a line of code is written.
- EXECBuild, then review the diff
The agent implements from the approved spec. The pull request is where a human checks the diff against the spec it was supposed to satisfy.
Output
Every column change is a gate a human approved. Skipping one is blocked by branch protection, not by trust.
There is a full working reference repo for exactly this: acme-store-sdd. It runs this flow on a GitHub Projects board, with each card moving as its .status gate is approved, and branch protection on the main branch that refuses a merge without a review. Clone it and read the .github/workflows and the .ai/sdd/specs folder together. The board is not the point. The board is the gate made visible, and you can see it live: seven columns, one per SDD stage, each card sitting where its spec’s .status puts it.
The bottleneck moves from writing code to integrating it
Here is the reason all of this earns its keep in a team, and it has nothing to do with typing speed.
Solo, your bottleneck was your own loop: you, one agent, one feature at a time. In a team, code generation gets cheap fast, because everyone has an agent. The team can produce several times more code than it used to. But the amount that actually ships does not grow at the same rate, because the wall moved. It is now review, deploy, and the coordination between people and squads.
A team can generate ten times the code and integrate roughly what it always did, because typing was never the constraint. Integration was. Reviewing, reconciling, making sure the thing one person built fits the thing another person built: that is the work that does not get cheaper just because the code appears faster.
The board draws this on the wall. Put a work-in-progress limit on the review column and watch cards pile up there. That pile is your real constraint, made visible. No faster agent clears it. It clears when the spec did its job as the coordination layer, so that the work of many developers and many agents fits together instead of colliding.
As teams start adopting agents at scale, the pattern is consistent, and it is not the one the tooling vendors sell. The agent is almost never the bottleneck. The integration is. A shared spec is how a team keeps the integration from becoming the wall, because it is the interface that lets parallel work fit together on the first try instead of the third.
Are you running SDD, or just filing specs?
Team readiness gate
- Required:Specs live in git, versioned next to the code they govern.If they live in a wiki or on a laptop, they are not a shared contract. They are private notes with extra steps.
- Required:Every spec is reviewed and approved in a pull request before implementation starts.A merged spec that nobody reviewed is a draft with a green checkmark.
- Required:The conventions live in shared steering files and skills, not in one senior developer's head.If onboarding a spec writer means a shoulder-tap, the bar is not in the tool yet.
- Required:The gate is visible: anyone can see which features are approved and which are still drafts.A board, one column per stage. If the gate only lives in a .status file nobody opens, it is not visible.
- Required:Branch protection blocks a merge without a review.The gate has to be physical, not a norm people remember on their good days.
- Required:Disagreement about a requirement happens in the spec, not at integration.If two developers discover they built different things when they try to merge, the argument surfaced at the most expensive layer.
FAQ
Who approves the gate in a team?
The reviewer role: the same person who would review the code, just doing it one step earlier on the document. In practice a tech lead or a senior on the squad approves requirements and design, and anyone competent can approve tasks. Approval is a named human act recorded in the pull request and the .status file, not an implicit 'looks fine'.
You do not need a committee. One competent reviewer per gate is enough. What you cannot have is no one, because a gate with no approver is not a gate.
What happens when two developers disagree on a requirement?
The disagreement goes in the requirements pull request, as comments, and gets resolved before either of them writes code. That is the entire economic argument for working this way.
The same disagreement found at integration costs two finished implementations that do not fit. Found in production it costs an incident. Move the argument to the cheapest layer to have it.
Do we really need a board, or is the .status file enough?
Solo, the file is enough, because you read it yourself. In a team the file is invisible, and an invisible gate gets skipped. The board is the .status made visible to everyone at once. It is a view on top of the files, not a second source of truth.
The board also surfaces the integration bottleneck, which a file cannot. A column filling up past its work-in-progress limit is a constraint you can point at.
We use Jira, not GitHub Projects. Does this still work?
Yes. The principle is columns equal SDD stages, and a card points to the spec in git. The brand of the board does not matter.
What matters is that the board reflects the gate and never becomes the place the spec actually lives. Git holds the artifact, the board reflects the state.
Does every feature need the full three-document spec in a team?
No, the rule is the same as solo. A one-hour fix does not earn a requirements.md. What changes in a team is that the threshold is a shared decision, not a personal one.
Agree on when a change needs a spec, then write that rule into your conventions and put it in the steering file, so the humans and the agent apply the same threshold instead of six different ones.
How does this scale past one squad?
The spec at the squad boundary becomes the contract between squads. When one team depends on another, the interface is a spec both sides approve, not a chat thread both sides forget.
That is the same mechanism one level up: move the coordination into a versioned artifact that both sides review, so the integration between teams is designed on purpose instead of discovered at the merge.
Where to go next
SDD does not change when you add people. The spec does the same thing it always did. What changes is that the discipline has to leave your head and become something a team can see, review, and enforce. Version it, review it in a pull request, put the gate on a board, and let branch protection hold the line. The method was always about moving decisions to the cheapest place to make them, and a team is where that pays the most.
The newsletter
Don't Code, Specify. A weekly dispatch from where AI agents meet real production. No hype, just what shipped and what broke.
Subscribe on Substack (opens in a new tab)