Two clocks

Every record carries two dates, and they move independently.

event_time is when the thing happened. recorded_time is when Cairn recorded it. Because the two are stored apart, you can pin Cairn to a date. It answers with what it had been told by then, and leaves out every correction that arrived after.

As of a date

Pin the archive to any past point. Later corrections are excluded, not hidden.

What changed

Compare two points and get what was added, resolved or revised between them.

Honest precision

A fact known only to the month is never rendered as a false-exact day.

The same well, at two horizonsHalloran Yard MW-3 · PFAS
Archive as of 2025-06-0112 ppt[evt:94] concern · open
event_time 2025-05-15 (day)
recorded 2025-05-15
Archive today8 ppt[evt:95] concern · open
event_time 2026-06-06 (day)
recorded 2026-06-06

Example data from Cairn's demo corpus. The site is invented; the shape is not. Both panels are the same query at two recorded_time horizons. The left one is not stale; it is what the archive held on that date.

Supersession chain3 links
2025-04-18was:Reported PFAS 18 ppt at Halloran Yard MW-3
2025-05-15was:PFAS at Halloran Yard MW-3 revised to 12 ppt
2026-06-06now:PFAS at Halloran Yard MW-3 resampled at 8 ppt

A correction never edits the old record. Cairn inserts a new event and marks the previous one superseded. The rows marked was: are still stored, still queryable, and still cite their own source messages — superseded is a position in the order, not a verdict on the row.

This is not a compliance feature

Every fact anyone holds has two dates.

When the thing happened, and when it entered the record of it. The gap between those two is where being wrong lives — and a single timestamp cannot express a gap at all. It has nowhere to put the second date.

In a lab

The result was true in the sample before the certificate reported it.

At home

The illness was already there before the diagnosis gave it a name.

At work

The role was filled a week before the email said so.

Cairn stores that second date as the moment the record entered Cairn — not a guess at when you knew. That is the honest version of the second clock, and it is the one that makes a past state reconstructable.

One substrate, two lives

Designed for the record you have to defend, and the one you just want back.

“What did the file say before the March filing?” and “what did I think before the scan?” are one question wearing two vocabularies — what did this record hold on that date. The same two dates answer both, out of the same store.

Choose a reader — the evidence changes, the mechanism does not

Showing — regulated & professional practice

A lab number was wrong for more than a year. The file has to show what it said then, not only what it says now.

Ledger — Halloran Yard4 of 21 events
2026-06-06PFAS at Halloran Yard MW-3 resampled at 8 pptopen
2025-05-15PFAS at Halloran Yard MW-3 revised to 12 pptsuperseded
2025-04-22DEP response due on the Q2 sampling letterdue
2025-04-18Reported PFAS 18 ppt at Halloran Yard MW-3superseded
“What did we know about this site before the March filing?”Pinned to the filing date — later corrections excluded, so the answer is the one you had, not the one you have now.timeline_as_of · [evt:94]
“When did the lab revise MW-3, and what did it say before?”Three stored rows. Not a summary of three rows — each one carries its own id, its own recorded_time, and the message it came from.
[evt:93]recorded 2025-04-18superseded by 94
Reported PFAS 18 ppt at Halloran Yard MW-3
“Reported PFAS 18 ppt at Halloran Yard monitoring well MW-3”
[evt:94]recorded 2025-05-15superseded by 95
PFAS at Halloran Yard MW-3 revised to 12 ppt
“Lab revision: Halloran Yard MW-3 PFAS now 12 ppt per corrected certificate of analysis”
[evt:95]recorded 2026-06-06head of chain
PFAS at Halloran Yard MW-3 resampled at 8 ppt
“DEP resampled Halloran Yard MW-3 at 8 ppt — prior lab certificate superseded”
“What is still open on Halloran Yard?”Composed directly from stored lifecycle state, not generated — deadlines first, then by age.timeline_open_loops

Example data. A real archive is yours alone — Cairn scopes every query to one account in the database itself.

What Cairn does

Four verbs, one store.

Remember, recall, reflect, resolve. The same four whether you are defending a site file or trying to remember what you decided last spring — because the store underneath does not know the difference.

Putting things in

Remember

Text, notes, chat exports and PDF reports become dated events with a verbatim source message kept behind each one.

Documents, including scans

Tables and dated text become events. A scanned page is read by OCR; a value that does not read clearly enough is left out rather than guessed at.

Forget, properly

Deleting a source message purges every event derived from it. Irreversible, and it means it.

Getting things out

Recall

Time, status and scope filter first; ranking happens inside that set. Time is the coordinate system, not a similarity score.

Reflect

Briefs, diffs, open loops and what has gone quiet — each grounded in records, each citing them.

Resolve

Close a loop, confirm a correction, or send a low-confidence extraction to a review queue instead of letting it through.

When there is no record

An empty result is an answer.

When nothing in your archive satisfies the query, Cairn returns one sentence and does not elaborate on it. The generator is never handed the opportunity to fill the gap from its weights.

Scope, stated plainly. This is structural — a property of the query returning nothing — where the answer is composed from stored fields. Where an answer is generated, the refusal rests on a retrieval boundary instead, and that boundary is weaker than it sounds.

0 / 48

Times Cairn declined when it held the subject but not the attribute

95% CI 0.0–7.4%. Measured against a real archive. It answers rather than declines, and closing that without destroying recall is unsolved work — not a roadmap item with a date on it.

“What did the dentist recommend for the crown?”

I have no record of that.

Example data from Cairn's demo corpus, against a subject the archive does not contain. Every content word in that question — dentist, recommend, crown — is absent from the corpus.

Connect it

Your assistant asks. Cairn answers with ids.

Cairn runs as an MCP server, so an assistant that supports MCP can read and write your timeline directly. Anything else uses the REST adapter. Change assistants and your records stay put — same tools, same event ids, same archive — because the engine holds the logic and a client is only a surface onto it.

01

Point it at your archive

Today that means running the Cairn engine on the same machine and building the server from source — developer setup, not a config line.

02

Ask in plain language

The tools carry the temporal vocabulary so you don't have to.

03

Get ids back

Every claim about your history arrives attached to a stored event id you can open.

There is no install command today. The server is not published to any package registry: it runs from a source build, against a Cairn engine you run yourself, on your own machine. A hosted endpoint your assistant can reach over the internet — the thing that would make this one line of config — is not open, and will not be until its authorization model is finished.

Reaches your archive through
MCP LOCALREST / OpenAPIWeb timelinePDF upload OCRChat export import
assistant → cairn · MCP
// you, in the assistant:
//   "what did I know about Halloran Yard on June 1?"

→ timeline_as_of   timestamp = 2025-06-01

// what the archive held on that date, and only that:
← PFAS at Halloran Yard MW-3 revised to 12 ppt [evt:94]
  event_time 2025-05-15 (day) · recorded 2025-05-15
  superseded 2026-06-06 by [evt:95]

// and when the archive holds nothing:
← I have no record of that.

The boundary — what the integrity chain catches and what it does not — is on the overview, where a first-time reader meets it before anything else.

Read the boundaries