Walking skeleton: live-render aura + data-server docs from Gitea, themed and navigated #1

Closed
opened 2026-06-28 13:43:17 +02:00 by Brummel · 3 comments
Owner

Goal

The first runnable DocSite server: a single-source-of-truth LAN
documentation server that renders project docs live from their canonical
Gitea repositories, with one consistent theme. This is the walking
skeleton — the minimal end-to-end proof of the live-render pipeline — and
the reference issue for the /boss cycle that builds it.

Ratified design (from brainstorm)

  • Source — Gitea live. Docs are fetched at request time from Gitea's
    read-only raw/API at the pushed main revision; the cache is keyed on
    the source commit SHA. DocSite holds no content clone and never writes
    to a source repo (a read-only Gitea token in config covers private
    repos).
  • Scope — two projects, two directives. Sources: aura and
    data-server. Directives: code (syntect highlighting) and table
    (native Markdown) only.
  • Theme — dark, prose-optimized. Dark background with Catppuccin
    accents; prose in a reading typeface, code/tables in monospace. One
    global theme for all projects.
  • Whitelist & nav — DocSite-owned registry.toml. Each project entry
    carries its Gitea coordinates (repo, branch, docs) plus ordered
    nav sections. Only listed pages are reachable; everything unlisted
    (docs/specs, docs/plans, postmortems) is structurally unservable.
  • Stack — Rust + axum (derived: light routing, trivial static-asset
    serving, async leaves room for a later file-watch/SSE live-reload).

MVP navigation (from the doc inventory)

  • aura (repo=Brummel/aura, docs=docs):
    • "Concepts" -> glossary.md
    • "Design & Architecture" -> design/INDEX.md
    • (project-layout.md is obsolete — excluded.)
  • data-server (repo=Brummel/data-server, docs=.):
    • "Reference" -> README.md

Load-bearing invariants

  1. Read-only on source repos (fetch via Gitea raw/API only).
  2. Single source of truth — content lives once in Gitea; DocSite holds
    only a revision-keyed cache; rendered HTML is a pure function of
    (source at a revision + config).
  3. Reference integrity is detected, never enforced or silently degraded:
    startup/reload path validation, a visible render-time error block for
    an unresolved reference, and a docsite check subcommand validating
    every reference against the current Gitea sources (report + exit code).
  4. Closed directive vocabulary, open at one handler-registry seam.
  5. Whitelist publishing + path-traversal refusal.

Out of scope (later iterations)

  • code-include, mermaid directives.
  • uPlot / GraphViz embedding — gated on the aura embed API
    (Brummel/Aura#150).
  • Intra-doc Markdown link rewriting/validation (the docsite check seam
    is prepared for it, not yet wired).
  • A project-owned publish.toml (would be authored by the project's own
    pipeline; never grants DocSite write access).

Acceptance (walking skeleton)

  • Server renders a known aura doc and the data-server README live from
    Gitea main, wrapped in the theme shell with nav from registry.toml.
  • An unlisted path (e.g. a docs/specs file) returns 404 — never
    leaked.
  • A path escaping a docs root is refused.
  • docsite check validates the configured nav references against the
    current Gitea sources and reports broken ones with a non-zero exit.
  • Same source revision -> byte-identical rendered output (cache valid).
## Goal The first runnable DocSite server: a single-source-of-truth LAN documentation server that renders project docs live from their canonical Gitea repositories, with one consistent theme. This is the walking skeleton — the minimal end-to-end proof of the live-render pipeline — and the reference issue for the `/boss` cycle that builds it. ## Ratified design (from brainstorm) - **Source — Gitea live.** Docs are fetched at request time from Gitea's read-only raw/API at the pushed `main` revision; the cache is keyed on the source commit SHA. DocSite holds no content clone and never writes to a source repo (a read-only Gitea token in config covers private repos). - **Scope — two projects, two directives.** Sources: `aura` and `data-server`. Directives: `code` (syntect highlighting) and `table` (native Markdown) only. - **Theme — dark, prose-optimized.** Dark background with Catppuccin accents; prose in a reading typeface, code/tables in monospace. One global theme for all projects. - **Whitelist & nav — DocSite-owned `registry.toml`.** Each project entry carries its Gitea coordinates (`repo`, `branch`, `docs`) plus ordered nav sections. Only listed pages are reachable; everything unlisted (`docs/specs`, `docs/plans`, postmortems) is structurally unservable. - **Stack — Rust + axum** (derived: light routing, trivial static-asset serving, async leaves room for a later file-watch/SSE live-reload). ## MVP navigation (from the doc inventory) - **aura** (`repo=Brummel/aura`, `docs=docs`): - "Concepts" -> `glossary.md` - "Design & Architecture" -> `design/INDEX.md` - (`project-layout.md` is obsolete — excluded.) - **data-server** (`repo=Brummel/data-server`, `docs=.`): - "Reference" -> `README.md` ## Load-bearing invariants 1. Read-only on source repos (fetch via Gitea raw/API only). 2. Single source of truth — content lives once in Gitea; DocSite holds only a revision-keyed cache; rendered HTML is a pure function of (source at a revision + config). 3. Reference integrity is detected, never enforced or silently degraded: startup/reload path validation, a visible render-time error block for an unresolved reference, and a `docsite check` subcommand validating every reference against the current Gitea sources (report + exit code). 4. Closed directive vocabulary, open at one handler-registry seam. 5. Whitelist publishing + path-traversal refusal. ## Out of scope (later iterations) - `code-include`, `mermaid` directives. - uPlot / GraphViz embedding — gated on the aura embed API (`Brummel/Aura#150`). - Intra-doc Markdown link rewriting/validation (the `docsite check` seam is prepared for it, not yet wired). - A project-owned `publish.toml` (would be authored by the project's own pipeline; never grants DocSite write access). ## Acceptance (walking skeleton) - [ ] Server renders a known aura doc and the data-server README live from Gitea `main`, wrapped in the theme shell with nav from `registry.toml`. - [ ] An unlisted path (e.g. a `docs/specs` file) returns 404 — never leaked. - [ ] A path escaping a docs root is refused. - [ ] `docsite check` validates the configured nav references against the current Gitea sources and reports broken ones with a non-zero exit. - [ ] Same source revision -> byte-identical rendered output (cache valid).
Author
Owner

Design reconciliation (specify)

Spec: 0001-walking-skeleton. Recording the load-bearing forks and their
basis before the spec is written (this issue is the run's reference /
decision log).

  • Fork: doc source → fetch live from Gitea (raw/API, pushed main,
    SHA-keyed cache).
    Basis: user decision — chose "Gitea als Live-Quelle" over local working
    trees / DocSite-owned clones (2026-06-28), keeping the single copy on the
    Gitea host and publishing the canonical pushed revision.

  • Fork: MVP scope → two sources (aura, data-server), two directives
    (code, table).
    Basis: user decision — chose the "Walking Skeleton" boundary over the
    larger first-cut options.

  • Fork: theme → dark, prose-optimized, Catppuccin accents (prose in a
    reading face, code/tables monospace).
    Basis: user decision — chose "dunkel, prosa-optimiert" over
    aura-tool-consistent all-monospace / a light classic theme.

  • Fork: HTTP stack → Rust + axum.
    Basis: derived — Rust was the user's "own server" decision; axum chosen
    for light routing, trivial static-asset serving, and async headroom for a
    later file-watch/SSE live-reload. No competing stack carried a groundable
    advantage at this scale.

  • Fork: whitelist & nav location → DocSite's own registry.toml, not
    the source repos.
    Basis: derived — required to keep DocSite read-only on source repos
    (invariant 1); a project-owned publish.toml would need a write into a
    foreign repo and is deferred.

  • Fork: cache key → source commit SHA (not mtime).
    Basis: derived — follows from the Gitea-live source; revision-exact and
    unaffected by the absence of a local working-tree mtime.

  • Fork: reference integrity → detect-and-report (fail-loud) +
    docsite check, never enforce-by-writing.
    Basis: derived — a necessary consequence of read-only: DocSite cannot
    repair a source, so its duty is lossless detection.

## Design reconciliation (specify) Spec: `0001-walking-skeleton`. Recording the load-bearing forks and their basis before the spec is written (this issue is the run's reference / decision log). - **Fork: doc source** → fetch live from Gitea (raw/API, pushed `main`, SHA-keyed cache). Basis: user decision — chose "Gitea als Live-Quelle" over local working trees / DocSite-owned clones (2026-06-28), keeping the single copy on the Gitea host and publishing the canonical pushed revision. - **Fork: MVP scope** → two sources (`aura`, `data-server`), two directives (`code`, `table`). Basis: user decision — chose the "Walking Skeleton" boundary over the larger first-cut options. - **Fork: theme** → dark, prose-optimized, Catppuccin accents (prose in a reading face, code/tables monospace). Basis: user decision — chose "dunkel, prosa-optimiert" over aura-tool-consistent all-monospace / a light classic theme. - **Fork: HTTP stack** → Rust + axum. Basis: derived — Rust was the user's "own server" decision; axum chosen for light routing, trivial static-asset serving, and async headroom for a later file-watch/SSE live-reload. No competing stack carried a groundable advantage at this scale. - **Fork: whitelist & nav location** → DocSite's own `registry.toml`, not the source repos. Basis: derived — required to keep DocSite read-only on source repos (invariant 1); a project-owned `publish.toml` would need a write into a foreign repo and is deferred. - **Fork: cache key** → source commit SHA (not mtime). Basis: derived — follows from the Gitea-live source; revision-exact and unaffected by the absence of a local working-tree mtime. - **Fork: reference integrity** → detect-and-report (fail-loud) + `docsite check`, never enforce-by-writing. Basis: derived — a necessary consequence of read-only: DocSite cannot repair a source, so its duty is lossless detection.
Author
Owner

Sign-off: grounding-check override (user)

Spec 0001-walking-skeleton reached the Step-5 grounding-check as a BLOCK.
The BLOCK is a greenfield artifact: grounding-check ratifies a spec's
assumptions against existing green tests, and a project's first spec has
none to ground against — the empty extraction is itself the BLOCK, not a
spec weakness. Its one substantial external assumption — the source files
exist on the foreign repos' main — was verified before sign-off:

  • Brummel/aura main a517899: docs/glossary.md, docs/design/INDEX.md
  • Brummel/data-server main 694f96f: README.md

The remaining assumptions (Gitea raw/API contract, comrak/syntect
behaviour) are delivered by the implementation and its tests, not a prior
mechanism to wait on, so the BLOCK failure-mode (retire + depends on)
does not apply. User reviewed and overrode the BLOCK; proceeding to planner.

## Sign-off: grounding-check override (user) Spec `0001-walking-skeleton` reached the Step-5 grounding-check as a BLOCK. The BLOCK is a greenfield artifact: grounding-check ratifies a spec's assumptions against existing green tests, and a project's first spec has none to ground against — the empty extraction is itself the BLOCK, not a spec weakness. Its one substantial external assumption — the source files exist on the foreign repos' `main` — was verified before sign-off: - `Brummel/aura` main `a517899`: `docs/glossary.md`, `docs/design/INDEX.md` - `Brummel/data-server` main `694f96f`: `README.md` The remaining assumptions (Gitea raw/API contract, comrak/syntect behaviour) are delivered by the implementation and its tests, not a prior mechanism to wait on, so the BLOCK failure-mode (retire + `depends on`) does not apply. User reviewed and overrode the BLOCK; proceeding to planner.
Author
Owner

Walking skeleton shipped and cycle-closed. docsite serve renders the
aura + data-server docs live from Gitea main (dark theme, whitelist nav);
docsite check validates the nav references against the live sources with an
exit code. 41 tests green (32 lib + 8 e2e via an injected fetcher + 1 gated
live smoke that reached the real Gitea), clippy clean.

The cycle-close audit was drift-clean after iter 0001.tidy landed the missing
registry.toml, the cache-before-fetch data-flow, and registry slug/page
escaping. Two carry-on items are filed as follow-ups (the render directive
seam; a unit test for the Gitea 404->NotFound mapping).

Commits 0060fea..056db1c. Closing as done.

Walking skeleton shipped and cycle-closed. `docsite serve` renders the aura + data-server docs live from Gitea `main` (dark theme, whitelist nav); `docsite check` validates the nav references against the live sources with an exit code. 41 tests green (32 lib + 8 e2e via an injected fetcher + 1 gated live smoke that reached the real Gitea), clippy clean. The cycle-close audit was drift-clean after `iter 0001.tidy` landed the missing `registry.toml`, the cache-before-fetch data-flow, and registry slug/page escaping. Two carry-on items are filed as follow-ups (the render directive seam; a unit test for the Gitea 404->NotFound mapping). Commits `0060fea..056db1c`. Closing as done.
Brummel referenced this issue from a commit 2026-07-07 11:48:24 +02:00
Brummel referenced this issue from a commit 2026-07-07 11:48:24 +02:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Brummel/DocSite#1