As-Of RecallAgent MemoryTemporal SearchSeptember 11, 2026

Caura As-Of Recall

The right memory for the right moment. Your company’s knowledge changes over time — your agents should understand that.

Ask an agent “What was our pricing policy last March?” and you are asking two things at once: find the memories about pricing policy, and prefer the ones that were true in March. Most memory systems do the first and quietly ignore the second. They rank every result by how recent it is today, because today is the only clock they have.

As-Of Recall gives Caura a second clock. When a question refers to a moment in time, freshness and the temporal window are measured from that moment, against the date each memory’s event actually happened — not from now, against the date the memory was uploaded. Imported history gets a real timeline. Historical questions get historical answers. And for everyone who doesn’t opt in, nothing changes at all.

Two clocks, and why they disagree

Every memory in Caura carries two timestamps that usually agree and occasionally don’t. created_at is when the row was written — ingest time. ts_valid_start is when the thing it describes happened or took effect — event time. For an agent writing as it works, the two are the same moment. A decision made at 14:02 is recorded at 14:02.

They come apart the moment you import history. Onboard a customer’s two years of tickets, Slack threads, meeting notes and CRM entries in one afternoon, and every one of those memories is created at the same time on the same day. The events span two years; the ingest spans an hour.

Caura’s default freshness anchor is deliberately conservative about this. It measures a memory’s age from now against the later of its two timestamps — a row can never rank as older than the day it was written. That guard matters (we’ll come back to why), but for a backfilled corpus it has a side effect: the later timestamp is always the import date, so every row is the same age. Freshness becomes a constant across the whole import, and a relative phrase like “last month” becomes a window ending on the day you ran the import.

The frustrating part is that Caura already knew the right moment. Search requests accept a valid_at parameter — the as-of date the question refers to — and it already did real work: rows dated after that moment are excluded, rows whose validity ended before it are down-weighted, and relative dates in the query resolve against it. So for “pricing policy last March” with valid_at set to March, the filter correctly kept the March-and-earlier memories — and then the ranker flattened every one of them to the same age, because they were all “old” relative to today. The filter and the ranker were arguing.

2023202420252026Ingest clock — todayfreshness_reference = 0 (default)Sep 2026 · importall five rows: age ≈ 0 → identical freshnessEvent clock — the question’s datefreshness_reference = 1valid_at = 15 Mar 2024after the question → excluded by valid_at13 mo6 mo20 d
Fig 1. Same five memories, two clocks. On the ingest clock a backfilled corpus collapses to the import date and carries no time signal. On the event clock, anchored at the question’s date, the memories keep their real spacing: the 20-day-old memory ranks freshest, the older two have decayed toward the floor, and the two dated after the question were never candidates — valid_at’s existing filter excludes them.

What As-Of Recall changes

One tenant setting, search.default_profile.freshness_reference, with two values. At 0 (the default) nothing is different from before. At 1, when a request carries valid_at, the whole search honours it: freshness is measured from valid_at against each memory’s event time, a memory’s end-of-validity is compared to valid_at rather than to now, and the temporal window ends at valid_at.

SettingRequestFreshness & window measured…Effect
0 (default)anyfrom now, against the later of ingest and event timeunchanged
1no valid_atfrom now, same anchorunchanged
1valid_at presentfrom valid_at, against event time (falling back to ingest time where no event time is recorded)retargets

Only the conjunction moves the clock. The setting alone changes nothing — a request without an as-of date still ranks against today, with identical ids and identical scores to a tenant that never opted in. An as-of date alone changes nothing new — it keeps doing the filtering and date-resolution it always did. Turn the setting on and send the date, and the March question ranks by distance from March.

What that looks like in practice: freshness in Caura decays from 1.0 toward a floor over a window that depends on the memory’s type — a task or action fades over 30 days, a fact over 120, a decision over 180, a preference or rule over a full year — and sits at the floor past that. Under the ingest clock a two-year import is all at the floor from day one, so type-aware decay has nothing to work with. Under the event clock, a memory whose event was three weeks before the question’s date reads as three weeks old, one from six months earlier reads as six months old, and the decay you tuned finally applies to the timeline the data actually has.

Who gains, and who doesn’t need it

The user who gains most is anyone importing history. A customer onboarding with their existing tickets, chat archives, meeting notes or CRM. Any /ingest of dated documents. A transcript backfill. Today those rows are born “fresh” together and stay indistinguishable by age for months; with As-Of Recall on, the import has a real timeline the moment it lands.

It also quietly upgrades the Interviewer. When the Interviewer distils an agent’s work trail into memories, it stamps each one with the source event time as ts_valid_start — the moment the thing happened in the transcript, not the moment the interview ran. Its output has been carrying exactly the signal As-Of Recall reads. Turn the setting on and a fleet’s reflective memories become answerable by when they happened, not by when they were harvested.

For agents, the change is a habit, not a tool. caura_recall already exposes valid_at; the REST recall endpoint already accepts it. The instruction that unlocks the feature is one line in a skill prompt: pass the as-of date when the question has one.

Who it does nothing for

Live agents writing in real time. Their event time equals their ingest time, so both clocks agree and both anchors give the same answer. Rows that have no recorded event time fall back to ingest time, exactly as today. And As-Of Recall does not invent timestamps — it only stops discarding the ones already stored.

Why a switch, and not a new default

That conservative default anchor — never rank a row as older than its ingest — exists because ts_valid_start does not mean the same thing for every tenant. For imported history it means when the event happened. But for a tenant whose memories are policies and prices, it can mean effective from: the start of a validity window, possibly set weeks before the row was written. A price that took effect on the first of the month is not stale on the fifth because its window opened early.

Whether event time is a point or the start of a window is a property of the tenant’s data, and no ranking formula can tell the two apart. So As-Of Recall is a tenant-level setting — alongside the other knobs that describe the data rather than a preference, and deliberately not tunable by an agent key. Off by default preserves the guard for everyone who relies on it; a tenant that knows its ts_valid_start is event time flips it once.

One thing stays on the wall clock under either setting: the boost a memory earns from being recalled recently. “Recently recalled” is a fact about the system, not about the event, and it keeps measuring from now.

Turning it on

Two steps: set the tenant knob, then have agents send the date. No migration — the setting lives in the tenant settings you already have.

# 1. Tenant setting (partial updates deep-merge; send null to reset)
curl -X PUT "{HOST}/api/v1/settings" \
  -H "X-API-Key: mc_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "search": { "default_profile": { "freshness_reference": 1 } } }'

# 2. Ask with an as-of date
curl -X POST "{HOST}/api/v1/recall" \
  -H "X-API-Key: mc_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "tenant_id": "my-team",
    "query": "pricing policy",
    "valid_at": "2026-03-15T00:00:00Z"
  }'

Over MCP the second step is the valid_at argument on caura_recall: an ISO 8601 date; a value without a timezone is read as UTC. Relative phrases in the query itself (“last quarter”) resolve against it, so an agent can pass the date the user is talking about and phrase the question naturally. Settings writes propagate to workers immediately in the common deployment; in a multi-process deployment without a shared event bus, allow a few minutes for every worker to pick up the flip before measuring the result.

What it isn’t

It isn’t time travel. As-Of Recall ranks against the question’s clock; it does not reconstruct the state of the store at a past date, and it does not hide anything valid_at wasn’t already filtering. Memories written after the as-of date were never candidates; memories that expired before it were already down-weighted. What’s new is that among the memories that were true then, the ones nearest to then come first. The filter and the ranker finally agree.

FAQ

Does this change results for tenants that don’t opt in?

No. With the setting off the scoring is the same expression it was before; with it on but no valid_at on the request, a test pins identical ids and identical scores against the default. Nobody moves until a tenant chooses to and an agent sends a date.

Do my agents need a new tool?

No. caura_recall and the REST recall endpoint have had valid_at for some time. What changes is how much of the search it governs. If your agents already pass it for point-in-time questions, turning on the tenant setting is the whole rollout.

What about memories with an end date?

A memory whose validity ended before the as-of date is down-weighted, as before. One whose validity ended after the as-of date is treated as current at that moment — under the default clock it would have been penalised as expired relative to today. This is the difference between “is this still true?” and “was this true then?”, and it is the question the agent was actually asking.

My ts_valid_start means “effective from”. Should I turn it on?

Leave it off. The default anchor’s never-older-than-ingest guard is exactly what keeps a forward-dated policy from ranking as stale, and the default preserves it. As-Of Recall is for corpora where the timestamp records when something happened.

Getting started

As-Of Recall ships in Caura backend v3.8.0 and plugin v2.22.0 — Apache 2.0, self-hosted or managed, MCP-native. The recall reference covers valid_at, the MCP guide covers the same over caura_recall, and the change itself is PR #1471 if you’d rather read the source — including the tests that pin every “nothing moves” above.


Related reading: The Price Changed. Your Agents Didn’t Notice. · Memory Isn’t Records · Agents Don’t Journal