AI agents
Read as MarkdownMemory provenance and quarantine
Give every memory item a stable identity, record a reviewed trust label for it, and see everywhere it flowed before and after that decision.
An agent with cross-turn memory can carry a bad fact from one conversation into every conversation after it. Answering “did this poisoned memory item spread, and to where” needs three things: a stable identity for the item, a place to record a human’s judgement about it, and a read that joins the two. This page covers the concept; the API reference carries the exact requests and fields.
What a memory item identity is
When your instrumentation declares which item a memory operation touched — gen_ai.data_source.id
for the store plus a declared item id — Anectico derives a stable item_key from your declared id
together with your organization, project and store. The id you declared is never stored or returned;
only the derived key is. That derivation is what makes the same item recognizable across two
conversations that never otherwise touch: two sessions that each declare the same item id in the
same store resolve to the same item_key, regardless of when either one ran.
A memory operation whose producer declares no item id — a framework’s bare search_memory call —
still counts as a memory operation, but carries no item identity. That absence means “the item half
is not instrumented,” never “no memory was read.” Declaring anectico.memory.item.id,
gen_ai.data_source.id, anectico.memory.item.provenance and anectico.memory.trust_label on your
memory spans is what fills it in.
No memory item content is stored anywhere. The identity is a hash, not the item’s bytes, and
item_provenance — the pointer to where the item came from — is bounded to a trace id, a
trace/span pair, or a sha256: digest. A free-form value in that field is refused rather than
kept.
Two labels, never folded together
A memory row can carry two different trust labels, and they answer two different questions:
declared_trust_labelis what your own instrumentation asserted about the item at write time, if anything —trusted,suspectorquarantined.trust_labelis what Anectico’s reviewed label said was in force at that row’s instant — the outcome of the labelling workflow below.
These are never merged into one value. If a poisoned item could relabel itself by asserting
trusted on its own telemetry, the review workflow would be worthless. Reported alongside
trust_label are trust_label_revision (which recorded judgement applied — zero means nobody had
judged the item yet) and trust_label_in_force_since (when that judgement was recorded).
Labelling an item
Any project member with agents:write can record a judgement about one item: trusted, suspect
or quarantined, with a required reason. You do not say who is labelling or when — both are taken
from your credential and the server clock, so the audit trail cannot be misattributed. A machine
credential that carries no user or key identity cannot label an item, and neither can any request
made on the platform’s own behalf: this is a decision a person makes.
Every label is a new, append-only revision — relabelling never overwrites the previous judgement. That is what lets you ask “who trusted this item an hour before the incident, and why” after the fact, which an in-place update would have destroyed. Reading an item’s current label is a separate, explicit question from reading its full history, and an item nobody has ever labelled answers as “not found” rather than as an empty label — “nobody has looked at this” and “somebody looked and said nothing” are different facts.
You can label an item before it has ever been observed. Containment often runs ahead of the next session: a reviewer who learns an item id is compromised can quarantine it immediately, so that when that item is next read, the flow already carries the judgement.
The review signal a quarantine opens
Labelling an item quarantined opens exactly one review signal, of kind poisoned_memory_item,
naming the item as its subject. A second quarantined judgement refreshes that same signal rather
than opening a duplicate. Labelling the item trusted again resolves it. Downgrading to suspect
neither opens nor resolves a signal — a downgrade from quarantine is an unfinished review, and
closing the queue entry would remove it from the surface a reviewer uses to finish that review.
You can watch this queue directly, or point an alert rule’s review_signals source at it to route
openings and clearings to a notification or escalation channel — see
See every agent that is running for the shared
review-signal queue this shows up in, and
Revoke an agent’s access for the separate two-person quarantine
flow that stops a credential, which a memory-item label does not touch.
A label is a judgement; it contains nothing by itself. Anectico does not scan memory for poisoning on its own, and labelling an item does not stop your agent from reading its own store or revoke any credential. The label is the record that something is now known to be bad — acting on that knowledge, inside your own memory store, is yours to do.
Where an item went, and under which label
Once an item has an identity, its complete observed flow is answerable: every place it was written
or read, oldest first, each carrying the reviewed label that was in force at that exact moment —
not the item’s label today. An item read while it was still trusted, and quarantined an hour later,
reports trusted on that earlier read and quarantined on everything after the decision. That
distinction is the entire point: it tells you which conversations carried the item before anybody
knew it was compromised, which is the question a poisoning incident actually needs answered.
The same read reports how many distinct sessions the item reached. One means it never left the session it was written in; two or more is cross-session propagation — an item that flowed from one conversation into another. If it flowed into a session that ran after the item was quarantined, that crossing happened under a stale trust label carried by whatever process read it, and is a fact worth investigating on its own.
An item that was never observed and never labelled answers as not found. An item you labelled before it was ever observed returns that label with no flow — that is the containment-runs-ahead case above, not an error.
Scopes
Reading a label, a label’s history, or an item’s propagation takes agents:read. Recording a label
takes agents:write. There is no separate memory-labelling scope: labelling an item is a governance
decision about an agent-observability subject, the same category of decision asset ownership and
review already require, so it uses the same pair rather than adding a third vocabulary to track. See
Scope recipes for agent jobs for the minimum scope set for a job that
includes memory review, and How agent access is enforced for what
these two scopes do and do not grant elsewhere.
What this does not do yet
Memory item content — the actual bytes a memory operation wrote or returned — is not part of the event contract and is never stored or returned by any endpoint, so there is nothing here that exposes what an item actually said. Labelling and propagation both operate on the item’s identity and its observed flow, never its content. There is also no automatic poisoning detector: every label is a human’s own recorded judgement, and nothing scans your memory store to produce one for you.