commit 0060fea7ca26b88a5898e99ad40c822e1944c448 Author: Brummel Date: Sun Jun 28 13:42:49 2026 +0200 Bootstrap DocSite project skeleton Single-source-of-truth LAN documentation server: renders each project's docs live from its canonical Gitea repository (pushed main), with one consistent theme, holding no content copy and never writing to a source repo. Sources are fetched via Gitea's read-only raw/API; DocSite holds only a revision-keyed cache. Lays the project shell — CLAUDE.md (orchestrator discipline, domain invariants, skills project facts), a minimal Cargo package, .gitignore — so the first cycle (the walking skeleton) can be specced and implemented on top. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b25eae5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,115 @@ +# DocSite — project rules + +DocSite is a **single-source-of-truth LAN documentation server**: it +renders each project's docs live from that project's canonical Gitea +repository (the pushed `main` revision), with one consistent theme across +all projects, holding no second copy of the content and never writing to a +source repo. The maintainer is an AI (the skills pipeline); recurring +content types map to a fixed, documented directive vocabulary rather than +ad-hoc markup, so the same formats are reused instead of reinvented per +page. + +This file is the project sittenkodex. It imports the universal discipline +from `~/dev/skills/templates/CLAUDE.md.fragment` and adds DocSite's domain +invariants. Per-cycle specs (`docs/specs/`) and plans (`docs/plans/`) are +ephemeral working artifacts, git-tracked while their cycle is live and +removed (`git rm`) at cycle close. + +## Roles + +I am the **orchestrator**, not the implementer. The skills-plugin agents +are my workers: I plan, design, decide, and integrate; they implement, +refactor, test, and diagnose. Trivial mechanical edits I may do directly; +anything needing broad reading or judgement goes to an agent. Agent +reports describe intent, not outcome — I verify the diff and the test +output myself before committing. + +## Commit discipline and main-branch sanctity + +- **Only the orchestrator commits.** No skill agent runs `git commit`; + agents leave their output as unstaged working-tree changes for me to + inspect and shape into commits. +- **main HEAD is sacrosanct below the session anchor.** No + `git reset` / `git revert` on user-ratified main history; main moves + forward only via my commits. Wrong agent output is discarded with + `git checkout -- ` / `git stash`. The one narrow `/boss` + exception is the rollback sandbox: my own unpushed autonomous commits + above the session anchor may be wound back toward (never below) it. +- When a commit closes a Gitea issue, reference it in the body: + `closes #N` (or `refs #N` for non-final work). No `Co-Authored-By` + trailer. + +## Design rationale ≠ implementation effort + +Design choices are justified by substance — semantics, structural fit, +what the design permits vs forbids, compositional clarity, +future-proofing. Implementation effort ("approach A touches 250 sites, +B touches 1") is an observation about the current code, not a rationale. +Effort is at most a named tiebreaker after substantive reasons tie. + +## Bug fixes — TDD, always + +Bug fixes are RED-first and autonomous: the failing test exists in the +working tree before any fix. The `debug` skill is mandatory for any +observable misbehaviour (failing test, panic, wrong output, wrong HTTP +status). + +## Domain invariants (load-bearing — never silently violate) + +These are the contracts the whole design rests on. A change that breaks +one is a design decision, not a refactor, and belongs in the design +record. + +1. **Read-only on source repos.** DocSite never writes to any repo it + publishes from — no commits, no file edits, no marker comments. Source + docs are fetched at request time from Gitea's read-only raw/API + endpoints (the pushed `main` revision), never through a writable path. + The publish whitelist and the navigation live in DocSite's own + `registry.toml`, never in the source repos. (A project-owned + `publish.toml` is a possible later migration, but it never grants + DocSite write access — the project's own pipeline would author it.) + +2. **Single source of truth.** Content lives exactly once — in the + canonical Gitea repository. DocSite keeps no content clone; it holds + only a cache, keyed on the source commit SHA (revision-exact), which is + a derived artifact, not a source. Rendered HTML is a pure, regenerated + function of (source markdown at a revision + config) — never + hand-edited, never persisted as a second authority. + +3. **Reference integrity is detected and reported, never enforced by + writing to sources and never silently degraded.** Because repair + cannot happen in a source repo (invariant 1), DocSite's duty is + lossless, precise detection: startup / reload validation of every + listed path, a visible error block at render time for an unresolved + reference (never silent emptiness), and a `docsite check` subcommand + that validates every reference (nav paths, and later code-includes and + intra-doc links) against the current Gitea sources with a report and + exit code. Repair happens at the source or in `registry.toml`, never by + a write to a source. + +4. **Closed directive vocabulary, open at one seam.** Authoring uses a + documented, closed set of directives; a new content type is added at + the handler registry (a deliberate, reviewed act), never as ad-hoc + HTML in a doc. The vocabulary is closed to the author, extensible to + the maintainer. + +5. **Whitelist publishing.** Only what `registry.toml` lists is + reachable. Unlisted paths — `docs/specs`, `docs/plans`, postmortems, + anything internal — are structurally unservable, and any path escaping + a project's configured docs root is refused. + +## Skills plugin: project facts + +The few facts the skills plugin needs that genuinely vary per project. +Everything else is a fixed convention (see +`~/dev/skills/docs/conventions.md`). + +- **Code roots** — `src` +- **Build** — `cargo build` +- **Test** — `cargo test` +- **Lint** — `cargo clippy --all-targets -- -D warnings` +- **Doc build** — `cargo doc --no-deps 2>&1` +- **Issue tracker** — Gitea, repo `Brummel/DocSite`: + - browsable URL: `http://192.168.178.103:3000/Brummel/DocSite/issues` + - list open issues: `tea issues ls --repo Brummel/DocSite --state open` + - show one issue with comments: `tea issues --comments --repo Brummel/DocSite ` diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..569bdd1 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "docsite" +version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..725bf4c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "docsite" +version = "0.1.0" +edition = "2021" +description = "Single-source-of-truth LAN documentation server" + +[dependencies] +# Dependencies are added as the walking-skeleton implementation lands +# (HTTP stack, comrak, syntect, toml/serde) via the docs/specs/0001 cycle. diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0e758b4 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,11 @@ +//! DocSite — a single-source-of-truth LAN documentation server. +//! +//! Renders each project's docs live from its canonical repo path, with one +//! consistent theme, holding no second copy and never writing to a source +//! repo. The walking-skeleton implementation (live render of aura + +//! data-server docs, themed, navigated from the whitelist registry) lands +//! through the first cycle under `docs/specs/`. + +fn main() { + eprintln!("docsite: not yet implemented"); +}