whereweup. Discuss your project

The bottleneck in an AI-assisted team is not the code

AI Process Engineering
The bottleneck in an AI-assisted team is not the code

For most of the last year I have watched a small team ship at a pace that would have needed three times the people two years ago. Two engineers, a monorepo with four packages, and Claude Code doing a large share of the implementation under review.

The surprising part was not how much code got written. AI made writing code cheap a while ago. The surprising part was where the new bottleneck moved.

It moved to coordination.

When code is cheap and fast, the expensive thing becomes making sure everyone, human and agent, is building the same system, against the same decisions, in the same shape. The failure mode is no longer "we cannot write this fast enough." It is "we wrote three slightly different versions of the same thing because nobody agreed on the contract first."

We fixed it with two layers. Not a tool, not a clever prompt. A spec-driven framework that both humans and agents work through, and a board convention that sits on top of it.

Two layers that hold the team together

The product is a marketplace where hosts create dinner experiences and guests book seats. The codebase is a monorepo with four packages: a Flutter mobile app, a Go serverless backend on AWS Lambda, a React admin portal, and the AWS CDK infrastructure. Four very different surfaces, two engineers, and an AI agent that touches all of them.

The first layer is the specs.md FIRE flow. This is the spec-driven engine. It is not a document you write once and forget. It is a flow: you establish a constitution, capture intents, decompose them into work items, and execute against them, with state tracked the whole way so neither a human nor an agent ever loses the thread. The artifact it centres on, the authoritative SPEC.md, is the contract. But the contract is alive, produced and maintained by the flow, not by someone's memory.

The second layer is the Azure DevOps board, governed by a convention strict enough that a machine can parse it. The board does not replace the specs.md flow. It sits on top of it. The flow decides what is true about the system and what work needs doing. The board is where that work becomes visible, routable, and trackable for the humans, and where the agent picks it up with full context.

Neither layer is novel on its own. Every team has a spec somewhere and a board somewhere. The leverage came from making both strict enough that an AI agent could act on them without a human translating first.

specs.md FIRE flow as the contract

Article content

The FIRE flow holds the things that must not be re-litigated in a pull request.

It starts with a constitution: the non-negotiable principles the system is built on. Then intents, which are statements of what should be true about the product, not tasks. Intents decompose into work items. Work items get executed, by a human or by Claude Code, and the whole sequence is tracked as state so the project always knows where it is.

The authoritative SPEC.md that the flow produces carries the data model, all eight core entities with every field and relationship, the API endpoints, and the architecture rules that are not up for negotiation: one Lambda per handler with no internal routing and its own granular IAM, the three-layer Handler to Service to Repository pattern in every domain with no shortcuts, pagination on every list endpoint, CloudFront in front of everything, separate Cognito pools for the app and the admin portal. Each package also has a tech-stack.md that pins the definitive stack for that surface.

The reason this matters is subtle, and I did not appreciate it until I watched it fail.

Early on, before the flow was authoritative, every pull request became a small architecture debate. Should this logic live in the handler or the service. Should we paginate this. Why does this domain look different from that one. The code was fine. The reviews were exhausting, because we were re-deciding settled questions one PR at a time, and the agent had no way of knowing which of our past decisions still held.

Once the rules lived in the flow, the dynamic flipped. You point an engineer or an agent at the spec and they produce code that fits. Review stops being "is this the right architecture" and becomes "is this a correct implementation of the architecture we already agreed on." Those are completely different amounts of work.

The flow is not documentation. It is the thing that stops the same conversation from happening fifty times.

The board convention, decoded

If the specs.md flow decides what is true, the board is where that truth turns into motion. And the board only works because every work item follows a mandatory, parseable convention. This is the part that sounds like bureaucracy and is actually the opposite.

The title prefix is the routing key. Every item starts with [App], [Backoffice], [Backend], [Infra], or [Docs]. The prefix is not decoration. It determines the default owner. Frontend surfaces route to the app engineer. Backend, infra, and docs route to the lead. The surface that owns the change picks the prefix. Cross-surface work either names the secondary surface in the body or splits into two linked items, because a work item that belongs to everyone belongs to no one.

Tags are how the board stays readable without anyone reading it. Every item carries a surface tag, a kind tag (feature, bugfix, refactor, tech-debt, chore, spike), an optional epic link, and any cross-cutting tags that apply, like security, payments, or observability. The vocabulary is controlled, so the tags actually mean something. Filter by payments and you see every piece of payments work across all four surfaces, without opening a single ticket.

The description has a fixed structure, and that structure mirrors what the FIRE flow already produces. Five sections, always in the same order:

  • ## Why leads with the symptom or the user gap, not the implementation. The problem, not the solution.
  • ## Acceptance criteria names concrete surfaces. A route, a screen, a column. When the frontend and backend share a contract, it includes the code shape, so both sides build to the same interface.
  • ## Non-goals says what this item is deliberately not doing, which is the single most effective way to stop an agent from over-building.
  • ## Files you'll touch points at the right part of the codebase so nobody, human or machine, goes hunting.
  • ## Depends on links the work that has to land first.

Here is the thing I did not expect. The work-item shape that falls naturally out of the specs.md flow is, almost exactly, the briefing an AI agent needs to do a task without a back-and-forth. The ## Why gives it intent. The acceptance criteria give it a definition of done. The non-goals fence the scope. The files give it a starting point. A well-formed work item is a complete prompt that happens to also be a good ticket. The flow produces it, the board renders it, the agent consumes it.

Humans and agents on the same rails

Once a work item is well-formed, the execution flow is the same whether a person or an agent picks it up.

Branches follow feature/wi-/. Commits are conventional and reference the work item number. Pull requests auto-link to the item and transition it as they move. Claude Code can create the branch, do the work against the spec, and open the PR, all correctly, because the flow and the convention told it everything it needed.

There is exactly one rule that never bends. The agent opens pull requests. A human merges them. No auto-complete, ever.

This is the gate that keeps the whole thing honest. The agent is fast, and the convention makes it productive, but speed without a review gate is just a faster way to ship the wrong thing. A human reads every diff against the spec before it lands. Because the architecture was already settled in the FIRE flow, that review is fast and focused. We are checking correctness, not relitigating design.

What changed, and what it cost

Before, work was described loosely, picked up with context in someone's head, and reviewed by re-explaining the architecture every time. New work meant a conversation. Onboarding meant tribal knowledge. The agent was useful but needed hand-holding on every task.

After, work flows from intent to work item to execution in a form both a person and an agent can act on directly. The board self-organizes by tag. Onboarding, human or agent, is "follow the specs.md flow and the board convention." Review shifted from architecture to correctness.

I want to be honest about the cost, because there is one.

The flow has a maintenance burden. Someone has to keep the spec true as the system evolves, or it quietly becomes a lie that everyone, including the agent, confidently builds on. We learned this the expensive way. At one point the spec said all list endpoints were paginated, but a newer cursor-based pattern had drifted in that the spec never captured. Claude Code, doing exactly what it should, read the spec, followed the documented pattern, and generated a batch of endpoints in the old style. The code was correct against the spec. The spec was wrong. We spent the better part of a day reconciling, and the lesson stuck: an authoritative flow is a liability the moment it stops being authoritative. The agent does not know the difference. It trusts the contract completely, which is exactly why the contract has to be maintained like production code.

The strictness also feels heavy at first. Running the full flow for a two-line fix can feel like ceremony. The honest answer is that for genuine one-line chores it sometimes is, and we let those be lightweight. For anything an agent will touch, the structure pays for itself the moment it removes a single round of back-and-forth.

The takeaway

The discipline that makes an AI agent productive is the same discipline that makes a human team scale. That is the whole point.

A spec-driven flow with a strict, parseable board convention on top sounds like overhead designed for machines. In practice it is the clearest possible way for humans to work too. The FIRE flow settles what is true. The prefixes route work whether the reader is a person or a parser. The tags make the board legible to everyone. A structured work item is a good ticket and a good prompt at the same time.

Run your flow and write your conventions strictly enough that a machine could follow them, and you get two things for the price of one. The AI leverage everyone is chasing, and the human clarity teams have always needed.

You were going to need the discipline anyway. Making it parseable is what makes it pay twice.


Originally published on LinkedIn.