Docs Module Guide
This module is the public docs site (docs.numer.ai), migrated from GitBook (numerai/docs) per Linear T-355. Docs are the public contract: public-facing behavior changes update these pages in the same PR — see the docs-sync skill (../skills/docs-sync/SKILL.md).
Structure
- Content: markdown under
numerai-tournament/,numerai-signals/,numerai-crypto/,community/,connect/— one page per route,index.mdper directory. - Site: VitePress (
package.json,.vitepress/config.ts); sidebar lives in.vitepress/sidebar.ts(generated from the GitBook SUMMARY.md at import; hand-maintained now — update it when adding/moving/removing pages). Theme tokens in.vitepress/theme/custom.cssmirror the vue app (vue/src/styles.css). - Serving:
Dockerfilebuilds the site and serves it with nginx (nginx.conf) on port 8080; infra interraform/(Fargate service behind the vue ALB via a host-header rule); deploys via.github/workflows/deploy-docs.yml(staging branch → staging, master → prod). Production deploys enqueue the deployed git SHA for new-user-agent docs ingestion. - Tooling:
scripts/is the poetry moduledocs-assets(image migration/upload, image lint, URL parity check).
Commands
make docs-install/make docs-dev/make docs-build: npm ci / dev server / production build.make check-docs(run from repo root before finishing any change here): python lint+types+tests, image lint, spell check, VitePress build (fails on dead internal links), and URL parity check. Its pre-commit wrapper streams output to the terminal and terminates the full process tree after 120 seconds.make docs-image file=path/to/image.png: upload an image and print its markdown snippet.make docker-docs cmd=stage-build/make tf-docs cmd=stage-plan: container and infra workflows.
Style
- Match the existing pages: short sections,
##/###headings, tables for parameter/score definitions, GitBook-era<figure>blocks are fine for captioned images. - Callouts use VitePress containers:
::: info,::: warning,::: danger,::: tipclosed by:::. - Link between pages with relative
.mdlinks (VitePress resolves them and the build fails on dead ones). - Authored FAQ pages are machine-read.
numerai-tournament/faq.mdandcommunity/office-hours-with-arbitrage.mdare registered inAUTHORED_FAQ_PATHS(new-user-agent/new_user_agent/authored_faq.py), which indexes each###heading ending in?as a standalone question/answer chunk and ranks it slightly above surrounding prose. On these pages write every question as its own###heading ending in?— a bolded question, or one ending in a period, is silently skipped — put the answer in the paragraphs directly beneath it, and use##only to group questions into topics. Renaming or moving one of these pages means updating that registry too, and a new Q&A page only opts in once it is added there.
Images
- Every image uses the canonical production URL under
https://numerai-public-images.s3.us-west-2.amazonaws.com/docs/; other hosts and local/relative paths failmake check-docs. The staging bucket mirrors the same keys but is not referenced by Markdown. - Upload via
make docs-image file=...— slugifies, uploads under thedocs/prefix to both buckets, prints the snippet. Staging (626191215000) and prod (074996771758) buckets are in different AWS accounts: run per env (opts="--env staging") under matching sessions or pass--staging-profile/--prod-profile. - URL format:
https://numerai-public-images.s3.us-west-2.amazonaws.com/docs/<slug>. Cache-Control ispublic, max-age=86400and there is no CDN purge path — prefer renaming a file (new key) over overwriting (--force).
URLs and redirects
redirects/gitbook-urls.txtis the frozen list of URLs the GitBook site served at migration (the SEO contract).docs_assets.check_parity(part ofmake check-docs) fails if any stops resolving.- Moving or renaming a page requires an nginx entry in
redirects/redirect-map.conf(/old-path /new-path;) baked into the image. - Route scheme is
cleanUrls:page.md→/page,dir/index.md→/dir. Canonical URLs have no trailing slash (seecanonicalUrlin.vitepress/config.ts).
One-time GitBook migration (history)
The import ran from numerai/docs at codex/v3-staking-docs (29c7687, master + the unmerged V3 staking docs): docs_assets.migrate uploaded 279 unique assets to both buckets and rewrote 232 image references; a codemod converted hints/embeds, fixed broken references, and renamed README→index; only the 69 published (SUMMARY.md-referenced) pages were imported — the unpublished legacy trees (community-content/, office-hours-with-arbitrage/, tournament/, connect/ extras, help/) stay in the archived repo. Migration decisions (hash-only dedupe, orphan uploads, slug collision suffixes, case-insensitive reference resolution) live in the docs_assets.migrate docstring.
Deploy and cutover state
Merging to master applies terraform (idle origin: ECR, Fargate service, target group, host-header listener rule on the vue ALB for docs.tournament.internal.numer.ai + docs.numer.ai, separate SNI cert) and deploys the container. The public docs.numer.ai DNS lives in Cloudflare outside this repo; cutover = point the Cloudflare docs CNAME (proxied) at docs.tournament.internal.numer.ai, purge, verify redirects/gitbook-urls.txt URLs, and submit the sitemap in Search Console. Until then GitBook keeps serving; rollback is re-pointing DNS.

