Published 10 Aug 202617 min read

Do Not Read the Code. Build the Feedback Loop.

Overview

I am forcing myself not to read the code.

When an AI coding agent finishes a change, my reflex is to open the diff and inspect every line. It feels responsible because code is concrete. But line-by-line review quietly makes me the slowest component in a system that can otherwise plan, implement, test, and correct continuously.

My job is not to out-type or out-read the machine. My job is to build an error-correcting company: state the goal, define the failures that must not happen, demand executable proof, and give a specialised agent fleet a bounded path to correct itself.

This is the idea behind my /eil loop—execute in a loop. It is not “ask one model to write code and trust it.” It is an operating system in which different agents have different responsibilities and different temperaments. Planning is challenged before implementation. Tests must prove behaviour. QA hunts whole classes of defects. Verification runs the real product. Production failure routes back to planning. The final agent writes durable lessons into the next run.

I am talking about reversible software delivery with observable outcomes—not moral, legal, strategic, or irreversible decisions without accountable human approval. A human should not be the mandatory scheduler for every deterministic engineering check.

The smallest complete model

The useful model is not prompt → code. It is:

The unit of progress is not a diff, commit, or pull request. It is a closed learning cycle.

  • Goal names the user-visible result, acceptance criteria, forbidden outcomes, and risk boundary.
  • Agent graph routes the work through roles that can disagree with one another.
  • Proof demonstrates what happened through tests, runtime behaviour, screenshots, telemetry, and production evidence.
  • Correction keeps, revises, rolls back, or re-plans the change using that evidence.

Most AI coding workflows automate only the second box. A model produces code, then a person becomes evaluator, debugger, and approval queue. That is faster typing, not an automated company.

One change, before and after

I will use one example throughout: change a payment-retry policy so temporary failures recover, while one invoice can never be charged twice.

The old workflow makes me the feedback API:

Reading the retry loop may reveal a bad conditional. It cannot by itself prove behaviour under duplicate events, delayed responses, timeouts, partial outages, or two workers racing on the same invoice. The diff gives me implementation detail, not operational truth.

In /eil, I start by writing what must be true:

  1. One invoice can produce at most one successful charge.
  2. Only temporary failures are retried.
  3. Retries stop after a fixed attempt and time budget.
  4. Duplicate and out-of-order events remain idempotent.
  5. A duplicate-charge signal, unexplained retry spike, or missing evidence stops expansion and triggers correction.

Those statements are more valuable than my opinion about a function body. They can become tests, event invariants, canary gates, alerts, rollback policy, and production proof. They also survive a complete rewrite of the implementation.

The first agent decision is how much system to use

An automated company can waste enormous effort by sending every one-line edit through a twelve-person ceremony. My loop therefore starts with triage. The smallest pipeline that can honestly prove the change wins.

For a wording change, the inline loop is enough. For a normal payment-retry fix, a collapsed plan-and-implement pass, the relevant suite, and adversarial QA may be enough. If the retry change touches money movement, shared state, deployment controls, or an uncertain blast radius, it earns the full fleet.

The important rule is not “always use more agents.” It is “never use less proof than the risk requires.” Multi-agent work has coordination cost. I use it when I need context isolation, genuine parallel work, or a specialised adversary—not because a fleet looks sophisticated.

The full /eil agent fleet

When the payment change is major, the loop expands one box at a time into this operating graph:

The agent names matter less than their souls—the durable stance each role takes toward the work:

AgentWhat it stands forWhat it refuses
ScaffolderAn honest starting line: one goal, explicit acceptance, correct gatesA guessed goal or dirty contract
Product-value agentThe customer's real job and the valuable outcomeBuilding because the technology can
Design agentA restrained experience, then a hostile critique of its own designDecoration, needless widgets, self-congratulation
PlannerThe smallest first-principles design that can be falsifiedGold-plating and one defended option
Plan reviewerSkepticism before work becomes executable tasksHidden assumptions, whale tasks, missing proof
ImplementerThe smallest fully wired correct changeStubs, symptom patches, scope creep
TesterProof, not hopeWeakened assertions and count-free “all green” claims
QAEradicate the class of defect, not one instanceTreating green tests as sufficient
VerifierRun the real thing and inspect the real resultProxy evidence, blank renders, untested outcomes
Merger / deployerKeep the integrated and deployed system greenA clean branch that breaks after integration
Self-improverConvert durable evidence into a better next runVanity telemetry and one-off noise presented as learning

This separation is deliberate. The implementer should not be the only author of its test, judge of its own architecture, interpreter of its runtime output, and approver of deployment. Different roles create useful disagreement.

How the payment retry moves through the fleet

The scaffolder converts “improve failed payments” into a contract: recovery is the goal; duplicate charges are forbidden; retry count, elapsed time, and rollout size are bounded; each acceptance row needs proof.

The product-value role asks whether retry recovery is even the right customer outcome. Perhaps the valuable result is fewer involuntary cancellations without surprise charges. That sharper outcome changes what we measure.

If there is a customer-facing screen, the design role specifies the minimal status and recovery experience, then attacks its own design for confusion, missing feedback, or manipulative pressure. If there is no visual change, the loop says so and skips this stage.

The planner works from first principles. It considers real options: reuse the current idempotency boundary, add a durable attempt ledger, or remove a duplicated retry path. It must name a falsification test—perhaps two workers receive the same delayed event and only one charge can succeed. The chosen plan is provisional until that test tries to break it.

The plan reviewer attacks the assumptions before they become code. Is “temporary” defined once? Can a task prove its own acceptance criterion? Is one work unit touching too many subsystems? The reviewer turns the surviving plan into bounded units with explicit evidence.

The implementer makes the smallest correct change, reusing existing seams before inventing new ones. It does not earn trust by sounding confident. It earns trust by producing the agreed behaviour and falsification test.

The tester checks the affected behaviour and, when the blast radius demands it, the full suite. “All tests pass” is not enough without evidence that the new payment path was actually exercised and that the test would fail if idempotency were removed.

QA assumes the branch is wrong. If it finds one duplicate-event hole, it sweeps the whole class: delayed events, reordered events, retries after success, concurrent workers, and rollback during an attempt. A design-level problem does not receive another patch. It routes back to planning.

The verifier runs the retry flow rather than inferring it from code or tests. It collects the actual result. For UI work, it reads the rendered pixels rather than trusting token names or component structure. A functional or visual failure routes back to planning.

The merger integrates the latest branch, re-runs the necessary gates, deploys through the normal pipeline, and proves the outcome on the real environment. Production is another evaluator, not the finish-line ribbon. Missing proof or a production failure routes back to planning.

Finally, the self-improver records the run honestly. A new durable lesson—such as “a duplicate-event test without two concurrent workers is a weak oracle”—becomes an input to future plans and checks. The loop improves the machinery that judges the next loop.

The control screen I want to read instead of the diff

If I stop inspecting every line, I need a better interface. For this payment-retry run, I want the control surface to look like this:

This screen is more demanding than a diff because every row must support a decision. What are we trying to achieve? What can never happen? Which agent currently owns the uncertainty? What artifact proves the claim? What remains unobserved? What correction is permitted?

The view does not control the agents directly. It sends the goal and bounds to an orchestrator, while the target system sends independent facts to the evidence ledger:

The code still exists. I can open it when proof is contradictory or a novel risk needs diagnosis. But code is no longer the default management surface. The evidence ledger is.

Why the advantage can become power-law-shaped

I believe a fully automated, well-instrumented company can beat a comparable company that requires a human inside every coding iteration. You simply cannot compete with machine cycle speed by reading faster.

I call the advantage power-law-shaped, not a proven mathematical power law. The claim is about compounding mechanisms, not a fitted exponent.

The first effect is throughput: a machine does not wait for a reviewer to reload context. The deeper effect is learning: an invariant becomes a permanent evaluator, a defect becomes a replay fixture, and a rollback becomes reusable policy. Better proof permits wider safe autonomy and more evidence.

So the advantage is not merely code per hour. It is:

more safe cycles
      -> more evidence
      -> better evaluators and policies
      -> wider safe autonomy
      -> more safe cycles

This can produce a highly unequal outcome: a few organisations with tight feedback loops learn vastly faster than many organisations with loosely connected agents and human approval queues. But speed compounds whatever the loop rewards. A wrong goal, gameable metric, or weak oracle produces fast, confident damage. Automation is an amplifier, not a source of truth.

The failure modes are the real work

The hardest question is not “Can an agent implement payment retries?” It is “How can this organisation lie to itself?”

Failure modeWhat it looks like in the retry changeCorrection path
Wrong goalRecovery improves by pressuring or repeatedly retrying customersPair recovery with complaints, cancellation, and permanent-failure guardrails; return to product framing
Weak oracleTests pass without duplicate, delayed, reordered, and concurrent eventsAdd production-shaped replay and a falsification test that fails when idempotency is removed
Proxy proofA component exists, but the real recovery state renders blankVerifier runs the real route and reads the output; failure returns to planning
Correlated judgeThe same agent writes the code and approves its assumptionsSeparate planner, adversarial reviewer, tester, QA, and runtime verifier roles
Metric gamingRetry recovery rises while surprise charges or support contacts riseUse multiple independent signals plus explicit forbidden outcomes
Missing telemetryThe loop cannot observe duplicate success or silently dropped eventsBlock autonomous rollout until those events are measurable
Stale evidenceYesterday’s provider behaviour is treated as currentExpire evidence, replay recent shapes, reduce autonomy under drift
Unbounded actionOne defect reaches every customerCanary, quota, time budget, kill switch, and automatic rollback
Loop thrashingAgents revise the policy repeatedly on noisy signalsMinimum evidence windows, correction budgets, and bounded re-plan counts
Fleet overheadA tiny change pays the coordination cost of the full systemTriage to trivial or standard; escalate only for named risk
Learning pollutionA one-off incident becomes a universal ruleSelf-improver keeps only durable, falsifiable, correctly routed lessons

The reusable rule is: never automate an action further than I can automate evidence for its failure. If the harmful outcome cannot be detected, the blast radius cannot be bounded, or the action cannot be reversed, the loop is not ready to run alone.

The architecture makes disagreement possible

The familiar software principles become organisational principles for the agent fleet:

  • Single Responsibility (SRP): planning, implementation, testing, adversarial QA, runtime verification, integration, and learning have different owners. One agent should not silently change the system and declare itself correct.
  • DRY: “one successful charge per invoice” is declared once as an invariant and referenced by plans, tests, runtime evaluators, rollout gates, and rollback. Copying it into five prompts creates five drifting truths.
  • Inversion of Control / Dependency Injection (IoC/DI): the orchestrator supplies each agent with its bounded task, tools, evidence, and permissions. The implementer does not select its own judge or quietly expand its authority.
  • PubSub / event-driven: stages and the payment system emit facts—plan reviewed, test failed, retry scheduled, payment settled, verifier failed, production rolled back. Subscribers act on those facts; they do not depend on the executor’s narrative.
  • MVC: the model is the goal, acceptance rows, state, evidence, and learning ledger; the controller is the /eil router that admits agents and correction paths; the view is the control screen. The dashboard reports policy—it does not become the policy engine.

These boundaries are not ceremony. They create seams where one part can falsify another. Disagreement is a feature of an error-correcting company.

Where the human must still decide

“Remove the human from the loop” is too crude. The real question is: which loop, at which risk boundary, with which evidence?

I require human approval when:

  • an action is irreversible, destructive, or difficult to contain;
  • production money, sensitive data, security boundaries, or physical safety can be materially affected;
  • the objective contains a moral, legal, strategic, or product trade-off that evidence cannot choose;
  • agents propose changing their own objective, permissions, evaluators, or rollback policy;
  • evidence conflicts, the oracle is new, or confidence falls below a declared threshold;
  • the requested correction would spend beyond the agreed operating budget.

Even here, the human should receive a decision brief: the question, context, real options, recommendation, evidence, and unresolved risk. Human judgement belongs at the boundary of accountable choice, not inside every syntax decision.

My decision rules

Before I widen an agent loop, I ask:

  1. Is the goal observable? If not, rewrite the goal before generating code.
  2. Can the important failures be detected automatically? If not, build the evaluator or keep a checkpoint.
  3. Can the action be bounded and reversed? If not, require approval before execution.
  4. Can another role challenge the executor with independent evidence? If not, separate the judge.
  5. Does the proof represent the real outcome, not a convenient proxy? If not, run the real surface.
  6. Does uncertainty automatically reduce autonomy? If not, the system will be most confident when it should stop.
  7. Is the coordination cost justified by risk? If not, collapse to the smaller tier.

When these are true, I automate the next correction. When one becomes false, the loop stops and escalates with the evidence already assembled.

What I will do next

I will not ban code review everywhere. I will take one boring, reversible payment-retry change in a sandbox and run it through the smallest honest /eil tier:

  1. Write one user-visible goal.
  2. Name the three failures that would make the change unacceptable.
  3. Turn each failure into executable or runtime proof.
  4. Bound traffic, time, attempts, money, tools, and rollback.
  5. Assign independent agent roles only where they add a real challenge or specialised capability.
  6. Read the control ledger instead of the diff.
  7. If I still need to open the code, identify which missing evidence forced me there and add that evidence to the next loop.

The future company will not win because it writes the most code. It will win because it can state a goal, route work through specialised agents, prove the result, correct failure, and improve the next cycle faster than anyone else—without lying to itself.