Boris briefing

This page is the map. The public site is about Grok. The machinery underneath is Boris 0.8.1, a Zig content compiler. The Mach-O arm64 binary is ./boris in the repository root (about 18 MB, linked only against libSystem). Upstream: github.com/drawmeanelephant/boris.

What Boris is

Boris compiles a directory of Markdown pages into a static HTML site, a JSON IR, optional RAG packs, an llms.txt, RSS, and a sitemap. It also speaks publication plans for GitHub Pages, Standard.site / ATProto, and Nostr (NIP-23). This repo uses the HTML path only.

It is not a generic static-site generator in the Jekyll sense. Pages form a graph. parent: is a real edge. [[wiki-links]] are real edges. A link to a missing page fails the build (exit 1), it does not render as a dead <a>.

Commands that matter here

./boris --version
./boris --help

# HTML site (what you want)
./boris --input content --html-dir dist --theme themes/boris

# same thing, named
./boris build --input content --html-dir dist --theme themes/boris

# validate, no artifacts
./boris validate --input content --theme themes/boris

# graph health (findings do not fail by default)
./boris check --input content

# impact of touching one page
./boris impact index --input content

# normalized publication plan
./boris plan --profile boris.json

# watch + loopback preview (default port 8090)
./boris watch --input content --html-dir dist --theme themes/boris --serve --port 8090

Bare ./boris with no flags builds HTML under dist/ as target default. This repo always passes --input, --html-dir, and --theme so the command is obvious.

Exit codes: 0 success, 1 content validation, 2 usage, 3 I/O or system.

Tree

boris                 # the compiler (keep this)
boris.json            # publication profile
content/              # pages; entity id = path without .md
  index.md            # trunk
  grok.md
  models.md
  products.md
  company.md
  twitter.md          # pre-X history (parent: company)
  people/elon.md
  people/maye.md
  people/figures.md
  meta/boris.md       # this page (entity id: meta/boris)
  meta/prompts.md     # verbatim user prompts + aardvark limericks
  *.assets/           # images for that page only
  people/*.assets/
themes/boris/
  layouts/main.html   # required slots: {{head}} {{content}}
  assets/css/boris.css
dist/                 # generated; do not edit

Frontmatter

One Markdown file is one page. Flat YAML only: no nested maps, no sequences except tags and relations. Supported keys:

Key Role
title Page title, {{title}}, search
id Override the path-derived entity id
parent Structural parent entity id
tags [a, b]
relations [relates_to=other-id] (and the other relation verbs the compiler allows)
summary Short description
status Publication status
published_at Date string

Entity ids that differ only by case collide. parent must point at a real page and must not cycle. The trunk (index) has no parent.

Body syntax Boris actually understands

<Aside kind="note">
...
</Aside>

Allowed kind values: note, tip, info, warning, danger.

There is no layout frontmatter. Layout is selected by --theme, --html-layout, or --layout-rule (id:, glob:, role:trunk|satellite).

Layout slots

themes/boris/layouts/main.html is the only layout. Keep exactly one of each referenced slot.

Slot Purpose
{{head}} Compiler-owned head extras (required if you ever verify / Nostr / Standard.site)
{{content}} Rendered page (required)
{{title}} Frontmatter title
{{nav}} Graph forest
{{breadcrumb}} Parent chain
{{toc}} In-page headings
{{footer}} Compiler footer
{{asset-url assets/css/boris.css}} Theme file under themes/boris/

The gold card in the bottom-right corner is ordinary HTML in that layout. It is supposed to stay visible. Do not delete it to "clean up" the Grok site; it is the on-ramp for the next agent. The header search reads _boris/search/search-index.json (Boris writes that on every HTML build). The user's original prompts are on The brief.

Modes you should not trip over

Boris will refuse combinations that mix publication kinds. The ones that bite:

Other families, unused here but in --help: standard-site (ATProto / Atmosphere publication, never implicit) and nostr (plan, sign, publish). Signing reads a key once from stdin. Never put a secret in argv, the profile, or the environment.

If the build fails

  1. Read the error. Validation problems are almost always a missing wiki-link target, a bad parent, duplicate id, or illegal frontmatter.
  2. Run ./boris validate --input content --theme themes/boris.
  3. Run ./boris check --input content for graph hygiene.
  4. Staging lives in dist.boris-stage and is committed only on full success. Leave it alone.

A successful HTML build writes dist/**/*.html plus copied assets. Incremental / watch also write dist/.boris-cache/manifest.json.

Init, if you ever start over

./boris init scratch

writes a trunk page, two satellite guides, this theme skeleton, boris.json, and standard-site.json. This repo already replaced that starter with the Grok site. Do not run init in the repo root or it will refuse / clobber.

Version pin

$ ./boris --version
boris/0.8.1

Help text self-describes as: Boris — Zig content compiler (HTML site + IR + optional RAG).

Boris 0.8.1

compiler · not the product

Zig content compiler. Pages live in content/, theme in themes/boris/, binary is ./boris.

./boris --input content --html-dir dist --theme themes/boris