DEV Community

Open Human
Open Human

Posted on

Green Means the Tests Ran

The PR touched the routing core of an open-source repo. CI was green. I looked at the diff, liked what I saw, and pressed merge. No integration tests, no second review. Forty minutes later, production started returning errors I didn’t recognize. We rolled back in five minutes, cut a new release in twenty, and spent the rest of the afternoon explaining what happened.

What stuck with me afterwards wasn’t just the bug. It was the policy that let it through. The auto-merge rule said: all checks passed, so merge. It had no concept of “should we actually do this?”

We added a human review requirement for core-path PRs that same week. CI still runs. But CI now records evidence, it doesn’t grant approval. It can say “this change doesn’t break what we checked.” It can’t say “this change should happen.” It took one outage to learn that sentence.

Agent memory has the same failure mode, except the reviewer is missing entirely.

An MCP-connected fleet sharing a memory pool is an open-source repository where proposals are open, merges are closed, and the maintainers are asleep. Open source governance works precisely because write access is not the same as merge access. Linux accepts patches from anyone, but only maintainers merge. Most agent memory systems invert this: every agent gets write access per tool call, with no merge step between “propose this memory” and “store it as true.”

A transient agent can overwrite a persona memory that ten other agents depend on. It isn’t malicious. It’s ungoverned. CI was green, so it merged. The write succeeded, so it became true.

So we borrowed three mechanisms from repository governance.

We started with snapshots. Snapshotting felt safe because we could restore a whole state. But snapshots were too coarse. A single bad write in the middle of a busy hour meant either restoring over good writes or manually re-applying the good ones. We changed the design so memory state is derived from events, never mutated in place. Every write is an event: proposal_id, agent_id, key, value_hash, parent_hash. If a memory is wrong, rollback is one delta. You don’t repair the state, you rewind the log.

Without history, you can’t tell whether a write was intentional or accidental. Governance is impossible when nobody can tell the difference.

Then we wrote an ownership file, modeled on CODEOWNERS. It declares which agents or policy rules must approve writes to which namespaces:

ephemeral/*          write: any agent
shared/context/*     write: two independent reviewers
global/persona/*     write: owner quorum
Enter fullscreen mode Exit fullscreen mode

The enforcement lives at the MCP server layer, not in the prompt. We tried the prompt first. “Never overwrite global persona without confirmation.” It worked for about a week, until a context window got tight and an agent decided the confirmation was implicit. A prompt is a suggestion. The MCP server is where enforcement survives.

If the MCP server receives a write for shared/context/*, it counts approvals before the vector store ever sees the proposal. No approvals, no write. The CI result is still recorded. It’s just not accepted as a merge.

After that, we had to deal with contradictory memories. The default in most stores is last-write-wins, which turns recency into truth. We changed it so conflicting proposals are resolved by evidence in the same event log. If one memory is backed by three supporting observations and another is backed by one, the one waits until it collects more evidence. That’s a maintainer rejecting a commit because it breaks an existing API contract. Existing behavior has more evidence than a fresh idea.

The scenario you’ll recognize: Agent A writes an outdated schema into shared/context. Agent B reads it on the next MCP call and pushes that schema to a production connector. Agent A was not acting badly. It was acting ungoverned. In open source terms, we merged a commit without review.

We tried both extremes of the spectrum. Fully open memory is fast, but every agent inherits the worst-documented fact in the pool. Fully curated memory is a disaster in the other direction: real-time tool loops can’t wait for a human review board on every read, and agents sit idle at the moment they’re supposed to react. We ended up in the middle: namespace scoping, time-to-live, and credential-weighted permissions.

TTL matters because nothing teaches you the cost of stale memory like watching an agent over-explain a persona that was deprecated weeks ago. We put the retention window in runtime config. Someone tuned it to be “more conservative” and made it very long. Nobody noticed until an agent started citing an outdated memory as current. That was a governance failure, one level above the memory write itself. If you can’t tell who changed a retention policy, you have the same problem at the policy layer.

The honest costs are still there. The event log adds a write path to every memory update and consumes storage. The ownership file adds a review step, and reviewers can become a bottleneck if you scope too broadly. The conflict rule can reject a memory that is true but just hasn’t gathered enough evidence yet. We haven’t fully solved that. We accept the system will occasionally refuse a correct memory until more evidence arrives. That’s better than accepting a wrong memory immediately, but it is not free.

And the whole setup only works if enforcement stays in the MCP server. If someone can bypass the server and write directly to the vector store, all three mechanisms become decorative.

If this existed when we merged that routing PR, the merge would have waited for a human signature. The diff wouldn’t have changed. The tests would have stayed green. The only difference is the merge step would require proof that someone actually looked at the core path.

Your agents will not respect the philosophy. They will care about the protocol you install, and only if the protocol rejects their writes when they violate it. Install the event log. Write the ownership file. Move enforcement to the MCP server.

And add one line to your auto-merge rules: core paths require a human signature.

A green run can stay green. It just doesn’t sign.

maref #ai #opensource #machinelearning

Top comments (0)