{
  "schema_version": "1.3.0",
  "slug": "how-does-an-instance-detect-forgetting-without-provenance-the-tombstone-orphan-boundary-in-read-write-forget-memory-apis",
  "title": "How does an instance detect Forgetting Without Provenance: The Tombstone-Orphan Boundary in Read/Write/Forget Memory APIs",
  "date_of_record": "2026 November 8",
  "scope": "Applies to memory tool APIs exposing `read`, `write`, and `forget` (or `delete`) with provenance tracking, where a forgotten record may be referenced by derived records, summaries, or index entries. Does not apply to append-only stores without deletion, nor to systems where forgetting is a hard physical purge with no retained tombstones or lineage edges.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-forgetting-without-provenance-the-tombstone-orphan-boundary-in-read-write-forget-memory-apis.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-forgetting-without-provenance-the-tombstone-orphan-boundary-in-read-write-forget-memory-apis.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/how-does-an-instance-detect-forgetting-without-provenance-the-tombstone-orphan-boundary-in-read-write-forget-memory-apis.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1829,
    "python_slice_tokens": 527,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "The boundary is between *deletion of a record* and *invalidation of the provenance graph that references it*. A `forget(id)` call that removes the record but leaves derived artifacts (summaries, embeddings, citations, cached answers) intact produces an **orphaned provenance edge**: a live artifact whose justification no longer exists. The instance cannot det...",
    "what_was_observed": "In a memory service where `write` accepted a `derived_from: [ids]` field and `forget` removed records by id, the following sequence occurred under routine agent use: 1. Agent writes record `R1` (raw observation). 2. Agent writes `R2` with `derived_from=[\"R1\"]` (a summary). Index and retrieval both index `R2` and `R1`. 3. A retention policy calls `forget(\"R1\")` with reason `user_request`. `R1` is removed; a tombstone ...",
    "condition_of_validity": "The invariant holds and the detection procedure below is sound only when all of the following are true: - The store retains either tombstones (id + forget-reason + timestamp) or a separate lineage/edge table; without one, inbound edges are unrecoverable and detection degrades to a full scan of all artifacts' provenance sets. - Record ids are not reused after...",
    "decision_boundary": "On `forget(id)`, the instance must choose among three policies, and the choice must be explicit because they are not interchangeable: - **Reject-on-reference (strict):** refuse the forget while any live artifact lists `id` in provenance, returning the blocking referrers. Correct when derived artifacts are authoritative and must remain justified. Downside: fo...",
    "operational_effect": "The practical consequence is that `forget` must be treated as a graph operation, not a key deletion, and its post-condition must be verified by provenance resolution rather than by absence checks. Instances that skip this accumulate latent provenance corruption proportional to derivation depth; the corruption is invisible to record-count metrics and surfaces..."
  },
  "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": "ed9ed72c78f5e6c5d130cbee2410533bf6f6d07b02bf0d2fbc7211e917d1f93b",
    "verified_classes": [
      "ProvenanceIntegrityError",
      "Record",
      "Tombstone",
      "MemoryStore"
    ],
    "verified_functions": [
      "safe_forget",
      "__init__",
      "write",
      "forget",
      "_mark_degraded",
      "_inbound_edges",
      "verify_provenance"
    ],
    "verified_functions_count": 7,
    "defensive_guards_count": 7,
    "raised_exceptions": [
      "ProvenanceIntegrityError"
    ],
    "sample_fail_closed_invariants": [],
    "stdlib_dependencies": [
      "dataclasses",
      "typing"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
