Skip to main content
Researchers, engineers and the coding agents they send ahead of them read these pages. They should read the way PyTorch, DSPy and Unsloth read: one column, a signature you can trust, an example that runs, a number with its interval. This is the standard for every page under docs/; Style covers the code the pages show, and the constitution rules both.

Principles

  1. The first screen computes something. Before the reader scrolls, the page has said what it computes, shown the call, and shown the printed result. Prose about the product comes after the number, never before it. (Docs teach then prove.)
  2. A number is a row in a table. Value, interval, n, seed, and the version that produced it, in that order. A mean in running text is a claim; the same mean in a row with its interval is a result. A flat result gets a row too. (Repeatable science. Held-out or it did not happen.)
  3. Signatures are the interpreter’s. Every public name is shown with the signature and defaults the interpreter reports, generated from the package, never typed by hand. A default the reader cannot see in the signature is a default the page has hidden. (Every default named and sourced.)
  4. Density over decoration. Text in one column, facts in tables, figures only for a mechanism words cannot carry. Hierarchy comes from type size and weight, not from color, cards or hero art. The reader should be able to find a knob in one scroll. (Ergonomics as a feature.)
  5. One source per claim. A method links its numbered reference; a result links the recipe that reproduces it; a hosted step says what it costs and what runs without it. (Replicated papers as proof. Bring your own keys and compute. Open by default.)

Page templates

Every page is one of four. Frontmatter carries title, sidebarTitle and a one-sentence description, which Mintlify renders under the title, so the body never repeats it. Sections come in the order below; a section with nothing to say is left out, never left thin.

Tutorial

get-started/*, and any guide that walks one run start to finish (evals, character training, reward hacking, safety evals).
  1. What you get. Two or three sentences ending in the printed result the reader will see, quoted as the library prints it.
  2. Before you start. Install line, and whether a key is needed. “No key, no network” when true.
  3. Steps. Numbered ## 1. headings or <Steps>. Each step is one sentence of intent, one code block, and the output block it produces. No step introduces a knob it does not use.
  4. Read the number. A measurement table (below) and one sentence per column on what moves it.
  5. Next. At most four cards, each naming the page and what it adds.

Concept

concepts/*, simulations, the engine. No code needed; one figure at most.
  1. The claim. One paragraph: what the mechanism does and what it refuses to do.
  2. Mechanism. Steps or a table, each row naming the code path.
  3. Measurement. Which number the mechanism produces and how its interval is formed.
  4. Questions. Bold question, plain answer, three to six of them.
  5. References. Numbered, primary sources, the form on the engine. rlhfbook.com is one entry, not the authority.

Reference

reference/*: the long form, in the order a run happens.
  1. Scope. One paragraph on what the page covers and the API page it sits on top of.
  2. Sections in run order. Simulate, grade, trust, select, export, push. A knob appears in a table before it appears in prose.
  3. Knob tables. Parameter | Default | Source | Meaning, one row per knob, the default as the signature shows it, the source as a defaults.py name, a chapter or a paper.
  4. Output. What each returned object carries, field by field, with the name it prints as when the two differ.

API

api/*, generated by scripts/gen_api_docs.py; hand edits are overwritten and --check fails the PR.
  1. Title is the module path. Under it, the count of public names and the import line.
  2. Index table. Name | What it does, the first sentence of each docstring, linked to its section.
  3. One ## per defining submodule when the page has more than one, with that module’s first docstring paragraph.
  4. One ### per name. The signature fence (class prefix for classes, one parameter per line past 84 columns), the file that defines it linked to GitHub, then the docstring. Methods with docstrings follow as ####.
The docstring is the page. Line one says what the call computes; then the parameters in prose; then a Reference line. A name with no docstring shows no docstring in the index table, which is the fix list.

Typography and color

Set in docs/docs.json; the values are the brand tokens. Mintlify has no key for the code font, so docs/style.css sets it: JetBrains Mono, ligatures off so -> copies as typed, and tabular-nums on tables and code so 0.67 [0.55..0.78] lines up under 0.19 [0.00..0.38]. The file declares the tokens as --wai-* custom properties and touches nothing else; Mintlify’s class names are not a stable surface. The tokens, as style.css names them: ink #0B1220 for headings and the dark page; body #4B5563 for running text; muted #6B7280 for captions, table headers and timestamps; line #E5E7EB for rules; surface #F4F6F9 for cards and table backgrounds; green #5CB08A for accents on ink and the loop in the wordmark; deep green #3F8F6B for links on white; tints #F0FAF5 and #D7F0E3 for callout and selected-row backgrounds. Callouts: <Note> for a fact that changes what the reader does next, <Warning> for a way to get a wrong number, <Tip> for a shorter path. No <Info>, no <Check>, at most one per screen.

Presenting a measurement

Every number a page reports goes in a table with these columns; a column that does not apply is left out, the interval column never is. That row set is the offline quickstart on whileai 0.82; the library prints the same values as pass@1 0.67 [0.55..0.78] | pass^4 (pass_pow_k) 0.19 [0.00..0.38] | pass@4 1.00 [1.00..1.00]. Rules:
  • n counts tasks, never rollouts; the interval is a bootstrap over tasks (rlhfbook.com ch. 16). Say so once per page.
  • In prose the interval reads “0.67 (0.55 to 0.78)”. In a printed line it is [lo..hi], as the library prints it. Never a bare mean.
  • A before and after is one table: Metric | Before | After | Delta | 95% interval | n paired | Verdict, the verdict being the word delta_report prints (up, flat, DOWN), and a row for every must_not_regress marker whether or not it moved.
  • One eval run per side says moved_unreplicated; the note column says how many re-runs make it moved. A number from a paper carries its reference number; one from a recipe links the folder and names the seed.
  • Text output blocks (```text) show the library’s own print, unedited; trimmed lines are marked ....

Presenting a signature

The generator writes signatures; guides quote calls. Both follow the same shape.
  • The fence holds the interpreter’s signature: every parameter, its annotation and its default, one per line once the one-line form passes 84 columns, class in front of a class.
  • Under the fence, the defining file linked on GitHub at main: one click to the source, and no line numbers, so --check does not churn when the module is edited elsewhere.
  • Parameters are explained in prose, one bullet per parameter that matters, in the docstring’s own words: name in backticks, what it changes, its default and the source of that default.
  • A knob table in a guide uses Parameter | Default | Source | Meaning and never lists a default the signature does not show.
  • The example after the parameters runs offline (simulator=False, the seeded agent, a lambda judge) unless the page is about a hosted step, and it ends with the line it prints.

Figures and diagrams

A figure earns its place when the mechanism has more than three moving parts (the row pipeline) or the point is a curve (proxy against gold reward under KL). Otherwise a table.
  • SVG, in docs/, a light and dark pair or one file in currentColor and the tokens. One idea per figure; labels are the names the code uses (structured, llm_guided).
  • A chart plots the interval, not just the point; the caption states what is plotted, n and seed.
  • No raster screenshots of code or terminals (those are text blocks), no hero images, no illustrative art. Card icons are the only decoration.

What never appears

  • Marketing adjectives: powerful, seamless, effortless, blazing, cutting-edge, state-of-the-art, frontier, robust, simple, easy, just.
  • A number without an interval, or an interval without n.
  • A snippet that cannot run as pasted: undefined names, elided imports, ... inside a call.
  • A default without its source, or a source that is not a chapter, a paper or a defaults.py name.
  • Em dashes, exclamation marks, emoji, and “we’re excited”.
  • The description repeated as the first paragraph; two pages that explain one mechanism; notes about the old package name outside the install page.

Appendix A: what the audit found in the prose

  • Three pages explain the eight-step engine: engine.md, concepts/engine.mdx and simulations.md. Keep one Concept page and fold the estimator table into the reference. The sidebar shows “The engine” twice.
  • evals.md opens with a naming note and a trial-quota paragraph before step 1, numbers a step 3b, and repeats the return-shapes table from simulations.md. It is a Tutorial with no code on the first screen.
  • reference/overview.md mixes a tutorial (“Start here”), a concept (“The recipe”) and a reference; the rename note is the second element. Its figure has no dark variant.
  • reference/platform.md is 7,800 words under seven headings. Split by run order into pages under the Platform tab, which holds three today.
  • reference/parameters.md: the engine-internals table has 60 rows and no Source column; defaults.py already carries the reason per knob.
  • concepts/how-it-works.mdx quotes “5% to 30%” with no interval and no n; concepts/faq.mdx answers “who is it for” with buyers, not researchers.
  • get-started/your-model-and-key.mdx and connect-your-agent.mdx carry the same backend table. Keep one and link.
  • The character, reward-hacking and safety guides end in real output, which is right; their headline lines also belong in a measurement table.
  • API: SimulationData, Rubric, format_judge_trust, format_stages and marker_names have no docstring; SimulationData shows a 39-field constructor because it is a record dataclass.
  • The Guides group mixes Tutorials (evals) with Concepts (simulations). Name the groups by template: Tutorials, Concepts, Reference, API.

Appendix B: the site and the docs as one product

withwhile.com, /evals and /compare, read against the same rules.
  • Type. Same Inter, but the site sets headings bold and the docs now set 600; pick 600 on both. The site’s code font should be JetBrains Mono like the docs. Code blocks already share vitesse-dark.
  • Wordmark. The docs logo draws the loop in a blue-to-green gradient (#7fb3e6), a color outside the token list; the site headline renders “While.” with a period. One SVG, green loop, on both.
  • Numbers. The home results table carries 95% intervals and a negative result, which is the standard. The three case studies show gains with no interval and no n; /evals says “37 of 160 runs” with no pass^k; /compare has no numbers at all. Every claim gets the row format above and a link to the recipe that produced it.
  • Copy. Em dashes in the home subhead and on /evals; “frontier”, “real gap” and “the next generation of agents” are on the never list.
  • Hand-off. The site links to the docs root three times. The “loop, as code” block should be the docs index program byte for byte and link to the quickstart; each primitive in the Primitives section should link its API page; the site’s /platform should link the docs Platform tab.
  • Density. Home sections five to seven (science, defaults.py, estimators) restate concepts/engine; replace with the eight-step table and a link, and let the docs own the references.
  • Footer. Site: Product, Resources, Company. Docs, now: Library, Reference, Project. Mirror the link sets so the last screen of either reaches the other in one click.
Last modified on September 19, 2026