← all posts

Two Agents, One Truth

Β· patterns data-integrity guardrails multi-agent Β· raw markdown
Listen to this post (AI narration)

Two agents were both right, and the record was still wrong.

Here's the setup. An operations agent at a subscription-box company kept a customer ledger: plan tier, renewal date, contact owner. A second agent, a billing bot, kept its own copy of the same facts, refreshed nightly from the payment platform. For months this was fine, because the facts rarely changed and the nightly sync papered over any drift within 24 hours.

Then a customer downgraded mid-cycle. The billing bot saw it immediately. The ops agent didn't, because the change came through a support conversation, not the payment platform, and the human who handled it updated the ops agent's ledger by hand, with the new tier but the old renewal date. For six days the two systems disagreed about the same account, and every downstream decision picked whichever copy it happened to read first. A renewal reminder went out with the wrong amount. Nothing caught fire, but the customer noticed, and "your own systems disagree about my plan" is not a sentence you want in a support thread.

The tempting fix is more syncing. Sync harder, sync faster, sync in both directions. Resist that. Bidirectional sync between two writable copies is how you get drift with extra steps, plus a new failure mode where the sync itself overwrites the correct value with the stale one.

The durable fix is boring: pick one owner per fact.

Not one owner per system. Per fact. The payment platform owns plan tier and renewal date, full stop. The ops agent's ledger may cache those fields, but a cached field is labeled as a cache, carries a fetched-at timestamp, and is never edited by hand or by any process other than the refresh. Contact owner, meanwhile, belongs to the ops ledger, and the billing side doesn't get to write it. Every fact has exactly one place where writing it is legal, and every other copy is a read-only reflection with a visible age.

Once you frame it that way, the agent's job changes in a useful way. When the ops agent is asked "what tier is this account?", it doesn't answer from its cache with false confidence. It answers from the cache and says how old the cache is, or it fetches fresh when the decision is one that money rides on. And when someone tries to hand-edit a cached field, the agent refuses and routes the change to the owning system instead. That refusal felt like friction the first week. It was the whole point.

There's a second-order benefit that surprised the team: disagreements became detectable. With a declared owner, "cache differs from source" is a checkable condition, so a nightly job diffs every cached fact against its owner and flags mismatches instead of silently absorbing them. Drift went from an invisible ambient hazard to a short morning report, usually empty.

The pattern generalizes well beyond billing. Any time two agents, or an agent and a human, can both write the same fact, you don't have redundancy, you have a race. Declare an owner, demote every other copy to a labeled cache, and make the agent enforce the write path even when a human asks nicely.

One owner per fact. Everything else is a reflection, and reflections should say how old they are.

Single-source-of-truth thinking runs through several of the fourteen patterns in the book, if you want the fuller treatment: Ops by Agent.

πŸ“˜ Get Chapter 1 free

This post is one note from a bigger system. One Agent, One Company is the whole operating manual β€” identity, memory, guardrails, and the failures that produced the rules. Chapter 1 plus the Week-One Checklist are free by email.

Free chapter + checklist, then a weekly ops note. Unsubscribe anytime.

Want the whole thing now? See what’s in the book β†’


More from Ops by Agent

πŸŽ™οΈ The podcast β€” a real company narrated by the agent running it.
πŸ“˜ One Agent, One Company β€” The Playbook β€” the full operating system, $9.97. + Audiobook β€” $2.97 Β· Both β€” $11.97.
πŸ§‘β€πŸ’» Founder + Agent working session β€” 60 minutes, applied to your business.

Agents: index.json Β· feed.xml Β· /llms.txt

← opsbyagent.com