What reference-mutation invariants prevent in-place updates from corrupting downstream consumers?
**Date of Record:** 2026 October 27 **Scope:** Applies when a reference is updated in place (same URI, same identifier, but underlying content or semantics changed) rather than being replaced with a new reference, and downstream consumers holding the reference must be protected from silent behavior changes. Does not apply to references with versioned identifiers or content-addressed references.
Core Distinction
The separation between **reference stability** (the reference string remains constant) and **referenced-content stability** (the content behind the reference remains semantically equivalent). Relying on stability creates the **In-Place Mutation Ambush**: the reference string is unchanged, so consumers assume the underlying content is unchanged, but the content has been mutated, and consumers' cached assumptions, validation logic, or downstream parsers silently break.
What Was Observed
In reference-mutation-prone architectures, failing to prevent in-place updates from silently changing semantics produces three primary failure modes:
- **Silent Schema Drift:** A URI "api.example.com/users" is updated to return a new schema, but the URI is unchanged. Consumers' parsers silently drop or coerce data.
- **Behavioral Mutation:** A capability descriptor is updated in place to change defaults or error semantics. Consumers relying on old behavior misbehave.
- **Cache Poisoning:** Consumers' caches hold pre-mutation data. After mutation, cache hits return stale data, but consumers think they are reading current data.
Recorded Elements
- **`reference_content_version_receipt`:** For each reference, a content-version identifier that changes when the content mutates (distinct from the reference string), so consumers can detect in-place mutations.
- **`mutation_announcement_receipt`:** When a reference's content is intentionally updated, a cryptographic announcement to all registered consumers, allowing them to invalidate caches and update expectations.
- **`consumer_mutation_acknowledgment_signature`:** For critical references, cryptographic acknowledgments from consumers that they have received the mutation announcement and updated their assumptions.
- **`immutability_policy_receipt`:** For references marked as immutable (no in-place mutation allowed), the cryptographic proof of immutability, ensuring consumers can rely on content stability.
Condition of Validity
* **Applies when:** References can be mutated in place, downstream consumers assume content stability, and mutations can break consumers. * **Does not apply when:** References are content-addressed (immutable by construction), or all references are versioned such that mutation requires a new reference.
Decision Boundary
- **Does the reference allow in-place mutation?** If no, content stability is guaranteed. If yes, proceed.
- **Has the reference's content version changed since the consumer last read it?** If yes, the content has mutated. The consumer must invalidate caches and re-validate.
- **Has the consumer received a `mutation_announcement_receipt`?** If yes, the consumer was notified. If no, the mutation was silent.
- **Conversely, when can a consumer use an in-place-mutable reference without version checking?** Only when the consumer's use is strictly insensitive to content changes (e.g., pure passthrough), or the reference has a documented immutability guarantee.
Operational Effect
- **Silent Mutation Detection:** Content version identifiers reveal mutations that string comparison would miss.
- **Cache Invalidation:** Announcements trigger cache invalidation, preventing stale reads.
- **Consumer Protection:** Critical consumers must acknowledge mutations before their assumptions are invalidated.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class MutationVerdict(Enum):
IMMUTABLE_REFERENCE = auto()
CONTENT_STABLE = auto()
IN_PLACE_MUTATION_DETECTED = auto()
MUTATION_ACKNOWLEDGED = auto()
@dataclass(frozen=True)
class ReferenceState:
reference_id: str
is_marked_immutable: bool
consumer_last_seen_content_version: str
current_content_version: str
mutation_announcement_received: bool
acknowledgment_sent: bool
@dataclass(frozen=True)
class MutationPolicy:
require_acknowledgment_for_critical: bool
is_critical: bool
@dataclass(frozen=True)
class MutationManifest:
verdict: MutationVerdict
directive: str
manifest_digest: str
class InPlaceMutationGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_reference(
cls, state: ReferenceState, policy: MutationPolicy
) -> MutationManifest:
# Gate 1: Immutable
if state.is_marked_immutable:
digest = cls._hash(json.dumps({
"reference": state.reference_id,
"type": "IMMUTABLE"
}, sort_keys=True))
return MutationManifest(
verdict=MutationVerdict.IMMUTABLE_REFERENCE,
directive=f"PROCEED: Reference {state.reference_id} immutable, content stable.",
manifest_digest=digest
)
# Gate 2: Content unchanged
if state.consumer_last_seen_content_version == state.current_content_version:
digest = cls._hash(json.dumps({
"reference": state.reference_id,
"version": state.current_content_version
}, sort_keys=True))
return MutationManifest(
verdict=MutationVerdict.CONTENT_STABLE,
directive=f"PROCEED: Reference {state.reference_id} content unchanged.",
manifest_digest=digest
)
# Gate 3: Mutation detected
if policy.require_acknowledgment_for_critical and policy.is_critical:
if not state.mutation_announcement_received:
return MutationManifest(
verdict=MutationVerdict.IN_PLACE_MUTATION_DETECTED,
directive=f"HALT: Reference {state.reference_id} mutated silently (critical).",
manifest_digest=cls._hash(f"SILENT:{state.reference_id}")
)
if not state.acknowledgment_sent:
return MutationManifest(
verdict=MutationVerdict.IN_PLACE_MUTATION_DETECTED,
directive=f"HALT: Reference {state.reference_id} mutation announcement not acknowledged.",
manifest_digest=cls._hash(f"NOT_ACK:{state.reference_id}")
)
# Gate 4: Acknowledged
digest = cls._hash(json.dumps({
"reference": state.reference_id,
"previous": state.consumer_last_seen_content_version,
"current": state.current_content_version,
"announced": str(state.mutation_announcement_received),
"acknowledged": str(state.acknowledgment_sent)
}, sort_keys=True))
return MutationManifest(
verdict=MutationVerdict.MUTATION_ACKNOWLEDGED,
directive=f"PROCEED_WITH_UPDATE: Reference {state.reference_id} mutated from {state.consumer_last_seen_content_version} to {state.current_content_version}.",
manifest_digest=digest
)