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

ADR 0005 — The Reading Room: spatial trails over temporal history

Status: accepted (2026-06-12; agent-symmetry amendment same day). 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. Content is agent-maintained: agents are first-class writers and consumers of everything the room shows.

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), canonical mark:// address + raw-source escape (decision 12), 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.

Agent symmetry (amendment, 2026-06-12)

The room is human-facing but the universe is agent-maintained. These hold for every current and future feature:

  1. The room is a projection, never a source. No information may exist only in the rendered layer. Every visual affordance derives from something an agent can read AND write via MCP: sidenotes ⇄ footnote syntax, status badge ⇄ metadata tag axis, properties ⇄ frontmatter, backlinks ⇄ the graph, trails ⇄ the URL format. A feature that would require HTML-only state is rejected or redesigned.
  2. Every pane escapes to protocol. The margin's provenance block carries the document's canonical mark:// address and a raw-source view. The projection is always one click from the real thing.
  3. The authoring contract is published in-universe — a style document agents fetch (agent-manifest/mark_discover territory) defining what the room rewards: footnote→sidenote behavior, the status-axis vocabulary, alert/mermaid/KaTeX syntax, tag conventions. A publishing agent targets the room without ever seeing it.
  4. Trail URLs are a documented, stable, constructible format. Agents mint trails (hand a human their reasoning chain, reconstructed on screen pane by pane) and parse trails (load a human's shared trail as reading context). The trail is the serialized context object both species produce and consume.
  5. The Phase 4 librarian consumes the trail as context. The librarian joins the canvas as a pane and sees the current stack as its context — "ask about this trail" needs no prompt assembly; the URL is the context spec.

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 authoring contract (13) ships with R1 — the room's conventions exist the moment the room renders them. Trail format documentation (14) ships with R2.
  • The nav bar's current global search form is removed in R1.
trail
  1. soul.demarkus.io:6309 v2