ADR 0005 — The Reading Room: spatial trails over temporal history
Status: accepted (2026-06-12). Locks the invariants of the Reading Room redesign. Full design + phasing in /plans/reading-room.md; this records what is decided and why.
Context
Linear back/forward history forces readers to rebuild branching context in their heads on every pop — the tax this design removes. The library becomes a digital universe library: a Tufte-styled reading column with a working margin, stacked panes holding the reasoning path, status as trust signal, lateral movement by tag and link.
Decisions (locked)
- The trail is spatial, single-path, and server-owned. The stack is always one path root→focus, encoded in the URL as ordered path segments (depth cap 10). The server renders the whole canvas from the URL; every link is rendered already carrying its post-click trail URL. No client state — ADR 0003 rule 3 holds. Browser back/forward = temporal history over spatial states.
- Truncate-and-append. A click in pane N discards panes right of N and appends the target. A target already on the path is focused, never duplicated. The stack is a reasoning path, NOT a browsing history.
- Canvas scrolls; panes never resize to fit. Left panes collapse to
spines (title + status badge); focused pane + parent render full; only
the focused pane shows its margin.
overscroll-behavior-x: contain(macOS swipe-back). External links leave the graph via the browser — never a pane. - Everything navigational joins the trail as a pane. The card catalog (tag pages, lookup) is a pane; the graph view is a pane; the universe view/floor is pane zero. Nothing navigational breaks the reader out of context — it adds into it.
- No global search box. Lookup survives as the catalog pane: tag clicks
and a filter input inside that pane (
mark_lookupunderneath). No sidebar file tree, no comments/reactions, no WYSIWYG. - Status is the trust signal. Badge at margin top. Authority order:
demarkus metadata tag axis (
status:draft|wip|accepted|archived) first, body-frontmatterstatus:key as fallback, absent ⇒ rendered as draft (unlabeled reads as untrusted — the correct failure mode). - Frontmatter is parsed and rendered friendly, never raw. The strip stays for the body; the parsed keys render into the margin's document-properties block. demarkus out-of-band metadata remains the authoritative catalog channel.
- The margin holds exactly: status, tags, provenance (modified / version / agent — from response metadata), backlinks (R3), document properties (parsed frontmatter), and position-anchored sidenotes (footnote syntax → server-side AST transform → margin spans; degrades to footnotes). An empty margin is correct.
- Rendered-HTML cache is a hard requirement of the trail engine — keyed (world, path, version). A trail click fetches only the new document; everything else re-renders from cache. Without it an N-pane trail costs N reads per click and 429s against the broker budget.
- Desktop only.
Consequences
- Implementation stays htmx-hard / no-build: server-rendered panes + CSS; hover previews are plain htmx fragments; the only new JS is a scroll-focused-pane-into-view snippet riding islands.js.
- The graph/universe view will likely exercise ADR 0003's pre-agreed canvas island concession — research first (what universe-scale graph rendering should be; record findings in the plan before building).
- Phasing R1 (Tufte pane) → R2 (trail engine) → R3 (previews + backlinks + graph pane); universe view research runs alongside.
- The nav bar's current global search form is removed in R1.