TLDR: If your RAG synthesis layer strips the date from a chunk before answering, you're not building a memory system — you're building a confident liar.

The Setup

I run a personal AI agent called Apollo (my always-on Claude-based assistant, wired into my Obsidian vault and project memory). Part of how it works: hybrid RAG (retrieval-augmented generation — basically, semantic search over my notes, then a synthesis pass to answer questions).

The retrieval was working great. The synthesis was quietly broken in a way I didn't notice for a while.

What Apollo Told Me

On May 25, 2026, I asked Apollo about a project state.

Apollo told me — confidently, no hedging — that I was "mid-migration from headless back to native Shopify."

That migration had shipped in March 2025.

Fourteen months earlier.

Apollo had retrieved a vault note from late 2024 and answered in present tense. The date was right there in the frontmatter. The synthesis layer just… threw it away and answered like it was live intel.

What Broke (and Why)

The chunk made it to the synthesis model with the text intact, but no temporal context.

So the model did exactly what it was designed to do: it answered the question from the information given. It had no way to know the source was 18 months old, that the thing it described was describing a transition now completed, that "mid-migration" had long ago become "done."

The date was load-bearing context. Without it, a past state became a present-tense claim.

And here's the part that makes it worse: it compounds.

A stale "current state" claim doesn't just give me a wrong answer once. It becomes Apollo's mental model of what I'm working on. It starts making recommendations against a world that no longer exists.

The Fix That Actually Worked

The fix was plumbing the date the last mile — into the synthesis prompt itself.

I updated the synthesis module in my vault RAG pipeline to:

  1. Pull file_mtime from the data store module plus frontmatter fields (date, created, updated, archived) for every retrieved chunk
  2. Format them into a dates: line via a new _date_line() helper
  3. Inject that into _PROMPT alongside the chunk text

Then I gave the synthesis model explicit staleness rules:

  • Inline the date with every fact — "on YYYY-MM-DD", "as of YYYY-MM", "back in YYYY". Never strip it.
  • Anything >6 months old describing a project state or decision? Hedge it: "as of YYYY-MM-DD — verify still current."
  • Anything >18 months old describing a transition, migration, or in-flight initiative? Call it historical — say explicitly "this was the state in YYYY, confirm where it landed."
  • If two chunks describe the same thing at different dates, the newer one wins — but surface both dates so I can see the timeline.

Shipped same day. (GREAT feeling when a fix is that clean.)

Why This Matters

Every builder I know thinks about what data goes into their RAG store.

Almost nobody thinks about what metadata travels to the synthesis model — because the retrieval worked, so it feels done.

It's not done. A date that lives in the DB but never reaches the model might as well not exist.

The Shopify migration story was a near-miss for me. If I'd been asking about a live client's situation instead of my own stack, I'd have walked into a call with 14-month-old "facts" served up with total confidence.

The date isn't metadata. It's part of the fact. Build like it.