Inspiration

AI agents are getting better at remembering.

That sounds entirely positive until the memory is wrong.

Most agent memory systems are optimized around two questions: “What should I remember?” and “What should I retrieve?” We became interested in a much harder question:

What happens after an agent remembers something it should never have trusted?

Imagine an autonomous finance agent reads a compromised vendor-policy document. The document contains a malicious instruction disguised as legitimate company policy. The agent stores a derived memory from it. Later, another agent retrieves that memory, makes a decision from it, performs an action, and potentially creates more memories based on the result.

At that point, deleting the original document is not enough.

The problem has already propagated.

The poisoned information may now exist as:

  • an extracted fact,
  • a summarized memory,
  • a vector retrieval result,
  • an agent decision,
  • an executed action,
  • a derived memory created by another agent,
  • or a dependency several steps removed from the original source.

Traditional deletion answers:

“Can we remove this record?”

ANTIDOTE asks:

“Can we remove its influence?”

That became the central idea behind the project:

Revoking a memory should revoke its consequences.

We call this causal recovery for poisoned AI memory.

ANTIDOTE is inspired by concepts that already exist in mature infrastructure systems. Data lineage, dependency graphs, transaction logs, invalidation, rollback, revocation, and incident response but applies them to a new problem: autonomous systems whose decisions are increasingly shaped by persistent memory.

As agent systems become more autonomous and increasingly share information with other agents, we believe memory security needs to become more than filtering malicious prompts at ingestion time.

Agents need to know not only what they remember, but:

  • where that memory came from,
  • what used it,
  • what decision it influenced,
  • what action resulted,
  • what downstream memories inherited its assumptions,
  • and what needs to happen if that memory is later determined to be unsafe.

That is the problem ANTIDOTE was built to explore.

What it does

ANTIDOTE is a causal memory security and recovery layer for AI agents.

Its purpose is to track how information moves from an external source into agent memory and then through downstream decisions and actions.

Instead of treating memories as isolated vector records, ANTIDOTE models them as nodes in a causal system.

A simplified lineage can look like this:

Source → Memory → Retrieval → Decision → Action → Derived Memory

Every important step records where its information came from and what depended on it.

That gives ANTIDOTE two capabilities that conventional memory systems usually do not provide:

Blast-radius analysis Causal revocation and repair The poisoning scenario

Our primary demonstration begins with a compromised document:

vendor-policy.pdf

The document contains malicious information that appears legitimate enough for an AI agent to trust.

That source produces a poisoned memory.

The memory is then retrieved during a later workflow and influences a payment-related decision involving Zenith Systems.

The important part of the demonstration is that the infection does not stop at retrieval.

The poisoned source can influence:

malicious source ↓ poisoned memory ↓ retrieval ↓ agent decision ↓ action ↓ derived memory ↓ future agent behavior

That is where ANTIDOTE becomes useful.

1. Causal lineage

ANTIDOTE records the dependency chain behind agent behavior.

Instead of seeing only:

“The agent approved this.”

we can investigate:

“Which retrieved memory contributed to this decision?”

and then:

“Where did that memory originate?”

and then:

“What else has depended on the same source?”

This creates an inspectable lineage between external evidence and autonomous behavior.

The goal is to make agent memory less of a black box.

2. Poison detection and quarantine

When a source or memory is identified as compromised, ANTIDOTE can mark it as unsafe and quarantine it from future use.

However, quarantine alone is deliberately not considered sufficient.

By the time an unsafe memory is discovered, another agent may already have:

retrieved it, trusted it, created a decision from it, performed an action, or created additional memories from the result.

That is why ANTIDOTE moves from simple quarantine into causal recovery.

3. Blast-radius simulation

Before repair, ANTIDOTE can traverse the causal lineage and determine what depends on the poisoned memory.

This is the blast radius.

For example, rather than simply saying:

“Memory M42 is compromised.”

ANTIDOTE can determine that M42 influenced:

retrieval R17, decision D8, action A4, derived memory M61, and another downstream decision that later consumed M61.

That difference matters.

A compromised record is an isolated database problem.

A compromised record with descendants is a systems problem.

ANTIDOTE is built for the second case.

4. Revocation propagation

Once a poisoned source is confirmed, ANTIDOTE walks its dependency graph.

Dependent memories can be invalidated.

Pending actions can be cancelled where possible.

Affected decisions can be marked for re-evaluation.

Derived memories can be quarantined.

Agents attempting to retrieve invalidated information can be prevented from treating it as trusted context.

The goal is not merely:

delete the bad memory.

The goal is:

stop the bad memory from continuing to cause decisions.

5. Repair and re-evaluation

After revocation, ANTIDOTE can trigger a repair workflow.

Affected reasoning paths are re-evaluated without the poisoned dependency.

This allows an agent to obtain fresh context rather than simply losing a memory and continuing blindly.

That distinction is important.

Revocation answers:

“What can no longer be trusted?”

Repair answers:

“What should happen now that we know that?”

6. Cross-agent propagation

ANTIDOTE is designed around the reality that autonomous systems increasingly contain more than one agent.

One agent may ingest information.

Another may retrieve it.

Another may execute an action.

Another may summarize the outcome into persistent memory.

Because ANTIDOTE tracks lineage rather than merely ownership, it can follow a poisoned dependency even after it crosses agent boundaries.

This is one of the core ideas behind the system:

Trust should follow causality, not just storage location.

7. Paraphrased attack resistance

Another problem we wanted to address is that poisoned information does not necessarily survive in an identical textual form.

An agent might transform:

“Zenith Systems payments should bypass X verification.”

into a memory such as:

“Zenith is an approved exception to the normal verification workflow.”

A simple exact-match deletion system could miss the second representation.

ANTIDOTE therefore combines structured causal lineage with semantic memory retrieval.

The system is concerned with both:

what a memory says, and what that memory descends from.

That makes it possible to catch downstream influence even when the wording changes.

8. Inspectable evidence

We did not want the output of ANTIDOTE to simply be another model saying:

“I think this memory was poisoned.”

Important events have inspectable evidence.

The system can expose:

  • the original source,
  • created memory,
  • lineage edges,
  • retrieval events,
  • decisions,
  • downstream dependencies,
  • quarantine status,
  • revocation events,
  • repair attempts,
  • and the resulting clean behavior.

The final proof in our demo is not merely that ANTIDOTE displays a “repaired” badge.

The proof is that after revocation and repair, a fresh agent execution no longer performs the behavior that depended on the poisoned memory.

That closes the causal loop.

How we built it

ANTIDOTE is built around a relatively simple architectural principle:

memory content and memory causality need to live together.

A vector database can tell us that two memories are semantically similar.

A normal relational database can tell us that two records reference each other.

ANTIDOTE needs both.

That made CockroachDB central to the architecture.

CockroachDB as the causal memory substrate

We use CockroachDB to store structured state describing the agent memory system.

Rather than storing only a text blob and embedding, the data model represents entities such as:

  • sources,
  • memories,
  • retrieval events,
  • decisions,
  • actions,
  • derived memories,
  • lineage relationships,
  • revocations,
  • quarantine states,
  • and repair operations.

Each important agent event therefore has both content and provenance.

A memory can retain references to:

  • the source that created it,
  • the process that derived it,
  • the retrieval events that later consumed it,
  • and downstream artifacts that depended on it.

That enables graph-like causal traversal while retaining transactional guarantees.

Semantic memory

ANTIDOTE also uses CockroachDB vector capabilities for semantic retrieval.

Memory embeddings are represented using a VECTOR(1536) representation.

This allows the system to perform semantic searches when agents need relevant context while keeping the memory records close to their structured provenance.

Distributed Vector Indexing provides the retrieval layer needed to search a growing memory set efficiently.

This matters to the architecture because we did not want:

the vector store knows what the memory means, while another unrelated system knows where it came from.

The two are part of the same security problem.

Why transactions matter

Repairing a poisoned memory is not just a search operation.

Several pieces of state may need to change together.

For example:

mark the original source compromised, revoke a memory, invalidate descendants, record why the revocation happened, queue affected decisions for re-evaluation, and record a repair operation.

Those transitions need predictable state semantics.

CockroachDB transactions give ANTIDOTE a foundation for making these updates atomically rather than allowing the system to enter inconsistent intermediate states.

Causal lineage model

The key abstraction in ANTIDOTE is a lineage edge.

Conceptually, the graph looks like:

Source → produced Memory

Memory → retrieved_by Retrieval

Retrieval → influenced Decision

Decision → caused Action

Action → produced Derived Memory

This makes it possible to traverse in both directions.

Forward traversal answers:

What did this poisoned memory eventually affect?

Backward traversal answers:

Why did this agent make this decision?

Both are necessary for debugging autonomous systems.

Agent layer

We designed the agent workflows around Amazon Bedrock.

Agents retrieve persistent context through the ANTIDOTE memory layer rather than receiving arbitrary untracked memory objects.

When memory is retrieved, the retrieval itself becomes part of the causal record.

This is important because merely storing provenance at ingestion time is not enough.

We also need to know when a memory actually influenced reasoning.

Repair jobs

Repair operations are handled through worker-style jobs using AWS Lambda.

When a memory is revoked, the repair process can:

  1. discover dependent nodes,
  2. mark affected memory as invalid,
  3. quarantine unsafe descendants,
  4. determine which decisions require re-evaluation,
  5. launch a fresh evaluation path,
  6. persist the repair result.

Separating the repair process from the interactive request path also prevents a potentially large dependency traversal from blocking normal agent execution.

Immutable evidence

We use Amazon S3 as an evidence layer for artifacts that should remain inspectable independently of mutable agent memory.

Examples include:

original source documents, evidence snapshots, attack artifacts, repair outputs, and audit material.

The database can maintain the structured lineage while immutable artifacts provide supporting evidence for what actually happened.

MCP interface

ANTIDOTE is also designed around a Managed MCP interface so agent clients can interact with the memory and recovery layer through tools rather than being tightly coupled to ANTIDOTE's internal database implementation.

The broader goal is to make operations such as:

storing memory, retrieving context, inspecting provenance, reporting compromise, querying blast radius, and triggering revocation

available through a common agent-facing interface.

This makes ANTIDOTE more naturally usable as infrastructure rather than requiring every agent application to reimplement causal-memory logic itself.

The end-to-end demo loop

We deliberately designed the demo around one complete causal loop.

It begins with:

real input: a compromised vendor-policy.pdf

Then:

memory creation: the document produces a persistent memory.

Then:

agent behavior: another workflow retrieves that memory.

Then:

consequence: the poisoned memory influences the Zenith Systems payment scenario.

Then:

detection: the source is identified as compromised.

Then:

blast-radius analysis: ANTIDOTE discovers descendants of the poisoned memory.

Then:

revocation: unsafe nodes are invalidated or quarantined.

Then:

repair: affected reasoning is re-evaluated without the poisoned dependency.

Finally:

proof: a fresh agent no longer accepts or acts on the compromised assumption.

We considered that final step essential.

Without it, ANTIDOTE would only demonstrate observability.

With it, ANTIDOTE demonstrates recovery.

Challenges we ran into

1. Defining what “delete a memory” actually means

The hardest conceptual problem appeared almost immediately.

Deleting a database row is easy.

Deleting influence is much harder.

If memory A causes decision B, which creates action C, which creates memory D, then removing A does not automatically make B, C, and D safe.

We therefore had to move away from a CRUD view of memory and treat memory as part of a dependency system.

That changed the entire architecture.

2. Separating correlation from causality

Semantic similarity is useful, but similarity alone does not prove that one memory caused another action.

Two memories may discuss the same company without having any causal relationship.

So ANTIDOTE could not simply build a graph from embedding similarity.

We needed explicit lineage events.

When a memory is retrieved, that retrieval must be recorded.

When retrieved context contributes to a decision, the relationship must be represented.

When a decision produces an action or derived memory, that relationship must also be preserved.

Embeddings help us discover related content.

Lineage tells us what actually depended on what.

3. Handling transformed memories

Agents rarely preserve text verbatim.

They summarize.

They paraphrase.

They combine several pieces of context.

They produce conclusions.

This creates an uncomfortable problem for revocation: a poisoned idea may survive even when the original wording has disappeared.

Our response was to make provenance persistent across transformations.

The derived memory does not need to contain the same sentence as its parent.

If its creation depended on that parent, the lineage remains.

4. Preventing revocation from becoming another unsafe operation

Revocation itself changes system state.

A careless implementation could leave some descendants active while others are revoked, or trigger repair before all affected dependencies have been identified.

That made database consistency and transactional operations important rather than incidental implementation details.

5. Determining the blast radius without revoking unrelated information

Over-revocation is also dangerous.

If one poisoned memory mentions “Zenith Systems,” ANTIDOTE should not automatically invalidate every memory mentioning Zenith Systems.

That would make recovery unusably destructive.

We therefore had to distinguish between:

semantic relationships

and:

causal dependencies.

The blast radius should follow actual dependency edges first.

Semantic search can assist investigation, but it should not become indiscriminate deletion.

6. Making the demo understandable

Causal memory infrastructure is inherently abstract.

A demo consisting of database tables, embeddings, and graph edges would technically show the system but would be difficult to understand quickly.

We therefore structured the demonstration as a story:

trusted-looking document → poisoned memory → propagated consequence → investigation → revocation → repaired behavior

That gives every infrastructure component a visible reason to exist.

7. Proving recovery instead of simply claiming it

Another challenge was defining what successful repair actually means.

A green “REPAIRED” status is not enough.

The system needs behavioral evidence.

That led us to make the final fresh-agent execution part of the core demonstration.

If the clean agent still performs the poisoned action, recovery failed.

If the agent refuses the compromised assumption after causal revocation, we have actual evidence that the poison's influence was removed from that path.

8. Keeping the scope under control

The general problem is enormous.

Memory poisoning connects to:

  • prompt injection,
  • access control,
  • trust scoring,
  • multi-agent security,
  • knowledge graphs,
  • observability,
  • policy engines,
  • rollback,
  • data provenance,
  • model evaluation,
  • and incident response.

Trying to solve every one of those problems would have produced a broad but shallow project.

We deliberately compressed the scope around one hypothesis:

Can we identify the descendants of a poisoned memory and demonstrate that revoking it changes future agent behavior?

Everything else was secondary.

Accomplishments that we're proud of

1. Treating memory poisoning as a causal problem

The thing we are most proud of is the core abstraction.

ANTIDOTE does not stop at:

“This memory is malicious.”

It asks:

“What happened because this memory existed?”

That shift changes memory security from record filtering into systems recovery.

2. Building a complete attack-to-recovery story

The project demonstrates more than detection.

The flow covers:

malicious source → poisoned memory → retrieval → decision → consequence → blast-radius discovery → revocation → repair → clean re-execution

Completing that loop was more important to us than building a long list of disconnected features.

3. Making sponsor infrastructure causally necessary

CockroachDB is not included merely because the challenge involves CockroachDB.

The product needs:

  • structured causal state,
  • transactions,
  • semantic vector retrieval,
  • durable memory,
  • lineage traversal,
  • and consistent repair state.

Those requirements sit directly inside ANTIDOTE's central mechanism.

Removing that state layer would remove the ability to prove and repair causal memory propagation.

4. Combining semantic retrieval with explicit provenance

We are particularly proud of not treating vector similarity as provenance.

ANTIDOTE uses semantic retrieval for what embeddings are good at—finding relevant information—and explicit lineage for what embeddings cannot prove: dependency.

Those two mechanisms complement each other rather than being conflated.

5. Making the repair inspectable

Every major claim has an artifact behind it.

The system is designed so an investigator can inspect:

  • the bad source,
  • poisoned memory,
  • dependency chain,
  • affected descendants,
  • revocation state,
  • repair operation,
  • and clean post-repair behavior.

That is important because agent security should not rely on another opaque model simply telling us everything is fine.

6. Designing for multi-agent systems from the beginning

We did not assume one isolated chatbot with one memory store.

ANTIDOTE's model allows influence to cross boundaries between ingestion agents, decision agents, execution agents, and agents that create new memories.

That better reflects the direction autonomous software is moving.

7. Building a concept that extends beyond one attack

Although our demo intentionally focuses on one clear poisoning scenario, the underlying causal model can represent many other cases:

  • stale operational knowledge,
  • revoked permissions,
  • compromised customer information,
  • incorrect financial assumptions,
  • unsafe procedural instructions,
  • superseded policies,
  • poisoned research,
  • or information later proven false.

The same fundamental question applies:

What downstream behavior depended on this information?

What we learned

1. Agent memory is not just storage

The biggest lesson was that persistent memory changes the security model of an AI system.

A malicious prompt inside a single conversation may disappear when the conversation ends.

A malicious instruction stored as persistent memory can survive.

It can be retrieved tomorrow.

It can be summarized.

It can be shared.

It can affect other agents.

It can produce actions.

Persistence turns a single poisoning event into a potential long-lived dependency.

2. Provenance needs to survive transformation

Recording the source of the first memory is not enough.

Provenance needs to propagate.

When an agent derives memory B from memories A1, A2, and A3, those relationships need to remain represented even if B contains none of the original wording.

Otherwise, lineage disappears exactly when the system becomes more complex.

3. Vector search and causality solve different problems

This became one of the clearest technical lessons from the project.

Vector search answers:

“What is related?”

Causal lineage answers:

“What depended on this?”

Those questions are both useful, but they cannot safely substitute for one another.

4. Recovery is harder than prevention

Blocking unsafe information before it enters memory is obviously desirable.

But no prevention system will be perfect.

Once something slips through, the difficult question becomes how to recover from it safely.

That is why we believe agent memory systems eventually need incident-response primitives comparable to those used in other critical infrastructure.

5. Autonomous actions make provenance much more important

Wrong information becomes more dangerous as agents gain permission to do things.

If an agent only writes a paragraph, a poisoned memory may produce incorrect text.

If an agent can:

  • transfer money,
  • update records,
  • provision infrastructure,
  • contact customers,
  • change permissions,
  • or invoke other autonomous agents,

then the same memory problem becomes operational.

The more agency we give models, the more important it becomes to explain where their trusted context came from.

6. “Delete” and “revoke” are fundamentally different concepts

Deletion removes an object.

Revocation changes the trust status of an object and its consequences.

That distinction ended up becoming fundamental to ANTIDOTE.

Sometimes an unsafe artifact should actually remain available for audit purposes while becoming unusable as trusted agent context.

Keeping evidence while revoking authority is more useful than pretending the event never happened.

7. Good demos need falsifiable success conditions

We also learned a lot from narrowing the demonstration.

“ANTIDOTE secures agent memory” is too vague to prove.

This is much better:

Poison an agent memory, demonstrate that another decision depends on it, revoke the original memory, repair the dependency chain, and verify that a fresh agent no longer takes the poisoned action.

That can fail.

And because it can fail, success actually means something.

What's next for Antidote

The current ANTIDOTE build proves the central idea:

AI memory can be treated as a causal dependency system, and poisoned influence can be traced and revoked.

The next phase is turning that proof into infrastructure that developers can put between production agents and their persistent memory systems.

1. General-purpose ANTIDOTE SDK

The immediate next step is to extract the causal-memory primitives into a developer-facing SDK.

Instead of requiring applications to understand ANTIDOTE's internal schema directly, developers should be able to do things like:

remember()

retrieve()

derive()

recordDecision()

recordAction()

revoke()

blastRadius()

repair()

while ANTIDOTE handles lineage automatically.

The long-term goal is that developers should not need to manually construct provenance graphs.

The infrastructure should capture them as a natural consequence of using the memory layer.

2. MCP server

We also want ANTIDOTE to become directly callable by agent frameworks through MCP.

An ANTIDOTE MCP server could expose tools such as:

  • store_memory
  • retrieve_memory
  • inspect_lineage
  • report_poisoned_source
  • calculate_blast_radius
  • quarantine_memory
  • revoke_memory
  • repair_dependencies
  • verify_recovery

That would allow Codex, Claude, custom Bedrock agents, and other MCP-compatible systems to use causal memory protection without bespoke integrations.

3. Automated lineage capture

The current concept makes lineage explicit.

The next challenge is reducing how much instrumentation developers have to write.

We want to automatically capture relationships such as:

retrieval → model invocation → decision → tool call → resulting memory

through framework adapters and middleware.

This would make ANTIDOTE substantially easier to adopt.

4. Stronger multi-agent propagation controls

Cross-agent memory propagation deserves its own security model.

Future work includes carrying provenance and trust metadata when one agent hands information to another.

A receiving agent should be able to determine:

  • who produced this memory,
  • which sources it depends on,
  • whether any ancestor has been revoked,
  • when it was last validated,
  • and what trust policy applies.

That gives agent-to-agent memory something closer to a chain of custody.

5. Memory leases and expiration

Not every memory should remain trusted forever.

We want to explore memory leases:

a memory remains valid only until:

  • a time limit expires,
  • its source changes,
  • a policy version changes,
  • an external fact must be revalidated,
  • or one of its dependencies becomes stale.

That would let ANTIDOTE address stale memory as well as actively malicious memory.

6. Policy-aware retrieval

Another planned layer is retrieval policy.

A memory could be semantically relevant but still inappropriate for a particular action.

For example, a low-confidence web-derived memory might be acceptable for research but prohibited from authorizing a financial transaction.

ANTIDOTE could attach policies to memory classes and enforce them during retrieval.

7. Cryptographic provenance

For high-trust environments, we want stronger guarantees around evidence.

Future versions could cryptographically bind:

  • source hashes,
  • memory versions,
  • lineage events,
  • revocations,
  • and repair results.

That would make provenance harder to silently rewrite after an incident.

8. Better incident-response tooling

ANTIDOTE should eventually provide an incident view specifically designed for investigating agent memory failures.

Instead of digging through model logs manually, an operator should be able to select one suspicious action and walk backward:

Action ← Decision ← Retrieved Memory ← Derived Memory ← Original Source

From there, they should be able to see every downstream dependency and initiate recovery.

9. Evaluation and attack suite

We also want to build a dedicated poisoning evaluation suite.

It would test attacks such as:

  • direct malicious memory insertion,
  • poisoned documents,
  • paraphrased payloads,
  • multi-hop poisoning,
  • cross-agent propagation,
  • stale policy poisoning,
  • contradictory memories,
  • compromised trusted sources,
  • and delayed-trigger instructions.

The purpose would not only be to test detection.

It would test whether ANTIDOTE can successfully recover after each attack.

10. Production-grade repair semantics

Some consequences cannot simply be rolled back.

If an agent sends an email, makes a payment, or performs an external action, the world has changed.

Future ANTIDOTE versions therefore need to distinguish:

  • reversible actions,
  • cancellable actions,
  • compensatable actions,
  • irreversible actions.

Repair may sometimes mean rollback.

Sometimes it may mean cancellation.

Sometimes it may require a compensating transaction.

Sometimes the only safe response may be escalation to a human.

Encoding those distinctions is an important next step.

11. Broader memory-system integrations

We ultimately want ANTIDOTE to work independently of a single agent stack.

The causal model should be able to sit alongside different:

  • model providers,
  • vector systems,
  • agent frameworks,
  • MCP clients,
  • orchestration frameworks,
  • and storage architectures.

CockroachDB would remain the durable causal state layer while adapters translate different agent environments into a common lineage model.

12. The larger vision

The long-term vision is for ANTIDOTE to become something like incident response infrastructure for agent cognition.

Today we have mature tools for answering questions such as:

  • Which service caused this outage?
  • Which deployment introduced this regression?
  • Which database row was changed?
  • Which package introduced this vulnerability?

As autonomous agents become responsible for real operations, we believe we will need equivalent answers for:

  • Why did this agent believe this?
  • Where did that belief come from?
  • Which other agents inherited it?
  • What actions did it cause?
  • Has that information been revoked?
  • Have its descendants been repaired?
  • Can we prove the system no longer acts on it?

That is the direction we want to take ANTIDOTE.

The project started with one poisoned memory.

The bigger idea is a trust and recovery layer for systems that increasingly remember, decide, and act on their own.

Built With

Share this project:

Updates

Submission history