← docs · ADR

The source of truth is an append-only event log; the graph and pages are projections of it

The single source of truth is an append-only, immutable event log (raw, deterministic). The Graphiti graph is not the source of truth — it is a projection of the log's distilled episodes. The standing pages (Idiom, Source-roadmap, Direction) and the strategic plan's version history are folds over the log. This refines ADR-0005: it keeps "everything is a projection, nothing hand-edited," but moves the root from a mutable LLM-lossy graph to an immutable log.

Status

proposed (2026-06-06; Voz ratifies)

Context

standing pages "projections too… nothing hand-edited" (0005 line 48). Two problems surfaced at runtime:

markdown that wiki_render.py:42 reads as a source; nothing renders them from the graph. 0005:48 is aspirational — the split-brain (markdown vs graph) the grill keeps hitting.

is non-deterministic; you cannot replay it to a faithful past state. "Versioning of strategic planning" (the mentee's ask) needs deterministic replay — which a mutable store, by definition, cannot give. "Single mutable source of truth" is an oxymoron for an auditable plan.

(0005:16). So the raw layer is already conceptually outside the graph; it just has no home. consolidate archives the transcript "raw, search-only" (consolidate/SKILL.md:23) — the would-be log, today only a cold blob, not an event stream. The handoff still flags a "full raw store" as persistence-gated.

Considered options

and lossy → no faithful replay; standing pages drift as hand-edited markdown (the observed split-brain).

and deterministic, so replay/versioning is faithful; the graph becomes a rebuildable read-model; the standing pages and Direction-history become folds — one truth, everything derived.

Decision

event per line, never mutated). Events: distilled episodes, voz.corrections, direction.sets, grill.curated marks, etc. Deterministic; replayable; human-legible. No event-store DB — JSONL is enough.

communities (the existing 0005 pipeline, now fed from the log, not treated as the store). Lossy, rebuildable, queryable — droppable and reconstructable from the log.

connection substrate; standing pages have edges too (Idiom term→cluster, Direction→what it directs). What differs is HOW an edge is written:

direction.set {relates_to:[...]}) and written to the graph by direct Cypher, no LLM — exactly what grill_writeback.py already does. Standing pages, Direction, curated grill marks. It lives in the graph and stays faithful, because the edge was declared, not inferred — so versioning survives.

entities/relations from prose. Knowledge clusters. Approximate by design. Versioning works because the asserted edges fold from the log, not because anything bypasses the graph.

0005:48 finally true (rooted at the log) and dissolves the standing-page/graph split-brain.

blob/file store (blog/entries/…), transient/prunable; an artefato.published event in the log ({slug, distills:[cluster:…], cites:[source:…]}) — the durable record; and a reference node + asserted edges in the graph (the artifact hung off the clusters it distills / sources it cites — CONTEXT.md's "Artefatos hang off the cluster", made real). Prune the blob → keep the event + distillation + connections.

Strategic history is faithful because the log is raw and deterministic.

store, referenced from the graph, transient/prunable — never event-sourced as blobs.

(the durable truth); the graph/wiki catch up via projection. Fixes the stranded-grill gap.

Consequences

"the graph is the single mutable source of truth" is superseded — the graph is a projection.

log gets the durability budget).

prove faithful versioning; migrate Idiom/Source-roadmap/clusters to projections after. Until migrated, hand-edited markdown remains an explicit stand-in (like chat-digest.md today).

pure-function folds, no framework (consistent with "shed scaffolding toward a legible core").

log's writer), and ADR-0005 (render unchanged — it now projects a graph that is itself a projection).