AID-I-004.005: Memory TTL, Staleness Decay & Forced Forgetting

Version 1.20261015 · Actionable sub-technique

Apply policy-defined trust decay, re-validation, downgrade, and deletion to persistent memory so stale records do not remain implicitly trusted. Bind each decision to the record version, tenant, trust tier, freshness metadata, retention policy, and deletion or downgrade evidence.

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.
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
  1. Authenticate the workload outside request JSON and resolve the exact tenant and namespace.
  2. Verify the signed policy envelope, issuer/audience/type, key status, monotonic version, applicability, and policy digest. Resolve retention_class, expires_at, and stale_after from that policy and the database timestamp. A policy may explicitly select no deadline; represent that as a policy decision, not an omitted field.
  3. 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.
  4. 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.
  5. 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

Automatically downgrade or quarantine trusted memory that exceeds TTL or staleness thresholds until it is re-validated by policy or human review.
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
  1. Verify the signed decay policy and derive tenant, namespace applicability, cutoff, database snapshot, and complete expected record population outside model control.
  2. 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.
  3. 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, increment record_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 mark REVALIDATED_CONCURRENTLY; otherwise a zero-row update is unresolved, not success.
  4. Retrieval excludes STALE immediately. Re-promotion requires the separate validation/promotion control and a new version; the decay worker cannot promote.
  5. 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

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.
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
  1. 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.
  2. 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 is ERROR; an unknown population is INSUFFICIENT_DATA.
  3. 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.
  4. 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. For LEGAL_HOLD, verify and store the bound hold receipt and mark EXCEPTED without deleting.
  5. 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.
  6. 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

Propagate deletion and downgrade actions across derived artifacts such as embeddings, summaries, secondary indexes, caches, and replicas instead of deleting only the primary record.
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

Commercial / hosted tools

Threat mappings

MITRE ATLAS

MAESTRO

OWASP LLM Top 10 2026

OWASP ML Top 10 2023

OWASP Top 10 for Agentic Applications 2026

NIST Adversarial Machine Learning 2025

Cisco Integrated AI Security and Safety Framework

Google Secure AI Framework 2.0 - Risks

Databricks AI Security Framework 3.0

AID-I-004.005: Memory TTL, Staleness Decay & Forced Forgetting | AIDEFEND

Loading interactive view…

A Practical Knowledge Base for AI Security Defenses

Version