diff --git a/AGENTS.md b/AGENTS.md index 69910f40..ac34acdf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ Do not invoke `bones/scripts/rc-*.sh` directly. - Rendering runs through the [Oliver](https://github.com/drawmeanelephant/oliver) binary: `oliver render --from markdown < file.md`, stdin → stdout body HTML, stderr = warnings. Discovery order is `RK_OLIVER_BIN` override, then `oliver` on `PATH`. The authoritative contract is `home/content/docs/oliver-contract.md`. - `bash rotkeeper.sh preflight` is the single renderer health check (discovery, executability, live smoke render); `render` routes through the same check. The adapter (`rc-oliver-adapter.sh`) strips a leading YAML frontmatter block before invoking Oliver. -- Oliver has no stable release yet: `setup.sh` (and CI) installs download-first from upstream's rolling `builds` release (binary + published `sha256sums.txt`, verified checksum and `oliver --version` reporting exactly the pin) and falls back to a Zig 0.16 source build — in both paths it pins commit `06dd6403c505b4863a54c548c978e494b55eb759` (the `OLIVER_PIN` variable in `setup.sh` — move it deliberately, never implicitly; the 2026-08-21 bump from `9ad86a3` (`9ad86a3763b8bd2f227fd5da94be9fc8ea5fa5fc`) via `06dd640` landed wrap fix #115 (PR #116, `wrap` parseArgs); the same-day bump from `6edb520c` landed Phase 6 S1+S2+S3+S4+S5 (`oliver meta` #107, `wrap` #108, `render` links #109, `plan`+`manifest` #110); the 2026-08-15 bump from `c8a8e06` adopted the builds release plus the `--version` stdout fix and GFM footnote/backref fixes; the 2026-08-14 bump from `e314dbbe` added the XHTML output profile (`--to xhtml`, fail-closed on raw HTML with `error.RawHtmlNotXmlWellFormed`) plus audit fixes #55–#58; the 2026-08-13 bump from `22b3c779` added the Cooklang frontend, CK1–CK5). XHTML is opt-in per page (`render_profile: xhtml` frontmatter) or per site (`render_profile` in `bones/config/rotkeeper.yaml`, default `html`), and needs an XHTML theme wrapper variant like `bones/templates/theme-spooky-dark-xhtml.html`. GFM pipe tables (alignment colons, escaped pipes) are supported; task lists and footnotes are not part of CommonMark and render literally — keep content CommonMark-safe for those. Textile input is supported via `input_format: textile` in `bones/config/rotkeeper.yaml` or via `.textile` source files, which always render as Textile regardless of the config default. Cooklang input works the same way: `input_format: cooklang` or `.cook` source files, which always render as Cooklang. Recipes live under `home/content/recipes/`. +- Oliver has no stable release yet: `setup.sh` (and CI) installs download-first from upstream's rolling `builds` release (binary + published `sha256sums.txt`, verified checksum and `oliver --version` reporting exactly the pin) and falls back to a Zig 0.16 source build — in both paths it pins commit `3f05bacb188ab28ad797430c82d9ee20080c5ed6` (the `OLIVER_PIN` variable in `setup.sh` — move it deliberately, never implicitly; the 2026-08-27 bump from `8460f28` to `3f05bac` landed the v3 generic hook (#269, oliver #127); the same-day bump from `06dd640` to `8460f28` landed shared template contract v2 (#244, oliver PR #126); the 2026-08-21 bump from `9ad86a3` (`9ad86a3763b8bd2f227fd5da94be9fc8ea5fa5fc`) via `06dd640` landed wrap fix #115 (PR #116, `wrap` parseArgs); the same-day bump from `6edb520c` landed Phase 6 S1+S2+S3+S4+S5 (`oliver meta` #107, `wrap` #108, `render` links #109, `plan`+`manifest` #110); the 2026-08-15 bump from `c8a8e06` adopted the builds release plus the `--version` stdout fix and GFM footnote/backref fixes; the 2026-08-14 bump from `e314dbbe` added the XHTML output profile (`--to xhtml`, fail-closed on raw HTML with `error.RawHtmlNotXmlWellFormed`) plus audit fixes #55–#58; the 2026-08-13 bump from `22b3c779` added the Cooklang frontend, CK1–CK5). XHTML is opt-in per page (`render_profile: xhtml` frontmatter) or per site (`render_profile` in `bones/config/rotkeeper.yaml`, default `html`), and needs an XHTML theme wrapper variant like `bones/templates/theme-spooky-dark-xhtml.html`. GFM pipe tables (alignment colons, escaped pipes) are supported; task lists and footnotes are not part of CommonMark and render literally — keep content CommonMark-safe for those. Textile input is supported via `input_format: textile` in `bones/config/rotkeeper.yaml` or via `.textile` source files, which always render as Textile regardless of the config default. Cooklang input works the same way: `input_format: cooklang` or `.cook` source files, which always render as Cooklang. Recipes live under `home/content/recipes/`. ## The BHO model diff --git a/GEMINI.md b/GEMINI.md index 801996e6..22410f31 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -2,7 +2,7 @@ If you are a Gemini agent (or a specialized subagent spawned by Antigravity) working within this workspace, these are your core directives for modifying or assisting with the Rotkeeper project. -**Current Version:** `v0.5.0` +**Current Version:** `v0.8.0` ## Context @@ -13,18 +13,15 @@ Rotkeeper is a terminal-driven flat-file system for compiling markdown "tombs" i 1. **Do not break the Bash Scripts**: The core of Rotkeeper is its `.sh` scripts. When editing them, always preserve the `set -euo pipefail` architecture, the `trap_err` / `cleanup` trap mechanics defined in `rc-utils.sh`, and the `main()` guard pattern. 2. **Respect the Subdirectories**: - - `home/content/` — Strictly for user markdown input. Write `.md` files here. - - `home/content/messages/` — Ingested content from decentralized payloads. Don't write here directly. + - `home/content/` — Strictly for user markdown input. Write `.md`, `.textile`, or `.cook` files here. + - `home/content/messages/` — Preserved payloads and messages. Don't write here directly. - `home/assets/` — Static assets (CSS, images, JS). Copied to `output/assets/` during `assets`. - `output/` — Strictly for generated HTML. Never edit files here manually; edit source markdown or templates instead. - `bones/scripts/` — Where the system logic lives. All scripts source `rc-utils.sh` → `rc-env.sh`. - - `bones/config/` — System configuration. Don't edit `rotkeeper.yaml` directly unless needed. + - `bones/config/` — System configuration (`rotkeeper.yaml`, `version`, `dip-whitelist.txt`). - `bones/templates/` — HTML templates used during render. - `bones/archive/` — Pack archives (tomb tarballs). - - `bones/releases/` — Release distributions. - - `bones/ingested/` — Ingested archive vault. - `bones/tmp/` — Temporary staging. - - `messages-from-my-friends/` — Decentralized inbox for `.tar.gz` payloads to be ingested. 3. **Use the Dispatcher**: Never invoke `bones/scripts/rc-*.sh` directly. Always run `./rotkeeper.sh `. Use `./rotkeeper.sh help` to see available actions. @@ -34,40 +31,50 @@ Rotkeeper is a terminal-driven flat-file system for compiling markdown "tombs" i | Command | Purpose | |---------|---------| -| `init` | Full workspace initialization (reseed + assets + render + scan) | -| `render` | Convert Markdown → HTML via Oliver | +| `init` | Full workspace initialization (paths + assets + render + scan) | +| `render` | Convert Markdown / Textile / Cooklang → HTML via Oliver | | `pack` | Archive output as `.tar.gz` tomb & export `source_markdown` JSON (also: `--content`, `--self`) | -| `release` | Create `lite` and `full` distribution `.zip` files | -| `ingest` | Unpack `.tar.gz` from `messages-from-my-friends/` into content | +| `preflight` | Report Oliver renderer availability and compatibility | +| `release` | Package canonical framework distribution `.zip` | | `scan` | Audit files against manifest | -| `verify` | Check asset SHA256 integrity | | `assets` | Generate asset manifest and copy to output | -| `index` | Build HTML index of rendered output | -| `templates` | List available HTML templates | -| `book` | Aggregate docs into binders (`--all`, `--scriptbook-full`, `--docbook`, etc.) | -| `meta` | Extract frontmatter metadata from content | -| `cleanup` | Back up and prune `bones/` (⚠️ destructive) | -| `reseed` | Reconstruct files from archive or bound markdown | +| `autopsy` | Catalog script help and file-write behavior into reports | +| `glue` | Auto-generate navigation glue for unindexed content directories | +| `links` | Audit rendered HTML links and local asset references | +| `a11y` | Audit theme accessibility (contrast, focus states, legibility) | +| `showcase` | Generate showcase preview pages for every HTML template | +| `dip` | Audit documentation coverage via DIP | +| `book` | Aggregate docs into binders (`--docbook`, `--scriptbook-full`, etc.) | | `status` | Display system state summary | | `bump` | Explicit semver bump (--major/--minor/--patch/--to) + changelog + git commit | -| `test` | Dry-run all scripts + Bats tests | +| `test` | Multi-layout integration test harness matrix (alias: `smoke`) | ## Available Templates -Use in frontmatter as `template: `: +Use in frontmatter as `template: ` (or select via `theme_registry` in `rotkeeper.yaml`): -- `rotkeeper-blog.html` — Blog-style layout -- `rotkeeper-doc.html` — Documentation with navigation -- `theme-dark.html` — Clean, flat dark theme layout - `theme-spooky-dark.html` — Fira Sans/Fira Code journal-terminal theme (default) - `theme-spooky-light.html` — Light reading variant of the Spooky theme +- `theme-spooky-dark-xhtml.html` — Strict XHTML variant of Spooky Dark +- `theme-dark.html` — Clean, flat dark theme layout +- `theme-light.html` — Academic parchment light theme +- `theme-brutal.html` — High-contrast monospaced brutalist layout +- `theme-kawaii.html` — Pastel playful theme +- `theme-overgrown.html` — Forest decay mossy aesthetic +- `theme-phosphor.html` — Amber phosphor CRT terminal aesthetic +- `theme-textpattern.html` — Classic editorial layout with site navigation +- `theme-necropolis.html` — Dedicated 404 Tomb-Not-Found theme +- `theme-daisy.html` — DaisyUI presentation layer prototype +- `theme-daisy-vanilla.html` — Zero-dependency twin of DaisyUI theme +- `rotkeeper-blog.html` — Blog-style layout +- `rotkeeper-doc.html` — Documentation with navigation -## Decentralized Content Pipeline +## Preserving Content When generating content that should be preserved: 1. Write `.md` files with YAML frontmatter in `home/content/`. 2. Run `./rotkeeper.sh pack --content` to bundle into a `.tar.gz`. -3. The archive lands in `bones/archive/` and can be copied to another repo's `messages-from-my-friends/` for ingestion via `./rotkeeper.sh ingest`. +3. The archive lands in `bones/archive/`. ## Workflow Example: Building a New Feature diff --git a/bones/config/rotkeeper.yaml b/bones/config/rotkeeper.yaml index 575019b0..c90039b4 100644 --- a/bones/config/rotkeeper.yaml +++ b/bones/config/rotkeeper.yaml @@ -1,3 +1,5 @@ +project: "Rotkeeper" +author: "draw me an elephant" title: "Rotkeeper Config" description: "Minimal valid config for rendering tests" default_template: "theme-spooky-dark.html" diff --git a/home/content/docs/bones/scripts/index.md b/home/content/docs/bones/scripts/index.md index 94749821..31601e0a 100644 --- a/home/content/docs/bones/scripts/index.md +++ b/home/content/docs/bones/scripts/index.md @@ -30,6 +30,7 @@ This folder contains the core shell scripts that run Rotkeeper's commands. - [tests/]() +- [rc-a11y]() - [rc-assets]() - [rc-autopsy]() - [rc-book]() diff --git a/home/content/docs/bones/scripts/tests/fixtures/template-golden/index.md b/home/content/docs/bones/scripts/tests/fixtures/template-golden/index.md new file mode 100644 index 00000000..523c8db6 --- /dev/null +++ b/home/content/docs/bones/scripts/tests/fixtures/template-golden/index.md @@ -0,0 +1,13 @@ +--- +title: "Index of template-golden" +template: "theme-spooky-dark.html" +rotkeeper_glued: true +--- + +# Index of template-golden + + +- [theme-brutal.golden]() +- [theme-spooky-dark-xhtml.golden]() +- [theme-spooky-dark.golden]() + diff --git a/home/content/docs/daisyui-map.md b/home/content/docs/daisyui-map.md index c03112d8..85f405d4 100644 --- a/home/content/docs/daisyui-map.md +++ b/home/content/docs/daisyui-map.md @@ -15,7 +15,7 @@ tags: # DaisyUI Primitive Map -This is the reference table for issue #249: which DaisyUI component or token implements each Rotkeeper UI primitive. Its consumers are the [DaisyUI prototype theme](#248) (`theme-daisy.html`) and the vanilla fallback that shares the exact same DOM (#250, `theme-daisy-vanilla.html`). The map records what the prototype does today, so the fallback (and any later theme) can target the same primitives with the same markup. +This is the reference table for issue #249: which DaisyUI component or token implements each Rotkeeper UI primitive. Its consumers are the [DaisyUI prototype theme](https://github.com/drawmeanelephant/rotkeeper/issues/248) (`theme-daisy.html`) and the vanilla fallback that shares the exact same DOM (#250, `theme-daisy-vanilla.html`). The map records what the prototype does today, so the fallback (and any later theme) can target the same primitives with the same markup. The live proof is the [showcase page for the theme](../showcase/showcase-daisy.html) and its [zero-dependency twin](../showcase/showcase-daisy-vanilla.html) — the same scaffolded body every theme renders, through the DaisyUI presentation layer and through hand-written CSS respectively. diff --git a/home/content/docs/index.md b/home/content/docs/index.md index c5dfd2e5..bffe3063 100644 --- a/home/content/docs/index.md +++ b/home/content/docs/index.md @@ -119,6 +119,7 @@ Sora prompt: “A glitching wiki carved into obsidian, with glowing CLI runes et - [scripts/]() - [.agentignore](<.agentignore.html>) - [.blessed](<.blessed.html>) +- [.editorconfig](<.editorconfig.html>) - [.gitignore](<.gitignore.html>) - [.shellcheckrc](<.shellcheckrc.html>) - [AGENTS]() @@ -128,17 +129,22 @@ Sora prompt: “A glitching wiki carved into obsidian, with glowing CLI runes et - [GEMINI]() - [README]() - [architecture]() +- [creating-themes]() +- [daisyui-map]() - [dip-matrix]() - [new-ritual]() - [oliver-contract]() - [onboarding]() - [patch]() - [pre-commit]() +- [publishing]() - [rotkeeper-reference]() - [rotkeeper-rituals]() - [rotkeeper-schemas]() - [rotkeeper]() - [textile-guide]() - [textile-showcase]() +- [themes]() - [workflow]() +- [xhtml-profile]() diff --git a/home/content/docs/oliver-contract.md b/home/content/docs/oliver-contract.md index f7985e5c..2747e50e 100644 --- a/home/content/docs/oliver-contract.md +++ b/home/content/docs/oliver-contract.md @@ -151,7 +151,7 @@ oliver wrap --template bones/templates/theme-spooky-dark.html \ The extended tokens joined the dialect with the shared template contract v2 (rotkeeper #244, pin move `06dd640` → `8460f28`, oliver #126). `$version$` is not frontmatter — the adapter injects it from the canonical version source, the same single source `--version` and `@HELP` `{VERSION}` use. `$subtitle$`/`$tags$`/`$asset_meta$` are read from the source frontmatter by the adapter with `yq --front-matter extract` (see provenance below); `$warnings$` is reserved — no adapter feed exists yet, so it substitutes empty. Site **navigation** is delivered as raw HTML through a literal `` placeholder (below), not an escaped token, because every non-literal `wrap` token html-escapes and a real nav is markup. The **v3 generic hook** (rotkeeper #269, pin move `8460f28` → `3f05bac`, oliver #127): the adapter merges every other scalar frontmatter key into `wrap_meta` (typed keys win the merge), so templates can reference any frontmatter field as `$field$` — `$page_type$` on the necropolis 404 theme is the first consumer. Bash keeps `TEMPLATE_DIR` boundary checks; Oliver handles interpolation when `wrap` is present. -## Extended metadata provenance (v2 + v3, implemented) +## Extended metadata provenance (v2 + v3, implemented) The extended tokens are live since the shared template contract v2 landed (rotkeeper #244): `oliver wrap` interpolates them on pins `8460f28`/`3f05bac` (oliver #126/#127, the latter adding the v3 generic hook), and the adapter feeds them into `wrap_meta`: diff --git a/home/content/docs/textile-guide.textile b/home/content/docs/textile-guide.textile index 53c97c3c..7ae8c0c7 100644 --- a/home/content/docs/textile-guide.textile +++ b/home/content/docs/textile-guide.textile @@ -31,7 +31,7 @@ Strikethrough uses a single hyphen pair: -like this-. Underline uses a plus pair h2. Links -A link is "label":target. A title in parentheses after the label becomes the hover title. Parentheses in the URL itself clash with the title syntax and get eaten — keep link URLs parenthetical-free. +A link is @"label":target@. A title in parentheses after the label becomes the hover title. Parentheses in the URL itself clash with the title syntax and get eaten — keep link URLs parenthetical-free. "Textile on Wikipedia":https://en.wikipedia.org/wiki/Textile is external. Bare URLs are links without ceremony: https://opencode.ai diff --git a/home/content/docs/workflow.md b/home/content/docs/workflow.md index d29c6a69..8f5246fa 100644 --- a/home/content/docs/workflow.md +++ b/home/content/docs/workflow.md @@ -13,7 +13,7 @@ tags: This guide walks the full Rotkeeper cycle from a cold checkout to a shipped framework zip. Every operation runs through the dispatcher: `bash rotkeeper.sh ` (or `./rotkeeper.sh`). -The cycle is: **preflight → init → author → render → verify → archive → release**, finished by the release-day checklist in section 8 below. +The cycle is: **preflight → init → author → render → verify → archive → release**, finished by the [release-day checklist](#8-release-day-checklist) in section 8 below. ## 1. Preflight — is the renderer ready? @@ -86,7 +86,7 @@ Archives the rendered HTML and metadata into a versioned tarball under `bones/ar `release` stages the repository against an explicit root-entry allowlist, excludes dev-only and forbidden trees (caches, logs, temp, output, credentials), generates `bones/config/release-manifest.txt` inside the archive, and fails fast on unexpected root entries, missing required files, or forbidden artifacts. The zip lands at `bones/archive/releases/rotkeeper-.zip`. -## 8. Release-day checklist +## 8. Release-day checklist Run the full loop before tagging a version — a release is only real when a clean environment reproduces the advertised workflow: diff --git a/home/content/index.md b/home/content/index.md index 6331d8c9..39973d40 100644 --- a/home/content/index.md +++ b/home/content/index.md @@ -87,5 +87,6 @@ Sora prompt: "A decayed tombstone interface for Rotkeeper.com—ghostly monospac - [recipes/]() - [rotkeeper/]() - [showcase/]() +- [404](<404.html>) - [my-first-page]() diff --git a/home/content/messages/index.md b/home/content/messages/index.md new file mode 100644 index 00000000..b688c155 --- /dev/null +++ b/home/content/messages/index.md @@ -0,0 +1,11 @@ +--- +title: "Index of messages" +template: "theme-spooky-dark.html" +rotkeeper_glued: true +--- + +# Index of messages + + +- [necromancer-notes-soul-audit]() + diff --git a/home/content/showcase/index.md b/home/content/showcase/index.md index 41d56877..c4af11c0 100644 --- a/home/content/showcase/index.md +++ b/home/content/showcase/index.md @@ -132,3 +132,25 @@ Preview every theme through the same content. Each card links to its full showca > Generated by `rotkeeper.sh showcase` — 15 themes. Run `bash rotkeeper.sh render` to refresh. + + +- [showcase-brutal-mac]() +- [showcase-brutal-pwsh]() +- [showcase-brutal-unix]() +- [showcase-brutal]() +- [showcase-daisy-vanilla]() +- [showcase-daisy]() +- [showcase-dark]() +- [showcase-kawaii]() +- [showcase-light]() +- [showcase-necropolis]() +- [showcase-overgrown]() +- [showcase-phosphor]() +- [showcase-preview]() +- [showcase-rotkeeper-blog]() +- [showcase-rotkeeper-doc]() +- [showcase-spooky-dark-xhtml]() +- [showcase-spooky-dark]() +- [showcase-spooky-light]() +- [showcase-textpattern]() +