Bug fixes
- Build lock is keyed on books/ so builds started from different
directories block each other (fixes two tests broken by 89b828efa3).
- ConfigManager resolves the repo root when binder runs from books/ or
binder/, so bib, newsletter, doctor and render paths are right.
- `build <word> --all` treats intro/scaling/agentic/physical as chapter
names (it built every volume), and Ctrl-C stops a --all loop.
- doctor checked chapter names that no longer exist and failed on the
generated _quarto.yml; info defaulted to a deleted books/contents.
- `headings apply --path <typo>` no longer rewrites the whole book;
`bib clean` stops on unreadable chapters instead of dropping entries.
- Discovery falls back to a line scan on invalid YAML instead of crashing.
- Volume III/IV were labeled Volume II in layout and release output.
Output
- Unexpected errors print the command, exception type, and raising
file:line (new cli/core/errors.py), with the traceback on stderr.
- Chapter-not-found suggests the closest names and the list command.
- Silent except blocks in bib lookups, info, headings, layout,
maintenance, preview and debug now say what went wrong.
Cleanup
- Shared qmd_files_under/display_path, file-rewrite loop, doctor result
helper, preview server, clean helpers, volume display names.
- Removed legacy import fallbacks, dead config attributes, legacy backup
restore logic, and unused imports.
Parallel and debug builds removed their worktrees only on normal exit or
Ctrl-C. SIGTERM (timeouts, agent harnesses) and SIGHUP (closed terminal)
killed the process before cleanup, and nothing ever swept the leftovers,
so detached worktrees piled up in $TMPDIR/binder-workspaces (28 GB today).
- run_jobs and the debug bisection now turn SIGTERM/SIGHUP into
KeyboardInterrupt, so their existing cleanup runs.
- run_jobs first removes runs whose binder process has exited (the pid is
in the run directory name) and prunes their worktree registrations.
- --keep-workspaces runs are marked and skipped by the automatic sweep.
- New `binder clean workspaces` removes leftovers on demand, kept runs
included.
Two builds in one worktree overwrite each other's generated _quarto.yml, index.qmd
and freeze files and fail with unrelated-looking errors. Hold an flock on
.binder-build.lock for the serial build path; the OS drops it when the holder dies,
so a killed build never leaves a stale lock. Separate worktrees do not contend.
Retitle the chapter ML Lifecycle and rename its folder, files, assets,
lab, slides, audit data, and instructor links, with redirects for the
old URLs. Section IDs keep the sec-ml-workflow prefix. Update the ch2
hand-off and the conclusion to name the lifecycle.
binder notation concordance <Macro> lists every use of one macro in the
book with its sentence, so a reviewer can see in one place whether all
uses mean what the registry says. The glossary assigner now matches a row
by exact site (line, col, token) when one line holds a symbol with two
meanings, and reads the 'symbol' field of the glossary brief.
A raw symbol's site now includes a descriptive subscript (A_{\text{component}}),
because the registry entry's LaTeX carries it; replacing only the base letter
would render the subscript twice. Index, power and transpose subscripts stay
outside the symbol.
binder notation assign turns a chapter glossary into exact edits with no
judgment: each site takes the glossary row for its glyph and line; retired
aliases take their canonical name; unmatched or doubly matched sites are
returned for review instead of guessed.
Every symbol in math must be a registered mlsysim macro. The check reads
math the way Pandoc does (body math matches Pandoc's AST on all 151 files)
plus figure/table captions, quiz JSON and fmt_math strings, and reports
raw letters, Greek letters, font/accent forms, decorated macros, retired
aliases, unknown commands, and macros a chapter has not declared.
- check notation --scope strict: ratchet on fingerprints (symbol + span),
so a commit can remove raw symbols but never add one; baseline
44,527 sites in 145 files
- check notation --scope conventions: registry naming and field rules
- binder notation report|find|verify|apply: work packages grouped by
section with candidate macros and meanings; registry search by meaning;
KaTeX MathML comparison proving an edit renders exactly as before
(including registry LaTeX changes); a deterministic applier that edits
only the exact tokens it is given and refuses anything that moved
- Exemptions by role, not glyph (exempt.yaml): index letters only in
subscripts, d as a differential, e as a base, T as a transpose
- 23 unit tests plus the Pandoc cross-check
- Refine Chapter 01 to serve as a focused architectural introduction without premature deep dives or duplicate walkthroughs.
- Remove compounding reliability wall and SWE-bench scaling charts from Sections 1.2 and 1.3, articulating reliability dynamics in prose.
- Streamline Section 1.5 closed-loop execution and eliminate redundant trajectory systems boundary diagram.
- Streamline Section 1.6 fail-plausible fault model by removing duplicate war story and request scope diagram.
- Convert Section 1.7 task specification contract into concise narrative prose, removing definition box and specification table.
- Maintain fallacies and pitfalls as a foundational architectural bookend across the stochastic computer subsystems.
- Distribute all 8 biographical footnotes (von Neumann, Wilkes, Karpathy, Gray, Lamport, Saltzer, Amdahl, Denning) evenly across page margins with zero collisions.
- Consolidate Volume 3 bibliography onto canonical books/references.bib and retire references-vol3.bib.
build --parallel [N] (with --each-chapter and --keep-workspaces) runs one job per format, volume, and chapter, each in a disposable git worktree snapshotted from the working tree, and collects logs and output under books/_build/parallel/<run-id>/. debug uses the same runner: the chapter scan can run in parallel, and section bisection now truncates chapters inside a worktree instead of rewriting the checkout's files. Process-group handling, the render environment, and signal handling move into shared core modules.
The cleanup removes the backup-and-comment fast-build path, which no config used and whose edits never reached Quarto. --no-cover now edits the generated _quarto.yml, --print-marks uses the shared TeX header, --all builds every volume, and chapters from several volumes are rejected. The debugger no longer deletes a volume artifact when a chapter has none, and the legacy section bisection script is gone.
- kits, labs, and the MLSys·im docs: _quarto.yml was a symlink to
config/_quarto-html.yml. The website config now lives at _quarto.yml.
The kits PDF build copies config/_quarto-pdf.yml over it for the render
and restores it afterwards, and the CI PDF job copies instead of linking.
- Book builds: the binder CLI wrote books/_quarto.yml and books/index.qmd
as symlinks. ConfigManager.activate_config (formerly setup_symlink) now
writes copies, and the first line of _quarto.yml names its source, which
status, doctor, clean, and save_latex_log read. The mapped chapter
harness snapshots and restores both files by content. The Linux container
job copies index.qmd, as the Windows job already did.
- StaffML: releases/latest was a symlink to the current release directory.
releases/latest.txt now holds the version and is replaced atomically on
publish; vault doctor, release publish, and the paper macro script read
it.
A worktree that still holds the old books/_quarto.yml or index.qmd symlink
is safe: the next build removes the link before writing, so the source
config and volume index are never overwritten through it.
The toolchain folder is now binder/, and the root ./binder symlink is gone.
The command is ./binder/binder: a plain path to the script, with no link and
no install step. Every invocation moved with it: pre-commit entries, workflow
steps, the VS Code extension's command palette, help text, and docs.
- bindery/ paths and bindery.* imports, including the chapter code cells
that import binder.tools.figures, now name binder/.
- Binder (mybinder.org) reads its configuration from a root binder/ folder
and refuses to build when binder/ and .binder/ both exist. .binder/postBuild
and .binder/requirements.txt move into binder/, so the TinyTorch "Launch
Binder" buttons keep working; binder/README.md records which file names the
toolchain must not use there.
- contributors/projects.json still pointed the book's contributor record at
publishing/; it now names binder/, where that .all-contributorsrc lives.
- The margin-figure reader-link audit report linked its 222 figures through
the retired quarto/ tree; the links now resolve under books/.
The hooks reformatted hidden Python cells and trimmed whitespace in the
Volume II chapters whose figure imports this rename touches.
Checks: ./binder/binder check cli passes (contract and canonical hooks),
binder.tools.figures imports, and every workflow YAML file parses.
binder test suite, excluding the four modules that cannot import mlsysim
through the root symlink (fixed separately): 7 failed, 346 passed.
The GitHub repository variables BOOK_ROOT, BOOK_TOOLS, BOOK_DEPS, and
BOOK_DOCKER still name the retired book/ layout and must change when this
reaches origin.