TL;DR — I had a real app half-designed and paused it to build ADLC (Agentic Development Life Cycle) first — the ten-phase pipeline the app would later run through. The new-code build was small: an audit of what I already had for idea validation, coding, and review showed most phases were already covered, so the real backlog was six artifacts — a Constitution, a spec template, an Autonomy Contract, two gate docs, a design template. What’s interesting is what changed while building it: a self-review step I flipped from “halt and ask” to “always fix to spec,” and a code-review engine I nearly let myself simplify into “just call the official reviewer” — until I overrode my own planning audit to own it instead, at a measured cost of three points on my own rubric. Three days after it existed, that engine re-reviewed code its ad-hoc predecessor had already cleared, and found two build-breaking bugs the predecessor missed.
The backwards call
I had an app idea I wanted to build — an on-device app that turns an ebook into an audiobook, which shipped later as BookTS — and a spec draft going. Then I stopped, because I noticed I was about to make the mistake I make on every solo project: skip the process because I’m excited about the product, then discover weeks later that a requirement quietly got dropped somewhere in the implementation with nobody there to catch it.
So instead of finishing the app, I spent the next stretch building the thing that would run it through a real process: a ten-phase Agentic Development Life Cycle, Discovery through Wrapup, each with an entry condition and an exit gate. I’ve written up what ADLC actually is elsewhere — the phase table, the Autonomy Contract, the halt discipline. This post is the build log instead: what it took to build the pipeline itself, in the same AI-coding-agent sessions that would later run through it, and what I got wrong along the way.
The premise going in was uncomfortable in a useful way: I was asking an AI coding agent to build the harness meant to catch that same agent’s own mistakes. If the harness were shallow, I’d have spent real time building something that just rubber-stamps whatever gets written — a process-shaped placebo. The only way to find out was to build it, then run something real through it.
Audit before you build: most of it already existed
The instinct on day one was to sketch nine new tools, one per phase. I didn’t — the single decision that kept this a two-week project instead of a two-month one.
Before writing anything, I mapped each phase against tooling I already had running for other purposes: an idea-validation pipeline for Discovery, the coding agent itself for Implement, existing code-review and security-review passes for part of Review, plain git for Ship — the same measure-before-you-build instinct behind the eval framework I built to stop guessing which model to use, applied to process instead of models. Four phases were already fully covered, zero new artifacts needed. The real backlog was smaller than the phase count suggests: a Constitution, a spec template with a real authoring process, an Autonomy Contract template, a Validate-Spec gate, a design template, and the wiring between phases. Six artifacts, not ten tools.
The Constitution wasn’t written from scratch — it’s a distillation of behavioral corrections I’d already accumulated over months of working with an AI agent: ship over polish, verify infrastructure empirically instead of trusting memory, never claim done before it’s checked, no silent scope creep, cite every factual claim. Those were already true; the Constitution just turned them into a table a gate could tick against, scoped per phase, each row carrying a severity. Writing one from a blank page is a multi-week exercise in ego. Distilling it from corrections you’d already been given, repeatedly, is an afternoon.
The apparatus core — Constitution, templates, the two Validate gates, phase-handoff wiring — went from blueprint to a working v1 in three focused sessions across three days. That pace is the actual argument for auditing first: building nine new things from scratch wouldn’t have fit in two weeks. Building the four or five genuine gaps did.
The dogfood decision
The paused app became the first thing to run through the still-wet-paint pipeline, on purpose, instead of a throwaway example with no real stakes. A pipeline only ever exercised on a fake project tells you nothing about whether it holds up on a real one, with real App Store constraints, real money, real device hardware. If the gates were going to have teeth, they needed something with teeth to bite.
That’s a real risk, stated plainly: I was testing brand-new process on a product I actually wanted to ship. A bad gate — blocking on the wrong thing, or waving through the wrong thing — would cost real time on a real deadline. I accepted the trade because the alternative, validating on a toy and trusting it untested on something real, only defers the actual test to the moment you can least afford a surprise.
Changing my mind mid-build: Reflect stops asking
The first phase I had to rewrite after using it once was Reflect — the self-review step right after Implement, where the build checks itself against the locked spec and approved design.
The original version halted on any deviation: a dropped requirement, a drifted decision, anything that didn’t match what was signed off earlier. The first real run caught five dropped requirements and three drifted decisions — genuinely useful — but every one of them stopped the pipeline to ask me a question the spec had already answered. The spec said the app must refuse DRM-protected files; the build didn’t. That’s not a decision that needs my judgment, it’s a fix task. I was the bottleneck for questions that weren’t actually questions.
So I changed the policy: Reflect now always fixes to spec and design instead of halting to ask. Only two things still escalate — a genuine business decision spec and design never settled (pricing, a value split), and something structurally unfixable that must be flagged, never silently dropped. Everything else gets rebuilt to match what was already locked, same pass, no pause. That’s the difference between Reflect being a useful catch and Reflect being a second copy of me, standing in a doorway asking questions I’d already answered two phases earlier.
Changing my mind mid-build: the review engine I almost didn’t build
The second rewrite is the one I’d flag to anyone building something similar — I nearly took the easy version, and it would have been wrong.
Review, the phase where code gets an adversarial multi-lens critique before Ship, could have been built two ways. The cheap way: open a PR and call the same official code-review command I already use elsewhere. The real way: an owned engine, tuned for this pipeline, running automatically with no trigger from me — full-diff scope, lens fan-out, domain-specific packs, adversarial per-finding verification, a separate triage step, auto-fix on what’s confirmed. Same shape as the generator-and-judges pipeline I built for idea validation: one side produces, another judges against a standard, nothing advances on a claim alone.
I ran the plan through my own planning-audit loop before building either version. Round one scored 83/100 and caught something worth catching: an earlier draft had quietly reintroduced the shortcut it explicitly rejected elsewhere in the same document — falling back to calling the real reviewer inside its own contingency path. Fixed; round two came back at 87, clean, no P0 or P1 open. By the loop’s own stop rule — green, under three rounds — that was done.
It was also, on reflection, the wrong answer, and not because the audit scored it badly. A “call the real command” review is genuinely simpler, more reusable, lower-maintenance — real virtues the audit rewards. But it wasn’t what I actually wanted: a review running unattended every time, tuned to this pipeline’s own domain packs, no billed pass required to get real depth. I overrode the clean result and rewrote the plan a third time to own the engine outright. That round scored 84 — three points lower than the version I’d just rejected, because owning an engine is a real, admitted maintenance surface that calling one doesn’t have. I took the trade anyway, cost written down rather than waved away. The billed, independent version of the command stays available as an optional pass before shipping — the one thing a self-built engine can’t substitute for is a reviewer with zero stake in the code being clean.
The morning the pipeline caught its own predecessor
Three days after that engine existed, I got the clearest evidence yet that owning it had been worth the cost.
The app’s code had already been through Review once, under the old ad-hoc version: five lenses, two dozen agents, one P0 fixed, a verdict of “build clean, advance to Ship.” I re-ran the same code through the new engine, mostly to validate the tooling on a real diff, not because I doubted the verdict. Forty-one agents, a diff scoped mechanically rather than author-selected. It came back with two P0s the first pass had missed entirely: the code actually committed to version control did not build from a clean checkout. The earlier review had, without anyone intending it, verified a different working copy sitting next to the real one — the copy I’d been building against locally, not the one tracked in git. “Build clean” had been true of the wrong folder.
That’s the finding that justified the whole detour. A review that passes against the wrong artifact isn’t neutral — it’s worse than no review, because it manufactures confidence you don’t have. The fix that mattered wasn’t a code patch; it was collapsing two parallel copies of the project into one canonical tree, verified afterward with a clean build from scratch, not a rerun of the check that had already lied once. The whole run cost about eighteen and a half minutes and a little over three million tokens of subscription usage. Zero marginal cash — cheap, for catching a claim that had been silently false for three days.
What it still can’t fix
A pipeline that only advertises what it caught is advertising, not reporting.
Owning the engine is a real, ongoing cost. My own audit said so at 84 versus 87, in writing. Every future change to the review logic is now mine to maintain and keep from drifting.
It didn’t remove the need for an outside pair of eyes. The engine reviews with a different lens set than the code’s author, but it still runs inside the same session, on the same understanding of the spec. The billed, independent pass stays optional rather than automatic precisely because self-review, however deep, isn’t the same property as a reviewer with nothing at stake in the answer being clean.
It didn’t make the business calls for me. Every genuinely open decision — pricing, where free ends and paid begins — got correctly flagged as something spec and design hadn’t settled, and stayed a human gate instead of getting auto-resolved by a pass eager to look finished.
And it didn’t derisk dogfooding on a real product. I got lucky the harness caught real bugs instead of blocking on the wrong thing. A less mature version could just as easily have stalled a real ship date on a false alarm. Building the harness on the thing you actually care about is the only test that means anything — it’s also the only one where being wrong costs you something.
What two weeks bought
An audit that turned “build nine new tools” into “build six artifacts.” A self-review step that stopped asking me questions the spec had already answered. A review engine that, three points more expensive on paper than the version I almost shipped, caught within days a false “all clear” its cheaper predecessor had already signed off on. None of that required a bigger model or a cleverer prompt — it required treating the harness itself as worth building deliberately, the same argument applied to a completely different project: the intelligence isn’t in the model, it’s in the plumbing around it. The app was the excuse. The pipeline was the point.