Skip to content

Draft: not yet reviewed by a clinician

Use this page to prepare questions for your care team. It does not replace their advice. Your own targets and doses come from your nephrologist, diabetes team and renal dietitian.

Building the handbook

The handbook is a static site built with MkDocs 1.6.1 and Material for MkDocs 9.7.7 (design note 08). It builds without internet access at runtime, loads nothing from a CDN, and is served by the app at /learn/. These steps are for contributors; readers need nothing.

Set up (once)

python3 -m venv .venv-hb
.venv-hb/bin/pip install --require-hashes -r handbook/requirements.lock

handbook/requirements.in pins mkdocs 1.6.1, mkdocs-material 9.7.7 and pymdown-extensions 12.1; handbook/requirements.lock adds hashes for every package. scripts/lock.sh regenerates it together with the app's locks (a weekly workflow proposes updates as a pull request), so the image, CI and your venv always build with the same versions.

Regenerate, preview, build

.venv-hb/bin/python scripts/build_handbook.py            # regenerate menus, tables, sources
.venv-hb/bin/python scripts/build_handbook.py --totals   # print every menu day's totals and checks
.venv-hb/bin/python scripts/build_handbook.py --check    # CI: fail if a generated file is stale
cd handbook
NO_MKDOCS_2_WARNING=true ../.venv-hb/bin/mkdocs serve    # preview at http://127.0.0.1:8000/learn/
NO_MKDOCS_2_WARNING=true ../.venv-hb/bin/mkdocs build --strict
  • LAN build (served by the app): mkdocs.yml, site_url http://localhost/learn/ (override with HANDBOOK_SITE_URL; set HANDBOOK_APP_LINK=/ for the "Back to the food log" link and the menu days' "Add this day to my plan" links).
  • GitHub Pages build: mkdocs build --strict -f mkdocs.pages.yml with HANDBOOK_SITE_URL set to the Pages URL. Each page's top bar links to the app's demo ("Try the app (demo)"), which the Pages workflow builds beside the handbook with python scripts/build_preview.py --pages <site>/demo.
  • --strict fails the build on a broken link, a page missing from the navigation, a missing snippet, or any external image or script (the privacy plugin never downloads anything).

Generated files (never edit by hand)

File Generated from
handbook/includes/sources.md handbook/sources.yml (reference links appended to every page)
docs/reference/sources.md handbook/sources.yml
docs/eat/_targets-table.md docs/research/targets_by_stage.json (with the diabetes protein floor)
docs/eat/menus/*.md, docs/eat/menus/_overview.md, docs/eat/grocery-lists.md handbook/data/menus.yml and data/foods.json

Each starts with (or carries right after its front matter) <!-- GENERATED by scripts/build_handbook.py; do not edit -->.

Write a page

  1. Start from handbook/templates/medical-page.md (or page.md for app and self-hosting pages).
  2. Fill in the front matter: title, description, slug (the file name, or folder name for index.md), audience, applies_to, status: draft, reviewed_by: "", reviewed_on: null, last_checked, and sources (every id the page cites).
  3. Medical pages keep the sections in order: In short, Your numbers, What to do, Examples, Ask your care team, Get help now if…, Sources. Use === "US units" / === "International" tabs for lab numbers.
  4. Cite with reference links: [KDIGO 2024 CKD guideline][K24], practice point 3.11.5.1.
  5. Pages under t1d/ and medicines/ start with --8<-- "includes/no-dosing.md".
  6. Add the page to nav in handbook/mkdocs.yml.
  7. Run python -m pytest --noconftest tests/test_handbook_content.py (in the handbook venv; --noconftest skips the app's test fixtures, which need the app's own dependencies) and the strict build.

Pages about the app and self-hosting

  • Use handbook/templates/page.md: what the reader wants to do, numbered steps, then "If something goes wrong", "Related pages" and "Sources". These pages do not need the medical section order.
  • Mark a feature that is not in the released app yet with Coming in v0.N, naming the next version (an admonition titled Coming in v0.6, or the words "coming in v0.6" next to it). When the feature ships, search for that phrase, describe what was built, and remove the marker; the v0.3.0 release removed every "coming in v0.3".
  • Name screens and buttons exactly as the app shows them, in bold (Plan → Saved meals). Link to other handbook pages with relative links; the build cannot check links into the app itself.
  • Commands live in one place: the repository's docs/deployment.md, docs/security.md, docs/https.md and SECURITY.md. Self-hosting pages explain the choices and link to the exact section there (an inline link such as docs/deployment.md#backups-and-restore on GitHub); they carry no command blocks of their own. tests/test_deploy.py checks that every such link points at a heading that exists.

How the handbook reaches readers

  • In the app. The image builds the site in a throw-away stage from handbook/requirements.lock (mkdocs build --strict, HANDBOOK_SITE_URL=http://localhost/learn/, HANDBOOK_APP_LINK=/) and the app serves it read-only at /learn/, with no sign-in. Because the theme needs a few inline scripts, /learn has its own security policy that allows exactly those scripts by hash; the app computes the hashes from the built files when it starts (Security). Keep pages free of scripts, inline styles and external media: the content checks below refuse them, and the policy would block them anyway.
  • Links from the app. Warnings, alerts, target notes and meal guidance link to pages by slug (app/guidance/topics.py, app/handbook.py). tests/test_learn_links.py checks that every /learn/ link in the app resolves to a page here, so renaming or moving a page the app links to fails the tests until the link is updated.
  • In CI (the handbook job in .github/workflows/ci.yml; the image jobs wait for it): build_handbook.py --check, the strict build, handbook/tools/check_links.py on the built site, the content checks, the app-link test against the built site, and tools/e2e/learn.py, which serves the built site with the real app and opens it in Chrome at phone and desktop sizes, failing on any security policy violation or failed request. A second job tries the build with Zensical, the Material team's successor, and may fail without blocking anything.
  • On GitHub Pages (optional): .github/workflows/handbook-pages.yml publishes the mkdocs.pages.yml build, with the app's demo in demo/, when the repository variable HANDBOOK_PAGES is true. The demo runs entirely in the visitor's browser with sample data and keeps the app's security policy as a <meta> element. Nothing the visitor does in the demo is stored unless they press Keep my data in this browser and tick "I understand"; then the demo keeps their data in that browser only (nothing is sent anywhere), and the sheet says it can be lost and should be exported. A weekly workflow (handbook-links.yml) checks every external link and opens an issue labelled handbook-links when some are broken.

Add or fix a source

Add an entry to handbook/sources.yml with cite, short, url, licence, checked (the date you checked it) and kind (one of guideline, consensus, study, review, patient-info, government, label, data, project, tool), plus an optional also list of more https:// links and a note with the exact facts you took from it. Then run scripts/build_handbook.py. Never copy text, tables or recipes from NKF, AKF, DaVita or the ADA, or adapt KDIGO tables and figures.

Content checks (tests/test_handbook_content.py)

  • Front matter is complete and valid; slugs are unique; dates are ISO.
  • Every cited id exists in sources.yml and is listed in the page's sources; medical pages cite at least three.
  • Every page is in the navigation; the slugs the app links to (handbook/data/slugs.yml) exist.
  • No <script>, <iframe>, style= or external images in pages.
  • No dosing: no "N units", no "take N mg", and no milligrams next to a medicine name; every page under t1d/ and medicines/ includes the no-dosing box. A reviewer-checked exception needs an inline <!-- dose-ok: reason --> on the same line.
  • Warnings only: reviews older than a year, figures older than this year, long sentences (reading grade above 9), "ESRD" outside the costs page, "renal" in a title.

Review flow

  1. A writer opens a pull request with status: draft.
  2. A named clinical reviewer for the section (see About) checks the facts against the sources, then sets status: reviewed, reviewed_by and reviewed_on; the draft banner then disappears.
  3. The review log on the About page gets a line.

Handbook text is licensed CC BY-NC-SA 4.0 and the code PolyForm Noncommercial 1.0.0; see Licences. The full contributor guide is handbook/README.md.

Sources

Not yet reviewed by a clinician. Facts and sources last checked 2026-10-07.