Approach

How I Build With AI

I don’t treat coding agents as magic, and I don’t pretend their code is handwritten by me. I use them as an implementation force multiplier inside a product-development process where I own the requirements, technical understanding, review, validation, and production outcome.

Disclosure

What I own, and what coding agents implement

01 — Foundation

Domain understanding before implementation

I came to pay-per-call from the buy side and the operations side: running acquisition, negotiating buyer terms, chasing disputed conversions, reconciling payout cycles, and absorbing the cost when routing or attribution was wrong. Requirements start from that operating reality rather than from a feature list.

It matters because the hard parts of a marketplace are not the screens. They are the contract semantics underneath them — what a buyer actually owes, when a call becomes billable, which party carries the risk of a bad minute — and those are product decisions before they are engineering ones. If I get them wrong, no implementation quality rescues the outcome.

02 — Research

Research until the implementation can be challenged

If I do not understand how a feature should work, I cannot responsibly evaluate what an agent built.

So the research runs until I can state what correct looks like without hedging: RTB request and response semantics, telephony behaviour under failure, the specific quirks of each provider’s webhooks, what a partner platform silently normalises. That standard is deliberately higher than “enough to write a ticket.” It is “enough to interrogate a diff.”

Reviewing generated code you do not understand is not review. It is acceptance with extra steps, and it is how teams end up operating systems nobody can explain.

03 — Specification

Specification before code

Every unit of work starts as a written artifact. An agent will happily implement an ambiguity; the specification is where ambiguity is supposed to die.

PRD
What the product must do, for whom, and what business condition it exists to change.
Requirements
System behaviour stated precisely enough to be wrong: endpoints, parameters, states, timing, tenancy, and what each integration is allowed to assume.
Acceptance criteria
The observable conditions under which the work is finished — written before implementation starts, so "done" is not negotiated afterwards.
Failure modes
The ways this feature can quietly be wrong in production, and which of them the tests, the alerts, or the controls are responsible for catching.

04 — Implementation

Coding agents implement

This is the part most portfolios blur. I am stating it plainly instead: the production code was generated under my direction, and the value I add sits on either side of that column.

Stage What I own What coding agents produce
Problem definition The opportunity, the operating constraint, and the business consequence of getting it wrong.
Specification PRD, requirements, API behaviour, acceptance criteria, failure modes. Prior-art research and drafting support against sources I check.
Implementation Direction, scope, sequencing, and the decision to reject work and re-cut it. The Go, TypeScript, and SQL that ships.
Tests The doctrine: what must never regress, and why that specific failure is expensive. The test code itself.
Review Adversarial review, root-cause challenges, verification against real system state. Second-agent review passes against my criteria.
Delivery Deliberate manual control over when production changes. CI/CD implementation.
Production Operation, incident ownership, postmortems, and the invariants they produce.

05 — Review

Adversarial review

Generated code arrives confident. It compiles, it explains itself well, and it is sometimes wrong in ways that only production will find. So review is adversarial by design: the default posture is that the work does not yet do what the specification says, and the burden of proof sits with the implementation.

The phantom-revenue incident is the reason this is not a stylistic preference. A symmetric mistake in billing configuration made a losing campaign look profitable, and every internal report agreed with itself the entire time. Self-consistency is not evidence.

  1. A second agent reviews the first one’s work against the acceptance criteria, not against its own explanation of itself.
  2. Symptoms get traced to a cause. A patch that makes the report look right and leaves the mechanism intact is a regression waiting for a quieter week.
  3. No premature success claims. "Implemented" is not a status I accept from a model, and neither is a green test run on its own.
  4. Claims are verified against actual system state: query the database, read the logs, inspect what is deployed.

06 — Testing

Testing is about failure risk, not coverage vanity

A coverage percentage measures how much code was executed, not how much risk was retired. The doctrine I set for DCE targets the failures that cost money or trust.

  • Real PostgreSQL via testcontainers wherever behaviour actually depends on the database, because most of the failures worth catching are transactional ones.
  • A regression receipt for every production bug class: the incident becomes a named test that fails on the old behaviour.
  • Idempotency and single-consumer execution wherever a repeat is possible — webhooks, retries, confirmations, settlement.
  • Boundary tests around money and time, which is where the expensive mistakes concentrate.
  • 16,212 Top-level Go test functions Authored by coding agents under a testing doctrine David defined; he did not hand-write these tests.
  • 2,971 Go test files
  • 28 Playwright end-to-end specs
  • 181 Production alert rules

07 — Feedback

Production feedback becomes product knowledge

Operating the system is not a phase after delivery; it is the input to the next specification. A failure that stays an anecdote will happen again. A failure that becomes a written invariant, a control, and an alert will not.

The AI-native product-development loop: eight steps that close on themselves A closed eight-step cycle. Read clockwise from the top: 1, understand the business problem; 2, research until i can challenge the solution; 3, define the prd, requirements and acceptance criteria; 4, direct coding agents through implementation; 5, review and test adversarially; 6, deploy deliberately; 7, observe production failure modes; 8, encode what was learned into permanent rules and controls. The eighth step returns to the first along a dashed arc labelled "encoded and reused", which is what makes this a loop rather than a list — the loop closes when a production failure becomes a permanent control. The connecting spine is brass because brass marks the primary control path. Steps four and five, the two steps where a coding agent is on the keyboard, carry verdigris node rings because verdigris marks agent pathways. Step eight is a filled brass terminal because closing the loop is itself the control point. encoded and reused Understand the business problem 1 Research until I can challenge the solution 2 Define the PRD, requirements and acceptance criteria 3 Direct coding agents through implementation 4 Review and test adversarially 5 Deploy deliberately 6 Observe production failure modes 7 Encode what was learned into permanent rules and controls 8
Eight steps. The loop closes when a production failure becomes a permanent control.

The phantom-revenue postmortem produced fifteen design invariants. Several of them are now controls and production alert rules in DCE — monitoring for economic inversion, unearned payout, and settlement-term mismatch — because the incident was expensive enough to be worth encoding permanently.

08 — Boundaries

Autonomy has boundaries

The interesting question is not how much an AI system can do. It is which actions it is allowed to take alone, and what has to be true before it takes them. In DCE’s partner-facing assistant that means mutations run through a two-turn confirmation with server-held arguments, ownership and expiry checks, and compare-and-swap execution, so a confirmed action cannot be replayed, tampered with, or applied to stale state.

In the operations layer the boundary is drawn around consequence rather than capability. Analysis, reconciliation, and drafting are delegated freely. Sending external communications and moving money are not delegated at all — not because the model would necessarily fail, but because those are the actions where being wrong is not recoverable by an apology.

The same principle covers ignorance: a system that cannot substantiate a number should say so rather than produce one. When the operations system met a five-figure billing line it could not verify, the correct output was a refusal, not an estimate.