METHOD.md marks each applicable clause met, partial, or open, including the
departures: no expert committee, no human indexing trial, and model-assisted
decisions the standard assumes people make.
- Two audits applied the all-and-some test to 127 specializes edges; the 27
both failed are retyped or removed, and specializes now exports as
skos:broader while part-of stays associative under Z39.19 8.3.3.2
- Compiler enforces SKOS S27; tests validate the export
- Concepts record added_in and computed warrant counts
- Release adds an OWL relations vocabulary, DCAT metadata, CITATION.cff,
scope notes, and redirect pages for identifiers
- Agreement reports Hooper and Rolling consistency
878 concepts (+71 net), 2,020 relationships (+326, -25, 25 reworded), 27
redefinitions, 67 alias sets, 33 background tags, 6 moves; guides 16 roles,
24 symptoms, 7 paths; gaps: attention-FFN disaggregation closed, verifiable
ML computation and reasoning-trace monitoring declared. Coverage judgments
updated for the new concepts and a blind held-out checklist added
(OSDI/NSDI/EuroSys/ASPLOS 2026, 202 papers, 22.3% covered, 96.5% homed).
Symptoms now declare the quantity they are measured by (`quantities`), so a
symptom's own metric no longer poses as a cause; the compiler, the StaffML
loader, and the explorer accept a check or lever that touches a cause or the
quantity and reject a quantity listed in another bucket.
README and CHANGELOG record the method, the numbers, and the open author
decisions.
The release (identifiers, definitions, relationships, guides, and every
download) moves from CC BY-NC-SA to CC BY 4.0 so courses and companies
can reuse it; the book prose keeps its own license.
Roles, production symptoms, and learning paths load from
shared/concepts/ml-systems-guides.yml. Every subject and concept must
exist, and every symptom check and lever must share a relationship with
one of the symptom's causes.
- Repair 16 unquoted YAML flow-mapping comma splits (key: null) across 6 sources and 9 relationships in ml-systems-field.yml and 1 source in ml-systems-framework.yml that truncated published scope, predicate, conditions, and role strings.
- Remove 2 case-insensitive duplicate aliases within the same concept (mlsys.matrix-unit and mlsys.kv-cache-eviction).
- Update 13 covered topics in courses-and-standards-2026.yml and mlsys-papers-2025-2026.yml whose subject field disagreed with the home of their cited concepts.
- Harden field_graph.py, framework.py, taxonomy_coverage.py, and taxonomy_agreement.py (with regression tests) to reject unknown keys, within-concept duplicate aliases, concepts with fewer than two relationships, disconnected concept graphs, and covered checklist topics whose subject disagrees with their concept homes.
Three independent reviewers (gpt-6.1-sol, gemini-4-argon-high,
claude-opus-5-5) reviewed 0.2 through different lenses; the merged set
was cross-checked item by item by all three before acceptance, and ten
more concepts came from StaffML questions that could not be tagged.
- 63 concepts and 148 relationships (798 concepts, 1,679 relationships)
- 15 definitions revised against their existing relationships; aliases
added to 9 more; TPOT and inter-token latency separated
- PII de-identification moved to Q3.3, inference compute estimate to F1.2
- Gaps: four closed, emerging substrates narrowed to photonic compute,
attention-FFN disaggregation added
- Coverage judgments name the covered mechanism (GRPO, 1F1B, denial of
wallet); AccelOpt out of scope like TritorX
The JSON download omitted the declared gaps shown on the page, and
concept records carried no pointer into the books, so a researcher or
instructor working from the download could not see either. JSON now
includes gaps (with subject code) and each concept's book_passages; the
concepts CSV gains a taught_in column.
Five names each resolved to two concepts, so a glossary lookup or a
tagger could land on either. The dedicated concept keeps the name:
Pareto frontier, SIL (safety integrity level), model export, data
loader (host-side loading), app memory limit (on-device budget). The
compiler now rejects a label or alias, case- and space-insensitive,
shared by two concepts.
A leftover build-output folder (books/vol1/02_ml_systems/, untracked HTML)
beside the renamed 02_system_paradigms/ made v1/02 ambiguous, so
concepts build and check failed in the main checkout. Count a folder as a
chapter only when it contains <folder>.qmd, and add a regression test.
framework_figures.py spelled the old site/explore path on its own, so a
render still dropped three SVGs there. It now uses concept_graph.SITE_DIR
like the other taxonomy builders, and the stray copies are removed.
The page moves from site/explore/ to site/taxonomy/, matching its title,
its nav label, and the identifier namespace the taxonomy already used.
/explore/ keeps unlisted noindex redirect stubs, with relative targets
so they resolve on both the live site and the dev preview subpath.
The binder now holds the folder and the public address in one place
(concept_graph.SITE_DIR and PAGE_URL), and the generated page data carries
the address so the on-page citation reads it instead of repeating it.
The dev preview rewrites links inside taxonomy/ like the other subsites.
A merge script that reused list objects emitted 30 anchors into
ml-systems-framework.yml, which StaffML's hardened loader rejects. Rewrite
the file in full (same data) and make the concepts build fail on aliases.
Subject agreement 78.7% (kappa 0.78) under the first rules and 83.7%
(kappa 0.83) after revising them on the same sample, which the record
marks as no longer held out.
The framework compiler now accepts a groups tier and nested readable codes
(L4.4), resolves chapter pointers to titles and clean published URLs, and
rejects scope notes that cite a row or area that does not exist. The field
compiler enforces a controlled relation vocabulary, rejects duplicate concept
pairs, and keeps retired concept identities pointing at a replacement.
Each build writes public downloads (CSV, JSON, SKOS Turtle, GraphML, BibTeX)
to site/explore/downloads. `binder concepts coverage` scores recorded
checklists and fails when a judgment cites a concept that no longer exists.
Chapter URLs now use the flattened published form (/volN/<chapter>/...).
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.
OSTI resets connections that present a browser user agent from a script, so
reseal could not read its citation_* tags. fetch_url now retries with
mlsysbook-binder/1.0 after the browser string fails.
Registry metadata can be incomplete: DataCite lists only the lead author
and a 2025 issue year for LBNL's 2024 data center report, so a full,
correct entry could not be re-sealed against its DOI. fetch_url now
parses a BibTeX export (e.g. LBNL's bibcite export) as source metadata,
so bib reseal --url <export> checks title, every author, year, and DOI
against the publisher's own record.
`bib add` refuses existing keys, so an entry edited after its gateway
seal (sentence-case title, @misc -> @inproceedings, venue, pages) had no
binder path back to a verified manifest record; records were re-written
by hand. `bib reseal --key K --note "..."` re-resolves the source the
entry was sealed from (or a --doi/--arxiv/--url given), compares title,
author surnames in order, year, DOI, and pages with the edited entry,
and rewrites the manifest record only if they all agree. It never edits
references.bib.
`fetch_url` now reads the page head and records Highwire citation_*
meta tags (title, authors, year, pages, venue, DOI) as evidence, so
publisher pages such as PMLR are checked on authors and pages rather
than on caller overrides. Author comparison folds LaTeX accent escapes
(M\k{a}dry), Unicode diacritics, and name particles.
Relocate master bibliography (references.bib), cryptographic ledger
(manifest.json), curated external provenance (canonical_provenance.json),
and staging candidate inbox (inbox.bib) into unified bibs/ directory.
Maintain books/references.bib as git-tracked relative symlink to
../bibs/references.bib for seamless Quarto and compiler compatibility.
Update Binder CLI, verification engines, pre-commit guards, codespell
rules, and gateway test fixtures to point to bibs/ paths.
- Add 'binder bib add' subcommand to resolve, authenticate, format, and cryptographically seal citations via DOI (Crossref/DataCite), arXiv ID, ISBN (OpenLibrary), or official URL.
- Add 'binder bib ingest' subcommand to batch-validate and promote candidate citations from books/bib-inbox.bib.
- Normalize page ranges with en-dash and enforce duplicate citekey and DOI collision detection.
- Add comprehensive unit and regression test suite in binder/tests/test_bib_gateway.py.
Adds docstrings to the 900 definitions and 8 modules that had none across the binder CLI, its checks, and the audit and maintenance tools, and corrects a few docstrings that no longer matched the code. Only documentation changed.
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.