91. Memory Consolidation v4: Derived Weights, Echo-Proof Corroboration, Supersession and Durability¶
Date: 2026-10-28
Status¶
Accepted 2026-10-28 — supersedes the weighing and reinforcement rules of ADR-0090 (and through it the reinforcement rule of ADR-0053). ADR-0090's running-time decay clock, evidence-gated promotion idea and rank ordering stand; ADR-0056 staleness-archiving is untouched.
Context¶
v3 fixed the decay cadence and gated promotion on corroboration, but four problems remained:
- W is path-dependent. Weight is mutated in place — reinforcement
+0.05, edge boosts±, decay multipliers all interleave across passes — so the same event history can yield different W depending on pass order and how boosts were clipped. Worse, positive edges re-applied their+0.05every pass (only the Evidence point was run-capped), so a live edge silently kept inflating its target. updatescorroborated the wrong end. The relation meant "the source updates the target", yet the boost landed on the target — the outdated claim got stronger when it was superseded.- Echo counted as much as corroboration. The flat
+0.05per near-duplicate restatement, capped at 0.90, let five re-statements in one sitting grind an inference fact to the cap — "one sitting cannot mint a trusted fact" held only forevidence, not for W. - "Stable" meant only
w ≥ 0.80. Nothing distinguished a fact that sat above the gate for days from one pushed over it by a burst of boosts moments ago; and nothing let a used fact forget more slowly than an ignored one.
Decision¶
Weighing — W is derived from persisted primitives, then decayed in time¶
Percept gains five fields (json:"…,omitempty"): prior (provenance strength — the birth weight table), contradictions (conflict events), superseded (0/1 flag — set while any live updates edge targets it; multiple edges do not stack), use_count (re-statements, recalls, injections), above_threshold_since (durability stamp). evidence (v3) stands as the corroboration count. The boost side of W is a pure function of these primitives:
derivedW = clamp(prior + corrobBoost(evidence) − contraPenalty(contradictions)
− supersedPenalty·superseded) // non-core capped at reconfirm_cap
corrobBoost(c) = 0.25·c/(c+2) // saturating: corrobBoost(2) = 0.125
contraPenalty(k)= min(0.10·k, 0.30) // saturating too
Corroboration saturates, so the second distinct confirmation matters far more than the tenth echo. Non-core derivedW is capped at reconfirm_cap (0.90) — corroboration never mints perfect confidence (the ADR-0053 invariant, now structural).
Events apply marginal deltas: an event moves the primitive counts and shifts W by exactly derivedW(after) − derivedW(before), so event effects telescope however many passes they arrive in, and re-running a pass over the same events changes nothing (the per-run award sets already capped them; now the W side is idempotent too). Re-affirmation (reinforcement) is the exception that proves the rule: a fact re-stated now refreshes W to derivedW outright — the forgetting curve restarts from the current derived strength, not from a decayed one.
Decay stays exactly v3's running-time exponential (session → 0 at 3 days half-life, global → the 0.20 floor at 60 days; core exempt; Δt clipped at updated_at), with two modulations: the half-life grows with use_count (1 + 0.25·min(use_count, 4) — up to 2× slower forgetting for facts that keep being put to use; repetition buys persistence, never truth) and halves while the percept is superseded (the newer claim wins by faster forgetting).
Gates: min_confidence and prune_threshold keep reading raw W — age never hides a fact, weak facts die. Promotion reads derivedW — forgetting is not falsifying: a fact affirmed strongly yesterday and one affirmed this minute are equally true, and a raw-W re-check at the end of the durability window would make the gate unsatisfiable (a session fact at the threshold drops below it within hours under the 3-day half-life). Hype still cannot mint: derivedW is saturated and run-capped, and the gates below hold.
Edge semantics — updates supersedes¶
| relation | corroborates | other effect |
|---|---|---|
extends, derives |
target (To) |
— |
updates |
source (From) — the newer claim |
target is superseded: half-life halved, promotion blocked while the edge is live |
contradicts |
— | one contradictions event per endpoint per run (−0.10 marginal, saturating at −0.30) |
Supersession is re-derived from live edges every pass (not a cumulative count), so removing an updates edge lifts the penalty and the promotion block. Contradiction events, like corroboration events, are permanent history (counts never decrease); a live contradicts edge additionally blocks promotion of both endpoints until resolved — v3's rule.
Promotion — strength, corroboration, durability¶
- Fast path (unchanged):
coreandproducer: userfacts promote atderivedW ≥ promote_threshold(0.80) — explicit assertions. - Everything else:
derivedW ≥ promote_thresholdandevidence ≥ 2(two distinct runs) and durability:above_threshold_sinceset andnow − above_threshold_since ≥ promote_stable_days(default 1) of running time. The stamp is set at the first pass observingderivedW ≥ threshold, cleared when derivedW dips below it (only events move derivedW — decay never clears the stamp). A boost burst cannot graduate on momentum; a twice-corroborated fact graduates a running day after it first crossed the gate. - A live
contradictsedge or anupdatessupersession defers (countedpromotion_deferred) until resolved. - Ordering preserved: promotion runs after the global pass, so fresh promotions are not decayed again in the same run.
Reinforcement — echo-proof¶
Re-stating a near-duplicate (Jaccard ≥ 0.60) re-affirms: evidence += 1 at most once per Store lifetime (as v3), use_count += 1, updated_at touched, W refreshed to derivedW. Additional re-statements in the same run change nothing — five echoes in one sitting move W once, not five times. The W trajectory of an inference fact is now the corroboration series 0.7 + 0.25·c/(c+2): 0.783 in run 1, 0.825 in run 2 (over the gate), converging to the 0.90 cap — instead of v3's flat +0.05 per restatement.
Migration¶
Pre-v4 percepts (prior == 0) are normalized once, on first touch: prior := W − corrobBoost(evidence) + contraPenalty(contradictions) — the stored strength with the count-derived boosts backed out, so re-deriving them cannot double-count. Boosts older models baked flat into W stay in the prior: a one-time, monotone-safe approximation. No existing fact is promoted by migration itself — above_threshold_since starts fresh, so the durability gate defers every non-fast-path promotion to a later pass.
Config and constants¶
reconfirm_boost is removed from the memory config block (the saturating corroboration term replaces it; the old key is ignored). promote_stable_days (1) joins it. The derived-weight terms (corrob_max 0.25, corrob_half_sat 2, contra_delta 0.10, contra_max 0.30, supersed_penalty 0.10, supersed_half_life 0.5, use_decay_slowing 0.25 / cap 4) are code constants like the old edge_boost — tune by rebuild until a real corpus says otherwise.
Consequences¶
- Consolidation is idempotent per run and order-independent in its boosts: every event applies exactly once, and re-affirmation — not pass noise — restores strength.
- Echo chambers are closed at the W level, not just the evidence level: repetition in one sitting adds nothing; only distinct runs (or distinct edges) corroborate.
- Superseded facts fade instead of being boosted; conflicts sink both claims but never below
prior − 0.30by penalty alone — pruning still decides death. - Used facts persist longer (spaced repetition) without becoming truer —
use_countmoves decay only. - The durability gate delays non-fast-path promotion by at least one running day past the threshold crossing; the graduation trajectory of a twice-corroborated fact is "cross → hold a day → promote".
- One deliberate asymmetry is documented and accepted: promotion reads derivedW while visibility/pruning read raw W, so a very decayed fact can graduate into global at low raw W (it re-earns rank through use like any other global).
Rejected alternatives and deferred work¶
confidence×activationsplit (carried over from ADR-0090's deferral): immutable truth vs. decaying availability, score = product — semantically cleaner ("never decay truth, decay availability") but a JSON-schema and every-read-path migration. The raw-W / derivedW gate split captures the operationally important half of it. Revisit if the single-W model conflates behaviors again.- Counting use toward
evidence— rejected: it would make "used" mean "true".use_countmoves decay only. Open question kept alive: if the corpus shows important-but-rarely-restated facts dying while sitting high on derivedW, the use/decay interplay is the first knob to revisit, not the truth terms. - Evidence slowing global decay beyond
use_count— deferred until a real corpus shows well-corroborated globals fading too fast. - Per-relation edge-boost tuning — the fixed saturating terms stay code constants (like the old
edge_boost) until a real corpus says otherwise. - Contradiction resolution beyond blocking promotion — deferred; for now conflicts sink both claims (−0.30 penalty cap) and resolution means
/forgetof one side or removal of the edge. - Corroboration saturation below the cap (max +0.25 of the 0.90
reconfirm_cap) is by design, not a tunable: even a well-corroborated inference fact never reaches user-level confidence through corroboration alone.