Skip to content
KoishiAI
ไทย
← Contents

Chapter 7 of 12 · Agentic Engineering — A Practitioner Playbook for Production Software with AI Agents

Zero to Production — The Nine Stages

A real feature added to a running system, from spec to rollout, naming who does each stage, how to write a spec an agent can genuinely work from, and how review changes when a person did not write the code.

A real example: adding coupons to a checkout service already in production. Each stage names who does it, roughly how long it takes, and what must come out of it.

StageWorkWhoRequired output
0Foundations (once per repo)HumanAGENTS.md, verify.sh, hooks, memory/, PR template
1Write the specHuman, with the agent asking questionsdocs/specs/coupon.md with no ambiguity left
2Break it downHuman5–8 subtasks, each closing a loop within 30 minutes
3RED — write testsAgentRed tests a human has read and approved
4GREEN — implementAgent (loop)The whole gate green, with real output
5ReviewHumanSpec, test quality, blast radius — not every line
6MergeHumanCI green on main, ADR updated, pitfalls updated
7Canary and measureSystem5% for 24 hours, every guardrail normal
8Full rolloutHuman approves100%, then remove the flag within two weeks

7.1 Stage 1 — a spec an agent can genuinely work from

A good spec is not a long one. It is one that leaves nothing to guess. The technique that works is to have the agent read the draft and name the questions it would otherwise have to guess.

Read this draft spec and give me the ten questions you would have to guess at
if you started implementing now, ordered by how much a wrong guess would hurt
users. For each one, propose the answer you think is right, so I only have to
confirm or correct it.

A structure that works:

# Spec: Coupon Discount (v1)

## Goal
A customer enters a coupon code at checkout and receives a discount by coupon type

## In scope
- Percentage coupons (1–100) and fixed-amount coupons
- Usage limits, both system-wide per coupon and per user
- Expiry dates

## Out of scope (v1) — stated explicitly so the agent does not over-build
- Stacking multiple coupons
- Product- or category-specific coupons
- Automatically generated per-user coupons

## Business rules
R1  The discount applies to the subtotal (before tax, before shipping)
R2  Tax is computed on the post-discount amount
R3  Shipping is not discounted
R4  The net total floors at 0 — an over-large discount clamps, it does not refund
R5  Round to two places, ROUND_HALF_UP, only when computing the discount
R6  A coupon counts as used when the order is paid, not when the code is entered

## Cases that must be rejected (with fixed error codes)
| Condition                  | HTTP | code                |
|----------------------------|------|---------------------|
| No such code               | 404  | COUPON_NOT_FOUND    |
| Expired                    | 422  | COUPON_EXPIRED      |
| System quota exhausted     | 422  | COUPON_EXHAUSTED    |
| This user's limit reached  | 422  | COUPON_USER_LIMIT   |
| Minimum spend not met      | 422  | COUPON_MIN_NOT_MET  |
| Two codes submitted        | 422  | COUPON_MULTIPLE     |

## Invariants (for the property tests)
I1  net_total >= 0, always
I2  discount + net_total == subtotal, always
I3  No value carries more than two decimal places
I4  Actual redemptions <= quota, always, even under concurrent requests

## Decisions already made (so the agent does not re-ask)
- Concurrency: SELECT ... FOR UPDATE on the coupon row, not optimistic locking.
  Reason: coupon counts are low, contention is not high, and we need I4 absolutely
- No Redis caching of coupon state in v1 — correctness matters more than latency here

## Definition of done
- Every R and I has at least one test, named after the rule (test_r4_...)
- verify.sh green
- A `coupon_v1` feature flag that can be switched off instantly

7.2 Stage 2 — breaking work down so the loop can close

A good subtask has a clear passing criterion, touches few files, and does not depend on work not yet done.

TaskWhat it isTest
T1Pure domain model and validation, no databasetest_coupon_domain.py
T2Repository and migration (expand phase)test_coupon_repo.py
T3Discount and tax calculation, R1–R5test_calculation.py
T4Concurrency and quota, I4test_concurrency.py
T5HTTP endpoint and error mappingtest_api_coupon.py
T6Feature flag and shadow modetest_rollout.py
T7Observability: metrics, logs, alertsInspected in staging

Order matters: T1 always comes first, because it is where any ambiguity in the spec surfaces. If T1 is hard, the spec is not clear enough — go back and fix it rather than pushing on.

7.3 Stage 5 — reviewing when a person did not write the code

Line-by-line reading does not scale when an agent produces code ten times faster than a person reads it. The focus of review has to move.

Before (human-written code)Now (agent-written code)
Read every line hunting for bugsRead every line of the tests — the implementation always runs toward them
Check style and namingLet the linter do it. Needing a style comment means the config is incomplete
Ask why it was written this wayAsk whether the spec matches what the business wanted — most bugs have moved into the spec
Look at the diffLook at the diff, plus files that should not have been touched but were, plus new dependencies
Trust that the author understands the systemCheck that the agent has not built a parallel pattern beside an existing one

Seven questions to answer before approving:

  1. Would these tests go red if I removed the main requirement from the implementation? (If not, the tests are worthless)
  2. Are all the rejection cases from the spec covered, or only the happy path?
  3. Is every touched file genuinely within the scope of this task?
  4. Are there new dependencies? Are they necessary? Who maintains them?
  5. Is there a migration? Is it reversible? How long does it lock the table?
  6. Can this feature be switched off instantly if it misbehaves?
  7. Are the blast radius and rollback plan in the PR description realistic?

A quick mutation test

If you are unsure whether a test suite is any good, break the implementation deliberately in one place — change a >= to a > — and run the tests. If nothing goes red, that suite is not worth maintaining. You can have the agent do this automatically: “generate ten mutants from this diff, run the tests, and report which mutants survived.”

What this chapter settles

The path from spec to production has nine stages, and a human owns stages 0, 1, 2, 5, 6 and the approval at stage 8. A good spec leaves nothing to guess. Subtasks should close a loop within thirty minutes. And review shifts from reading code line by line to reading the tests and checking the boundaries.

The next chapter covers MCP: when to use it, how to design it, and the prompt-injection exposure that arrives with tool output.