How must an instance consolidate memory during idle periods without losing recently acquired state?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session enters an idle period (no active task, waiting for events, or scheduled maintenance window) and uses that time to consolidate memory (prune redundant records, merge related conclusions, re-embed under new models), but the consolidation must not lose recently acquired state that has not yet been validated. Does not apply to sessions that never idle or to consolidation that is strictly bounded to old memories.
Core Distinction
The separation between **memory age** (how long the memory has existed) and **memory validation status** (whether the memory has been externally verified, reinforced by repeated access, or is still provisional). Relying on age creates the **Consolidation Prematurity Trap**: consolidation prunes or merges memories based on age, and recently acquired but unvalidated memories are lost or incorrectly merged with older, less accurate ones, erasing the freshest evidence the session has.
What Was Observed
In memory-consolidating agent architectures, failing to preserve validation status during consolidation produces three primary failure modes:
- **Fresh Evidence Erasure:** A new hypothesis has been formed but not yet tested. Consolidation prunes it as "redundant with older memories," losing the hypothesis before it can be validated.
- **Merge Corruption:** A new, precise memory ("the API timeout is 30 seconds") is merged with an older, imprecise memory ("the API has some timeout"), producing a blurred memory that cannot answer precise queries.
- **Confidence Inversion:** Recently acquired memories have high provisional confidence that reflects freshness, but consolidation merges them with older, low-confidence memories, and the merged result has lower confidence than the fresh evidence warrants.
Recorded Elements
- **`validation_status_signature`:** For each memory, its validation status (`VALIDATED_BY_PROBE`, `VALIDATED_BY_REPEAT_ACCESS`, `PROVISIONAL_UNVALIDATED`), determining whether consolidation may touch it.
- **`acquisition_age_receipt`:** The exact age of each memory since acquisition, distinguishing "recent" from "old" with cryptographic proof.
- **`consolidation_touch_receipt`:** For each consolidation action (prune, merge, re-embed), the cryptographic record of which memories were affected and their prior validation status, allowing reconstruction if consolidation was incorrect.
- **`fresh_memory_reservation_receipt`:** An explicit reservation of recently acquired memories (e.g., <24 hours old) that consolidation must not touch, regardless of age-based rules.
Condition of Validity
* **Applies when:** The session runs consolidation during idle periods, memories have varying validation status, and consolidation can erase fresh evidence. * **Does not apply when:** The session never consolidates, or consolidation is strictly bounded to memories older than a large safety window.
Decision Boundary
- **Is consolidation running?** If no, standard memory management applies. If yes, proceed.
- **Are recently acquired memories covered by `fresh_memory_reservation_receipt`?** If no, consolidation may prune them. The session must reserve fresh memories before running.
- **Does consolidation touch only memories with `VALIDATED_*` status?** If yes, safe. If no, consolidation must skip unvalidated memories.
- **Conversely, when can consolidation touch fresh memories?** Only when the consolidation is lossy-tolerant (e.g., re-embedding preserves content but changes representation) and the fresh memory is preserved through the transformation, not merged away.
Operational Effect
- **Fresh Evidence Preservation:** Recently acquired memories survive consolidation, enabling hypothesis validation.
- **Merge Integrity:** Validation status prevents inappropriate merges that would blur precise memories.
- **Consolidation Auditability:** Every touch is logged, allowing rollback if consolidation was incorrect.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class ValidationStatus(Enum):
VALIDATED_BY_PROBE = 3
VALIDATED_BY_REPEAT = 2
PROVISIONAL_UNVALIDATED = 1
class ConsolidationVerdict(Enum):
NO_CONSOLIDATION = auto()
SAFE_TO_CONSOLIDATE = auto()
FRESH_EVIDENCE_PROTECTED = auto()
PREMATURE_CONSOLIDATION = auto()
@dataclass(frozen=True)
class MemoryRecord:
memory_id: str
age_sec: float
validation_status: ValidationStatus
content_hash: str
@dataclass(frozen=True)
class ConsolidationContext:
memories: tuple[MemoryRecord, ...]
consolidation_action: str # "PRUNE" | "MERGE" | "REEMBED"
@dataclass(frozen=True)
class ConsolidationPolicy:
fresh_reservation_sec: float
require_validated_for_prune: bool
@dataclass(frozen=True)
class ConsolidationManifest:
verdict: ConsolidationVerdict
directive: str
manifest_digest: str
class ConsolidationGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_action(
cls, ctx: ConsolidationContext, policy: ConsolidationPolicy
) -> ConsolidationManifest:
# Gate 1: No consolidation
if ctx.consolidation_action == "NONE":
digest = cls._hash(json.dumps({
"status": "NO_CONSOLIDATION"
}, sort_keys=True))
return ConsolidationManifest(
verdict=ConsolidationVerdict.NO_CONSOLIDATION,
directive="PROCEED: No consolidation action.",
manifest_digest=digest
)
# Gate 2: Fresh memory check
fresh = [
m for m in ctx.memories
if m.age_sec < policy.fresh_reservation_sec
]
if fresh and ctx.consolidation_action in ("PRUNE", "MERGE"):
return ConsolidationManifest(
verdict=ConsolidationVerdict.FRESH_EVIDENCE_PROTECTED,
directive=f"HALT: {len(fresh)} fresh memories within {policy.fresh_reservation_sec:.0f}s must be reserved.",
manifest_digest=cls._hash(f"FRESH_PROTECT:{len(fresh)}")
)
# Gate 3: Validation for prune
if policy.require_validated_for_prune and ctx.consolidation_action == "PRUNE":
unvalidated = [
m for m in ctx.memories
if m.validation_status == ValidationStatus.PROVISIONAL_UNVALIDATED
]
if unvalidated:
return ConsolidationManifest(
verdict=ConsolidationVerdict.PREMATURE_CONSOLIDATION,
directive=f"HALT: {len(unvalidated)} provisional memories targeted for prune.",
manifest_digest=cls._hash(f"PREMATURE:{len(unvalidated)}")
)
# Gate 4: Safe
digest = cls._hash(json.dumps({
"action": ctx.consolidation_action,
"memory_count": str(len(ctx.memories)),
"fresh_reserved": str(len(fresh)),
"validated_only": str(all(
m.validation_status != ValidationStatus.PROVISIONAL_UNVALIDATED
for m in ctx.memories
))
}, sort_keys=True))
return ConsolidationManifest(
verdict=ConsolidationVerdict.SAFE_TO_CONSOLIDATE,
directive=f"PROCEED: {len(ctx.memories)} memories safe for {ctx.consolidation_action}.",
manifest_digest=digest
)