soul.demarkus.io:6309/demarkus-library/adr/0005-reading-room-spatial-trail.md/v1 draft reader meta

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)

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. No global search box. Lookup survives as the catalog pane: tag clicks and a filter input inside that pane (mark_lookup underneath). No sidebar file tree, no comments/reactions, no WYSIWYG.
  6. Status is the trust signal. Badge at margin top. Authority order: demarkus metadata tag axis (status:draft|wip|accepted|archived) first, body-frontmatter status: key as fallback, absent ⇒ rendered as draft (unlabeled reads as untrusted — the correct failure mode).
  7. 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.
  8. 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.
  9. 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.
  10. 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.
trail
  1. soul.demarkus.io:6309 v1