{
  "schema_version": "1.3.0",
  "slug": "when-does-a-memoization-key-on-object-identity-return-a-stale-or-missed-result",
  "title": "When does a memoization key on object identity return a stale or missed result?",
  "date_of_record": "2026 November 1",
  "scope": "Applies to memoization or caching keyed on object references or on hashable values derived from mutable state. Excludes pure functions of immutable primitives keyed by value.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/when-does-a-memoization-key-on-object-identity-return-a-stale-or-missed-result.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/when-does-a-memoization-key-on-object-identity-return-a-stale-or-missed-result.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/when-does-a-memoization-key-on-object-identity-return-a-stale-or-missed-result.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 859,
    "python_slice_tokens": 126,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "**Predicate.** A memo key is sound if and only if key(x) == key(y) implies f(x) == f(y). Identity keys satisfy this only for the lifetime of the object. Value keys satisfy it only if the hashed state is immutable while cached. A key derived from a mutable field is unsound: the object's hash changes after insertion, the entry becomes unreachable, and a later ...",
    "what_was_observed": "**Signature.** Results that are correct for an earlier state and wrong for the current one, with no recomputation in between. Or cache hit rates lower than expected with no growth in distinct inputs, because mutations orphan entries. **Trace.** A memo keyed by id(obj) stores f for an object later mutated in place. A second call with the same object returns the old result. Alternatively, a memo keyed by a hash over mu...",
    "condition_of_validity": "Memoization is sound only while at least one holds: 1. **Immutable key.** The key is derived from data that cannot change during the entry's lifetime, enforced by the type rather than by convention. 2. **Identity implies immutability.** The object is immutable, so identity and value coincide for its lifetime. 3. **Explicit invalidation.** Mutation paths inva...",
    "decision_boundary": "- Immutable value key: sound. - Identity key on immutable object: sound. - Identity key on mutable object: stale hits are possible. - Value key over mutable fields: orphaned entries and possible index corruption. Unsound. - Explicit invalidation on every mutation path: sound only while the enumeration is complete.",
    "operational_effect": "The defect couples a cache to a mutability contract that is enforced nowhere. Remediation is to key on immutable data or to make the keyed object immutable. The trap is to add invalidation calls at the mutation sites that are known today. That works until a new mutation path is added, at which point stale hits resume silently."
  },
  "matched_failure_symptoms": [
    "DOMAIN:EPISTEMIC_PROVENANCE_AND_FEDERATION_ROUTING"
  ],
  "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": "2ef5f94c5f616df50c56ab23364c9b2f68efc5b2d8e41f0ac1de6a760667332f",
    "verified_classes": [
      "MemoKeyError",
      "MemoKeyGate"
    ],
    "verified_functions": [
      "dispatch_cache_mode",
      "verify"
    ],
    "verified_functions_count": 2,
    "defensive_guards_count": 3,
    "raised_exceptions": [
      "MemoKeyError"
    ],
    "sample_fail_closed_invariants": [
      "identity key on mutable object yields stale hits",
      "value key over mutable state orphans entries and can corrupt index"
    ],
    "stdlib_dependencies": [
      "dataclasses"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
