docs: documentation site (MkDocs Material) — no-drift, AI-native#12
Conversation
Build the public documentation site so the advertised Documentation URL (https://block.github.io/model-ledger) stops 404ing. Docs-only; no SDK changes. - mkdocs.yml — Material theme, mkdocstrings/Griffe API reference (generated from src/, cannot drift), mermaid, multi-surface content tabs - docs/ — landing (four surfaces + self-building-graph demo), 60s quickstart, concepts (DataNode / Snapshot / Composite), guides (agents/MCP, backends, connectors), recipe cookbook, auto API reference - docs/stylesheets/extra.css — "technical-archive" theme: serif display, warm paper, oxblood accent, hairline rules - docs_hooks/llms_txt.py — build-time llms.txt + llms-full.txt + per-page .md for AI agents, zero extra dependencies - .github/workflows/docs.yml — build --strict on every PR, gh-deploy to GitHub Pages on push to main - pyproject.toml — add [docs] optional-dependencies extra - .pre-commit-config.yaml — exclude mkdocs.yml from check-yaml (custom tags) - .gitignore — ignore /site/ build output Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Craft pass over the docs landing + shareability: - Landing moment: the hero is now two columns; a dependency graph assembles itself on the right — nodes pop in (declared), then edges draw in (connect() links them), visualizing the core thesis. Pure inline SVG + CSS, no JS; respects prefers-reduced-motion. - Open Graph card: scripts/make_og_card.py renders a 1200x630 "technical-archive" social card (docs/assets/og-image.png); overrides/main.html injects per-page og:/twitter: meta so shared links preview beautifully. - Favicon + logo: docs/assets/favicon.svg — a minimal oxblood graph glyph, scalable, light/dark safe. - 404: overrides/404.html — "This node isn't in the graph." with routes home, to the quickstart, and the reference. Docs-only; strict build green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The API reference is generated from source and `mkdocs build --strict` catches
broken references/links. The remaining risk was hand-written prose: a tutorial
snippet calling an API that has since changed. Now the snippets run in CI.
- tests/test_docs_examples.py — extracts the runnable ```python blocks from each
docs page (including tab-indented ones), skips blocks needing external
resources (Snowflake/boto3/live connectors/GitHub), and execs each page's
blocks in one namespace. A renamed param or removed method fails the PR.
- Fixes two real bugs the test caught in the snippets:
* Ledger.record() is record(model, *, event, payload, actor) — event/payload/
actor are keyword-only and required (had conflated it with the MCP tool).
* inventory_at() needs a timezone-aware datetime; naive dates raised TypeError.
point-in-time recipe rewritten to a self-contained, honest demonstration.
- .github/workflows/docs.yml — run the example tests (blocking) before build +
deploy; add an advisory `griffe check` step flagging breaking public-API
changes vs. the base branch.
- pyproject.toml — add griffecli to the [docs] extra for `griffe check`.
Verified: deliberately breaking a snippet turns the test red; reverting is green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b3a7c619f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pull_request: | ||
| paths: | ||
| - "docs/**" | ||
| - "docs_hooks/**" | ||
| - "mkdocs.yml" | ||
| - "src/**" | ||
| - "tests/test_docs_examples.py" |
There was a problem hiding this comment.
Include MkDocs inputs in the workflow path filters
When a PR or main push changes only the new MkDocs templates under overrides/, this workflow will not run because the path filter only includes docs, hooks, config, source, and the docs test. I checked mkdocs.yml and it sets theme.custom_dir: overrides, so overrides/main.html and overrides/404.html are real build inputs; a template-only fix would skip both strict validation and the GitHub Pages deploy, leaving the published site stale or unvalidated. The same gap also applies to dependency/build inputs such as pyproject.toml.
Useful? React with 👍 / 👎.
What
A complete public documentation site for model-ledger, built with MkDocs Material and wired to deploy to GitHub Pages. Docs + CI only — no changes to the SDK's public API.
Highlights
mkdocstrings/Griffe;mkdocs build --strictfails CI on any broken reference, link, or nav entry;tests/test_docs_examples.py), so a changed API breaks the build. (Writing this already caught two real bugs in the snippets.)llms.txt,llms-full.txt, and a raw.mdfor every page (small local build hook), so the docs are consumable by coding agents.Deploy
.github/workflows/docs.ymlbuilds with--stricton every PR and runsmkdocs gh-deployon push tomain, publishing to https://block.github.io/model-ledger/.Adds
documentationtooling:docsoptional-dependencies extra (mkdocs-material,mkdocstrings[python],griffecli).mkdocs.yml,docs/,docs_hooks/,overrides/,scripts/make_og_card.py.🤖 Generated with Claude Code