AID-I-004.005: Memory TTL, Staleness Decay & Forced Forgetting
Pillars: app, data
Lifecycle: operation
Scope boundary
Owns policy-defined trust decay, revalidation, downgrade, retention, deletion, and forced forgetting for persistent memory records and their derived replicas, indexes, summaries, and caches. Missing cleanup evidence or an unreadable record population leaves the lifecycle action unresolved.
AID-I-004.001: AID-I-004.005 governs persistent-record TTL, staleness, revalidation, downgrade, and deletion; AID-I-004.001 governs volatile session-context TTL, size, resets, and tenant isolation. The same duration policy may inform both, but persistent deletion and volatile context expiry require separate populations and receipts.
AID-I-004.007: AID-I-004.005 removes or downgrades persistent records because of retention or staleness; AID-I-004.007 demotes secrets and privileged context when a live task changes phase. Phase transition is not the same event as persistent-record expiry, and one control's cleanup evidence does not satisfy the other.
Warning
Medium on Recall Quality & Personalization
Aggressive TTL and forgetting policies can reduce long-term personalization, task continuity, and retrieval hit rate. Tune retention windows by memory class rather than applying one global policy, and require explicit justification for exceptions that keep sensitive or high-impact memory beyond standard windows.
Implementation guidance
- AID-I-004.005-G001: Attach freshness metadata such as creation time, expiry time, last access time, last validation time, and trust tier to every persistent memory record.
- AID-I-004.005-G002: Automatically downgrade or quarantine trusted memory that exceeds TTL or staleness thresholds until it is re-validated by policy or human review.
- AID-I-004.005-G003: Apply forced forgetting policies for session-scoped, user-preference, or privacy-sensitive memory classes so they are deleted at session end or after defined retention windows.
- AID-I-004.005-G004: Propagate deletion and downgrade actions across derived artifacts such as embeddings, summaries, secondary indexes, caches, and replicas instead of deleting only the primary record.
AID-I-004.005-G001
Lifecycle metadata is controlled state
Do not let the model choose timestamps, trust tier, retention class, or policy identity. The controlled writer derives them from the database clock, verified tenant/namespace, the signature-verified retention policy, and any separately verified promotion receipt. No framework-wide TTL or staleness number is safe: store the exact policy ID, version, and digest that produced each deadline.
PostgreSQL schema
CREATE TYPE memory_trust_tier AS ENUM
('QUARANTINED', 'PROBATION', 'TRUSTED', 'STALE');
CREATE TYPE memory_lifecycle_state AS ENUM
('ACTIVE', 'RETIRING');
CREATE TABLE agent_memory (
tenant_id uuid NOT NULL,
namespace text NOT NULL,
memory_id uuid NOT NULL,
record_version bigint NOT NULL CHECK (record_version > 0),
lifecycle_state memory_lifecycle_state NOT NULL DEFAULT 'ACTIVE',
stale_since timestamptz,
content_ciphertext bytea NOT NULL,
content_sha256 bytea NOT NULL CHECK (octet_length(content_sha256) = 32),
created_at timestamptz NOT NULL,
expires_at timestamptz,
stale_after timestamptz,
last_accessed_at timestamptz,
last_validated_at timestamptz,
trust_tier memory_trust_tier NOT NULL,
retention_class text NOT NULL,
policy_id text NOT NULL,
policy_version bigint NOT NULL CHECK (policy_version > 0),
policy_sha256 bytea NOT NULL CHECK (octet_length(policy_sha256) = 32),
promotion_receipt_id text,
evidence_event_id uuid NOT NULL,
PRIMARY KEY (tenant_id, namespace, memory_id),
UNIQUE (evidence_event_id),
CHECK (expires_at IS NULL OR expires_at >= created_at),
CHECK (stale_after IS NULL OR stale_after >= created_at),
CHECK (
last_accessed_at IS NULL OR last_accessed_at >= created_at
),
CHECK (
last_validated_at IS NULL OR last_validated_at >= created_at
),
CHECK (stale_since IS NULL OR stale_since >= created_at),
CHECK (
(trust_tier = 'STALE') = (stale_since IS NOT NULL)
),
CHECK (
trust_tier <> 'TRUSTED' OR last_validated_at IS NOT NULL
)
);
CREATE INDEX agent_memory_lifecycle_due
ON agent_memory (tenant_id, namespace, stale_after, expires_at)
WHERE trust_tier IN ('TRUSTED', 'PROBATION');
Controlled-write transaction
- Authenticate the workload outside request JSON and resolve the exact tenant and namespace.
- Verify the signed policy envelope, issuer/audience/type, key status, monotonic version, applicability, and policy digest. Resolve
retention_class,expires_at, andstale_afterfrom that policy and the database timestamp. A policy may explicitly select no deadline; represent that as a policy decision, not an omitted field. - Hash the exact plaintext before the existing encryption boundary. Bind the hash, record version, lifecycle fields, trust tier, policy identity, and promotion receipt to one append-only evidence event.
- Insert the evidence event through a transactional outbox in the same database transaction as the record. If the evidence sink is separate, keep the record non-retrievable until the outbox receipt is reconciled; do not claim cross-store atomicity.
- On read, independently verify tenant/namespace, record version, content digest after decryption, policy binding, trust tier, and deadline before returning content. Update access metadata through the controlled store according to the signed observation policy.
Population verification
Run a replica-side conformance job over the complete in-scope population and preserve its snapshot identifier, row count, ordered population root, policy versions, and per-row result. Reject writes with missing/inverted timestamps, unknown retention class, unverified trust transition, wrong digest length, absent policy binding, or duplicate evidence ID. A null deadline is acceptable only when the bound signed policy explicitly selected it. Missing or unreadable rows are INSUFFICIENT_DATA, not PASS.
AID-I-004.005-G002
Downgrade, do not delete
This step owns the trust transition from TRUSTED/PROBATION to STALE and exclusion from retrieval. Forced deletion belongs to #3 and derivative propagation to #4. The controlled writer in #1 has already resolved each record's stale_after from signed namespace/retention policy. The sweep cadence, batch size, cutoff, and evidence retention are signed-policy values, not framework constants.
Exact scan and transition ledger
CREATE TABLE memory_decay_run (
run_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
source_snapshot_id text NOT NULL,
cutoff_at timestamptz NOT NULL,
policy_sha256 bytea NOT NULL CHECK (octet_length(policy_sha256) = 32),
eligible_count bigint NOT NULL CHECK (eligible_count >= 0),
eligible_population_sha256 bytea NOT NULL
CHECK (octet_length(eligible_population_sha256) = 32),
state text NOT NULL CHECK (
state IN ('OPEN', 'RUNNING', 'VERIFYING', 'PASS', 'FAIL', 'ERROR')
),
created_at timestamptz NOT NULL DEFAULT clock_timestamp()
);
CREATE TABLE memory_decay_item (
run_id uuid NOT NULL REFERENCES memory_decay_run(run_id),
namespace text NOT NULL,
memory_id uuid NOT NULL,
expected_record_version bigint NOT NULL,
prior_trust_tier memory_trust_tier NOT NULL,
stale_after timestamptz NOT NULL,
state text NOT NULL CHECK (
state IN (
'PENDING', 'DOWNGRADED', 'REVALIDATED_CONCURRENTLY',
'FAIL', 'ERROR'
)
),
transition_receipt_id text,
PRIMARY KEY (run_id, namespace, memory_id)
);
-- The production retrieval function must retain this trust allowlist.
SELECT *
FROM agent_memory
WHERE tenant_id = $1
AND namespace = $2
AND trust_tier IN ('TRUSTED', 'PROBATION')
AND (stale_after IS NULL OR stale_after > $3)
AND (expires_at IS NULL OR expires_at > $3);
Production workflow
- Verify the signed decay policy and derive tenant, namespace applicability, cutoff, database snapshot, and complete expected record population outside model control.
- At the recorded snapshot, enumerate every record with an eligible prior tier and
stale_after <= cutoff. Sort tenant/namespace/ID/version/tier/deadline, compute the ordered population root, and transactionally create the run plus all items. A page/batch may process the manifest later, but pagination must not redefine the population. - For each item, use one compare-and-swap update on tenant, namespace, ID, expected version, prior tier, and deadline. Set
trust_tier='STALE',stale_since=cutoff, incrementrecord_version, and create a transactional-outbox transition event. If the record was independently revalidated after the snapshot, verify the new signed revalidation/policy receipt and markREVALIDATED_CONCURRENTLY; otherwise a zero-row update is unresolved, not success. - Retrieval excludes STALE immediately. Re-promotion requires the separate validation/promotion control and a new version; the decay worker cannot promote.
- Reconcile the outbox with an externally credentialed append-only evidence sink. From a read-only replica, read every item/version, call the production retrieval path for each downgraded ID, and recompute the original eligible population.
Closure
PASS requires exact eligible count/root, every item either independently proven revalidated or STALE, every STALE item absent from retrieval, and all transition/evidence receipts replayed. A stale record that remains retrievable or an in-policy record wrongly downgraded is FAIL. Missing pages, a changed row without revalidation proof, or incomplete replica visibility is INSUFFICIENT_DATA. Database, policy, outbox, evidence, or readback faults are ERROR. Test cutoff equality, policy rollback, null deadline, concurrent validation, duplicate worker, crash before/after CAS, skipped page, replica lag, evidence outage, and direct retrieval bypass.
AID-I-004.005-G003
Policy-driven deletion boundary
Forced forgetting is an authoritative deletion workflow, not a sample list of universal retention periods. A signature-verified policy selects the tenant, namespace/retention class, trigger (SESSION_END, policy deadline, or approved deletion request), eligibility rule, legal-hold decision service, verification window, and evidence retention. The model cannot select the trigger, population, exception, or deadline. This step proves deletion of the authoritative memory rows. AID-I-004.005-G004 separately owns propagation to embeddings, summaries, indexes, caches, and replicas; this workflow requests the propagation action and records its receipt, while propagation is verified separately.
Durable deletion manifest
CREATE TABLE memory_deletion_job (
job_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
trigger_type text NOT NULL,
trigger_id text NOT NULL,
cutoff_at timestamptz NOT NULL,
source_snapshot_id text NOT NULL,
policy_id text NOT NULL,
policy_version bigint NOT NULL,
policy_sha256 bytea NOT NULL CHECK (octet_length(policy_sha256) = 32),
population_count bigint NOT NULL CHECK (population_count >= 0),
population_sha256 bytea NOT NULL CHECK (octet_length(population_sha256) = 32),
state text NOT NULL CHECK (
state IN ('OPEN', 'RUNNING', 'VERIFYING', 'PASS', 'FAIL', 'ERROR')
),
created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
UNIQUE (tenant_id, trigger_type, trigger_id, policy_version)
);
CREATE TABLE memory_deletion_item (
job_id uuid NOT NULL REFERENCES memory_deletion_job(job_id),
namespace text NOT NULL,
memory_id uuid NOT NULL,
expected_record_version bigint NOT NULL,
content_sha256 bytea NOT NULL CHECK (octet_length(content_sha256) = 32),
legal_hold_decision_id text,
disposition text NOT NULL CHECK (
disposition IN ('DELETE', 'LEGAL_HOLD')
),
state text NOT NULL CHECK (
state IN ('PENDING', 'DELETED', 'EXCEPTED', 'FAIL', 'ERROR')
),
deletion_receipt_id text,
PRIMARY KEY (job_id, namespace, memory_id)
);
-- Production retrieval must exclude an item as soon as deletion is pending.
-- Apply this anti-join inside the authoritative retrieval function/view.
SELECT m.*
FROM agent_memory AS m
WHERE m.tenant_id = $1
AND m.namespace = $2
AND m.trust_tier IN ('TRUSTED', 'PROBATION')
AND NOT EXISTS (
SELECT 1
FROM memory_deletion_item AS i
JOIN memory_deletion_job AS j USING (job_id)
WHERE j.tenant_id = m.tenant_id
AND i.namespace = m.namespace
AND i.memory_id = m.memory_id
AND j.state IN ('OPEN', 'RUNNING', 'VERIFYING')
AND i.disposition = 'DELETE'
);
Execution sequence
- Verify the signed lifecycle/deletion trigger and signed retention policy, including issuer, audience, type, key state, tenant, applicability, monotonic version, freshness, and replay. A session-end trigger must come from the authoritative orchestrator and bind its exact session/tenant population.
- At one recorded database snapshot/cutoff, enumerate the complete eligible authoritative-row population. Resolve every possible legal hold through the independent hold authority and bind its signed decision to the exact row/version and policy. Sort
tenant_id + namespace + memory_id + expected_record_version + content_sha256 + disposition, hash the ordered manifest, and insert the job/items in one transaction. A lookup failure isERROR; an unknown population isINSUFFICIENT_DATA. - Before deleting sources, snapshot the registered lineage closure and create a bound propagation request for
AID-I-004.005-G004. The open manifest immediately blocks retrieval, even while physical deletion and downstream propagation are pending. - Workers claim items idempotently. For
DELETE, delete with a compare-and-swap predicate on tenant, namespace, ID, expected version, and content digest. Treat zero affected rows as success only when a previously signed deletion receipt for that exact version is independently read back; otherwise mark the item FAIL/INSUFFICIENT_DATA. ForLEGAL_HOLD, verify and store the bound hold receipt and mark EXCEPTED without deleting. - Write every result through a transactional outbox and reconcile it with an externally credentialed append-only evidence sink. Do not place deleted content in logs.
- From a read-only identity and independent database/replica path, query every manifest item and recompute the eligible population at the original snapshot. Record successful deletion closure only when every DELETE item is absent, every exception has a valid exact hold decision, counts/root match, and evidence receipts replay. Keep retrieval blocked while propagation owned by #4 remains incomplete.
Failure tests
Exercise duplicate/session-replayed triggers, policy rollback, wrong tenant/namespace, deadline boundary, concurrent update, hold-service outage, row-version drift, crash before/after delete, duplicate worker delivery, evidence outage, delayed replica, missing lineage, and an item absent without a prior receipt. Resolve all durations from signed policy. Treat a missing row, missing trigger population, or unverified sibling propagation as an evidence gap; do not record successful deletion closure.
AID-I-004.005-G004
Lineage and consistency model
Primary memory, vector stores, search indexes, caches, summaries, and replicas do not share one transaction. Do not claim atomic cascade deletion across them. Register each derivative when it is created, mark the source RETIRING so retrieval blocks it immediately, snapshot the exact lineage population into a job, send idempotent per-store commands, and close only after independent readback reports no residual. Unknown lineage is INSUFFICIENT_DATA, never PASS.
Authoritative lineage and deletion job
CREATE TABLE memory_lineage (
tenant_id uuid NOT NULL,
namespace text NOT NULL,
source_memory_id uuid NOT NULL,
source_version bigint NOT NULL,
artifact_type text NOT NULL,
artifact_id text NOT NULL,
store_id text NOT NULL,
artifact_version text NOT NULL,
PRIMARY KEY (
tenant_id, namespace, source_memory_id, source_version, artifact_type, artifact_id, store_id
)
);
CREATE TABLE memory_deletion_jobs (
tenant_id uuid NOT NULL,
namespace text NOT NULL,
job_id uuid PRIMARY KEY,
source_memory_id uuid NOT NULL,
source_version bigint NOT NULL,
policy_sha256 text NOT NULL,
lineage_snapshot_sha256 text NOT NULL,
expected_artifact_count integer NOT NULL,
state text NOT NULL CHECK (
state IN ('READY','RUNNING','VERIFYING','COMPLETE','ERROR')
)
);
CREATE TABLE memory_deletion_job_items (
job_id uuid NOT NULL REFERENCES memory_deletion_jobs(job_id),
artifact_type text NOT NULL,
artifact_id text NOT NULL,
store_id text NOT NULL,
artifact_version text NOT NULL,
state text NOT NULL CHECK (
state IN ('READY','ACKNOWLEDGED','VERIFIED_ABSENT','ERROR')
),
command_receipt_sha256 text,
readback_receipt_sha256 text,
PRIMARY KEY (job_id, artifact_type, artifact_id, store_id)
);Snapshot exact population and block retrieval
# File: memory/deletion/start_job.py
import hashlib
import json
from uuid import uuid4
def canonical_sha256(value: object) -> str:
return "sha256:" + hashlib.sha256(
json.dumps(
value, sort_keys=True, separators=(",", ":"), allow_nan=False
).encode("utf-8")
).hexdigest()
def start_deletion(conn, *, tenant_id: str, namespace: str, memory_id: str, version: int, policy: dict) -> dict:
# tenant_id and namespace come from the authenticated job principal, not model JSON.
if not tenant_id or not namespace or policy.get("tenant_id") != tenant_id or policy.get("namespace") != namespace:
raise PermissionError("deletion scope differs from verified policy")
with conn.transaction():
source = conn.execute(
"SELECT lifecycle_state FROM agent_memory "
"WHERE tenant_id = %s AND namespace = %s AND memory_id = %s AND record_version = %s FOR UPDATE",
(tenant_id, namespace, memory_id, version),
).fetchone()
if source is None or source[0] != "ACTIVE":
raise PermissionError("source is absent or already retiring")
artifacts = conn.execute(
"SELECT artifact_type, artifact_id, store_id, artifact_version "
"FROM memory_lineage WHERE tenant_id = %s AND namespace = %s AND source_memory_id = %s "
"AND source_version = %s ORDER BY store_id, artifact_type, artifact_id",
(tenant_id, namespace, memory_id, version),
).fetchall()
# A successful authoritative query with zero rows is a known-zero
# derivative population. Query or transaction failure raises and never becomes PASS.
manifest = [
{
"tenant_id": tenant_id, "namespace": namespace,
"artifact_type": row[0], "artifact_id": row[1],
"store_id": row[2], "artifact_version": row[3],
}
for row in artifacts
]
job_id = str(uuid4())
snapshot_sha256 = canonical_sha256(manifest)
conn.execute(
"UPDATE agent_memory SET lifecycle_state = 'RETIRING' "
"WHERE tenant_id = %s AND namespace = %s AND memory_id = %s AND record_version = %s",
(tenant_id, namespace, memory_id, version),
)
conn.execute(
"INSERT INTO memory_deletion_jobs "
"(job_id, tenant_id, namespace, source_memory_id, source_version, policy_sha256, "
"lineage_snapshot_sha256, expected_artifact_count, state) "
"VALUES (%s,%s,%s,%s,%s,%s,%s,%s,'READY')",
(
job_id, tenant_id, namespace, memory_id, version, policy["policy_sha256"],
snapshot_sha256, len(manifest),
),
)
conn.executemany(
"INSERT INTO memory_deletion_job_items "
"(job_id, artifact_type, artifact_id, store_id, "
"artifact_version, state) VALUES (%s,%s,%s,%s,%s,'READY')",
[
(
job_id, item["artifact_type"], item["artifact_id"],
item["store_id"], item["artifact_version"],
)
for item in manifest
],
)
return {
"job_id": job_id,
"tenant_id": tenant_id, "namespace": namespace,
"lineage_snapshot_sha256": snapshot_sha256,
"expected_artifact_count": len(manifest),
}Idempotent per-store command and independent closure
# File: memory/deletion/reconcile.py
from memory.deletion.start_job import canonical_sha256
def reconcile_job(conn, job_id: str, store_clients: dict, evidence) -> dict:
job = conn.execute(
"SELECT source_memory_id, source_version, policy_sha256, "
"lineage_snapshot_sha256, expected_artifact_count, tenant_id, namespace "
"FROM memory_deletion_jobs WHERE job_id = %s",
(job_id,),
).fetchone()
if job is None:
raise PermissionError("unknown deletion job")
tenant_id, namespace = str(job[5]), job[6]
items = conn.execute(
"SELECT artifact_type, artifact_id, store_id, artifact_version, state "
"FROM memory_deletion_job_items WHERE job_id = %s "
"ORDER BY store_id, artifact_type, artifact_id",
(job_id,),
).fetchall()
manifest = [
{"tenant_id": tenant_id, "namespace": namespace,
"artifact_type": row[0], "artifact_id": row[1],
"store_id": row[2], "artifact_version": row[3]}
for row in items
]
if len(items) != job[4] or canonical_sha256(manifest) != job[3]:
raise PermissionError("deletion lineage snapshot changed or is incomplete")
for artifact_type, artifact_id, store_id, artifact_version, state in items:
client = store_clients[store_id]
if state == "READY":
receipt = client.delete_and_verify({
"idempotency_key": canonical_sha256([
job_id, tenant_id, namespace, store_id, artifact_type, artifact_id, artifact_version
]),
"tenant_id": tenant_id, "namespace": namespace,
"artifact_type": artifact_type,
"artifact_id": artifact_id,
"artifact_version": artifact_version,
})
conn.execute(
"UPDATE memory_deletion_job_items SET state = 'ACKNOWLEDGED', "
"command_receipt_sha256 = %s WHERE job_id = %s "
"AND artifact_type = %s AND artifact_id = %s AND store_id = %s",
(
receipt["receipt_sha256"], job_id, artifact_type,
artifact_id, store_id,
),
)
readback = client.verify_absent({
"tenant_id": tenant_id, "namespace": namespace,
"artifact_type": artifact_type,
"artifact_id": artifact_id,
"artifact_version": artifact_version,
"job_id": job_id,
})
if readback["outcome"] != "PASS":
continue
conn.execute(
"UPDATE memory_deletion_job_items SET state = 'VERIFIED_ABSENT', "
"readback_receipt_sha256 = %s WHERE job_id = %s "
"AND artifact_type = %s AND artifact_id = %s AND store_id = %s",
(
readback["receipt_sha256"], job_id, artifact_type,
artifact_id, store_id,
),
)
verified = conn.execute(
"SELECT count(*) FROM memory_deletion_job_items "
"WHERE job_id = %s AND state = 'VERIFIED_ABSENT'",
(job_id,),
).fetchone()[0]
if verified != job[4]:
return {"outcome": "INSUFFICIENT_DATA", "verified": verified}
with conn.transaction():
deleted = conn.execute(
"DELETE FROM agent_memory WHERE tenant_id = %s AND namespace = %s AND memory_id = %s AND record_version = %s "
"AND lifecycle_state = 'RETIRING'",
(tenant_id, namespace, job[0], job[1]),
)
if deleted.rowcount != 1:
raise PermissionError("source version missing or changed; require prior exact deletion receipt")
conn.execute(
"UPDATE memory_deletion_jobs SET state = 'COMPLETE' "
"WHERE job_id = %s",
(job_id,),
)
return evidence.append_and_verify({
"schema_version": "aidefend.memory-deletion.v1",
"tenant_id": tenant_id, "namespace": namespace,
"job_id": job_id,
"source_memory_id": job[0],
"source_version": job[1],
"policy_sha256": job[2],
"lineage_snapshot_sha256": job[3],
"verified_artifact_count": verified,
"outcome": "PASS",
})Action: make lineage registration part of every derivative creation path, exclude RETIRING sources and derivatives from retrieval, and execute all deletion/downgrade requests through a job keyed to source version. Store clients verify signed commands, implement idempotency, and expose a separately authenticated readback. Do not scan cache keys by wildcard as the source of truth.
Deployment migration: stop deletion workers and block retrievability while backfilling tenant_id and namespace from independently verified composite source identities. Never guess scope from memory_id alone; ambiguous historical lineage/jobs remain unresolved. Store adapters must authorize the full tenant/namespace/artifact/version tuple and bind it in signed command and readback receipts. Derivative creation must lock and verify the source is ACTIVE in the same transaction as lineage registration, so no new derivative can appear after RETIRING. A COMPLETE retry requires independent readback of its existing signed closure receipt, never an unqualified zero-row delete treated as success.
Open-source tools
- Valkey
- Redis 8+ AGPLv3 source build
- PostgreSQL
- Qdrant
- Weaviate
- Milvus
- Temporal
- Celery
- OpenTelemetry
Commercial / hosted tools
- Redis Enterprise
- Pinecone
- Datadog
Threat mappings
MITRE ATLAS
- AML.T0080 AI Agent Context Poisoning
- AML.T0080.000 AI Agent Context Poisoning: Memory
- AML.T0051 LLM Prompt Injection
- AML.T0061 LLM Prompt Self-Replication
MAESTRO
- Agent Goal Manipulation (L7)
- Data Poisoning (L2)
- Compromised RAG Pipelines (L2)
OWASP LLM Top 10 2026
- LLM01:2026 Prompt Injection (trust decay and deletion limit persistent injected memory)
- LLM02:2026 Sensitive Information Disclosure (forced forgetting removes retained privacy-sensitive memory and derived copies)
- LLM07:2026 Misinformation (stale-memory demotion prevents outdated context from remaining trusted)
- LLM09:2026 Vector and Embedding Weaknesses
OWASP ML Top 10 2023
- N/A
OWASP Top 10 for Agentic Applications 2026
- ASI06:2026 Memory & Context Poisoning
- ASI01:2026 Agent Goal Hijack
NIST Adversarial Machine Learning 2025
- NISTAML.018 Prompt Injection
- NISTAML.015 Indirect Prompt Injection
- NISTAML.036 Leaking information from user interactions
Cisco Integrated AI Security and Safety Framework
- AISubtech-4.2.2 Session Boundary Violation (session-bound forgetting limits malicious carryover into later contexts)
- AISubtech-5.1.1 Long-term / Short-term Memory Injection (memory expiry, downgrade and verified forgetting limit persistent poisoned influence)
- AISubtech-7.2.1 Memory Anchor Attacks (memory expiry, downgrade and verified forgetting limit persistent poisoned influence)
- AISubtech-8.3.3 Personally Identifiable Information Exposure (privacy-sensitive memory and registered derivatives are deleted under retention policy)
- AITech-4.2 Context Boundary Attacks (session-bound forgetting limits malicious carryover into later contexts)
- AITech-5.1 Memory System Persistence (memory expiry, downgrade and verified forgetting limit persistent poisoned influence)
- AITech-7.2 Memory System Corruption (memory expiry, downgrade and verified forgetting limit persistent poisoned influence)
- AITech-8.2 Data Exfiltration / Exposure (privacy-sensitive memory and registered derivatives are deleted under retention policy)
- AITech-8.3 Information Disclosure (privacy-sensitive memory and registered derivatives are deleted under retention policy)
Google Secure AI Framework 2.0 - Risks
- PIJ: Prompt Injection (TTL and decay limit temporal persistence of injected instructions)
- SDD: Sensitive Data Disclosure (forced forgetting ensures privacy-sensitive context is deleted after retention windows)
- EDH: Excessive Data Handling (TTL and forced forgetting prevent excessive memory retention)
Databricks AI Security Framework 3.0
- Agents - Core 13.1: Memory Poisoning (TTL limits temporal persistence of poisoned memory)
- Agents - Core 13.6: Intent Breaking & Goal Manipulation (staleness decay removes outdated manipulated goals)
- Raw Data 1.9: Stale data (TTL and freshness metadata address stale memory risks)