Skip to content

fix(language): the docs gain a tutorial, a glossary and a Python API page, lose a third of the words a model writer reads, and say data is attached rather than bound - #695

Closed
FBumann wants to merge 38 commits into
mainfrom
claude/docs-overhaul
Closed

FBumann wants to merge 38 commits into
mainfrom
claude/docs-overhaul

Conversation

@FBumann

@FBumann FBumann commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Prompt: Can you do one PR for me to look at instead of a 10-stack? But keep the stack intact

Note

The following content was generated by AI.

What this changes

This PR shows the stack as one diff against main, frozen at ffcd68e. It has the same content as the head of #696. The stack has moved on since: #697 sits on top, and this PR does not get it. Merge either this PR or the stack, not both.

What this contains, bottom to top
  1. docs: a glossary defines each word the docs use in a fixed sense #675 A glossary, later cut to the words no reference page owns, plus a table of words with two senses.
  2. fix(language): an unknown operator's refusal points at the limits page instead of an escape key that does not exist #676 An unknown operator's refusal points at docs/about/limits.md instead of an escape: key that does not exist. The curve-by-hand how-to writes sos: {along: …}.
  3. docs: what spec.expand() returns is stated once, as a different model that binds the same data #677 spec.expand() is described once, not in contradicting copies.
  4. docs: a development section holds the PyPSA parity pages and the contributing guide #678 A Development section in the nav.
  5. docs: one Python API page documents every public name, including the typesetting functions #679 One Python API page for every name in math_spec.__all__, in Reference beside "Typeset the math".
  6. docs: a first tutorial writes the dispatch model one block at a time, checks it and prints it #680 A first tutorial, built from dispatch.yaml.
  7. docs: the notation page heads each section with the construct it shows #682 The notation page is headed by construct.
  8. docs: the nav keeps tutorials, how-to guides, reference and about for model writers, and puts the rest under development #683 The nav: Home, Tutorials, How-to guides, Reference, About for model writers. Development holds Building on math-spec, Contributing, and Proofs of concept.
  9. docs: each page keeps only what its reader needs, and a fact stated twice keeps one home #686 The cut. The model-writer sections go from 35,678 to about 24,200 words.
  10. fix(language): messages and docs say data is attached rather than bound, so a bound is only a variable's limit #694 Data is "attached", never "bound", so "bound" means only a variable's limit.
  11. docs: what spec.expand() returns is documented on the model writer's python api page, and reading.md keeps only which program an engine reads #696 The Spec.expand docstring, on the model-writer API page, is the home for the call. This was first a commit inside docs: each page keeps only what its reader needs, and a fact stated twice keeps one home #686. docs: each page keeps only what its reader needs, and a fact stated twice keeps one home #686 now reverts it, and docs: what spec.expand() returns is documented on the model writer's python api page, and reading.md keeps only which program an engine reads #696 re-applies it, so the content here is unchanged.

Not in this PR: #697 (a Program API page for engine authors, no per-module pages, and file-and-program.md folded into reading.md).

Totals and gates at ffcd68e

Why

One diff is easier to review than eleven.

🤖 Generated with Claude Code

https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y

The glossary sits in the Reference section after "Reading a loaded model",
and the language index links it. Each entry links the page that owns the
rule, and a closing table names the words the pages use in two senses.

Sentences, measured with the docs-writing script: n 81, avg 16.5,
median 16, over 25: 8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…e instead of an escape key that does not exist

The message told the author to "use a declared escape", and the closed
schema has no `escape:` key. It now says a file cannot add an operator and
names docs/about/limits.md. The module docstring said the same.

The sos fragment in the curve-by-hand how-to wrote `over: bp`, which the
schema refuses; the key is `along`.

The test that asserted 'escape' in the message now asserts the limits page,
and a new test asserts the absence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
… vocabulary

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…ributing guide

The six PyPSA pages leave Reference > Examples and Contributing leaves
About. A new last nav section, Development, holds both. It is outside
the four Diataxis kinds. The PyPSA files stay in docs/examples/, where
tools/gallery.py writes them; their content is unchanged.

The examples catalogue lists only the Examples pages and points once
to the PyPSA pages. The nav comments, the docs-writing skill and
CONTRIBUTING.md now describe the section.

Sentences (docs-writing section 7): docs/examples/index.md n 11,
avg 11.5, median 11, over25 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
… that binds the same data

The call is described on reading.md "Formulations written out"; what a
block writes out is on piecewise.md "Writing a formulation out". Every
other page says one sentence and links there. file-and-program.md loses
"The rows", which contradicted the "same math" wording elsewhere.

Words (wc -w), 11586 -> 11265 over the ten pages.

Sentences (docs-writing section 7), before -> after:
- piecewise.md: n 71 median 15 over25 12 -> n 67 median 14 over25 10
- reading.md: n 80 median 15 over25 13 -> n 83 median 15 over25 12
- file-and-program.md: n 32 median 16 over25 4 -> n 25 median 18 over25 4
- typeset.md: n 42 median 16 over25 4 -> n 41 median 16 over25 4
- see-an-expansion.md: n 28 median 11 over25 2 -> n 28 median 9 over25 2
- what-counts-as-public-api.md: n 21 median 15 over25 4 -> n 20 median 15 over25 3
- limits.md: n 55 median 19 over25 14 -> n 55 median 19 over25 13

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…typesetting functions

docs/reference/api.md renders each name in math_spec.__all__ from its
docstring, grouped by task, and links reading.md for the classes in
math_spec.program. It sits under Reference, before Examples.

The per-module pages skipped every __init__.py, so to_latex, to_typst,
to_markdown, typeset, typeset_declaration and FORMATS had no page. The
hook now appends those per-module pages to the Development section as
Modules. The docs-writing skill and the contributing page say so.

Sentences (docs-writing section 7): docs/reference/api.md n 23, avg
3.1, median 2, over25 0; the script counts the directive option lines.
The four prose sentences are 16, 1 (the wrapped "task."), 15 and 7
words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
… checks it and prints it

docs/first-model.md opens the Tutorials nav section. Every command output
on the page was produced by running the command on the file shown above it.

Sentence length, docs/first-model.md: n 52, avg 6.9, median 6, over 25: 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
Headings name the construct as a topic noun ("Sum through a relation",
"Cyclic forward shift") rather than the golden model's declaration name,
and the rows are grouped by construct family in the order of the language
reference. Each YAML fragment keeps its block key, so a reader still sees
whether a row is a constraint, an expression or a variable. The intro says
what the page shows and where the operator reference is; the test facts
were already in the generator's docstring.

The generator refuses a fixture declaration with no heading, one placed
twice, and two sections with the same heading.

Page: 1479 -> 1547 lines, 5972 -> 6153 words (block keys and longer
headings; the intro went from 262 to 113 words).
Sentences, whole page: n 116 avg 14.7 median 13 over25 10 -> n 110 avg
14.0 median 13 over25 7. Intro: n 11 avg 23.3 median 17 over25 3 -> n 9
avg 12.0 median 11 over25 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…b3' into claude/fix-sos-key-and-escape-message
…on math-spec, and one for development

Each top-level tab is one reader. Writing models holds the tutorial, the
how-to guides, the language reference, the notation and typeset pages, the
glossary, the examples, the limits and the changelog. Building on math-spec
holds reading.md, the Python API, the file and the program, and what counts
as language. Development holds contributing, what counts as public API, the
PyPSA parity pages and the module pages. Folders stay by kind, so no URL
changes.

The docs-writing skill and CONTRIBUTING.md say the nav is by reader, then by
kind. The skill's link to reading.md points at the page's current path. The
tutorial links the glossary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…s, and the notation page moves to development

The glossary keeps only the words no reference page owns, and the words with
two senses (1588 to 616 words). The tutorial shows each new block once, and
the whole file once, folded (1419 to 767 words); every output on it is what
the command prints. The notation page renders the typesetting test model, so
it moves to the Development tab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…how-tos lose what another page already says

README drops the "Why" section, the symbols paragraph, the shell block and the
Spec and Program section, and links the pages that own them. limits.md drops
"Solver capability", which what-counts-as-language owns, the composition
section and the history in its table. file-and-program keeps only the why.
reading.md keeps the API and drops the engine recipe and the instructions.
typeset shows the symbol table once. The how-tos drop rationale;
installation gives the one install command. Words, these files: 12310 to 9797.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…rogress)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…e, which moved to development

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…he top, and everything a model writer does not need under development

Development holds three groups: building on math-spec (reading a loaded
model, the Python API, the file and the program, what counts as language),
contributing (with what counts as public API and the module pages), and
proofs of concept (the PyPSA pages). This replaces the tabs by reader, which
repeated Reference and About in two tabs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…nd, so a bound is only a variable's limit

"The data binds", "the data bound to", "at bind" and "Bind the rows" become
"attach" throughout: the refusal messages in src (the assumption sentence,
the missing-breakpoint message, the degree and dtype messages), their
docstrings, the docs, the expansion fixtures and the tests that match them.
The glossary's Bind entry is now Attach, and says "bound" means only a
lower or upper limit on a variable.

Kept, as a different sense: operator precedence ("NOT binds tighter"), a
macro call site binding its formals, the binding side of a bounded link,
and Python name binding.

Regenerated: schema/math-spec.schema.json, tests/typesetting/golden, the
expansion, notation and gallery pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
@read-the-docs-community

read-the-docs-community Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

…ypeset and check pages link it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
…python api page, and reading.md keeps only which program an engine reads

The Spec.expand docstring, which the Python API page in Reference renders, is
now the one home for the call: the kinds and their order, the ValueError, a
different model that takes the same data, itself where there is nothing to
write out, and no caching. It no longer says "the same math". reading.md's
section says which program an engine reads. Five links point at the API
entry. The three claims reading.md checked move to tests/test_expand.py, and
the page's claim count drops from 22 to 19. Schema regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
# Conflicts:
#	docs/reference/reading.md
#	src/math_spec/model.py
main's #689 makes an open bound null and a bound never infinite. The
variables section keeps that rule and drops the warning box, as this
branch's cut did. The quoted advice message on errors.md and check.md now
says "bounds.lower is open", which is what advice prints since #689, and
reading.md no longer names an infinite bound among what to_yaml leaves out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A89tReSh8rTBG9ocy7688y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants