.html, which `overrides/`
# supplies. `provider` is not a fixed enum, so no plugin is involved.
#
# Which property it reports to is decided in that partial and nowhere
# else — the site is baked into the `pa-*.js` bundle it requests. This
# one is `docs.apprafter.dev`, separate from the landing's.
#
# Cookieless and with no cross-site identifier, so there is no consent
# banner to gate it behind, and docs-site/Caddyfile sets no CSP to widen.
# `docs/hooks/llm_export.py` also writes into `extra`, which is why this
# key is spelled out here rather than assumed absent.
extra:
analytics:
provider: plausible
plugins:
- search
# The CLI reference is generated (`just docsgen-generate`), so its
# nav is generated with it: `docs/reference/cli/SUMMARY.md` is a nav
# fragment docsgen emits alongside the pages. Listing 26 command
# pages by hand here would be a second source of truth that drifts
# the first time a command is added.
- literate-nav:
nav_file: SUMMARY.md
# Provisioned in flake.nix for exactly this and never wired up, so
# until now a rename silently 404'd the published URL — nothing in
# `just docs-check` can see a URL that used to exist, because the
# build only knows the tree it was given.
#
# An entry goes in the SAME commit that renames or deletes a page,
# keyed on the OLD source path. This map is the only record that a URL
# existed; there is nowhere else to infer it from.
#
# What it cannot do: it maps page → page, never anchor → anchor. A
# section that moves to another page leaves its `#fragment` behind.
# In-repo referrers are caught by `--strict` (`links.anchors: warn`
# above); an external deep link lands at the top of the page it named,
# and that is the accepted cost of moving a section.
- redirects:
redirect_maps: {}
# Build hooks. mkdocs loads these by PATH (not as importable modules)
# and calls the same event API a plugin gets, so a hook can do what no
# packaged plugin here can — pygments ships no CUE lexer, and nixpkgs
# has no llms.txt plugin (ADR 0057 §"Keep MkDocs-Material" records both
# as accepted costs).
#
# Hooks live under docs/ so they sit beside what they act on; that also
# puts them inside docs_dir, where mkdocs would otherwise copy them to
# the site as static files — hence the exclude_docs entry above.
hooks:
# Registers a CUE lexer and FAILS THE BUILD if the registration did
# not take. pymdownx.highlight catches a lexer-lookup failure and
# falls back to `text`, so without that self-check a broken hook is a
# green build with every ```cue fence silently unhighlighted.
- docs/hooks/cue_lexer.py
# Writes llms.txt, llms-full.txt and a markdown twin per page into
# the built site. Nothing it writes is committed: all three derive
# from committed content at build time, so they cannot drift from it.
# Listed after the lexer because it captures each page's markdown and
# a hook that edited markdown would have to run first to be seen.
- docs/hooks/llm_export.py
markdown_extensions:
- attr_list # explicit {#stable-anchor} ids — the docs cross-reference gate resolves against these
- admonition
- pymdownx.details
- pymdownx.highlight # explicit: a build hook registers a CUE pygments lexer and needs this extension present to attach to
- pymdownx.superfences:
# Structural concepts (the tier model, the bootstrap → Argo CD
# handover, the need → claim → secret → env chain, the migration
# gate) are carried as `mermaid` diagrams. Material renders these to
# `` and loads mermaid.js itself; the source
# fence reaches the twin/bundle unchanged (it IS the diagram).
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.snippets: # guides include REAL files instead of carrying copies
# Snippet paths are written repo-root-relative (e.g.
# "examples/applications/redis-app.cue"). `!relative $config_dir`
# anchors that root to this file's directory rather than to the
# caller's CWD — a bare `base_path: ["."]` silently depends on
# every caller cd-ing to the repo root first.
base_path: !relative $config_dir
# Traversal above the base is blocked (this is the default; pinned
# here because a repo-root base is worth being explicit about).
restrict_base_path: true
# A missing include is a hard build failure, not a literal
# "--8<--" line nobody notices.
check_paths: true
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tasklist:
custom_checkbox: true
- tables
- toc:
permalink: true
nav:
- Home: index.md
- Operator Guide:
- Overview: operator-guide/index.md
# Ordered by the sequence the work happens in (plan.md 2.23e), not
# by artefact family. Each comment below says which step of that
# sequence a page is, and a page that cannot answer that question
# is in the wrong place.
#
# 1-4: stand a cluster up.
- Quickstart: operator-guide/quickstart.md
- Managing targets: operator-guide/target-store.md
# 5: firewall and domains. Both are about cluster-owned resources
# (the zones on the platform Gateway and the certificate that
# terminates TLS for them), which is operator work.
- Connect a domain: operator-guide/connect-a-domain.md
- Cloudflare Origin CA cert: operator-guide/cloudflare-origin-cert.md
# 6: backup. Moved up nine places. The page tells the reader to set
# it up before they need it, and position 15 of 19 under a heading
# called "Day 2, and getting out of trouble" is not before.
- Back up a cluster: operator-guide/backup-restore.md
- Restore from a backup: operator-guide/restore.md
- Backup retention & integrity: operator-guide/backup-maintenance.md
# 7: dependencies. Secrets comes FIRST of them, up eight places:
# `backup-restore.md` already sends the reader here, and seals a
# SealedSecret on their behalf, before they have met sealing —
# and both `postgres` and `redis` assume sealed credentials exist.
- Secrets: operator-guide/secrets.md
- Postgres: operator-guide/postgres.md
- Redis: operator-guide/redis.md
- JetStream: operator-guide/jetstream.md
- Persistent disk: operator-guide/persistent-disk.md
- Shared volumes: operator-guide/shared-volumes.md
- Shared databases: operator-guide/shared-databases.md
- Egress policy: operator-guide/egress-policy.md
# 8-9: reading a failure, then the platform's own lifecycle.
- Troubleshooting: operator-guide/troubleshooting.md
# Not a setup step: bootstrap already applies the reservations and
# the swap (ADR 0055 decision 7), so this is the retrofit for an
# older node, a node whose swap step failed, or reading the posture.
- Node preparation: operator-guide/node-prep.md
- Platform management: operator-guide/platform-management.md
- Migration plans: operator-guide/migration-plans.md
# Both machine pages sit last on purpose. The `target add` wizard
# already makes the choice, so `Choosing the machine` is the
# reference for the exceptions — a scripted target, a rejected
# SKU, a pre-default cluster — none of which a first-time operator
# is doing; and moving a machine is a rare rebuild off the
# critical path that used to interrupt the backup block.
- Choosing the machine: operator-guide/choosing-the-machine.md
- Moving to a bigger machine: operator-guide/moving-to-a-bigger-machine.md
- Recovery: operator-guide/recovery.md
- How it works:
# Mechanism, split out of the guides by ADR 0058: a guide is a
# recipe, and an explanation of what the platform does behind a
# step is a different job for a different reader. Sits after the
# two guide sections because that is the order the reader meets
# them in — run the recipe first, come here when it surprises you.
- Overview: how-it-works/index.md
- Declared Postgres dependencies: how-it-works/needs-pg.md
- Declared Redis dependencies: how-it-works/needs-redis.md
- Declared JetStream dependencies: how-it-works/needs-jetstream.md
- Declared disk dependencies: how-it-works/needs-disk.md
- Egress derived from declared dependencies: how-it-works/egress-policy.md
- The target store on disk: how-it-works/the-target-store.md
- GitOps and the CUE plugin: how-it-works/gitops-and-the-cue-cmp.md
- Node reservations and swap: how-it-works/node-reservations-and-swap.md
- How the approval gate works: how-it-works/the-approval-gate.md
- What cluster-bootstrap installs: how-it-works/what-cluster-bootstrap-installs.md
- How the platform upgrades itself: how-it-works/platform-upgrades.md
- Cross-application shared volumes: how-it-works/cross-application-shared-volumes.md
- Shared databases: how-it-works/shared-databases.md
- How a restore replays a backup: how-it-works/how-a-restore-works.md
- How retention and the integrity check work: how-it-works/backup-retention-and-checks.md
- Per-environment deploy: how-it-works/per-environment-deploy.md
- The image digest: how-it-works/the-image-digest.md
- The public route: how-it-works/the-public-route.md
- Source credentials: how-it-works/source-credentials.md
- Sealing a secret: how-it-works/sealing-a-secret.md
# Worked examples: a whole assembly rather than one mechanism.
# Both are real deployments in this repository, included from the
# manifests they describe rather than copied.
- "Worked example: the documentation site": how-it-works/deploying-the-docs-site.md
- "Worked example: the landing site and its CMS": how-it-works/deploying-the-landing-and-cms.md
- Right-sizing an application's requests: how-it-works/resources-and-autoscaling.md
- Health checks on a running application: how-it-works/health-checks.md
- Developer Guide:
- Overview: dev-guide/index.md
# Ordered as the work happens (plan.md 2.23e), which for a
# developer starts before the manifest exists.
- Quickstart: dev-guide/quickstart.md
# Steps 3-4: the image is the input the platform takes (ADR 0010),
# and the moving tag is how a new build reaches it. One page,
# because it is one story.
- From source to a running image: dev-guide/build-and-push.md
# What the platform then does with that tag — read before the
# manifest names it, which is why it is above `application-cue`.
- Image iteration: dev-guide/image-iteration.md
# Step 5, and the three things you reach for while filling it in.
- Writing Application.cue: dev-guide/application-cue.md
- Deploying more than one environment: dev-guide/environments.md
- Resources and autoscaling: dev-guide/resources-and-autoscaling.md
- Health checks: dev-guide/health-checks.md
- Secrets: dev-guide/secrets.md
# Last of the "describe your application" run: the reader has now
# met every field that can hold a change for approval, and has not
# yet been told that some of them do.
- When a change needs approval: dev-guide/when-a-change-needs-approval.md
# Steps 6-7: connecting the manifest to the cluster, and the
# credentials a private source needs to do it.
- Private repos & registries: dev-guide/private-repos-and-registries.md
# Step 10. Split out of `image-iteration` (2.23e): a reader looking
# for "undo" does not know to look under "iteration".
- Rolling back a bad deploy: dev-guide/rollback.md
- Reference:
- Overview: reference/index.md
# Expanded by literate-nav from reference/cli/SUMMARY.md, which
# docsgen writes — a new top-level command needs no edit here.
- CLI: reference/cli/
# Hand-written on purpose: only four of these variables are
# declared through clap (`#[arg(env = …)]`), so the generated
# tree cannot carry the rest — they are read by `std::env::var`
# in command code, or by a dependency (miette, owo-colors,
# tracing-subscriber).
- Environment variables: reference/environment.md
- Contributing:
- Overview: contributing/README.md
- Setup: contributing/setup.md
- Writing documentation: contributing/documentation.md
- Documentation gate: contributing/documentation-gate.md
# The file stays under operator-guide/ so its eight inbound
# references keep resolving, but it is listed here: it is the
# runbook for publishing THIS project's documentation, and two of
# its five steps edit this repository — the GHCR package visibility
# of `apprafter/docs`, and `landing/`. Neither is an operator
# action. `llm_export` derives `audience` from the nav group first,
# so the machine-readable audience follows this move for free.
- Publishing this site: operator-guide/publish-the-docs-site.md
- License headers: contributing/license-headers.md
# Which license covers which directory and how the FSL conversion
# works. It was reachable by URL but absent from the nav, which
# made it findable only by search — this is a page visitors look
# for by name.
- Licensing: license.md
- ADRs: adr/README.md
- Status: status.md