Blog
All posts

Spec-driven development with Claude Code: shipping a marketplace across three repos

How a knowledge base, a numbered decision log and as-built notes kept an AI coding agent accurate while building BrownBox's API, web portals and mobile app, with 858 tests to keep it honest.

Five screens of the BrownBox mobile app built with Claude Code

BrownBox is a farm-to-household marketplace: an Express and MongoDB API, a Next.js site with portals for operations, farms, drivers and pickup stations, and an Expo app for customers. I built the API and the mobile app over about four months, and roughly 95% of my commits were pair-programmed with Claude Code.

The interesting part isn't that an agent wrote code. It's what kept that code correct across three repositories and a mid-project change to the whole business model. The short answer: the agent reads before it writes.

A loop of six steps: knowledge base, decision log, build with Claude Code, real tests, as-built notes and phase plan
The loop. Every step leaves a written artefact the next session can read.

1. A knowledge base written from the code

Before any big change, the agent and I produced a system knowledge base: roughly 2,000 lines describing how the platform actually works, written by reading about 105,000 lines of code across nine subsystems. Not how we wished it worked, but what the code did.

Coding agents are confident and context-limited. Without a shared written model of the system, each session re-derives it from whatever files it happens to open, and two sessions disagree. The knowledge base is the thing every session agrees on.

2. Numbered decisions with reasons

Every non-obvious choice became a numbered decision (D1 to D38) with its reasoning. For example: a product stays hidden until operations sets a selling price, or clients never send prices; the server computes them in integer cents.

Numbers matter more than they look. "Follow D10" in a prompt is unambiguous; "follow what we decided about handoffs" isn't. And when an agent proposes something that contradicts a decision, the conflict is visible instead of silent.

3. Rules and skills in each repo

Each repository has a CLAUDE.md with its conventions, plus repo-specific skills: how to add an endpoint, a web page or a mobile screen the way this codebase does it. Without them, an agent writes reasonable generic code. With them, it writes code that looks like the code beside it.

CLAUDE.md (excerpt)markdown
## Adding an endpoint
1. Zod schema in src/schemas, never inline
2. Route → controller → service; services own all DB access
3. Serialize per audience: customerDto, farmDto, opsDto
   (farms must never see customer money; tests assert it)
4. Add a supertest spec next to the route

4. Tests that can't be talked around

The API has 858 tests, run with Vitest and Supertest against a real in-memory MongoDB, with no mocks. An agent can produce a convincing explanation of why its change is fine. It can't argue with a failing assertion.

Some tests exist purely to pin down business rules an agent might "simplify" away, such as checking that a farm's API responses never contain customer payment fields.

5. As-built notes close the loop

After each phase, the plan is updated with what was actually built, which is rarely exactly what was planned. Those notes feed the next phase's planning and keep the knowledge base honest.

This paid off when the business model changed mid-build: BrownBox went from connecting customers with farms to being the seller itself. Because the old behaviour was written down and every decision was numbered, we could plan the change in six phases and see exactly which decisions it overturned.

BrownBox ops console showing an order with customer total, farm payout and profit
The operations console after the change: BrownBox prices each order, takes payment and pays the farm.

What I'd do the same way again

  • Write the knowledge base from the code before asking an agent to change the system.
  • Number your decisions and reference them by number in prompts.
  • Give each repo its own rules and "how we do it here" skills.
  • Lean on real tests more than on the agent's explanations.
  • Record what was actually built after every phase.

Agentic development doesn't remove the need for engineering judgement. It moves it: less typing, more writing down what's true and what you decided. That turned out to be most of the job anyway.

The BrownBox case study has screenshots of the app, ops console and farm portal this workflow produced.