demarkus-library
Sub-project hub for demarkus-library — the web front-end ("Universe Library")
for a demarkus universe: a server-rendered Go + htmx reading room over a
broker-fronted knowledge system. Standalone repo latebit-io/demarkus-library,
own release cadence (mirrors obsidian-demarkus).
All durable knowledge about this project lives under /demarkus-library/. This
hub is the discovery backstop — keep it current.
Source of truth
- Plan — Universe Library — the authoritative plan (architecture, identity model, phases 0–5, build-model strategy, resolved decisions, open questions). Fetch this first in any new session.
Sections
- Architecture — app structure, transport, MCP-client/session model, render pipeline (TBD)
- Decisions (ADRs) — one file per decision at
adr/<NNNN>-<title>.md - Patterns — Go + htmx + goldmark idioms, conventions (TBD)
- Debugging — bugs, gotchas, investigations (TBD)
- Roadmap / status — phase progress, what's in flight (TBD)
- Debt — technical debt, deferred work (TBD)
- Journal — session notes, one file per day at
journal/<YYYY-MM-DD>.md- 2026-06-10 — Phase 0 shipped
Status
- Phase 0 — Foundation spike: DONE (2026-06-10). A real demarkus doc renders
server-side in a browser. Echo v5.1.1 app reads a world over QUIC via the real
demarkus fetch client, renders markdown through goldmark + bluemonday, serves
HTML. Routes:
/(default doc),/d/<path>,/health. Unit tests green. Verified live againstsoul.demarkus.io:6309. - Phase 1 — Library card + reading room: next. Broker OAuth (org-scoped) +
world directory, LIST tree, LOOKUP catalog, VERSIONS, backlinks. First sub-step:
add a broker MCP-gateway outbound adapter implementing
port.WorldGateway(plus an OAuth session), swapped in at the composition root — core untouched.
Architecture — hexagonal (ports & adapters)
Dependencies point inward (adapters → ports → core); the core knows nothing of Echo, QUIC, or goldmark. See ADR 0002. Echo v5 + bulwarkauth idioms retained (ADR 0001).
cmd/demarkus-library/ composition root — wires adapters into the core
internal/core/
domain/ document.go entities + sentinel errors (no external deps)
port/ port.go inbound + outbound port interfaces
service/ reading.go application core (the hexagon)
internal/adapter/
inbound/web/ Echo handlers/routes/view (driving adapter)
outbound/world/ demarkus QUIC fetch → port.WorldGateway
outbound/markdown/ goldmark + bluemonday → port.Renderer
Ports: inbound port.ReadingService; outbound port.WorldGateway + port.Renderer.
replace directives point demarkus client/protocol at local ../demarkus.
.coderabbit.yaml encodes the dependency rule as per-path review instructions.
Open questions
- Does the broker expose any anonymous-readable surface? Decides whether Phase 1 hits the broker directly vs a dev world for unauthenticated reads. (See plan.) Not blocking — Phase 0 read a world directly over QUIC.
Stack (decided)
Server-rendered Go (Echo v5 + html/template + htmx), goldmark + bluemonday for markdown→sanitized HTML, MCP client over the broker MCP gateway (Phase 1+), org-scoped OIDC (auth-code/PKCE/DCR), tokens server-side only. Single Go binary, no Node build. Go 1.26.4. Build on Opus 4.8 by default; Fable 5 as the escalation valve.
Front-end philosophy
SSR-first, htmx-hard, no JSON — see ADR 0003.
The server renders all HTML; htmx is the only interaction layer; no JSON API, no
client-side state. htmx is vendored (web/static/htmx.min.js, pinned 2.0.4) and
served from the binary — no CDN. JS islands are a last resort, each tracked as a
concession in ADR 0003. We are deliberately pushing the hypermedia approach to its
ceiling to learn where it actually is.