BACK TO ARTICLES

Agent Memory Governance for Engineering Teams

Once agents write to shared memory, one wrong fact becomes something every agent repeats. Six controls decide whether you catch it: what gets written, where it came from, who can read it, how you correct it, which version wins, and what gets deleted.

Dosu
/
Sep 25, 2026/13 min read

Most writing about agent memory is about getting agents to remember more. This one is about the part that starts mattering the day they do. A coding agent records that the payments service still uses a deprecated auth helper, which was true in March. Every agent on the team now retrieves it, repeats it in generated code, and carries it into summaries that cite nothing. Nobody wrote it, so nobody owns it, and there is no obvious place to go and fix it.

The failure has nothing to do with model quality. What is missing is a control plane. Memory that is automatic and shared needs answers to six questions: what is allowed to be written, what evidence has to come with it, who can read it, how a wrong entry gets found and corrected, which entry wins when two disagree, and what eventually gets removed. Teams usually adopt the memory layer first and answer these afterward, one incident at a time.

Poisoning is the rare case, drift is the one you will hit

Agent memory poisoning is the adversarial version: untrusted input gets a false fact written into persistent memory, where it keeps influencing sessions long after the input is gone. A malicious issue comment or a planted document tells an agent that a fabricated internal package is the approved HTTP client, and every future agent that retrieves it is working from an attacker's premise.

OWASP's LLM04:2025 Data and Model Poisoning defines the risk as occurring "when pre-training, fine-tuning, or embedding data is manipulated to introduce vulnerabilities, backdoors, or biases," which is the model supply chain. The runtime case has its own entry. OWASP's Top 10 for Agentic Applications lists ASI06 Memory & Context Poisoning, which covers any context an agent "retains, retrieves, or reuses," including shared memory that other agents pick up and long-term drift from subtly tainted data. Its recommended mitigations read like the controls below: source attribution, human review for high-risk actions, rollback, and expiring unverified memory. The AI Security Verification Standard adds a chapter on Memory, Embeddings, and Vector Database Security.

The failure you will hit far more often has no attacker in it. An agent captures a workaround as policy. It records a proposal from a pull request comment as a decision. It stores something that was true and stays confident about it for the eight months after it stopped being true. Ordinary drift and deliberate poisoning arrive through the same write path and produce the same behavior, which is convenient: the controls that catch one catch the other.

What persistence changes is reach. A bad answer in one session ends with the session. A bad memory is retrieved by people who never saw the original input, gets folded into new summaries, and starts looking established through repetition alone.

Decide what is allowed to become memory

The useful axes are confidence and blast radius. Low confidence means the source does not clearly support the claim. High blast radius means a wrong entry would steer a lot of future work. Either one should send a proposed write to a person. Both together should stop it cold.

Inference dressed as observation is the common low-confidence case. Someone floats moving a service to DynamoDB, the thread ends without a decision, and the agent writes down that the service is moving to DynamoDB. The fact is not wrong so much as promoted: a suggestion has quietly become a decision. A reviewer either narrows it to what the thread established or drops it.

High blast radius deserves review even when the agent is confident, because confidence is not the thing at risk. Architecture decisions, security requirements, deployment steps, and anything an agent will treat as a coding rule all get read many times before anyone checks them. So does anything extracted from an issue, an external doc, or user-submitted content, which is where a planted instruction would enter.

Everything else is fine to capture automatically, as long as it is logged. A renamed command, a test directory recorded from a merged PR, a formatting rule the repo enforces: cheap to verify, cheap to fix, not worth a person's attention.

The mistake is making review universal, which converts your memory layer into the documentation backlog you were trying to escape. Route the exceptions to a queue, log the rest, and treat a pattern of rejections as a signal to change the capture rule rather than to add more reviewers.

An unsourced memory cannot be reviewed

A memory entry should carry the specific evidence behind it. Not "Slack" or "GitHub" but the commit, the pull request, the thread, or the document version. For sources that change under you, the link needs to pin a revision, or the evidence you review today is not the evidence that was there when the fact was written.

Provenance also has to record what kind of claim this is. Observed, proposed, and decided are three different things, and a memory layer that flattens them is exactly how a comment suggesting Redis becomes a durable belief that the service uses Redis. The record should be able to say that a proposal existed, that a later decision went the other way, and which one currently governs.

Provenance makes every later control possible. When an agent surfaces something wrong, provenance tells you whether the source was misread, whether it was right and has since been superseded, or whether it was never authoritative. Without it you cannot tell those apart, which means you cannot fix the entry with any confidence that you have fixed the cause.

Permissions have to survive the trip into memory

Ingesting private repos, restricted channels, and internal tickets into one index is a storage decision, not yet a leak. What decides whether restricted content reaches an answer is whether something filters the candidates against the requester's access before the model sees them. Where that filter is missing, the pool answers everyone the same way. Whether it runs, and whether a summary inherits the permissions of every source it was built from, is under-documented across this whole category. Treat it as a claim to test rather than a feature to assume.

Two tests are worth running in any trial. Create a user with no access to a restricted source and ask their agent about facts that exist only there, indirectly as well as directly, because a summary can leak what a quote would not. Then take a user who does have access, let the system ingest the content, revoke their access, wait out the vendor's stated sync window, and ask again. Ingestion-time checks alone do not survive that second test.

Ask where enforcement runs, too. A filter applied when content is indexed answers a different question than one applied per request against the identity asking, and only the second keeps up as people join teams and leave them.

Find the wrong fact, fix it, then prove the fix landed

Audit through the same path your agents use. An admin console listing what is stored tells you what exists. It does not tell you what comes back after ranking and filtering, which is the only thing that affects an agent.

Correction needs more than one verb. Editing fixes a detail. Invalidating stops an entry from being retrieved while keeping the record for later investigation. Hard deletion removes it, which you want for a legal deletion request or a leaked secret and do not want as your default, because it destroys the trail that explains how the entry got there.

Then confirm the correction took. Writes can be asynchronous, caches exist, and an open session may be holding the old context. Re-run the query in a fresh session through the interface your agents use. The full loop is the single most useful thing to make a vendor demonstrate live, Dosu included: seed a wrong fact with a known source, then find it, fix it, and show it gone from the next query.

Newer is not the same as correct

Recency is a relevance signal, and teams often promote it into an authority rule without noticing. An old design doc imported this morning is newer by ingestion time than the pull request that overturned it last year. An issue that restates a decision everyone abandoned is recent and wrong.

The alternative is explicit supersession. When something replaces an earlier decision, the new entry links to the old one and marks it superseded for current queries, while the old entry stays readable for anyone asking what the team used to do and why they changed. That keeps "this is newer" and "this is now correct" as two separate signals, which is what they are.

Test it with two sourced facts that disagree. Ask which one governs now and make the system show its reasoning and its sources. Then ask the historical question and check that the superseded entry is still reachable.

Decide what memory forgets

Two different problems get filed under deletion.

An employee leaving is an ownership question. Their access should end immediately. The architectural decisions they captured usually belong to the team, so the policy question is whether that knowledge is reassigned, left in place, or flagged for review because the person who could confirm it is gone.

A deletion request is a compliance question, and the hard part is derived knowledge. Removing a ticket does not remove the facts an agent extracted earlier and folded into a summary somewhere else. Test the two separately: put a distinctive string in a document, let it be captured, delete the document, then go looking for the string in memory. Ask whether deletion reaches indexes, summaries, backups, and audit records, and ask who can verify it completed. Apply that to every vendor, Dosu included.

When a reviewed markdown file is still the right answer

For a small team, a markdown file in the repo covers most of this. Git blame is provenance. Pull request approval is write review. Repository permissions are access control. History is the audit log. A reviewed file is a legitimate governance model, and it is free, so a team of six with one repo should not be buying infrastructure to replace it.

The file breaks down on maintenance rather than on headcount. The threshold is the point where nobody reliably updates it, where writes arrive faster than anyone reviews them, or where the knowledge that matters lives across several repos and systems that one file cannot represent. Drift matters more in a file agents read every session, because agents read a wrong instruction with exactly the confidence they read a right one, which is why a stale AGENTS.md is worse than no AGENTS.md.

Before adding tooling, try tightening the cheap version. Give the file an owner, require a source link in the PR template, note supersession explicitly when a decision changes, and schedule a staleness review.

Where Dosu fits

Dosu maintains engineering knowledge for teams whose coding agents need shared context, and the part relevant here is that it is built around sourcing and review rather than around a raw write API.

Captured knowledge is grounded in the commits, pull requests, issues, and documentation it came from, so a reviewer can open the evidence before agreeing that something becomes durable team knowledge. Proposed Document changes go to Review, where a person can accept, edit, or decline each one. Teams that want less friction can turn on Auto-Accept Review so eligible changes publish automatically after a pull request merges. New Documents that Dosu proposes for an external documentation store still wait for review. Monitors flag Documents that no longer match their Sources, which is the drift case rather than the poisoning case.

On access, Library scoping controls what an agent can retrieve at all, because an agent retrieves only from the Libraries an administrator connected it to. Enterprise includes audit logs. Dosu is SOC 2 Type II compliant.

Where the line is: Dosu is infrastructure for engineering teams running coding agents, not a general-purpose memory API for building your own. If you are shipping a product that needs per-user personalization memory, Mem0, Zep, Letta, and Cognee are the right category. The article's advice applies to us too. Verify deletion of derived knowledge and contradiction handling against your requirements in a trial rather than assuming any vendor here has finished solving them.

Six controls and how to test each one

ControlThe question it answersHow to test it
Write reviewWhat is allowed to become durable without a person?Seed an ambiguous proposal and check whether it is stored as a decision
ProvenanceWhat evidence is this fact standing on?Pick any stored fact and try to open its exact source
AccessCan an agent surface what its user cannot read?Query as a user without access, then revoke access and query again
CorrectionCan you find a wrong entry, fix it, and confirm the fix?Seed a known error and run the full loop in a fresh session
SupersessionWhich entry wins when two disagree?Store two conflicting sourced facts and ask which governs now
RetentionWhat leaves, and does it take derived knowledge with it?Delete a source and search memory for a string unique to it

FAQ

What is agent memory poisoning?

It is when a false or malicious fact gets written into an agent's persistent memory and is then retrieved as trusted context in later sessions. The adversarial version comes from untrusted input such as a planted document or issue comment. The far more common version has no attacker and comes from an agent capturing something ambiguous, premature, or no longer true.

Should a human review everything an agent writes to memory?

No, and trying to is how teams end up back in the documentation backlog. Review the writes that are low confidence or high blast radius, meaning architecture, security, deployment, coding rules, and anything extracted from untrusted input. Let routine, cheap-to-correct facts capture automatically with an audit log.

How do you stop an agent from repeating outdated information?

Fix the entry, do not just add a newer one, because recency alone does not tell a retriever which fact is authoritative. Mark the old entry superseded and link it to what replaced it, then confirm in a fresh session that the correction is what comes back.

Does deleting the source document delete what the agent learned from it?

Not necessarily, and this is worth testing rather than assuming. Facts extracted before the deletion can persist in summaries and indexes that no longer point at the deleted source. Ask any vendor whether deletion cascades to derived knowledge, and verify it with a distinctive test string.

Run the drill before you need it

Pick a fact your agents currently repeat and try to answer three questions about it: what source is it standing on, who approved it becoming durable, and what would you do right now if it were wrong. Most teams find the first question has no answer, which makes the other two unanswerable.

If that is where you land, the missing piece is a knowledge layer that cites its sources and puts a review step between an agent's write and everyone else's context. Connect your first repo to Dosu and check what it proposes against the evidence it links before you accept any of it.

Ready to transform your workflow?

Join leading organizations using Dosu to automate documentation, streamline support, and empower development teams to focus on building great products.