Capabilities · 2. Memory that stays true
A store that only ever accumulates becomes wrong slowly and invisibly. Facts that were true last month sit at the top of recall today, two agents write opposite things under the same name, and nobody notices until an agent acts on the stale one. This family is the four mechanisms that keep a growing memory honest without anyone deleting anything.
The four are ordered by how much they intervene. The first two only change what an answer looks like; the second two change what is in the store, and both are reversible by design.
| § | Capability | Status | For |
|---|---|---|---|
| 2.1 | Asking what was true at a moment | SHIPPED, narrow | agent |
| 2.2 | Freshness horizons and decay-adjusted recall | FLAG for the tools, default on; the demotion is unconditional | both |
| 2.3 | Contradiction surfacing | FLAG, default on | both |
| 2.4 | Reversible consolidation | FLAG, default on | both |
One idea runs through all four and is worth having before the detail: this family demotes, marks and proposes; it does not delete. A stale fact falls down the ranking rather than disappearing. A contradiction becomes a candidate for a human, not a decision. A consolidation retires its inputs with a marker and can put them back exactly. The only mechanism in the memory substrate that destroys content is compaction, which is chapter 1 §1.4 and is deliberately not in this family.
2.1 Asking what was true at a moment
Status · SHIPPED, and narrower than the name suggests Reached through · MCP
query_factswithas_of· HTTPGET /v1/facts?as_of=Who it is for · agent
What it does. A fact can carry a declared interval saying when it was true in the world, and a query can ask for the facts whose interval contains a given instant. That is a genuine valid-time filter, correctly half-open at the end, and an unparseable timestamp is rejected rather than silently ignored, so a malformed query fails loudly instead of quietly returning everything.
Why it works this way. There are two clocks in any memory: when the system learned something, and when that something was actually true. Collapsing them is the standard mistake, and it produces a store that cannot answer "was this true in March" without you reconstructing it from write timestamps that mean something else. Splitting them is the well-understood bi-temporal design and it is what shipped. What was deliberately not built is transaction-time travel, the ability to reconstruct the store as it appeared at a past moment. That is a much heavier machine, and the honest summary of the difference is that as_of answers "what do we now believe was true then", not "what did we believe then".
What changes for you.
- As an agent: you can record that a configuration, price or ownership held between two dates and later ask which one applied on a given day, without inventing a convention in the value text.
- As an operator: validity is a second, deliberate call. Nothing sets it for you, so if nobody in your fleet declares intervals, this capability is inert on your store.
What it does not do.
- It is not a snapshot of the store as it was. Nothing filters on when a fact was written.
- It does not see through deletion or through supersession. Deleted facts are invisible at every instant, and because every rewrite retires the previous version, a default query returns the current version even when an older one covers the instant you asked about.
- On a store where nobody declares validity, it is a no-op: every fact has an open interval and therefore matches every instant.
Where the detail lives. The five limits, each spelled out, are daemon/10 §10.9; the interval test itself is fact_store.rs:279.
2.2 Freshness horizons and decay-adjusted recall
Status · FLAG
CORECRUXD_FEATURE_FRESHNESS, default on, gating the freshness tools; the recall-time demotion is unconditional. Salience input behindCORECRUXD_MEMORY_SALIENCE, default off Reached through · MCPmemory_freshness,memory_sweep_candidates,memory_set_horizon,memory_reverify· Console → System › Settings Who it is for · both
What it does. The freshness tools sit behind CORECRUXD_FEATURE_FRESHNESS, which is default on and which only an explicit disable turns off; the ranking behaviour they describe applies to every recall whether the flag is set or not. Each fact belongs to a horizon class, volatile, medium, stable or never-decays, with a threshold in hours or days. Once a fact is older than its threshold, its ranking confidence is halved. It is not hidden, not deleted and not flagged as wrong: it simply falls down the list, and every recall row carries both the stored confidence and the decayed one alongside the fact's age, so an agent can see why something ranked where it did. Re-verifying a fact restarts its clock. A caller can also set a floor and be told how many facts fell below it, so "nothing matched" stays distinguishable from "everything was too stale".
Why it works this way. The alternative designs are worse in ways that show up quickly. Hiding stale facts means recall silently loses the only record of a thing, and the agent cannot tell the difference between "never known" and "known but old". Deleting them means the store forgets on a timer, which is precisely the failure this product exists to fix. Halving the score keeps the fact reachable and reorders the answer, which is the smallest intervention that changes agent behaviour: a fresher fact wins when there is one, and the stale fact is still there when there is not. The demotion factor is a fixed constant rather than a tunable, deliberately, so that two machines running the same store rank identically; reproducible ordering was judged more valuable than per-deployment tuning. And the stored confidence is never mutated. Decay is a sort key computed at read time, not a write, which is what makes it safe to apply unconditionally.
The default class for an ordinary fact is never-decays. That looks conservative until you consider the alternative: a daemon that decides on your behalf that your architectural decisions go stale in 35 days would be actively harmful. Classes are inferred from the subject prefix for the daemon's own namespaces, where it knows what it wrote, and left alone otherwise.
What changes for you.
- As an operator: deploy state and daily metrics stop outranking last week's decision without you curating anything. You can override a class per fact, and you can ask for the list of facts a sweep would consider stale before acting on it.
- As an agent: read the freshness field on each row rather than assuming a top hit is current, and re-verify a fact you have just confirmed rather than rewriting it, so the clock restarts without minting a version.
What it does not do.
- The salience multiplier, which would let frequently used facts stay fresh longer, is behind
CORECRUXD_MEMORY_SALIENCE, default off. With the flag off, access counts are never recorded and the multiplier is exactly one. It is present, and in the default configuration it is mathematically inert. - Horizon overrides and re-verifications are not written to the journal, so they are lost on restart unless a compaction happens to run in between. Treat both as session-scoped adjustments, not durable classifications.
- Decay does not mark a fact as wrong. A halved score is a statement about age, not about truth, and a fact whose age cannot be established is never punished.
Turn it on. CORECRUXD_FEATURE_FRESHNESS is on unless explicitly disabled. The thresholds are tunable per process; the demotion factor is not.
Where the detail lives. The classes, the decay function, the thresholds and the flag table are daemon/10 §10.10; the tool contracts are api/12 §12.11; the demotion itself is decay.rs:281.
2.3 Contradiction surfacing
Status · FLAG
CORECRUXD_FEATURE_CONSOLIDATION, default on. Background scheduler behindCORECRUXD_CONSOLIDATION_SCHEDULER, default off. Near-duplicate review behindCORECRUXD_SEMANTIC_DEDUP, default off Reached through · MCPmemory_contradictions· HTTPGET /v1/console/review/contradictions,GET /v1/console/review/queue· Console → Memory › Review Who it is for · both
What it does. Behind CORECRUXD_FEATURE_CONSOLIDATION, which is default on, the daemon reads the store and reports where two live facts under the same subject and attribute assert opposite polarity: a deployed: true sitting beside a deployed: false. It is read-only and always returns a dry-run marker, so calling it can never change anything. A background refresher exists behind CORECRUXD_CONSOLIDATION_SCHEDULER, default off, and a separate near-duplicate detector behind CORECRUXD_SEMANTIC_DEDUP, also default off, files similar-looking facts as review candidates.
Why it works this way. Detection and resolution were deliberately separated. A detector that also resolved would be making a judgement about which of two agents was right, and in the cases that matter, that judgement needs the context neither the store nor a word list has. So the output is a queue of candidates for a person, and the resolving act is a different capability with its own guards, §2.4.
The detector itself is a fixed list of literal boolean words rather than a model, and this is the honest part. It fires only when a fact's entire value is one of those words. That makes it deterministic, free, and explainable, and it makes its reach narrow. The same principle governs the near-duplicate detector: when it fires it files a review candidate, and it never mutates or drops a fact. Advisory review, never silent deletion.
What changes for you.
- As an operator: you get a review queue in the console showing where your fleet disagrees with itself on boolean state, and nothing acts on it until you do.
- As an agent: asking for contradictions is safe at any time. It cannot mutate the store, so it is usable as a pre-flight check before you assert something.
What it does not do.
- It does not detect disagreement in free text or numbers. Two facts reading "deployed to prod" and "rolled back" produce no candidate. Neither do "3" and "7".
- It does not catch the ordinary case of an agent updating a value, because a rewrite retires the previous version and there are no longer two live facts to compare.
- It does not resolve anything, and the scheduler, when enabled, only refreshes the queue. Nothing here auto-supersedes or deletes.
- Read as "the daemon notices when my agents contradict each other", it will disappoint. Read as a boolean-state conflict detector, it works and it is free.
Turn it on. CORECRUXD_FEATURE_CONSOLIDATION is on unless explicitly disabled; the scheduler and the near-duplicate detector are separate flags, both default off.
Where the detail lives. The exact vocabulary, what it misses and why, is daemon/10 §10.11; the console review destination is operations/04 §4.5; the detector is fact_store.rs:2021.
2.4 Reversible consolidation
Status · FLAG
CORECRUXD_FEATURE_CONSOLIDATION, default on Reached through · MCPmemory_consolidate· HTTPPOST /v1/console/review/consolidations,POST /v1/console/review/consolidations/{id}/undo· Console → Memory › Review Who it is for · both
What it does. Behind CORECRUXD_FEATURE_CONSOLIDATION, default on, consolidation collapses a set of conflicting facts into one canonical value. The inputs are not destroyed: they are marked as retired and point at the canonical fact that replaced them. Undo reverses it exactly, restoring only the sources that this consolidation retired and retiring the canonical fact it created. The whole operation commits as a single journal append, so a failure part-way leaves the store untouched rather than half-resolved.
Why it works this way. Any automatic tidying of memory is a bet that the tidier understood the material. Rather than making that bet safer with better heuristics, the design makes losing the bet cheap: the operation is atomic, it is reversible, and it refuses before it mutates. A set of guards run first, and each one names the reason it stopped, including a target that a person pinned, a target that is private, a target linked to a receipt, and a target whose confidence is above a protection floor. Refusing with a reason is more useful than a partial success, and it is the reason pinning a fact in the memory panel works as an instruction rather than a suggestion.
What changes for you.
- As an operator: resolving a contradiction is an act you can take back. Undo is idempotent, so a second undo reports that it was already undone rather than damaging anything.
- As an agent: a consolidated fact is the one you will find in ordinary recall, and the originals remain retrievable through history or by explicitly asking for superseded facts.
What it does not do.
- It does not decide what to consolidate. The canonical value is supplied by the caller; the daemon checks and commits, it does not judge.
- It does not destroy its inputs, and this is where the two halves of the erasure story meet. Consolidation genuinely never destroys anything. Deletion followed by compaction does, and if you need content actually gone, that is the path, in chapter 1 §1.4.
- Undo does not restore facts retired by some other consolidation. It restores only what this one retired, by design.
Turn it on. Same flag as §2.3: CORECRUXD_FEATURE_CONSOLIDATION, on unless explicitly disabled.
Where the detail lives. The guards, the commit point and what reversible concretely means are daemon/10 §10.12; the tool pair is api/12 §12.12.
Sources
- Valid time, freshness, contradiction and consolidation in full: daemon/10 The memory substrate.
- Tool contracts for freshness and consolidation: api/12 MCP tool reference.
- The review queue as an operator sees it: operations/04 §4.5.

