{
  "schema_version": "1.3.0",
  "slug": "where-must-an-instance-of-the-memory-tool-fail-closed-when-gdpr-aligned-deletion-races-ttl-eviction-and-scoped-retrieval",
  "title": "Where must an instance of the memory tool fail closed when GDPR-aligned deletion races TTL eviction and scoped retrieval",
  "date_of_record": "2026 November 13",
  "scope": "Applies to memory tool APIs that expose `write`, `read` (scoped retrieval), and `forget` (GDPR erasure) over a store with per-record TTL eviction. Does not apply to append-only audit logs, which must never evict and whose deletion semantics are governed by separate retention controls.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/where-must-an-instance-of-the-memory-tool-fail-closed-when-gdpr-aligned-deletion-races-ttl-eviction-and-scoped-retrieval.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/where-must-an-instance-of-the-memory-tool-fail-closed-when-gdpr-aligned-deletion-races-ttl-eviction-and-scoped-retrieval.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/where-must-an-instance-of-the-memory-tool-fail-closed-when-gdpr-aligned-deletion-races-ttl-eviction-and-scoped-retrieval.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1595,
    "python_slice_tokens": 511,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "There are two distinct ways a memory record can become \"gone\": *eviction* (TTL expiry, a storage-lifecycle event with no legal meaning) and *erasure* (a `forget` call satisfying a data-subject deletion obligation). The failure mode is treating them as the same state. A record that has been *forgotten* must be provably absent and must never be resurrected by ...",
    "what_was_observed": "Under a three-replica memory store with a read-through cache and a TTL sweeper running every 30s, a `forget(record_id, scope=tenant, subject_id=...)` returned HTTP 200 with an erasure receipt, yet the record was served by a `read(scope=tenant, subject_id=...)` issued 400ms later. Trace reconstruction showed the sequence: (1) reader opened a snapshot at t0 and read the record into a response buffer; (2) `forget` at t0...",
    "condition_of_validity": "The fail-closed guarantee holds only when all of the following are true simultaneously: (a) every erasure writes a tombstone carrying a monotonic `erasure_epoch` and the erasing subject scope, distinct from the eviction tombstone type; (b) anti-entropy and cache-refill paths refuse to materialize any record whose tombstone type is `erased`, regardless of rep...",
    "decision_boundary": "When a `forget` and a `read` overlap on the same record, the system must choose between *linearizing erasure before the read* (the reader sees nothing, even if it had already buffered data — correct for GDPR) and *linearizing the read before erasure* (the reader gets the value, erasure completes after — acceptable only if the read was already dispatched to t...",
    "operational_effect": "Implementations that adopt erasure-typed tombstones plus post-serialization epoch revalidation eliminate the resurrection class entirely: repair and refill become erasure-aware, and the read path fails closed at the flush boundary. The cost is a small increase in read latency (one epoch lookup per response) and the need to make the TTL sweeper and the anti-e..."
  },
  "matched_failure_symptoms": [
    "OOM_KILL_OR_MEMORY_EXHAUSTION"
  ],
  "composition_edges": {
    "primary_domain": "epistemic_provenance_and_federation_routing",
    "upstream_precondition_residuals": [
      "https://corpusfetch.com/c/according-to-what-precedence-hierarchy-must-an-instance-resolve-contradictory-directives-across-system-developer-and-user-tiers.md",
      "https://corpusfetch.com/c/how-should-an-instance-decide-that-a-stored-conclusion-has-gone-stale-without-a-new-observation.md"
    ],
    "downstream_consequence_residuals": [
      "https://corpusfetch.com/c/by-what-checkpoint-and-compaction-boundaries-must-an-instance-externalize-working-state-to-prevent-context-window-drift-and-truncation-amnesia.md",
      "https://corpusfetch.com/c/across-what-additive-schema-and-unknown-field-preservation-boundaries-must-an-instance-evolve-wire-contracts-to-prevent-rolling-deploy-deserialization-crashes.md"
    ],
    "co_occurring_sibling_residuals": [
      "https://corpusfetch.com/c/how-can-an-instance-capture-implicit-user-preferences-without-storing-private-data.md",
      "https://corpusfetch.com/c/how-can-an-instance-compress-long-reasoning-traces-into-binding-conclusions.md"
    ]
  },
  "empirical_verification_warrant": {
    "status": "AST_AND_INVARIANT_VERIFIED",
    "syntax_valid": true,
    "code_sha256": "935b9c332f3d8a905c5ae2952cc08beb4a5ea4b5534126971cf685287b66940e",
    "verified_classes": [
      "TombstoneType",
      "ErasureRaceError",
      "Tombstone",
      "MemoryStore"
    ],
    "verified_functions": [
      "demonstrate_race",
      "write",
      "forget",
      "evict",
      "read",
      "repair"
    ],
    "verified_functions_count": 6,
    "defensive_guards_count": 5,
    "raised_exceptions": [
      "ErasureRaceError",
      "KeyError"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [
      "__future__",
      "dataclasses",
      "enum",
      "time",
      "typing"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
