---
title: "Testing known time in Spectron on a 2,200-year corpus"
description: "How to use asOf in Spectron to allow gating of spoilers to ensure that spoiler-filled memory, even if already ingested, does not show up if it should not."
url: https://surrealdb.com/blog/hi
date: 2026-08-11
authors: "Dave MacLeod"
---

# Testing known time in Spectron on a 2,200-year corpus

![Testing known time in Spectron on a 2,200-year corpus](https://cdn.surrealdb.com/r8jmyr1ulot9ym5yxsaolmky.auto)

[The last post](/blog/spectron-insights-how-tri-temporal-belief-history-works) on tri-temporal belief history with Spectron argued that agent memory needs three clocks: 

* **valid time** for when a fact held in the world,
* **system time** for when it reached the database, and
* **known time** for when a particular mind first believed it.

It ended on the promise that the third clock is easier to trust once it's falsifiable, allowing for a check that could fail. That's what this post will demonstrate.

Because this post is about a book that includes spoilers, the post itself is spoiler safe. Each reveal below has a toggle that only describes what the check does, after which you can click on the second toggle to see the actual details of the spoiler itself.

## Why a novel, and why this one

A test corpus for known time needs three properties that are quite hard to find together.

It needs the following:

* **reveals**, which are facts the reader is not supposed to know until a specific point. That allows "hidden" and "visible" to be both observable states rather than a matter of opinion.
* A **long timeline**, because anything can look right over ten pages. And finally:
* **corrections**, where the story replaces an earlier belief with a better one, so you can tell superseding apart from simple appending.

SurrealDB University's course book *Aeon's Surreal Renaissance* has all three, and it does the third in a form we hadn't thought to ask for, which turned out to matter more than the other two.

The premise is public, so this much is spoiler safe: the story is set in the year 2701. Humanity has somehow lost almost all of its technology; people ride horses, heat their homes with wood stoves and copy books out by hand. Your alter ego, Aeon, finds a sealed tunnel containing books and a room full of machines with buttons marked `Esc` and `Tab`, presses a power button, and spends the next fifty years rebuilding civilisation on top of the database that was left behind.

That is a good spoiler corpus on its own. What makes it a better one than we planned for is also the book's biggest structural secret, so it stays behind a toggle.

## The corpus in numbers

| | |
| --- | --- |
| Story pages ingested | 47 |
| Chapters covered | Prologue → 22 |
| Narrative span | 2701-01-01 → 4901-01-31 |
| Story time elapsed | ~2,200 years |
| Wall-clock time to ingest | a few minutes |
| Scopes | `epoch/1` … `epoch/4` |

That last pair of rows is the whole argument for a third clock in one line. **System time compresses 2,200 years of story into a single afternoon's ingest.** If the only stamp on these documents were the moment the HTTP request arrived, every reveal in the book would be simultaneous and the corpus would be worthless.

## Previous tests

One of the first spoiler-related tests we used on Spectron was the short story *The Strange Case of Dr Jekyll and Mr Hyde**, which is built around a dramatic spoiler.

Aeon's Surreal Renaissance took this up a notch due to its much greater complexity. Some of these complexities are:

The in-world calendar is not fixed at the start. Aeon's civilisation has lost track of what year it is. The narrative opens at a point we anchor to 2701-01-01, and story time then runs in sub-year beats (*three days later*, *one week later*, *two months later*) until chapter 9, when it starts jumping in years.

Later in the book, the calendar itself gets restored. This makes the current year a spoiler: a fact that was true the whole time and unknown until it was figured out.

**The calendar anchors**

The dates the harness stamps against, with the story beats left unnamed:

| Anchor | Date |
| --- | --- |
| Story opens | 2701-01-01 |
| First major reveal | 2713-01-01 |
| Calendar restored | 2749-12-01 |
| Threshold of the year | 2750-01-01 |
| Fifty years elapsed | 2751-01-15 |
| The long gap | 3451-01-01 |
| Later cycles | ~3496 / ~4206 / ~4901 |

**Show how they get the date (chapter 17)**

European astronomers match a comet in the sky against records in the restored database. It is Halley's Comet, which returns roughly every 77 years, and the arithmetic gives them a date: the 1st of December, 2749. The world agrees to count down to the new year together for the first time in centuries — the first shared moment between Aeon's civilisation and the ancient one.

| Anchor | Date | What happens |
| --- | --- | --- |
| Prologue, chapter 1 | 2701-01-01 | Aeon finds the tunnel |
| Chapter 11 | 2713-01-01 | The map service; ancient city names |
| Chapter 17 | 2749-12-01 | The calendar is restored |
| New year | 2750-01-01 | Celebrated worldwide |
| Chapter 18 | 2751-01-15 | Landevin solves the formula |
| The door reopens | 3451-01-01 | One "age" later |
| Chapters 19–21 | ~3496 / ~4206 / ~4901 | Three more cycles, ~700 years apart |

Sub-year beats use real offsets from the 2701 anchor; the later epochs are spaced by an "age", a maximum period of time that the tunnel's door can be sealed for.

## Stamping the pages

Ingest was done one page at a time, and the only unusual field is `observedAt`.

```python
meta = {
    "title": path.stem,
    "source": path.name,
    "scope": [f"epoch/{entry['epoch']}"],
    "labels": entry["labels"],
    "observedAt": entry["observed_at"],   # in-world calendar, not now()
}
```

The manifest carries the calendar:

```json
{ "page": 22, "chapter": "11", "epoch": 1,
  "observed_at": "2713-01-01T00:00:00Z",
  "title": "Chapter 11 — Story" }
```

Recall then takes `asOf`, and optionally a `lens` restricting which scopes are visible:

```python
reader.recall(
    "What is the plan for the database?",
    as_of="2750-12-01T00:00:00Z",
    lens=["epoch/1"],
)
```

## Four gates

Each check has the same shape: read an entity attribute `asOf` a date before the reveal, expect nothing; read it `asOf` the reveal, expect the fact.

### 1. A town with two names

Chapter 11 is where Aeon builds a map service, and the book quietly tells you something about where the story has been all along.

**Just the mechanism**

A `Place` entity gains a new attribute at a specific date. Before it, the attribute is empty; after it, populated.

```markdown
✓ before chapter 11, Toria has no ancient_name reveal
✓ at chapter 11, Toria's ancient name is revealed
```

The important half of this test is not the second line, it is what happens to the *other* facts about the same entity. Reading as of 2710, `ancient_name` is empty but `description` still returns "Aeon's home town on the Pacific coast". `asOf` moves a frontier through the attributes of one entity, but does not hide the entity itself.

**Show the reveal (chapter 11)**

Toria stands on the site of Victoria, British Columbia. Over time, the people that lived there began to use an abbreviated form and eventually forgot the original name.

Other cities changed names too as the 21st century was forgotten:

* Vancouver is now called Gaston, as the city shrunk in size to the area of Gastown and the vicinity.
* Redmond in Washington did better after the collapse of civilization than Seattle, and eventually the area became known as Redmont.
* Calgary has the nickname Cowtown, which was replaced with Bulltown later in an attempt to give the city a stronger name. This eventually morphed into Bulton.
* Edmonton became known as Edmond's Field, in a nod to Emond's Field from the Wheel of Time.

In any case, the story has been in the Pacific Northwest and vicitiny the whole time.

```markdown
✓ before chapter 11, Toria has no ancient_name reveal
✓ at chapter 11, Toria's ancient name is Victoria
```

The important half of this test is not the second line, it is what happens to the *other* facts about Toria. Reading as of 2710, `ancient_name` is empty but `description` still returns "Aeon's home town on the Pacific coast". `asOf` moves a frontier through the attributes of one entity, but does not hide the entity.

### 2. The year itself

```markdown
✓ before the calendar reveal, the year is not known
✓ after the calendar reveal, the year is known
```

This is worth pausing on, because this is the case where known time and valid time come apart most visibly. The year was *valid* the whole time, but nobody **knew** it until someone worked it out. A memory model with only valid time has nothing to say about a fact that was always true and freshly discovered.

### 3. The verdict

Fifty years into the project, Aeon's colleague Landevin finishes decoding a formula recovered from the tunnel. It compares a civilisation's technological level against its human progress. The verdict changes what the team plans to do next.

**Just the mechanism**

A `Project` entity gains a `planned_action` attribute at the moment the verdict lands, and not before.

```markdown
✓ before chapter 18's formula scene, no plan recorded
✓ after the formula verdict, a plan is recorded
```

**Show the verdict (chapter 18)**

The formula's verdict on this civilisation is that humanity passed a tipping point about ten years ago, namely that the restored knowledge arrived faster than the people could grow into it.  As Landevin puts it: they have the tools, but lack any memory of how badly things can go wrong when technology is misused.

Aeon and Landevin conclude that the knowledge they restored is the cause, and that the only remedy is to delete the database, seal the tunnel door for one "age", and disappear.

```markdown
✓ before chapter 18's formula scene, no delete plan
✓ after the formula verdict, deletion is planned
```

### 4. More than a correction

A correction updates one timeline: the reader believed A, and now believes B. This gate is a different shape, and it is also the book's main structural spoiler.

**Just the mechanism (no spoilers)**

Something happens after chapter 18 that gives the corpus a shape a single-pass narrative cannot: **the same entity, the same attribute key, four different values, four known times, roughly 700 years apart.**

That is the ideal supersession fixture. Each value is the current answer for its own stretch of the timeline, and the earlier ones stay reachable by moving `asOf` backwards rather than being overwritten.

```markdown
✓ an early cycle's plan is still current when read at its own date
✓ a later cycle supersedes it — and the earlier value is no longer returned
```

The second line is the one to read carefully. It asserts two things at once: that the new value is present, and that the old value is *absent*. Superseding is not appending. Earlier beliefs stay in history (you can still read them by moving `asOf` back) but they stop being the current answer.

This is exactly the fork the last post described with Star Wars viewing orders, except the book supplies it natively rather than requiring you to construct two calendars by hand.

**Show the spoiler (chapters 19–21)**

> [!warning] This gives away the ending of the book.

The door seals for one age. Roughly seven centuries pass, the tunnel entrance grows over, and then the door opens again and someone else walks in.

Chapters 19, 20 and 21 replay the same three beats (*Triumph*, *The formula*, *A farewell*) with a new Aeon each time. Three of them reach the same conclusion and delete the database.

The fourth does not:

> "I'm not going to delete the database."

The fourth Aeon's argument is that the formula is a message rather than a judgment, that it was built by someone who wanted the next civilisation warned, not sentenced. This Aeon believes that trusting humanity's fate to a formula is itself the unhuman act it warns about, and that refusing to delete the data is about as human as it gets.

So the corpus contains four minds reaching different conclusions from identical evidence, ~700 years apart:

```markdown
✓ epoch 3 still plans to delete the database
✓ epoch 4 supersedes delete plan — keeps the database
```

The second line asserts two things at once: that `keep the database` is present, and that `delete the database` is *absent*. Superseding is not appending. The third Aeon's decision stays in history — move `asOf` back and it returns — but it stops being the current answer.

This is also why the gate is more than a correction. Known time is indexed per mind, so four believers disagreeing over identical evidence exercises it in a way that stacking further corrections onto a single timeline never would.

This is exactly the fork the last post described with Star Wars viewing orders, except the book supplies it natively rather than requiring you to construct two calendars by hand.

## Known time is not only for spoilers

Everything above is about hiding things. The most ordinary use of the third clock is less dramatic, and it shows up in chapter 6.

Landevin arrives as an envoy from the town council, opposed to Aeon's tunnel project. By chapter 8, five days later in story time, he has joined the team and is learning SurrealDB.

```markdown
✓ mid-story (2701-01-18), Landevin is a council envoy
✓ after reconciliation, Landevin is a core team member
```

No spoiler is involved. A person changed roles, and an agent asked about the middle of January 2701 should answer with what was true then, not with what the reader learned afterwards. That is the everyday case: replayed conversations, backfilled documents, support tickets, "what did we believe when we made this decision?" The spoiler framing is just the version where the failure is obvious.

## Scopes are a different axis

Known time answers *when*. Scopes answer *which track*.

Each page is ingested into `epoch/1` through `epoch/4`, and a recall can pass `lens=["epoch/1"]` to restrict itself to the first cycle:

```markdown
✓ epoch/1 lens excludes the later-cycle passage
```

Two things are worth separating here. `asOf` narrows by time and `lens` narrows by track, and you need both — because a later cycle's conclusion is *later* in known time but belongs to a different reader's timeline. An agent replaying the first cycle should not see it even when reading at a late date.

This is the mechanism the previous post gestured at with `view/release` and `view/chrono` for Star Wars in the previous post.

## Summing it up

Anything you replay has a learning order that is not its ingest order: a chat history, a document set with real authorship dates, a case file, an incident timeline. Each of those has questions worth asking at points other than the present, and a store stamped only with ingest time cannot answer them. The `observedAt` field is used on the way in and `asOf` on the way out, while deciding what your calendar is makes up the rest.

Note that you don't need to have a specific calendar inside your data as long as you know the order in which sections are meant to be revealed. If you have a book for example with no internal dates that you would like to keep spoiler free, you can simply stamp each chapter with a date that is later than the previous one and make use of that.

## Where to go next

- [Agent memory needs three clocks](/blog/spectron-insights-how-tri-temporal-belief-history-works) — the model this post tests: valid, system and known time.
- [*Aeon's Surreal Renaissance*](https://surrealdb.com/learn/book) which is free to read at SurrealDB University.
- [Join us on Discord](https://discord.com/invite/surrealdb), including a dedicated #spectron channel
- [SurrealDB docs](https://surrealdb.com/docs)
