Most writing about spec-driven development uses one example, usually a neat new feature in an empty repository. Real teams do not choose their work that way. In the same fortnight they build something new, change something old that nobody fully understands, fix a defect reported that morning, and add an AI feature the business is excited about.
If the method only works for the first of those, it is not a method. It is a demo.
This part works through four examples, each a different shape of work, and shows how much specification each one actually needs. We are still following Kestrel Mutual, a fictional South African insurer. All figures are illustrative. Kestrel sells life, funeral and household cover to about 420,000 policyholders, and earlier parts of the series followed its assisted account recovery feature. Here the same team takes on four other pieces of work.
| Example | Shape of work | How much specification | The artefact that mattered most |
|---|---|---|---|
| A. Claim-status notifications | Greenfield service | Principles, feature spec, design, tasks, evidence | The principles, written before any design |
| B. Policy documents by email | Brownfield change to a monolith | Change proposal, delta, bridge controls | The delta: what changes, what must not |
| C. Double submission on the payment form | Small defect | A mini-spec of five lines | The one line about idempotency |
| D. Claim document classification | AI feature | Behaviour, thresholds, evaluation and evidence | The rule for what happens when the model is unsure |
Example A: a greenfield claim-status notification service
The intent
Kestrel’s claims team takes a steady stream of calls that amount to one question: “Where is my claim?” The intent is short:
Customers should receive timely, consent-aware updates on their claim status through their preferred channel. Operations staff must be able to see whether each message was delivered and retry the ones that failed.
Two words in that sentence do a lot of work. Consent-aware means Kestrel only messages a customer on a channel they agreed to, for a purpose they were told about. Preferred channel means WhatsApp for some customers, SMS for others and email for the rest, which is a very South African mix.
Principles first
Before anyone designed anything, the team wrote five principles. In Spec Kit’s vocabulary this would be part of the constitution; in any vocabulary it is the set of rules every later decision is checked against.
- No notification is sent without a recorded purpose and a preference check.
- Business services request a notification by publishing an event. They never call a channel provider directly.
- Personal data in logs is minimised.
- Delivery is asynchronous and idempotent.
- A channel failure never rolls back the business transaction.
Two terms need explaining. Asynchronous means the claims service does not wait for the message to be sent before carrying on. Idempotent means that processing the same request twice has the same effect as processing it once: if the same event arrives again, the customer does not get a second message.
Each principle closes off a tempting shortcut. Without the second, the quickest way to ship is for the claims service to call the WhatsApp provider directly, and six months later three services have their own copy of that integration. Without the fifth, a WhatsApp outage could block a claim approval, which is absurd said out loud and easy to build by accident.
The feature specification
The behaviour is written as a scenario in Gherkin, the Given/When/Then format used in behaviour-driven development (BDD), so that product owners and testers can read it as easily as engineers:
Scenario: Notify a customer that a claim is approved for payment
Given a claim is approved for payment
And the customer has opted in to WhatsApp notifications
When the claim-approved event is accepted
Then one WhatsApp notification is requested
And the delivery state is recorded
And a repeated event does not create a duplicate message
The last line is the one a coding agent would most likely miss if nobody wrote it down. Most event systems guarantee delivery at least once rather than exactly once, so duplicates are normal, not exceptional. Customers who receive “Your claim has been approved” three times start to wonder what else is broken.
The design
The claims service publishes a claim-approved event to an event broker, a piece of infrastructure that holds events and passes them to whichever services have subscribed. The notification service picks it up, checks the customer’s consent and channel with the preference service, sends the message through a channel adapter, and records the delivery state. When the provider later confirms delivery, it calls back, and the notification service checks that the callback is genuinely signed by the provider before trusting it.
Tasks and evidence
The plan broke into nine tasks, each small enough for one person or one agent to complete and one reviewer to check:
- Define the claim-approved event and its idempotency key.
- Define the preference query contract.
- Implement the notification request handler.
- Add the WhatsApp adapter behind a channel interface.
- Store request and delivery states.
- Process signed provider callbacks.
- Add a retry and dead-letter policy (a dead-letter queue holds messages that failed repeatedly, so a person can inspect them instead of retrying forever).
- Add metrics, traces and a support view.
- Run the acceptance, security and failure tests.
The evidence that the service works is decided up front, not assembled at the end:
- contract tests for the event and preference interfaces;
- a duplicate-event test;
- a provider-timeout and retry test;
- a callback-signature test, including a forged callback that must be rejected;
- an inspection of logs for personal data;
- an operational alert and a runbook.
Example B: a brownfield change to the policy administration monolith
Current behaviour
Kestrel’s policy administration system is an older monolith: one large application that does many jobs. When a customer buys a policy online, it emails the policy schedule during the purchase, and waits for the email provider to respond before confirming.
Two problems follow. When the email provider is slow, checkout is slow. When the provider fails at the wrong moment, it is sometimes unclear whether the purchase completed, which creates support calls and occasionally a duplicate policy.
Describe the change, not the whole system
For brownfield work, the useful question is not “what should exist?” but “what changes from what we already promise?” This is where an OpenSpec-style delta earns its place. In OpenSpec, a change carries a proposal, delta specs, a design and tasks; the delta lists requirements as added, modified or removed, and once the change is complete the deltas are merged into the durable specifications.
Kestrel is tool-neutral, but the team borrowed the shape:
- Added: a policy-issued event with a stable identifier and a schema version; an asynchronous delivery state.
- Changed: purchase success no longer depends on the email provider’s response.
- Preserved: the content of the policy schedule, the customer’s contact preference, and the audit record.
- Removed later: the direct call to the email provider, once two reconciliation periods run clean.
The Preserved line is what makes this a good delta. In a brownfield system the things that must not change are usually the things nobody wrote down, and they are exactly what a coding agent “tidies up”. If your team is still discovering what an old system actually does, reverse-engineering legacy systems with coding agents covers that earlier step.
The design, including the bridge
The design uses a transactional outbox. When the purchase commits, the monolith writes a policy-issued record into an outbox table in the same database transaction. Either both the purchase and the outbox record are saved, or neither is. A separate relay then publishes outbox records to the broker, and the new notification component sends the email. The customer’s purchase no longer waits for anyone’s email server.
The old path is not deleted on day one. It stays behind a feature flag, a switch that turns behaviour on or off without redeploying, so the team can run both paths while they compare results and switch back quickly if something is wrong.
Bridge controls
A bridge state is only safe if someone has decided how to run it:
- dual-path comparison without sending the customer two emails;
- reconciliation between outbox records and published events;
- an alert when the delivery backlog grows;
- a rollback flag that has been tested, not just configured;
- retirement criteria for the old path, and a named owner who will remove it.
Temporary paths without an owner become permanent architecture.
Example C: a small defect, with a quick spec
A customer reported that during a slow response they clicked Pay twice on the once-off premium payment form, and were debited twice.
This does not need a product requirements document, a design review or a workshop. It does need five lines written down before anyone, human or agent, starts changing code:
- Disable the submit button after the first accepted click.
- Show progress without clearing what the customer entered.
- Use an idempotency key at the payment API, because a disabled button alone is not enough.
- Re-enable the button only after a recoverable client-side failure.
- Test a rapid double-click, a page refresh and a network retry.
The third line is the point of writing anything at all. The fastest fix is to disable the button, and it passes a quick manual test. It does not survive a weak mobile connection whose browser retries the request, or a page refresh. The idempotency key lets the payment service recognise a repeated request and not debit again, whatever the browser does.
This is what “scale the ceremony with risk” from Part 1 looks like in practice. The spec is small because the change is small. It still exists because the change touches money.
Example D: AI-assisted claim document classification
The intent
Claims arrive with supporting documents: death certificates, copies of identity documents, bank confirmation letters, medical reports, affidavits. Today an administrator opens each one and routes it by hand. The intent:
Classify incoming claim documents to reduce manual routing, without allowing a misclassification to change a claim outcome silently.
The second half of that sentence is the whole design problem. A classifier that is right most of the time and quietly wrong the rest of the time is worse than no classifier, because nobody is looking for the errors.
What the specification must define
| The spec defines | Why it matters at Kestrel |
|---|---|
| Supported document classes | Anything outside the list must be recognised as unknown, not forced into the nearest class |
| A representative evaluation dataset | Real claim documents, including poor scans and phone photos, not tidy samples |
| Precision and recall for each class | Precision: how often a “medical report” label is right. Recall: how many medical reports it finds. Both, per class |
| Confidence thresholds | Set per class from the evaluation results, not picked because they sound reassuring |
| Abstain or unknown behaviour | What happens when the model is unsure |
| Human-review rules | Which documents a person must confirm, and when |
| Data handling and retention | Where documents are processed, who can see them and how long anything is kept |
| Model and prompt version evidence | Which version classified which document, so a problem can be traced |
| Drift monitoring | How the team notices when accuracy falls as documents change |
| Rollback | How to return to manual routing in minutes |
| Cost and latency targets | What a classification may cost and how long it may take |
Notice what is not in the table: the name of a model. The model name is a design choice. The behaviour, the risk and the evidence belong in the spec. Kestrel can swap models next year without rewriting the specification, and the evaluation set tells them whether the new one is actually better.
Routing by confidence
The routing rule has three outcomes. High confidence routes the document automatically, and the decision is logged and reversible. A middle band goes to a person. Low confidence, or a document that fits no known class, makes the system abstain: it declines to guess and hands the document to manual routing.
Medical reports get a stricter rule. Health information is special personal information under section 26 of POPIA, which starts from a prohibition with limited exceptions, so Kestrel’s spec requires a person to confirm any medical report before it can affect a claim. That is a design decision for Kestrel’s privacy and legal people to confirm, not something to take from an article; which data can AI touch gives the plain-language background. For how to build the evaluation set itself, see evaluating AI agents.
What the four examples have in common
The four specifications look nothing alike, but they share what matters. Each names the behaviour that is easiest to get wrong: duplicate messages, silently changed behaviour, double debits, confident misclassification. Each decides what evidence will prove it works before the work starts. Each is small enough that nobody approved a document they did not read. And none tells an engineer or an agent which classes and methods to write. A specification that prescribes file names and method signatures has become slow code, and it will be out of date by the second pull request.
What to take from this part
Scale the specification to the shape of the work. A new service, an old monolith, a defect and an AI feature each need a different amount and kind of spec.
Write the principles before the design on greenfield work. Each principle closes off a shortcut that would otherwise become architecture.
On brownfield work, specify the change and what must be preserved. The unwritten behaviour is what an agent is most likely to tidy away.
Even a small defect needs the one line that matters. Five bullets that include idempotency beat a quick fix that passes a manual test.
For AI features, specify behaviour under uncertainty. Thresholds, abstention and human review belong in the spec; the model name does not.
Next: Part 8: Govern decisions and evidence, not document volume.
How CloudNala can help
We work alongside delivery teams on their real backlog rather than a sample project: choosing the right weight of specification for each piece of work, writing the deltas and bridge controls for changes to older systems, and defining the evaluation sets, thresholds and review rules that an AI feature needs before it touches production data. The aim is a team that can make that call for itself on the next piece of work.
Work with CloudNala
CloudNala helps organisations move from technology ambition to practical execution across cloud, AI, data, platform engineering and digital services.
Whether you are exploring AI, modernising your cloud environment, building a public-sector digital service, or turning an idea into a working MVP, we can help you shape the roadmap and deliver the next step.
Plan an SDD Pilot or write to us at consult@cloudnala.co.za