GUIDE

RAG citations that can actually be checked

A citation that resolves to a page which has since changed proves nothing. This is the difference between grounding and provenance, and how to fix the second one without touching your retrieval stack.

Written 19 August 2026

Two different problems wearing one name

Teams say “citation problem” and mean one of two things.

Grounding: did the model's claim actually follow from the retrieved passage, or did it invent a plausible reference? This is the well-covered one — reranking, verification passes, claim-to-span checking, judge models. Real work, and not what this page is about.

Provenance: six months later, can you show what that source actually said at the moment your system read it? Almost nobody handles this, and it is the one that hurts in an audit, in a dispute, or in any conversation where the other side has read a different version of the page.

You can be perfectly grounded and still have no provenance. The answer quoted the passage faithfully; the passage is simply not there any more.

Why a URL stops being a citation

  • The page is edited, and the sentence you relied on is gone or reworded.
  • The page is removed, and the link 404s.
  • The content is personalised or geographically varied, so the reader sees something different from what your retriever saw.
  • The document is versioned silently — same URL, revised numbers, no changelog.
  • A data vendor restates a historical figure, and your answer now cites a number that no longer appears anywhere.

Every one of these produces the same conversation: “the system said the source said X, and the source does not say X.” Without a record from the moment of retrieval, that conversation has no ending.

What good enough looks like

Not every application needs this. A support bot answering from your own versioned docs mostly does not — you control the corpus and can pin a revision. It matters when the source is outside your control, when the answer influences money or a decision that gets reviewed, or when somebody who does not trust you will read the citation later.

When it does matter, a citation should carry four things:

  1. The exact passage or field the answer depended on, not just the document.
  2. A hash of the retrieved content, so alteration is detectable rather than arguable.
  3. An independent time — one that does not come from you, since your own clock is what is being questioned.
  4. A way for a reader to check it without asking you for anything.

The cheap version, which you should do first

Store the retrieved text alongside the answer, hash it, and record the hash and timestamp in your own log. That covers most internal reviews and costs nothing but storage. If you want a stronger clock, submit the daily digest of that log to a free OpenTimestamps calendar — see timestamping a file for free.

This fails in exactly one place: the record is yours. When the disputed question is what an external source served and the other party doubts your good faith, a log you maintain cannot resolve it — not because it is wrong, but because it is yours.

The version that survives someone else's scepticism

Seal the source at retrieval time with a third party. Elucora fetches the source, pins the exact passage or JSON field, signs a record of what was served and when, and appends it to a public append-only log with an RFC 3161 timestamp and a Bitcoin anchor. Your citation becomes a receipt ID that anyone can verify offline against published keys.

In practice it is one call at retrieval time, and the receipt ID travels with the answer. There is a working starter at elucora-rag-citations, and the API documentation covers the rest. Verifying a receipt needs no account, which matters here: the person checking your citation is usually not your customer.

What this does not fix

It does not make the source correct. A sealed citation of a wrong page is proof that the page was wrong, which is useful and is not the same as being right. It does not detect hallucination — if the model cites a receipt that does not support its claim, provenance will not catch that; grounding work will. And captures are HTTP rather than a browser, so a source that renders its content in JavaScript is captured as the shell the server sent.

Handle grounding and provenance as two problems. Most teams have started on the first and have nothing at all for the second.