Skip to content

Documentation Architecture

The repository uses Zensical for both user-facing documentation and linked maintainer notes.

Layout

  • zensical.toml is the site configuration.
  • docs/ is the Markdown source directory.
  • site/ is the generated static output directory and remains ignored by git.
  • The explicit nav in zensical.toml lists user-facing sections and one maintainer-notes entry point.
  • docs/AI/README.md indexes every durable technical note by owning subsystem; individual notes stay out of the top-level navigation.
  • docs/overrides/ holds the theme's Jinja templates (currently 404.html) and is wired up through theme.custom_dir in zensical.toml.

Theme Overrides

The overrides directory lives under docs/ rather than at the repository root so the root stays limited to source, tests, scripts, and configuration. Zensical resolves theme.custom_dir relative to zensical.toml, so the setting is custom_dir = "docs/overrides".

The cost of nesting overrides inside docs_dir is that the build treats them as static assets and copies them verbatim to site/overrides/, which would publish unrendered Jinja source. zensical.toml declares the MkDocs-standard exclude_docs key for this, but Zensical 0.0.62 does not implement it and ignores it silently, so the CI docs step deletes site/overrides after the build. Drop that cleanup once a Zensical release honours exclude_docs.

Alternatives considered:

  • Keeping overrides/ at the repository root. This avoids the copied-asset problem entirely, but adds a root-level directory that exists purely for the docs build.
  • Pointing custom_dir at a directory outside both the root and docs/, such as .zensical/overrides. This hides templates that maintainers edit as often as the pages themselves.

Content Split

Use the main docs for:

  • conceptual explanations,
  • setup and notebook workflows,
  • supported environments and algorithms,
  • curated API references generated from Python docstrings,
  • glossary and troubleshooting.

Main docs must describe executable commands and current artifact/configuration contracts. Prefer repository-relative paths in examples; cluster aliases that exist only on one machine should be called out explicitly.

Use docs/AI/ for:

  • implementation details,
  • design rationale,
  • migration notes,
  • known edge cases,
  • alternatives considered.

Do not expand docs/Overview.md with technical depth. It is now a compatibility pointer into the richer docs tree.

User-Page Map (refreshed 2026-10-06)

The user pages were last brought up to date with the September–October work on 2026-10-06. Four pages exist specifically for that work, and each is the user-facing entry point for a cluster of AI notes:

User page Summarizes
concepts/guarantees.md shielding/exact-anytime-adversarial.md, anytime-ambiguity-sets.md, robust-margin.md, pursuit-rate-radii.md, randomised-shield.md, opponent-model/opponent-level-gap.md
workflows/final-policy-evaluation.md reinforcement-learning/final-policy-*.md
workflows/analysis-and-audits.md the scripts/ catalogue and the predeclared-screen procedure
workflows/ablations.md notebooks/ablation-notebooks.md, opponent-model/private-reward-inference-ablation.md, experiments/floor-patience-screen.md

When a new analysis script, notebook key, or shield variant lands, add it to the matching page and to reference/configuration.md rather than only to an AI note. User pages state current defaults and campaign settings, not results; dated results stay in reports/ and goal.md.

The teaching website under shielding/teaching-site/ is inside docs_dir, so Zensical copies its self-contained index.html as a static asset and rewrites relative links to it. User pages link to AI/shielding/teaching-site/index.html directly; the strict build checks the link target exists.

Audit Reports

Result and audit reports live in reports/, outside the Zensical site, in one folder per month of the report's date: reports/<MM>/, for example reports/08/2026-08-16 reward-safety and guarantee audit.md. A draft carries a DRAFT prefix in the folder of its drafting month, and moves to the folder of its completion date when it is renamed to that date.

A finished report is a record and is not rewritten when later work supersedes it. Instead, each superseded passage gets a dated blockquote, > Outdated as of YYYY-MM-DD: ..., stating what changed and pointing to the report that replaces it. Update those pointers when the replacing report is renamed.

Commands

Preview locally:

uv run zensical serve

Build strictly:

uv run zensical build --strict

Zensical is a dev dependency in pyproject.toml, so use uv run rather than relying on a globally installed executable.

mkdocstrings-python is also a dev dependency. Zensical uses it to render the curated API pages under docs/reference/api/.

Update Rules

When changing a user-facing workflow, update the relevant docs/workflows/ page.

When changing a concept that users need to understand before running experiments, update docs/concepts/.

When adding or renaming a reusable public Python surface, update the matching API page under docs/reference/api/. Prefer explicit module.symbol blocks for high-value symbols rather than documenting whole modules indiscriminately.

When changing implementation details that future agents or developers need, add or update an AI note and link to it from docs/AI/README.md.

Every AI note belongs in an owning subfolder such as architecture/, joint-graphs/, opponent-model/, shielding/, notebooks/, or operations/. Do not recreate a flat collection at the root.

Documentation-only changes should run both:

uv run python scripts/run_tests.py changed
uv run zensical build --strict