Articles

Jul 10, 2026Harsh ChandraTech Talk

Designing Autonomous Agent Loops: Architecture Beyond Prompts

Automatically translated from the Japanese original.

Note: This article is a written adaptation (restructured in manuscript form) of an internal slide-style deck. Its subject is the design of a resilient multi-agent "Generator-Evaluator" architecture that keeps writing, reviewing, and merging code even while you sleep.

The End of the "Human Clock"

Traditional AI usage ran on the "human clock." The agent waits for input, a human presses Enter, tokens are generated, and it stops. Repeat. In June 2026, a turning point arrived. Peter Steinberger (OpenClaw), Boris Cherny (Claude Code), and Addy Osmani (Chrome) each independently converged on the same realization within the same week: the tools had crossed a threshold.

The essence of the shift is this: stop being the person who prompts the agent, and become the person who designs the system that does it for you. An autonomous loop engine has three properties: (1) it fires on a timer (waking up on a schedule), (2) it spawns parallel sub-agents (helpers), and (3) it feeds itself (yesterday's output becomes today's input).

The Four-Layer AI Protocol Stack

AI usage can be organized into four layers; the higher the layer, the larger the blast radius when something fails.

LayerCore concernBoundary unitBlast radius of failureWhere the human stands
Layer 1: PromptWhat you tell the modelA single exchangeAn immediately obvious wrong answerTypist
Layer 2: ContextWhat you put in the windowA single sessionConfident but wrong reasoningEditor
Layer 3: HarnessArming a single run (tools/actions)A single taskA bad diff caught before shippingReviewer
Layer 4: LoopScheduling the harnessUnattended iterationStructural rot that advances over daysArchitect

Anatomy of a Loop That Keeps Running

An autonomous loop consists of five nodes.

  1. Discovery — backed by Skills (SKILL.md). The project's permanent knowledge, paying down "intent debt."

  2. Handoff — backed by Worktrees. Independent git directories for parallel execution.

  3. Verification — backed by sub-agents. The separation of Generator and Evaluator: "something that can say no."

  4. Persistence — backed by connectors (MCP) and memory. State lives in files on disk (such as ./state/triage.md). The agent forgets, but the repository does not.

  5. Scheduling — backed by automation infrastructure (local cron, GitHub Actions, cloud routines). It closes the cycle.

Worktree Parallelization

The problem: two agents editing the same working directory is like two engineers committing to the same line. Collisions break unattended pipelines. The primitive: isolate independent working directories, as in claude --worktree fix/auth-test 'draft the fix'. The effect: parallelization goes from "works but messy" to "works and clean." Multiple independent working directories within a single repository make high-throughput issue triage possible.

The Self-Persuasion Bubble — Separating Generator from Evaluator

The anti-pattern is a Generator grading its own homework. The Generator isn't looking at its code; it's looking at its own chain of self-persuasion. The GAN split, by contrast, separates the Generator from the Evaluator and casts the Evaluator as an adversarial code reviewer: "Assume this code is broken until proven otherwise. Don't praise it. Find where it fails."

The core insight: tuning an independent Evaluator into a rigorous skeptic is far more achievable — both mathematically and in practice — than getting a Generator to be critical of its own output.

Verdicts Through External Execution

The flaw: if the Evaluator only reads the code, its verdict is "does this look correct?" rather than "does this actually work?" The shift: connect the Evaluator to an external execution environment (e.g., Playwright MCP). The new standard: the Evaluator clicks buttons, forces screen transitions, captures DOM state, and runs tests. The verdict moves from "intent" to "behavior." The flow becomes: Evaluator agent → Playwright MCP connector → DOM inspection / screenshots / test runner → pass/fail verdict.

Maker-Checker Stopping Conditions

When should a loop end? The /goal primitive expresses "keep going until the condition is met" (for example: /goal all tests in test/auth pass and lint is clean). The Generator (a heavy model) writes the code, the Evaluator (a heavy model) runs the tests via MCP, and the Gatekeeper (a fast, fresh model) evaluates the /goal. If it is satisfied, the loop exits; if it fails, the reasons for rejection are sent back to the Generator.

The principle: the decision that work is complete must be made by a fresh model carrying none of the context baggage of the model that did the work. And there is a line worth remembering: the floor of the loop is the Evaluator. The Generator sets the ceiling on what gets produced; the Evaluator sets the floor on what doesn't.

Five Ways a Loop Fails

Missing elementAnti-patternSymptomRequired fix
No verificationThe nodding loop100 turns of approving its own garbageImplement Generator-Evaluator separation
No persistenceThe amnesiac loopRediscovers exactly the same work every morningForce state files to be written to disk
No schedulingThe manual loopHasn't run once since the day it was demoedWire up cron/event triggers
No discoveryThe blind loopStill spending 30 minutes pasting in "fix this bug" every single timeBake the heuristics into SKILL.md
No handoffThe tangled loopFive parallel agents wreck a single git directoryEnforce isolation with --worktree

Deterministic Interleaving at Enterprise Scale

Stripe's "Minions" pipeline — trigger (Slack) → context orchestrator (Sourcegraph/Jira) → code generation (LLM) → mandatory linter gate → lint fixes (LLM) → git commit → human review (1,300 PRs per week) — merges 1,300 machine-generated PRs a week (powered by the open-source framework Goose).

The secret is letting deterministic systems do the deterministic work. Context gathering and linting are strictly hard-coded, and the LLM is confined entirely within guardrails bounded by hard rules. Environments are treated as "cattle, not pets": Devboxes on EC2 are swapped out and destroyed immediately to avoid state rot.

Execution Topology — Where Does the Loop Live?

TopologyMachine stateSessionMinimum intervalLocal FS access
Cloud (Cloud Routines / GitHub Actions)Works even with the machine offNot required1 hourNone (clean clone) → best for overnight triage
Desktop (macOS cron)Machine onNot required1 minuteYes → best for periodic repository maintenance
Local (/loop command)Machine onRequired1 minuteYes → best for high-frequency checks during development

Calling a local re-run "running while you sleep" is an exaggeration. Local scheduling buys you frequency; cloud scheduling buys you true autonomy. No single scheduler gives you both.

The Vicious Cycle of the Unwatched Loop

An unattended loop carries four risks: verification debt (merging code that passes tests but hides subtle logic flaws) → comprehension rot (your mental map of the codebase drifts away from reality) → cognitive surrender ("I don't know how this works, but let's accept the PR") → token waste (an unwatched agent spawns helpers all night, endlessly retrying futile bug fixes). These are not four separate risks; they are a single, compounding failure mode. A loop without a rigorous Evaluator has handed the authority over its spending to its own bugs.

The Economics of Zero-Cost Generation

What becomes abundant: generation. The cost of code, plans, fixes, and pull requests trends toward effectively zero, and mechanical labor collapses. What stays scarce: judgment. A loop can generate 100 candidate implementations, but it chooses among them based on "looks right," not "is actually right." The loop as amplifier: a loop is a faithful multiplication sign. Bring understanding and it amplifies understanding; bring laziness and it amplifies disaster.

Operational Circuit Breakers

  1. Always read a sample (defense against comprehension rot): every day, pick a machine-generated PR at random and check whether you can explain it in your own words. If you can't, your mental map is already stale.

  2. Set caps before shipping (defense against token waste): per-run budget limits and maximum retry counts are not about saving money; they are circuit breakers that convert open-ended risk into bounded risk.

  3. Leave one door open (defense against cognitive surrender): build at least one checkpoint that pauses for a human — not so that you intervene every time, but to guarantee that you can.

Deploying the Minimal Resilient Loop

The minimal configuration looks like this: fire on a schedule (cron: cloud automation), run a skill (morning-triage: discovery), and write the results to ./state/triage.md (persistence). Carry out any fixes discovered in a worktree (fix/$finding: handoff), and judge them against a /goal of "tests pass and lint is clean" (verification). Output folders are split into ./inbox/ (everything unverified), ./state/, and ./src/, and the rule is: never auto-merge. Everything unverified lands in ./inbox/.

Finally, let's close with these words.

"Build the loop. But build it as someone who intends to remain an engineer, not as someone who merely presses a button."

The end

Read next ↓

Share this article