The Ledger
The Ledger is the reason Keel is worth more than a shared document. Prose does not just consume the world model — it feeds facts back into it. Write “Kael's left hand is scarred” and that becomes a first-class fact with provenance and a validity window; every later generation and every continuity check consults it.
What a fact is
Two timestamps, and they answer different questions. That distinction is the heart of the system.
The two clocks
true_at — story time: is this fact TRUE at
this moment in the world?
known_at — reading order: does the READER know
it yet? In a linear book these collapse into one sequence and every other
tool conflates them. The moment you allow a flashback, they come apart.
The payoff, concretely: a memory scene set in the Old Era can state a
fact from year −1500 that the reader has never met. The continuity check
does not scream — true_at(Y-1500) says the fact holds. And the
reveal system now knows that fact is spent for everything downstream in
reading order — known_at flips the moment the flashback's
position passes. Meanwhile must_not_reveal — the list of
unpaid promises plus truths the reader has not been shown — is computed
from exactly these two clocks, and is fed to Davy as
section V8. In a flashback it is the only thing
keeping the scene from leaking the future.
Promises
Every setup, question, or threat gets an id and a due-by. The Ledger surfaces what is still hanging — and payoffs that arrive with no setup:
Promises appear in the Ledger view (5), in the rail's ledger
lens, and unpaid ones ride Davy's do-not-reveal list until they are
discharged.
Getting facts in — always through your hands
Nothing enters the Ledger without you. Three routes, from most to least explicit:
1. Record one directly:
2. Mark it in the prose. Plank's @fact and
@ref make extraction deterministic — the extractor stops
having to infer:
3. Extract with triage. Deterministic markup facts always; AI proposals when a key is configured — and either way the list is proposals, not writes:
Without a provider it says so and does the markup half: (no AI provider — markup-only extraction; set ANTHROPIC_API_KEY for ledger.extract). A noisy ledger cries wolf and gets switched off — which is why triage is mandatory and confidence rides along on every AI proposal.
Refs — quote-anchored, always rebuildable
The third table is derived: which leaf mentions which entity, anchored by
a short quote rather than a character offset — offsets rot the
moment text moves; a quote can be re-found. Refs come from explicit
@ref directives plus word-bounded name matches, and are
recomputed wholesale at every keel index --rebuild — exact for
canon, good enough for drafts. They are what makes the
blast radius deterministic instead of a
guess.
| keel fact add / list | record and inspect facts |
| keel promise add / pay / list | open, discharge, review promises |
| keel extract <leaf> [--accept …] | propose facts from prose; you choose what lands |
| @fact{…} · @ref{…} | make it explicit in the prose itself |
| view 5 · ledger lens | the Ledger in the TUI |