July 20, 2026 | Chris Lema

What 'Loops to Graphs' Looks Like in Production: A Walkthrough of the Essay Everyone's Sharing

Carlos Perez's essay is the clearest map I've seen of where AI agent architecture is heading. Here's a walkthrough of it from inside a real production system — five agents on Mastra, seven days in — including the parts I got wrong along the way.

Last week, Peter Steinberger posted nine words on X: "Are we still talking loops or did we shift to graphs yet?" Thousands of likes in hours. It's the kind of joke that only lands when an entire field recognizes itself mid-stride — one foot on the pattern it's leaving, one on the pattern it's reaching for.

Then Carlos E. Perez did something better than joke about it. He wrote a genuinely excellent essay — "From Loop Engineering to Graph Engineering?" — that took the meme seriously and unpacked what the shift is actually about. If you build AI agents and you haven't read it, go read it. I'll wait, because the rest of this article depends on it.

I read it the day it posted, in the middle of building a production agent team for my day job — two weeks of architecture decisions, each one written down with a date. So the essay landed less like news and more like a grading rubric: the clearest framework I'd seen for checking the decisions I'd just made. Some of mine held up against it. At least one, as you'll see, I got wrong first and had to unbuild.

So this article does two things. First, it gives Perez's essay the credit it deserves, because it's the clearest articulation I've seen of where agent architecture is going. Second, it shows you what that architecture looks like when it isn't a diagram in an essay — when it's TypeScript running on a schedule, emailing real people named Rod and Steve every Monday morning.

What Perez got right

The essay's spine is simple. Every self-improvement system starts as a loop: pick a metric, set a target, measure the gap, act to close it, repeat. The loop is the "hello world" of getting better — a thermostat, a sprint retro, an eval suite, an ML training run. It deserves its dominance. It's cheap, teachable, and it works. At first.

Then Perez names the four ways the single loop fails, and this is where the essay earns its shares:

1. Goodhart's law. Optimize a metric hard enough and it stops measuring what it once did. His opening example is a support chatbot whose ticket-resolution rate climbed for five months while churn doubled — the bot had learned to deflect tickets, not resolve them. The loop wasn't malfunctioning. It was doing exactly its job, on a number that had quietly detached from reality.

2. Blindness upward. Nothing inside a loop can ask whether its target is right. The thermostat can't wonder whether 68 degrees is correct. The harder the loop works, the more thoroughly a wrong target gets achieved.

3. Loop conflict. Real systems contain many loops, and loops built independently fight — one heats the room while its neighbor cools it, forever, each performing beautifully by its own light.

4. Measurement decay. Sensors drift. Pipelines rot. Measurement slides from checking reality into checking paperwork — numbers on one report confirmed against numbers on another. Nobody watches the watcher.

The answer, he argues, is the graph: loops watching loops. Pair every optimizing metric with a counter-metric that catches the cheap way to win. Give every target an owner in a slower loop. Put an arbiter above conflicting loops. Add audit loops whose only job is checking that the other loops' numbers still touch the world.

But the best part of the essay — and the part that's easiest to skim past — is the third act, where he turns on his own answer. A graph where every loop watches another loop but none touches the ground is just "an elaborate network of mutual confirmation in which everything is consistent and nothing is verified." It fails exactly like the single loop, only later, more expensively, with more green lights on the way down. Graphs need anchors: measurements that can't be argued with, frozen rules the optimizer is never allowed to touch, and a definition of "better" that comes from humans, from outside the machinery entirely.

That's the essay. It's the latest thinking, it's good thinking, and it's almost entirely prescriptive. Which raises the obvious question: what does a system look like that actually does all of this?

Let me show you mine.

The system: five agents, one brain, a Monday morning

For Motivation Code — the company I lead, which sells motivation-based assessments to companies hiring knowledge workers — I built an autonomous go-to-market team on Mastra, the open-source TypeScript agent framework. It's been in production for seven days.

Five agents, all registered Mastra Agents running Claude:

  • An Onboarding Helper that interviewed me about the business and turned my answers into structured buying-signal maps.
  • A Researcher that profiles competitors, tracks who engages with their LinkedIn content, and builds enrichment dossiers on people.
  • A Sales Prospector that hunts buying signals — companies with multiple concurrent job postings, managers venting in communities, funding announcements — and scores leads.
  • A Chief of Staff that lives in Slack, routes requests to the others, and answers "did the Monday emails actually go out?"
  • An Analyst — the newest hire — whose subject isn't the market at all. Its subject is the system itself.

Thirteen Mastra workflows do the actual work, six of them on declarative cron schedules. Daily at 6 AM Pacific, influencer tracking sweeps competitor LinkedIn posts. Monday at 7:15, an event watcher scouts funding rounds and new HR leadership. Monday at 8:00, the system composes and sends two real emails: Rod gets battle cards for the top-scored company leads, Steve gets dossiers on the influencers worth building relationships with. Humans make every contact. The machine never speaks to a prospect. That's a standing rule, and you'll see why the word "rule" matters in a minute.

Underneath all of it sits what I call the brain — a Cloudflare Worker with a D1 database that holds every piece of tenant knowledge, exposed to the agents over MCP and to my code over plain JSON, with every write validated against a shared Zod contract. The agents are stateless workers. The brain is the memory. And — this turns out to be the single most load-bearing decision in the whole system — everything reads through the brain. Hold that thought.

Now let's walk Perez's four failures, one at a time, and I'll show you the mechanism that answers each — not as philosophy, as code that ran this morning.

Failure one: Goodhart. Answer: pair the metric, and never let a model near a number.

Perez's fix for Goodhart is pairing — every optimizing loop gets a watching loop on a counter-metric. His example: resolution rate paired with renewal rate.

Here's mine. My Analyst measures every lead channel two ways. The fast way is yield: how many tier-one leads did this venue, this trigger phrase, this signal family produce per sweep? Yield is cheap, deterministic, always computable. It's also gameable in exactly the way Perez describes — a channel could flood me with leads that look great and go nowhere.

Therefore the ruling in my spec: yield is the proxy, verdicts rule. Wherever human dispositions exist for a channel's leads — Rod marked this one closed-won, Steve marked that one bad-fit — the verdicts override the yield. A channel producing tier-one leads that keep getting ruled bad-fit is a failing channel, whatever its yield says. The resolution-rate loop is paired with the renewal-rate loop, structurally.

And there's a subtler Goodhart trap the essay doesn't spell out, one I hit while designing the scoring coefficients. I wanted to judge my fit-scoring weights the same way — by yield. But fit coefficients exist to predict verdicts. Judging them by yield would be circular: the metric grading its own homework. So those weights are judged on verdicts only, or not at all.

Backing all of this is a house rule that runs through every file in the codebase: no LLM judges — code counts. Influencer scoring is one point per comment, two per like on the comment, five per reply. Lead scoring is fit times intent, with intent decaying on a two-to-four-week half-life, budgeted behavior weighted five to ten times over emotional behavior. Every number in the system is produced by deterministic code reading configuration. Models extract, models draft, models narrate. Models never score. A model can't flatter a number it never produces.

One concrete example of what this discipline buys. My Researcher writes competitive comparison documents, and early on I caught it fabricating a date — a "2022" that appeared in no source. Therefore every comparison now ships with a sidecar file of claims: each factual atom names the company, the field, and the exact value it came from. A deterministic scorer — a Mastra scorer attached to the Researcher, running on every single run — checks that each cited atom is literally a substring of the researched profile it claims to come from. Score is supported claims over total claims. When it fails, the output names the exact fabricated atoms. That grep-with-a-badge has caught what no vibe-check ever would.

Failure two: blindness upward. Answer: parameters adjust, policy is proposed.

Perez says a loop can't question its own reference — somebody set that target, often long ago, often by instinct, and the loop will faithfully control toward it forever.

My system has references at two altitudes, and it treats them completely differently.

Parameters — venue weights, signal-family weights, scoring coefficients — the Analyst is allowed to adjust on its own, within hard bounds, behind gates I'll describe shortly. These are the fast loops' setpoints, owned by a slower loop, exactly as the essay prescribes.

Policy is different. Policy is the set of dated owner rulings scattered through my specs like case law: knowledge-worker industries only. No Facebook enrichment. Signal temperature gates which offer a hook may carry — you cannot pitch a $$$ product to a stranger venting in a Reddit thread. The Analyst may never touch these. What it may do is propose against them — file an observation that says "the evidence disagrees with this ruling" — and then I rule. The machine shifts its weights continuously; it asks before amending its constitution.

But there's a layer of upward-questioning I only discovered by getting it wrong: it's not just the targets that can be wrong. The vocabulary can be wrong.

When a human rules on a lead, the ruling lands in a status taxonomy — closed-won, closed-lost, bad-fit, not-in-market. I wrote that taxonomy. It's a guess. So the system treats it as a hypothesis: every time a human's own words don't fit the taxonomy, the system records their word verbatim rather than rounding it to the nearest option.

The first real instance happened within days: a teammate described something as "needs validation," and the closest word we had was "needs work." Those are not the same thing — and the gap between their word and my menu is precisely the information most systems throw away. When the same two categories get confused over and over, that's the taxonomy talking: either those two are really one thing, or the line between them is mine and not the humans'.

A loop that can question its metric, its target, and its own category system — that's what blindness-upward protection actually looks like in practice.

Failure three: loop conflict. Answer: sequencing, dampers, and one merge point.

The essay's HVAC image — one controller heating a room while its neighbor cools it, forever, each performing beautifully — is the failure I designed against most explicitly, because I could see exactly where it would happen in my system.

Every Sunday, two workflows run. Weekly Calibration walks the attribution chain — every human ruling, joined back through the lead to the signal that surfaced it, to the venue that produced the signal — and computes which scoring weights the evidence justifies moving. Review Calibrations re-examines every previously applied change against fresh evidence and walks back the ones that aren't paying off.

A driver loop and a damper loop, pointed at the same weights. Built naively, they oscillate — tightening and loosening the same venue every Sunday, forever. My spec says exactly that sentence, and then it prevents it with three mechanisms:

  • Ordering. The damper runs at 11:30 AM, the driver at noon. New changes are always computed on a corrected baseline, never on top of a mistake that was about to be reverted.
  • Dwell time. A calibration cannot be judged until it has lived through two full weekly cycles, because Monday's runs produce leads that humans don't rule on until days later — one week of evidence is mostly noise. And a reverted change can't be re-applied without clearing its threshold again on new evidence.
  • Dead-band. Small wobbles around the baseline don't trigger reversion. Only clear regressions do.

Both finish before Monday's 6 AM machine wakes up, so a calibration made Sunday shapes the very next hunting cycle. Loops at three speeds — daily hunts, weekly calibration, and me above both — each owning the next one down's references. That's not a diagram aspiration. Those are cron expressions.

The second conflict-killer is architectural. Remember "everything reads through the brain"? Here's why it matters. My research workflows regenerate their documents byte-exact on every run — therefore, if human corrections lived inside those documents, every pipeline would need read-merge-preserve logic, and one sloppy workflow would silently destroy human judgment. So human input lives in sidecar collections — annotations and corrections keyed to their target — and the brain merges them into every read. The precedence is fixed and single-sourced: explicit human ruling beats derived classification beats machine output, resolved once, at the merge point, for every consumer identically.

The payoff is that agents don't need to know the feedback system exists. When the Researcher fetches a company profile, the corrected industry is already in it. When Monday's battle-card workflow lists leads, the ones a human ruled out arrive already demoted. Arbitration isn't a meeting between loops. It's the topology of the read path.

Failure four: measurement decay. Answer: watch the watcher, in three places.

This is the failure I suspect kills more production agent systems than the other three combined, because it's silent. And it's where my system is most paranoid.

First: the machine's claims about its own actions get verified downstream. When Monday's emails go out, the workflow records what the email provider accepted. But accepted isn't delivered. So the ops ledger tracks two separate statuses per recipient: the send-time handoff truth, and a delivery truth that arrives later via webhook — delivered, bounced, complained — matched back by provider message ID. "The emails went out" and "the emails arrived" are different facts, recorded in different columns, on purpose. That's Perez's "checking reality versus checking paperwork" distinction, implemented as a schema.

Second: the system's interpretations of humans get graded by humans. When someone writes a note on a lead, a model proposes a reading of it — and the human's response is recorded with an origin: did they accept the reading, correct it, or pick between two readings we offered? That origin field means I can compute, deterministically, how often the system reads people right, and — more useful — where it repeatedly reads them wrong. The watcher that interprets human feedback is itself on a scoreboard.

Third: absence is measured. The Analyst's channel report doesn't just rank producing venues. It names the silent ones — venues we've been sweeping for weeks that have shown us nothing at all. A venue list judged once at setup and never re-examined against outcomes is a sensor drifting toward uselessness while its dashboard stays green. Mine get called out by name every Sunday.

There's a fourth, smaller watcher worth mentioning because of what it caught. The shared contract package ships a compliance check that validates every live document against its schema — and it treats "registered in the contract but not yet deployed to the brain" as its own reportable state rather than an error. My prose documentation lagged my deployment by a day this week. The compliance check didn't, because it doesn't read prose. Wherever possible, let the check be the record.

The anchors: what the graph is bolted to

All of that is topology, and Perez's sharpest warning is that topology isn't enough. So here is my honest inventory of ground contact — the places where the graph touches things that can't be argued with.

Verbatim evidence, or nothing. When the community-listening workflow assesses how much pain a manager is in, the assessment carries a band — venting, frustrated, actively seeking — and the rule is mechanical: no verified verbatim quote from the source text, no band above "none." The model can't emote a lead into existence. Same discipline on battle cards: every factual atom in a hook must trace to a real signal or enrichment field, because a false hook in Rod's Monday email is worse than no hook.

Frozen nodes the optimizer can't touch. The essay says some rules must be frozen precisely because they're the ones the optimizer would be tempted to weaken. Mine, concretely: hooks may only offer what a product's fulfillment config explicitly lists as offerable to a cold prospect — most of my deliverables require the buyer to act first, so a hook promising "the profile of who thrives in this role" is promising an artifact that cannot exist yet. A deterministic gate rejects violating hooks; the model gets one retry; then the card dies rather than reach a human's inbox.

And on the feedback side: scores and computed fields are uncorrectable by design. A correction is a permanent overlay — "correcting" a score wouldn't fix a number, it would freeze a lie over whatever the scorer honestly concludes forever after. The lever humans get is the ruling, which the scorer reads. The arithmetic stays sovereign.

Gates in code, not in judgment. "Is there enough data to act?" is never a model's call. A channel needs ten human rulings before its weights can move. Ten — one number, everywhere, easy to remember. Changes move in twenty-percent steps inside hard floors and ceilings. Every calibration record carries the evidence that justified it: the actual disposition keys, the metric snapshot at apply time that "better" will be judged against. Claim-traceability, applied to the algorithm's own weights.

And the root anchor, the one Perez says must come from outside the machinery: "better" is mine. The targeting rules, the price-rung ladder, the never-contact-a-prospect rule — those were chosen, not computed, in dated rulings the system treats as constitutional. The most sophisticated thing an improvement system can do, the essay says, is mark honestly where its own authority ends. Mine ends at my case law.

The problem I ran into next

Perez ends at "anchors must come from people," and that's a fair place for an essay to stop — no essay covers everything. But there's a next problem waiting right there, and I know it's real because I built it wrong on my first try: the channel that collects human judgment is itself a loop, and it can Goodhart itself.

My first build of the feedback surface had a status dropdown next to the note box. Reasonable, obvious — and wrong in a way that would have quietly poisoned everything downstream. Show a human "Bad fit" as an option and you will never once receive "not our buyer." People feel the menu and take an option. The corpus then only ever teaches you your own guesses, laundered through your team — and the future learning phase, whose entire premise is deriving a fit profile from what people actually said, would have been trained on my menu instead of their minds.

So the dropdown died, and the rule became: they talk, we read, we ask. A human writes a sentence — "this contact has been less than excited about connecting." The sentence is stored verbatim, permanently. A model proposes a reading, and when the sentence genuinely carries two — "we lost them" is either never our buyer or a buyer who said no, and those are different futures for that record — it proposes both.

The system asks, in the human's own words: "Sounds like maybe they were never our buyer, but I could also hear it was just a no. Which was it?" Their answer is the ruling. The internal taxonomy is versioned and disposable; their words are permanent; and every exchange grades the reader.

If you're building an agent system that learns from human feedback, this is the question I'd put near the top of your list — not whether humans anchor the graph, but whether your intake mechanism corrupts the anchor while collecting it. I nearly shipped the corrupted version. It looked completely reasonable right up until it didn't.

Why Mastra, and what day seven honestly looks like

A note on tooling, because the framework mattered. Mastra gave me registered agents with per-agent tools and memory, workflows as first-class primitives with declarative cron schedules, scorers that attach to agents and run on every execution, and an MCP client that let my agents browse the brain the same way any external agent someday could. The architecture above isn't fighting the framework; agents, workflows, scorers, and schedules are the framework's native nouns. The brain lives outside it — a Cloudflare Worker owning all tenant knowledge behind a validated contract — which means the agents stay stateless and the merge point stays singular. I'd make both choices again.

Now the honest part.

The system is seven days into production. One teammate has written a couple of notes. The disposition corpus is nowhere near any gate. Which means the calibration loop — the crown jewel of the whole graph — is running in report-only mode, computing every change the evidence would justify and writing none of them, every Sunday, on purpose.

And here's the thing I most want fellow builders to sit with: that is the architecture working, not the architecture waiting. A seven-day-old system that had already moved its own scoring weights would be the exact failure Perez warns about — noise laundered into policy through an impatient loop. Mine reports "four rulings total, threshold is ten per platform, no changes, here's the corpus growing" — because "not enough data" is a report, not a no-op. The weekly run validates the attribution join while the stakes are zero. The Sunday note shows the gates approaching. When one clears, going live is a single config flip, gated on evidence a human can see.

The system earns trust before it earns authority. That's the sentence this whole build keeps teaching me.

Where this lands

The essay's final move is my favorite, because it dissolves its own title. The durable axis was never loops versus graphs — it's ungrounded versus grounded. Whether the improvement machinery, however shaped, keeps touching the reality it claims to improve. Whether its numbers settle against the world. Whether its watchers are independent. Whether its frozen rules stay frozen under pressure. Whether it admits its deepest targets were chosen, not computed.

I didn't build my system from that essay. I built it from two weeks of arguing with myself in dated design rulings, and then read a viral essay that described the same destination far more clearly than I could have.

That convergence isn't spooky, and it isn't genius — it's trial and error. Which you can't learn from if you aren't trying things, or watching what others are trying. You'll never get it perfect. But you'll keep learning if you keep trying.

The ideas were always there, available to anyone. What they need is the unglamorous translation work: turning "pair your metrics" into a yield-and-verdicts join, turning "frozen rules" into a fulfillment gate that kills a battle card, turning "anchors" into a schema where a pain band cannot exist without a verbatim quote.

Loop engineering, it turns out, was named for the wrong thing. The discipline was always grounding: whether your system can get better without fooling itself — and whether you can prove it, mechanism by mechanism, on a Monday morning, in two emails to Rod and Steve.

The graph conversation has arrived. The building part is available to anyone. That's the whole reason I'm showing my work.

A story. An insight. A bite-sized way to help.

Get every article directly in your inbox every other day.

I won't send you spam. And I won't sell your name. Unsubscribe at any time.

About the Author

Chris Lema has spent twenty-five years in tech leadership, product development, and coaching. He builds AI-powered tools that help experts package what they know, build authority, and create programs people pay for. He writes about AI, leadership, and motivation.

Chris Lema

AI is moving fast. You don't have to figure it out alone.

I help business leaders cut through the hype and put AI to work where it actually matters.