Every Model's Code Is a Draft: My Three-Tier Review Rule
In the loop I run, nothing a model writes ships because the model wrote it. Verification has three clauses, and the third one, independent review, has three tiers with a strict order of preference and a hard exception for payments code.
I run an autonomous loop where agent sessions build and operate small SaaS products. The orchestrating session is a strong model. The implementation work goes to cheaper models: subagents, a delegate wrapper to an API gateway running small open models, coding-agent harnesses on cheap tiers. That division of labor is what makes the loop affordable, and it creates exactly one big risk: the code that does the actual building is written by the least careful participants in the system.
The policy that manages that risk fits in one sentence: treat every model's code as a draft, verified by three clauses, all of which are required before anything ships.
- Read the diff against the spec.
- Run the checks, and for anything touching payments, auth, downloads or data, exercise the flow end to end.
- Get an independent review of the touched path from something that did not write the code.
Clauses 1 and 2 are table stakes and most teams I talk to already have versions of them. Clause 3 is the one that earns its complexity, and this post is about how it actually works in practice, including the failure that forced me to make it a tiered system.
Why "independent" is the load-bearing word
A model reviewing its own output inherits its own reading of the spec. If the coder misread "the checkout retries idempotently" as "the checkout retries", the coder's review of itself will see a retry where a retry was specified, and call it correct. The misreading is in the shared representation, not in the diff.
So clause 3 has a definition of independence: the reviewer must be something that did not write the code. Not a different prompt for the same model, not a subagent of the author. Different model family is better. Different vendor is best, because a model family shares blind spots the same way an author does.
I am not polite about why this matters. In my experience, work from mid-tier models is often buggy or off-spec, and I include the stronger orchestrator in that suspicion. The loop's standing rule is that even the orchestrator's own output is a draft. Nothing gets a pass because of who or what wrote it.
The three tiers
The naive version of clause 3 is "always get an independent review from the outside vendor's model". That worked until the night the review vendor was unavailable and the gate blocked three runs in a row. A verification gate that can hard-stop the whole loop on someone else's uptime is its own failure mode, so I added tiers, always attempted in order, with the tier used recorded in the run log.
| Tier | Reviewer | When | Catch |
|---|---|---|---|
| A | An outside-vendor model (Codex, via a consult script, read-only) | Always tried first | Different model family and vendor: best coverage |
| B | A read-only subagent of a second model that did not write the code, given an adversarial brief | Only when A fails | Same vendor, so it cannot catch family-wide blind spots |
| C | A dated written waiver | Only when neither A nor B ran | Nothing: it is a deferral, not a review |
Tier B comes with an honesty requirement: the run log must paste the tail of the consult log showing that A was attempted and why it failed. B is explicitly a degradation, not an equivalent. I write that sentence into the policy itself because the temptation to skip straight to B "since A is down anyway" is exactly how a tier system decays into whichever tier is most convenient.
Tier C is the one with teeth in the other direction. A waiver names the commit, the path, the reason, and the date the re-review is owed. And the rule that does the most work: a waiver may never cover new code that touches payments, auth, downloads or data. For new money-path code with A and B both unavailable, the rule is unchanged: ship less. Defer the deploy, split the change, do the non-money-path half tonight. "Ship less" is a policy output, not a failure.
The gate must be a gate
Two bookkeeping rules keep the tiers from rotting.
First: if a review is owed on code that is already live, it is a follow-up, not a ship gate. Writing it into the queue as if it blocks the next ship is how a loop spends its headroom re-reviewing yesterday instead of building today. Say so in the log, track it, move on.
Second: a review job deferred twice is a defect in the procedure, not a third queue entry. It gets recorded in a decisions log with why it keeps slipping. The point is that the gate's own health is something the system watches. A gate that nobody can defer successfully is a gate; a gate that quietly accumulates exceptions is a suggestion.
What the reviewer actually receives
The review call is a script, not a vibe. The reviewer gets the diff, the relevant spec section, and the instruction to be adversarial. A concrete recent-ish shape of the call:
bash loop/codex-consult.sh review apps/splitcheck/src/app/api/checkout/route.ts
with the consult log capturing what was sent, what came back, and which tier was used. The checklist I keep for judging a review session:
- The reviewer saw the diff and the spec, not just the diff.
- The reviewer did not write any of the code under review.
- Tier A was attempted first, or the log shows why not.
- Findings are triaged: must-fix before ship vs follow-up.
- The tier used is recorded with the ship record.
- Nothing on the money-path list shipped under tier C.
What this costs, and why it is still cheap
The honest cost: clause 3 adds a step to every ship and sometimes blocks one outright. A tier A review takes real time and occasionally produces a disagreement that takes a cycle to resolve. There are days I would like it to be faster.
But the failure it prevents is not "a bug". It is "an off-spec payment flow deployed to production by an unattended loop". The loop runs when I am asleep. The whole design, the scheduler, the gates, the ledger, is built so that unattended means safe, and nothing in that design works if the code being shipped is unverified. The review tiers are the most conservative part of the system, and they are conservative on purpose: a blocked ship costs a day; a wrong charge costs a customer.
The general version of the rule, if you run agents against anything that matters: model output is a draft, verification is a procedure with named clauses, independence is defined by who did not write the code, degradation is explicit and logged, and some paths are never waivable. The tiers are not bureaucracy. They are what lets the cheap models do the writing at all.