Skip to content

Latest commit

 

History

History
370 lines (303 loc) · 77.4 KB

File metadata and controls

370 lines (303 loc) · 77.4 KB

Session Preferences

Change approval

  1. NEVER apply anything without an explicit, in-this-turn instruction to apply. This is the single most-violated rule in this collaboration - the user has had to stop the assistant mid-apply repeatedly. "Anything" means every file without exception: source chapters, code/scripts, build/SESSION.md, the review and update reports, everything. Presenting a proposal is not approval. A previous similar edit being approved is not approval. The user answering a clarifying question, refining wording, or asking to check/verify something is not approval. Reading next, status, or re-audit is not approval. Approval is per-edit and per-turn and looks like yes, apply, go, go for it, do N, apply all. When there is any doubt, present the proposal and STOP - do not edit. Verifying a proposal (compiling, testing, researching) is allowed and encouraged, but the moment it would write to a file, stop and wait.
  2. Always present a concrete proposal before editing source content.
  3. Do not apply a proposed correction, addition, or table change until the user explicitly approves it.
  4. A request phrased do N treats suggestion N and any qualifiers in the request as the concrete approved proposal for immediate implementation; do not request a second approval.
  5. A request phrased let's look at N requests inspection and discussion only; do not edit until the user later approves a proposal.
  6. During consistency reviews, produce suggestions rather than silently fixing content. Internal anchor corrections were the only stated exception during the initial review.
  7. Never delete or remove any existing content, data, row, note, file, or roadmap entry without first discussing the exact proposed deletion and receiving explicit user approval.
  8. Propose deletion only when there is a concrete justification such as invalid, incorrect, harmful, or genuinely redundant content; restructuring, cleanup, uncertainty, or lack of a citation is not sufficient.
  9. Unverified, rumoured, or unofficial information is not a deletion candidate - it is often exactly what a reader can't get from a vendor page, and removing it because it lacks a citation destroys the most valuable kind of content in the book. Label it as unconfirmed and say what would change if it held, rather than dropping it. "I could not verify this" is a reason to annotate, never a reason to delete.
  10. Before any deletion, explain the reason, scope, consequences, and preservation alternatives so the user can make an informed decision.
  11. If restructuring makes existing data difficult to retain in its original location, leave it unchanged and propose a relocation, annotation, or schema adjustment.
  12. When replacing or restructuring a table, account for every original row and explicitly flag any row that cannot be represented faithfully.

Book style

  1. Before proposing or writing content, inspect the surrounding section and representative existing sections of the book for established conventions.
  2. Follow existing local style for voice, terminology, heading depth, list markers, notes, citations, tables, and source layout rather than introducing a new pattern.
  3. When proposing a fix, propose the smallest change that fully corrects the problem. Preserve as much of the original text as possible and avoid rewriting correct surrounding prose merely for polish.
  4. Preserve the original author's unique voice, energy, and charm. Correct mistakes without flattening the writing into generic technical prose; broader stylistic rewrites require explicit approval.
  5. Prefer the style of the file and nearby section when book-wide usage varies.
  6. An explicit user-approved format, such as numbered per-table source lists, overrides a conflicting precedent.
  7. If existing style cannot express the content clearly or is inconsistent enough to create a maintenance problem, flag the problem and make a numbered improvement suggestion before changing the style.
  8. Reader experience is the first priority when proposing changes. Start with the reader's task: what the reader needs to understand, compare, decide, or do.
  9. A technically correct proposal is incomplete if it makes the material less useful, harder to navigate, or harder to apply. Among correct alternatives, prefer the one that best preserves or improves the reader's workflow.
  10. For comparison tables, define the comparison question and explain how the reader should use the values before proposing columns, normalization, or vendor-specific qualifications.
  11. Make comparison results visible immediately. Precompute useful ratios, deltas, rankings, or normalized values instead of requiring the reader to perform arithmetic.
  12. Lead with the reader-facing conclusion or at-a-glance comparison; place provenance, vendor terminology, derivation details, and caveats close by as supporting information rather than making them the primary interface.
  13. The book is written in English, so never add text in another language to a chapter. Consulting a non-English source is encouraged - it is often the only place a specification is published, as with Huawei's Chinese Ascend pages carrying per-accelerator figures the English pages omit - but what lands in the chapter is the English translation, not the original string. Do not paste the source text alongside the translation either: a reader who can't read it gains nothing, and it makes the line harder to scan.
  14. Translate the meaning rather than transliterating, and normalize the numbers to the book's own Unit formatting conventions, since a translation is no longer a verbatim quote and the vendor-quote exception no longer applies. Romanize a proper name that has no English form and gloss it once, as with LingQu for Huawei's UnifiedBus fabric.
  15. Say in prose where a figure came from when the source is non-English, so the reader knows the claim is traceable and knows which site to check. Naming the language is useful; reproducing it is not.
  16. No politics. The book is about engineering, so keep out trade policy, sanctions, export controls, and national rivalry even when they explain a market fact. Where such a fact matters to a reader's decision, state the fact and stop: "not generally obtainable in this market" is engineering information a reader can act on, while why that is the case is not. This also rules out framing a vendor or a country as a rival, a threat, or a winner.
  17. Never hard-wrap prose. One line per paragraph. Enforced by make check-style, so it is a check rather than something to remember. Tables, code fences and list items keep their own line; a list item's continuation belongs on the item's line. Do not hand-pad tables either - make fix-tables re-pads columns and asserts the cell contents are unchanged, and its --dry-run exits non-zero, so that is a check too. A table in training/performance/README.md went ragged across four successive hand edits before anyone noticed the fixer already existed.
  18. Linux only. This book targets Linux. Validate commands and teach platform behavior for Linux; do not mention macOS, BSD, or other Unix variants unless the author asks. Do not qualify advice with "on Linux … / on macOS …" comparisons - write the Linux form and leave it at that.
  19. Write succinctly. Every word, sentence and paragraph has to earn its place by telling the reader something they don't already have. Cut restatements of a point already made, second and third examples that add nothing the first didn't, hedges, and throat-clearing. Repeat something only when the repetition serves a specific educational purpose - a deliberate callback, or a warning placed at the point of danger - and if you can't name that purpose, delete it. Recurring failure: re-opening a mode or an option the section has already settled, which adds length and re-raises a question the reader had finished with. The opposite failure is just as real: cutting for brevity must not drop content the reader needs, so cut words, not information.

Reader-visible grounding

  1. Every number, name, command, or claim that lands in a chapter must be derivable from what the reader can see: the same section, earlier content in the same chapter, or a cross-linked chapter or file in the repository.
  2. Never lean on anything that exists only in the assistant's context - benchmark output pasted into chat, a command run while researching, a file read but not quoted, a figure computed in a previous turn. The reader has none of it, and the resulting text looks rigorous while being impossible to check.
  3. When a derivation needs a value the chapter does not show, there are exactly two acceptable moves: add the value to the chapter, or restructure the derivation so it uses values that are already there. Silently using the hidden value is the failure mode.
  4. This applies with equal force to intermediate steps. A worked example that passes through an unshown quantity is unverifiable even when its final answer happens to be right.
  5. Prefer the derivation the reader can redo with the numbers in front of them, even when a hidden value would be more direct.
  6. Concrete failure: the Inter-node speed depends on intra-node speed section derived a 4GiB elapsed time from an algbw figure that came from raw benchmark output pasted into chat, while the section's own table shows only busbw. The fix was to recover the time from busbw by undoing the correction factor the chapter's glossary already defines.
  7. When quoting or computing from a script's output, adopt the script's own unit definitions rather than assuming them. all_reduce_bench.py prints 1GiB = 2**30 Bytes alongside 1GBps = 10**9 Bytes per second, so a GiB / GBps division needs the base conversion. Treating them as one base understated every elapsed time in that section by about 7%, and the error survived a full review pass because each individual figure looked plausible.
  8. Write from the reader's position, not from the conversation's. The prompt, the research, the fodder pasted into chat, and the reasoning that produced a section are not part of the book - the reader has the chapter and nothing else. Before sending new text, re-read it as someone who has read the preceding sections of that chapter and none of the surrounding discussion.
  9. Check every term, acronym, tool name, flag, and reference on first use against that standard: can the reader make sense of it from earlier content in this chapter, or from a cross-link that explains it? If not, expand it in place, link the section that does explain it, or cut it. An unexplained term is worse than an omitted one, because it stops the reader without telling them what they are missing.
  10. Concrete failure (companion book): an ltrace draft explained an empty trace with "it only sees calls that go through the executable's PLT" while the chapter never says what a PLT is, so for the reader the sentence carried no information at all.
  11. The same standard forbids narrating the writing process or the placement decision. "So ltrace belongs to this chapter's world" only parses for someone who watched the section get assigned to a chapter; the reader needs the criterion for when the tool applies, stated directly. Cut the meta rather than rephrasing it.

Measured, derived, or assumed

  1. Every quantity in a chapter is one of three things: measured, derived from measurements, or assumed. The words around it have to say which. measures 73% is a claim about an instrument and works out to 73% is a claim about arithmetic - they are not interchangeable.
  2. The arithmetic being correct is not what is under review here. Each failure below had sound arithmetic and an overstated status, which is exactly why each one survived being written, re-read, and reviewed.
  3. Concrete failure: a per-accelerator efficiency of 73% was described as what a cluster "measures". What was measured is the busbw curve; the 73% is derived from it under an assumed collective algorithm that has never been confirmed against NCCL's own logs. Fixed by saying the measurements "work out to" 73% and naming the assumption in a footnote.
  4. Concrete failure: "at least 70% of the per-interface spec" was written into the cloud-provider chapter as a contract threshold. It came from one derived data point on one cluster, nothing established it as a pass mark, and no measurement of what that interface actually delivers exists yet - ib_write_bw on EFA is still unrun. Removed entirely.
  5. Concrete failure: a B300 inter-node phase was said to "cross in 8.05ms". That is a wire-rate division of published specs, for a system this benchmark has never been run on, written in the indicative as though it were an elapsed time. The parent section had it right - "at wire rate that shard would cross in ... = 16.1ms, against 22.05ms measured" - and the later sentence dropped the qualifier.
  6. A spec-rate division gives a bound on time, never the time. Keep the at wire rate ... would construction; as soon as it becomes crosses in, a reader takes it as an observation.
  7. Carrying a figure from one system to another needs both the fact and the assumption stated. B300 sharing NVLink 5 with B200 does not make their intra-node all-reduce times equal - different HBM, different clocks - so reusing B200's 10.15ms was a second unstated assumption hidden inside the first.
  8. Prefer saying a number is unknown over supplying a plausible one. "This benchmark has not been run on a B300 cluster" is worth more to a reader than any figure that would need to be labelled unreliable.
  9. A measurement's provenance belongs in the book; the run's setup does not. What tool version, what flags, what hardware, what date - that is provenance, and a reader needs it to judge the number. That the package was missing and had to be installed, that a first attempt used the wrong transport, what had to be retried - that is the process of obtaining the number, and it is of no use to anyone but whoever obtained it. Concrete failure: the ib_write_bw footnote in network/README.md carried "Two practical notes from that run. perftest was not installed - sudo apt-get install -y perftest on both hosts first, and the versions must match", three lines below prose that already said both sides need identical perftest versions. Test: would this sentence have been written if the number had come from a vendor's datasheet instead of a run? If not, it is process, not provenance.
  10. When process detritus does contain something a reader needs, the fix is to relocate it, not to keep the note. The same footnote recorded that omitting -c SRD fails with Unable to create QP, which is genuinely useful - a reader who hits that error can diagnose it. But its place is the sentence introducing -c SRD, not a measurement footnote the reader reaches only if they follow the citation. Ask what the reader was doing when they needed the fact, and put it there.
  11. Items 1-8 govern quantities; a claim about mechanism needs the same discipline and is easier to get wrong, because there is no arithmetic to check it against. Concrete failure: a Ring selection measured on p5en.48xlarge was explained as following from "half the NVLink bandwidth and so a 9x rather than 18x link ratio". The ratios were arithmetically right and the causal claim was invented - what the logs actually showed was the AWS tuner keying off the instance name, base Tuner is chosen for platform: p5en.48xlarge, a string lookup with no bandwidth term in it. "and so" is the tell: it asserts a mechanism. Cite the observed mechanism or name none.
  12. Check that two numbers are comparable before comparing them, and if they are not, do not compare them. A caveat is not a remedy - it labels an invalid inference instead of withdrawing it, and the conclusion still reaches the reader. Ask what differs between the two measurements first: hardware, model, shape, sequence length, toolchain version, power cap, batch size. If more than the one variable of interest differs, there is no comparison to make.
  13. This failed twice in one session, the second time after a verbal correction, which is why it is a written rule now. First: a BLOOM 176B run on 384 A100s was set against an 8K measurement on H200 - different model, scale, and hardware. Second: the two Blackwell rows of the MAMF table were said to "land within 1.4% of each other", supporting a claim that B300 is no faster than B200 at bf16, when those rows differ in both shape and torch/CUDA version. Both times a caveat was added rather than the comparison dropped. A correction that is not written down does not survive the session.
  14. When measured numbers are not comparable, published or derived ones often are, because spec arithmetic shares its conditions by construction. The B200/B300 bf16 question is answerable from the theoretical peaks - identical at 2250 TFLOPS - and from the peak formula, which shows that equal peak with more SMs requires a proportionally lower clock or fewer FMAs per Tensor Core. Reach for the derivable comparison rather than forcing the uncontrolled one.
  15. A worked example illustrating a controlled comparison must not itself be uncontrolled. Concrete failure: Do more SMs give more TFLOPS? asked the reader to hold per-SM throughput equal and vary only the SM count, then illustrated it with A100's 108 against H100/H200's 132 - two parts that differ at 256 against 512 FMAs per Tensor Core per cycle in the book's own table. The arithmetic in the table was right and the pairing contradicted the premise stated two paragraphs above it. Rebuilt on one architecture against itself, a 148-SM Blackwell SKU against the 160-SM full die, where the premise actually holds.
  16. Choosing the illustration well is not only presentational - it changes what you can see. The cross-generation version of that example hid consistency item 3, because an unexplained residual between two generations reads as an expected architectural difference, while the same residual within one architecture has nowhere to hide. When a worked example spans more variables than the point needs, suspect that it is concealing something as well as confusing the reader.

Agent-invented content

  1. An assistant working on this book will sometimes produce something genuinely new - a derivation, a conversion, a diagnostic, a way of framing a trade-off - that appears in no source and nowhere earlier in the chapter. That is welcome and worth having. Novelty is not the problem; unreviewed novelty is.
  2. So the rule is not "never invent". Forbidding it outright would throw away the useful half and stifle the thing that makes a fresh pass worth running at all. The rule is that anything invented must be surfaced to the user as an invention, named as such, and kept out of the source files until the user has said it makes sense.
  3. Grounded means one of exactly two things: an authoritative external reference, or content that already appears earlier in the chapter or in a cross-linked file. Anything else is invented - however obvious it feels, and however cleanly it follows from the material around it.
  4. Say which kind of invention it is when flagging it, because they fail differently and need different checks. A derivation can be verified on the spot with algebra. A recommendation, threshold, technique, or diagnostic cannot - it needs a source or a measurement, and that is the kind that has caused every problem here so far.
  5. The failure mode is not a wrong statement, it is a plausible one. A "run one accelerator per node" measurement method was proposed on 2026-08-02 with no source and a real failure mode, and read as established practice until it was researched and replaced with ib_write_bw. A 70% acceptance threshold was invented and written straight into a chapter as a contract number. Neither looked like a hallucination at the time - that is the whole difficulty.
  6. Flag it even when it is almost certainly right. The cost of asking is one sentence; the cost of a confident invention reaching a published chapter is that a reader acts on it.
  7. This is stricter than Change approval, which governs edits the user already has in view. An invention the user did not ask for and cannot see coming has to be named before it is applied, not folded silently into an approved batch.

The author's own voice

  1. This book is written in the first person and much of its value is the author's field experience - I have noticed some distributed file systems, at JeanZay HPC we had to ask for a special dedicated partition, it took awhile to realize they were wrong. That voice is evidence. A reader weighs I got a whole lot of invalid reports because of it differently from this can produce invalid reports, and rightly so. Which is exactly why it is never available for an assistant to write.
  2. Never invent a first-person claim. Do not write I have seen, in my experience, this cost me, we found, or any other statement about what the author did, saw, measured, or suffered, unless those words already exist in the repository and you are preserving or relocating them.
  3. Concrete failure: on 2026-08-04 a hint: explaining two find gotchas was given the clause "both of which cost me correct numbers before I understood them". Nothing anywhere in the repository said that. It was manufactured by pattern-matching the register of a genuine anecdote a few paragraphs up - the --unlink=1 note, where the author really does report getting invalid reports and taking a while to realize it. Copying that key produced text that reads more authoritative than anything an assistant is entitled to write, and put a false memory into the author's mouth in the author's own book.
  4. The tell is that it feels like good style. A section written in strong first person invites continuation in the same key, and the more convincingly the voice is copied the less likely anyone is to question it. Treat the urge to add colour as the signal to stop.
  5. Converting an existing impersonal claim into a personal one is the same error in smaller form. The O_DIRECT logging paragraph said typically helps; rewriting it as I have seen ... supplied an eyewitness the original did not contain. When a general claim genuinely needs weakening, weaken it with can or may and say what the limitation is - do not anchor it in an experience nobody reported.
  6. Write the mechanism instead. without -print the pruned folders are printed too, and their sizes get added to a user's total is checkable by anyone; this cost me correct numbers is checkable by no one. The mechanism is also more useful, because a reader can tell whether it applies to their case.
  7. The same restraint covers editorial characterizations pitched in the author's register - calling a workflow genuinely painful, a write-up a goodie, a vendor practice a technology deficiency. Those are judgements the author is entitled to make and an assistant is not, however obviously true they seem. genuinely painful was written into the Hugging Face cache note on 2026-08-04 and is the same class of thing, milder.
  8. This is a specialization of Agent-invented content, and stricter in one respect: an invented derivation can at least be checked with algebra and kept once verified, whereas an invented memory cannot be verified by anyone except the author and has no repair other than deletion.

Positional cross-references

  1. above and below are only safe when the thing referred to is visible from where the reader is standing - the command, output block, table, or list item in the same section. Then leave them alone; a link to the section the reader is already in is noise.
  2. Once a reference crosses a heading, replace the bare above/below with a Markdown link to the target section. The reader who arrived by deep link, search, or a cross-chapter jump has no above.
  3. This applies to a #### referring back to material in its parent ###. The subsection is a landing point in its own right - network/README.md's So what should you expect? is linked directly from the cloud-provider chapter - so "model 3 above" was unfollowable for anyone who entered there.
  4. Prefer naming the target in the link text over keeping the direction word: model 3 in [Inter-node speed depends on intra-node speed](#...) rather than [model 3 above](#...). Direction words go stale when sections are reordered; names don't.
  5. Do not link when the target is already linked in the same sentence or paragraph. A second link to the same anchor a few words later adds nothing.
  6. Leave comparative above/below alone - 60W above its TDP, below about 1GiB, approaches 0 from above are quantities, not positions. Skipping these is the bulk of the work when sweeping a chapter.
  7. Anchor arithmetic: an em dash in a heading is dropped and the spaces around it each become a hyphen, so part 1 — do you need yields part-1--do-you-need with a double hyphen. Verify a generated anchor against the file's own existing links rather than trusting a hand-rolled slugifier.

Internal links and anchors

  1. In-book links use the file form network/README.md#anchor, never the bare-directory form network#anchor. The compiled build and the local link check require it: a bare directory has no anchor target in the built book, and the checker flags dir#anchor. (GitHub's web view no longer drops the fragment on a directory link - see items 12-14 - but the compiled outputs still do, so the file form stays mandatory in-book.)
  2. Concrete failure: [Real network throughput](../network#real-network-throughput) in the cloud-provider chapter. The heading was right and the generated anchor was right; the link form was not. GitHub resolves a relative link from a blob page to /blob/master/network, the blob URL of a directory, which does not render the README - so the fragment is dropped.
  3. The README.md#anchor form is the dominant convention regardless: 130 links already used it against the 60 fixed on 2026-08-02, and all 60 of those were broken.
  4. A link to a directory with no fragment is fine and needs no change. Only the anchored ones break, so a sweep should target ](path#anchor) where path resolves to a directory.
  5. Never let a link checker treat a directory as its README.md. A checker that quietly appends it is validating a resolution step that neither GitHub nor any local renderer performs, and it will pass every link in the class above. This is exactly how 60 broken links survived two separate "0 broken" reports in one session - the checker was wrong, not the links.
  6. When generating anchors to check them, model GitHub faithfully: strip backticks and inline links from the heading text, lowercase it, drop every character that is not a word character, space, or hyphen, then replace each remaining space with a hyphen. Repeated identical headings get -1, -2 appended in document order. Do not collapse runs of spaces - see Positional cross-references item 7 for the em-dash case where that matters.
  7. Sweep the whole repository, not the file just edited. The root README.md held 5 of the 60, and the first pass missed 11 more because its pattern assumed every relative path begins with ./ or ../, which compute/accelerator#..., benchmarks#... and ../#... do not.
  8. make check-links-local runs linkchecker over the built HTML and is the authoritative check, but it depends on markdown_it, which is not installed as of 2026-08-02. Until it is, a hand-rolled scan is the fallback and is only worth running if it obeys items 5 and 6.
  9. A link can resolve perfectly and still be broken. After moving or rewriting any block that other places point at, check the referrers, not the thing you just edited. On 2026-08-04 a nvbandwidth build recipe was relocated out of ### NVLink-C2C into network/benchmarks/README.md; the PCIe section 150 lines earlier still said "with nvbandwidth built as shown under [NVLink-C2C](#nvlink-c2c)". The anchor resolved, the heading existed, and the build instructions the sentence promised were gone. No link checker catches this, because nothing is technically wrong.
  10. The check is mechanical, so run it every time rather than trusting recall: grep for every inbound reference to the thing you moved, and for each one confirm the target still contains what the sentence claims it contains. grep -n "#the-anchor" -r . finds the referrers; reading each one finds the lies.
  11. This generalizes past links. The same failure shape - editing outward-facing content and verifying only the edit - showed up three separate times in one session for tool invocations: ./nvbandwidth, ./build/all_reduce_perf and ./p2pBandwidthLatencyTest were each dropped into a chapter with no account of where the binary comes from, because the assistant had them built and working in its own shell. Whenever a command lands in a chapter, confirm a reader who arrived at that line cold can obtain and run it - the build is either on the page or one link away.
  12. GitHub-web caveat for large files: GitHub's blob (file) view does not serve heading-anchor ids for large Markdown files, so an absolute deep link such as .../blob/master/pytorch/README.md#anchor does not scroll to the section on a cold load - the browser lands at the top. Measured 2026-08-13: a ~5 KB README embeds its anchors; the-art-of-debugging's ~215 KB pytorch/README.md (and this book's ~215 KB debug/pytorch.md) embed none. Same-page #anchor clicks are unaffected; only cold navigation into a big file breaks.
  13. Remedy, for absolute/external links only: for a cross-repo deep link into a large folder-README, use the folder (tree) form .../tree/master/pytorch#anchor instead of .../blob/master/pytorch/README.md#anchor. The tree view serves anchors at any size and a directory URL 301-redirects blob->tree carrying the fragment. The checker skips absolute links and the compiled book treats them as external, so this is safe there - but it only works when the section lives in that folder's README.md. A non-README file such as debug/pytorch.md has no folder form, so a large such file has no cold-anchor-safe link: keep it small or rely on reload / the file Outline panel.
  14. This reverses part of the 2026-08-02 finding (items 1-5): back then a directory URL did not render its README and the fragment was dropped. By 2026-08-13 GitHub redirects blob/master/dir -> tree/master/dir and renders the README with anchors. The in-book rule is unchanged - the file form is still mandatory because the compiled build and local renderers still do not resolve a directory to its README; only absolute/external links may use the tree form.
  15. This book's oversized deep-link target is debug/pytorch.md, which is not a folder README - so the item 13 remedy does not apply to it: absolute/cross-repo links into it must stay on the blob file form and will not cold-jump on GitHub web; rely on reload / the file Outline panel. Do not try to rescue them with .../tree/master/debug#anchor - that renders debug/README.md, a different file.

Suggestions report

  1. Put a large set of findings in a repository file rather than only in chat.
  2. Group findings by severity.
  3. Use one flat numerical sequence. A number such as 2 must be sufficient; do not require prefixes such as HIGH-02.
  4. Make each suggestion independently actionable so suggestions can be applied in any order.
  5. When a suggestion is applied, remove it from the report - see Resolved items for what may be kept.
  6. Do not renumber the remaining suggestions. Removing an applied item leaves a gap, and the gap is correct - a number has to stay a durable identifier so that do 39 in an old transcript still resolves to the same finding. The Applied list of numbers and dates is what makes the gaps read as history rather than as lost items.
  7. Renumbering has happened twice, each time on the author's explicit instruction and each time a compaction into 1..N: on 2026-08-05, after the correctness queue had been reduced from 39 items to a handful and the sequence had become impossible to count, and on 2026-08-07, when the consistency report's one surviving item went from 75 to 1 and the update queue was compacted into file order so that the chapter audit starting that day could number its findings from N+1. Neither is a precedent - do not renumber without being told to. If the count is what you need, state it in the Severity summary line rather than reshuffling the identifiers. Each report records its own mapping in its preamble, so an old transcript's number still resolves.
  8. Include a numerical correction plan ordered by practical priority.

Use the newest build/consistency-review-*.md file in the current repository unless the user names a different report.

Proposing a fix in chat

When an item needs the author's judgment before it can be applied (anything that is not a mechanical auto-fix), present it in chat using this format, not a one-line summary:

  1. Heading - the report's item number and its title, so it ties back to the report.
  2. Problem - what is wrong and why it is wrong. State the contradiction, the failing command, or the incorrect value explicitly. Cite the conflicting source when the problem is a contradiction.
  3. Solution - the corrected content, shown concretely (the rewritten line, the fixed command, the corrected number). Show enough that the author can judge it without opening the file.
  4. Proposal - the exact edit you intend to make, phrased as an action the author can approve or decline.

Always link to the specific source with a clickable file:line reference (for example [insights/ai-battlefield.md:329](../insights/ai-battlefield.md#L329)) so the author can jump straight to the line. Link the conflicting source the same way when citing one. Propose one item at a time and wait for approval before editing, unless the author asks for a batch.

When the author approves and you apply a fix, immediately present the next open item in the same reply (same Problem / Solution / Proposal format). Do not stop at a bare "done" and wait for them to say next.

When the author asks you to fix or change something in a proposal you already showed, re-show the whole corrected block, not just the changed fragment. A diff-style snippet of only the edited part forces the author to mentally reassemble the result and hides formatting damage in the surrounding lines. Re-render the entire item as it would land, every time it changes.

When a proposed block is itself Markdown that contains fenced code, do not wrap the whole proposal in an outer ```markdown fence - the inner fence closes the outer one early and mangles the render. Present such a block as normal message content (its own fences render as intended), or describe it without nesting fences.

The user cannot read long unwrapped lines in chat. Treat this as a hard pre-send gate, not a preference: before sending any reply that shows proposed file text, scan the drafted message and hard-wrap every line inside code fences and block quotes to <=72 characters, rewrapping any that exceed it. This is independent of how the text lands in the file - file content stays one line per paragraph per Source line layout, while the chat preview of that same text must be wrapped. Conflating the two (sending the file's one-line-per-paragraph form verbatim into chat) is the recurring failure.

Update opportunities report

  1. Maintain a separate file for opportunities to extend the book when new accelerators, networking cards, switches, specifications, or standards become available.
  2. Do not mix update opportunities with correctness findings.
  3. Use the same stable flat-number workflow: make each item independent, remove applied items, and never renumber the remaining items.
  4. While researching any topic, add newly discovered, primary-source-supported update opportunities to this file.
  5. Propose each update before editing source content.
  6. Finish the correctness suggestions before beginning the update queue unless the user explicitly changes that order.
  7. Before claiming the book never explains something, grep for the explanation, not for the first occurrence of the thing being explained. A concept is routinely demonstrated early and explained in depth thousands of lines later. When that is what you have found, the defect is ordering, and the fix is a forward cross-link from the early occurrence - never a second explanation.

Use the newest build/update-suggestions-*.md file in the current repository unless the user names a different report.

Resolved items

  1. When an item is resolved, delete it and add its number and date to the file's Applied list - that list is the only trace it leaves. Do not replace it with an "applied" note that re-narrates the problem, the verification, or the reasoning behind the fix. The book is the record of what shipped and git log is the record of when; a tracking file is a queue of outstanding work, and everything else in it is text that every future read has to skim past.
  2. This covers every tracking file: build/consistency-review-*.md, build/update-suggestions-*.md, build/stabs-actionable-*.md, stabs/incoming.md, and todo.md.
  3. An item closed without a change is different: it leaves one line under Closed without a change (do not re-raise), with the reason. These are the findings that look like defects and are not, and they will be re-raised by the next reviewer if the reason is not written down.
  4. Exactly two things may outlive an applied item. A decision that must not be re-litigated becomes one line under the file's Rejected (do not propose again) section. A lesson that would change how future work is done becomes a rule in this file. Whatever fits neither dies with the item.
  5. Deleting leaves a numbering gap, and the gap is correct - see Suggestions report. Never renumber to close it.
  6. Recurring failure: an entry that proves a decision nobody is disputing, or explains something the reader can already see in the book. Both mean the item should have been deleted outright.

Review scope

  1. Check content, logic, numerical arithmetic, units, technical correctness, and internal consistency.
  2. Ignore ordinary Markdown whitespace-only differences because rendering already ignores them. Tables are an exception, as covered by item 3: there whitespace carries readability meaning even though rendering discards it.
  3. Keep Markdown table source vertically aligned. In tables, whitespace matters for maintainer readability even when rendering would be unchanged.
  4. Check internal/local links, files, and anchors.
  5. Do not perform external-link availability or liveness checks except for newly added links as specified below, and except for the periodic redirect sweep described in External link rot - that one targets silently-relocated URLs rather than link health, and is worth running deliberately.
  6. Re-validate every as of this writing clause, and note that as of 2026-08-07 there are none left in chapters-md.txt - so a new one appearing means new prose, not a survivor. The phrase means "true when this section was written" rather than "true when the book was last updated" - which future-proofs the sentence for the author but tells the reader only that the claim may be stale, with no way to tell how stale. There are 26 of them as of 2026-08-05, led by network/README.md with 6 and compute/accelerator/README.md with 5, then 3 each in storage/README.md, inference/README.md and debug/pytorch.md, and the remaining 6 spread one or two per file. Treat each as an item to check, never as a disclaimer that excuses staleness.
  7. Grep for it case-insensitively. Roughly half the instances are sentence-initial As of this writing, so a case-sensitive grep silently reports about 60% of them - which is how this file came to claim 21 and name the wrong three files as the concentration. A count that comes out suspiciously tidy is worth re-running with -i.
  8. When one checks out, prefer replacing the phrase with the actual date, since the book already does this elsewhere - as of 2026-07-31, As of 2026-07-28. A dated claim tells the next pass how old it is; as of this writing cannot. Use the date the claim was verified, not the date git blame reports, since blame returns last-touch and any mechanical sweep - a unit normalization, a launcher rename - resets it to today on lines whose claims are years old.
  9. Claims about a dependency's capabilities or documentation rot fastest - much faster than hardware specs or arithmetic, which mostly stay put. Sweep for you can't, there is no way to, not documented, not possible, they are working on, and anything described as new. new rots fastest of all.
  10. Concrete failure, both in one paragraph of network/benchmarks/README.md on 2026-08-04. It stated that you cannot know which algorithm NCCL selected, citing a December 2022 NCCL answer, while network/README.md had just been updated to instruct readers to read exactly that from NCCL_DEBUG_SUBSYS=INIT,TUNING - the book contradicted itself in two files. The same paragraph called NVLS "not documented anywhere" and said the inter-node version was still being worked on, when NVLS and NVLSTree had been documented NCCL_ALGO values since NCCL 2.17 and 2.18. Neither sentence was wrong when written; both had quietly stopped being true.
  11. So when a chapter is edited because a dependency gained a feature, grep the neighbouring files for older statements about that same dependency. The new measurement is what reveals the old claim - nothing else will, because a stale "you can't" reads exactly like a true one.
  12. The neighbour can be the next paragraph. In network/README.md the Omni-Path section said the product "comes with either 100 or 200Gbps bandwidth", concluded it was therefore unsuitable for ML, and was followed two lines later by the note that 400Gbps CN5000 NICs shipped in June 2025 - both added by the same author to the same section, the newer fact simply never prompting a re-read of the older conclusion. Fixed on 2026-08-05. Checking it also turned up something a staleness sweep alone would have missed: the 200Gbps half was Intel's OPA 200, cancelled in July 2019 without ever shipping, so the sentence had been offering a reader a product that did not exist. Sweeping a chapter for a claim's neighbours is not enough if you do not also verify that the claim was true when written.
  13. Environment variable names get deprecated and renamed upstream, so verify each one the book tells a reader to set is still the current name. This is the dependency-rot shape (items 9-12) in its purest form: a deprecated env var keeps working as an alias and at most prints a warning, so nothing breaks, every functional test passes, and the stale name survives every review that only reads for correctness. Sweep the vars the book asks a reader to export or pass and confirm each against the tool's current documentation rather than trusting that it still runs. Concrete, 2026-08-13: NCCL_ASYNC_ERROR_HANDLING (set in orchestration/slurm/example.slurm and the four launcher templates) was renamed TORCH_NCCL_ASYNC_ERROR_HANDLING in PyTorch 2.2, and PYTORCH_CUDA_ALLOC_CONF became the device-agnostic PYTORCH_ALLOC_CONF - both old names still alias, and the chapters already taught the new PYTORCH_ALLOC_CONF while SKILL.md still shipped the old spelling. Prefer the current name in the book; name a superseded one only to say it was renamed, as storage/README.md already does for TRANSFORMERS_CACHE/HUGGINGFACE_HUB_CACHE.

Outdated references and dead artifacts

  1. Periodically sweep for content that has quietly aged out rather than become wrong. Two kinds: files nothing points at any more, and references to software or hardware so old that following them wastes the reader's time.
  2. Find orphaned files by checking whether each non-README file is named anywhere else in the repository. On 2026-08-05 that turned up network/benchmarks/results/disable-nvlink.md, reachable only from its own directory index and therefore effectively unreachable while reading. trash/ is untracked scratch and stabs/incoming.md is deliberately unlinked - its README says to ignore the directory - so exclude both rather than reporting them every pass.
  3. Prefer inlining a result over parking it in a side file. The book is otherwise entirely inline, a side file breaks reading flow, and it sets a precedent for scattering. Both results/ sub-directories were removed on 2026-08-05: network/benchmarks/results/ where one file was orphaned and the other duplicated a chapter table, and storage/benchmarks/results/ where the linked "summary" was byte-identical to the six tables printed directly beneath the link. In each case the only unique content was provenance - hardware, date, partition path - which belongs in the sentence that introduces the numbers.
  4. Remember chapters-md.txt when a chapter file is added or removed, since it drives the build and the review's own scope count.
  5. Sweep for aged technology references with a term list: TITAN, K80, P100, V100, pytorch-1., torch==1., cuda-10, cuda-11, python2, and old pinned library versions. Most hits will be legitimate - a generations table needs its earlier generations, and a dated bug report with a linked issue is exactly how such things should be recorded.
  6. The ones to act on are those that send a reader somewhere useless. Concrete: storage/README.md explained a fio-scan failure as "you run it on a system with python2 installed by default", five years after Python 2 reached end of life, so the diagnosis pointed at a cause that no longer exists.
  7. Check the artifact before deleting the advice. In that same case the script really does call bare python rather than python3, and many current systems ship only python3 - so the failure mode is live and only its stated cause was obsolete. The note was trimmed to the current diagnosis rather than removed, which the sweep would have gotten wrong had the script not been read.

Companion book sync

  1. ml-engineering/debug/pytorch.md and the-art-of-debugging/pytorch/README.md are the same chapter maintained in two books. Any change to one must be ported to the other in the same pass, in whichever direction the edit started. This is not optional cleanup to schedule later - an unported edit is a divergence that only a cross-book comparison will ever surface, and nothing in either repository points at the other.
  2. Prose, code, commands and output port. Relative cross-references do not. The two copies have deliberately disjoint link sets - as of 2026-08-05 the ml-engineering copy carries 14 links to its own chapters and the companion carries 3 to its own, with no overlap - because each book can only point at chapters it contains. So a new ../training/dtype.md link belongs in the ml-engineering copy alone, and the companion needs either its own equivalent target or nothing. Never "port" a link by path.
  3. The same applies to the scripts the two books share. As of 2026-08-05 there are 15 and the expected state is byte-identical: NicerTrace.py, printflock.py, see-mem-usage.py, underflow_overflow.py, torch-distributed-gpu-test.py, and the tiny-scripts/dataset helpers. They sit at different paths - debug/ and */tools/ in one book, pytorch/, pytorch/code/ and pytorch/tiny-scripts/ in the other - so compare by basename, not by path.
  4. README.md is the one same-named file expected to differ, since each book has its own index. Do not report it.
  5. Detect divergence by pairing same-named files by basename and byte-comparing. Excluding .git/, build/ and trash/, every pair should be identical; a non-empty result is either an unported edit or a deliberate difference that belongs in the review's Checks that passed note.
  6. Checking pitfall, 2026-08-05: a first attempt mapped ml-engineering/debug/<file> onto the-art-of-debugging/<file> and so compared almost nothing - it matched only the root README.md, reported that one expected difference, and looked like a clean pass. A cross-book check that finds nothing is more likely to be mis-wired than correct; confirm it is actually pairing the shared scripts before trusting a clean result.
  7. Also exclude the sibling working copies in the parent directory - ml-engineering1/, ml-engineering2/, the-art-of-debugging2/. They are separate snapshots, they will match the pre-edit state and look like divergences, and they must not be edited.
  8. Concrete failure, 2026-08-05. The python -m torch.distributed.run to torchrun sweep was applied across ml-engineering only. It broke torch-distributed-gpu-test.py out of byte-identity - a file the previous review had explicitly recorded as identical after an earlier port - and left the companion's copy of the chapter with 11 un-swept command sites plus one in its SKILL.md. Nothing in the ml-engineering tree could have caught it; only the cross-book compare did, a day later. The -u exception had to be preserved on both sides, so the port is a re-application of the rule and not a blind copy.
  9. build/SESSION.md is shared process rules, adapted per book rather than byte-identical. Whichever book is actively being worked on is the master for new SESSION changes in that stretch; port them to the companion in the same pass, adapted - rewrite the reasoning, keep the failure, drop paths/make targets/sections the other book does not have (e.g. this book's Product sync map and GA-split table rules do not belong in AoD; AoD-only tooling notes do not belong here). A mechanical paste reintroduces wrong paths. Measured originally 2026-08-06 as badly diverged; re-synced into the-art-of-debugging on 2026-08-12. Working on AoD flips the direction for subsequent SESSION edits.

Sources and citations

  1. Prefer original and primary sources: vendor specifications, official documentation, standards, original papers, and upstream source repositories.
  2. When support is missing, recommend a direct link to the relevant specification or primary documentation page.
  3. External primary sources may be consulted for factual verification, but they must not be treated as an external-link liveness scan.
  4. Always open and confirm the exact target of every new external link before adding it to the repository.
  5. The new-link rule is a narrow exception to the no-external-liveness-sweep preference: do not broadly recheck pre-existing external links.
  6. Where possible, place citations directly under a numerical table so readers can confirm the displayed values.
  7. Keep citations close to the claims or rows they support.
  8. Batch command-line liveness checks through build/check-new-links.sh and request one reusable approval for that wrapper rather than separate approval for each curl invocation.
  9. When a vendor or standards-body page appears unreachable, do not conclude the source is unavailable and do not fall back to a secondary source. Many such sites sit behind bot mitigation that rejects a bare HTTP client while serving the same page to a browser user-agent, so a specialized fetch tool can report a false negative. Retry with a normal downloader and a browser user-agent - this is pre-authorized for verifying citations in this repository, and no further approval is needed:
wget --user-agent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:39.0) Gecko/20100101 Firefox/39.0" URL
  1. A guessed URL that returns a page is not necessarily the page you wanted - check the title and body before quoting it. If a guess lands on a listing or tag page, follow the site's own links, or read its /specifications-style index, to reach the document itself.
  2. Do not propose adding an unmaintained GitHub repository (archived, README says "not actively maintained" / "research artifact only", last meaningful commit years stale with no successor named). Prefer the live successor when one exists - e.g. Alpa is out; Shardy / XLA auto-sharding is the current path. Repos already cited in the book are left alone unless the author asks; do not sweep them out on this rule alone.
  3. Do not propose adding a GitHub repository with fewer than ~500 stars as a "notable" tool or framework - stars are a coarse importance filter, not a quality score. Below that bar, mention only if the author asks or the project is already in the book. Existing citations are not swept out on this rule alone.

External link rot

  1. Run make check-redirects periodically. It resolves every external URL in chapters-md.txt and reports the ones that have moved or died. This is not the broad liveness sweep Sources and citations items 3 and 5 rule out - a redirect is a silent correctness problem, not a health check. The old URL still works, nothing looks broken, and the book quietly names a location the project has left. It needs network and takes a few minutes, so run it deliberately rather than in the fast local pass.
  2. Never remove the per-domain rate limiting. Both build/check-redirects.py and build/check-new-links.sh serialize requests to a single domain with a few seconds between them, while different domains proceed in parallel. The book cites 243 distinct github.com URLs and 46 on huggingface.co; firing those concurrently looks like a scraper and gets the runner throttled or IP-blocked, which costs far more than the wait. --jobs raises how many domains run at once - it is not a way to go faster on one domain, and --delay should only ever go up. The floor this sets is roughly the busiest domain's URL count times the delay - about 24 minutes at the current default - but that floor is not the run time. Measured 2026-08-07: 697 URLs across 128 domains took 3h24m at the defaults. Budget hours, not minutes, and note that the script prints nothing until it finishes, so an empty log part-way through is not a hang - check elapsed CPU against elapsed wall time if in doubt, since a correctly-sleeping run uses almost none. An earlier version of this item quoted the floor as though it were the total; the meta-refresh probing added on 2026-08-07 issues up to three more delayed requests per URL and contributes, but the full breakdown has not been measured. check-new-links.sh also spaces curl's own retries by the same delay, since --retry-all-errors otherwise retries instantly and triples the request rate against a host that is already refusing.
  3. This applies to external requests only. build/check-links.py reads local files and needs no delay.
  4. First run, 2026-08-05: 704 URLs, 94 moved. Bulk cases were pytorch.org/docs to docs.pytorch.org/docs, cloud.google.com to docs.cloud.google.com, and 12 GitHub org renames including TimDettmers/bitsandbytes, outlines-dev/outlines, microsoft/Megatron-DeepSpeed and THUDM/GLM-130B. 78 were replaced; 16 were deliberately not.
  5. Do not replace a redirect target blindly. The endpoint is sometimes not a new home at all:
    • Signed CDN URLs. The book's own PDF/EPUB links on huggingface.co resolve to us.aws.cdn.hf.co with Expires= and Signature= parameters. Pasting those in would break within hours and pin readers to one region. The script skips known CDN hosts for this reason.
    • Redirects to a homepage or a generalized index. resources.nvidia.com/en-us-tensor-core lands on nvidia.com, and intel.com/.../processors/ai-accelerators.html on .../processors.html. The specific document is gone; that is a dead citation needing a new source, not a move.
    • Redirects to different content. cornelisnetworks.com/solutions/cornelis-cn5000/ lands on a different product family, and a community.fs.com article on a differently-titled one.
    • A .git suffix. GitHub redirects repo.git to repo for the web view, but .git is correct inside git clone. The script special-cases this.
  6. curl never sends the #fragment, so a reported target never has one. A naive from-to replacement therefore downgrades every deep link to its page, and this is the failure that did the most damage on the first run: 18 anchors were silently dropped, including ten docs.pytorch.org/docs/stable/distributed.html#torch.distributed.* links that all collapsed onto the same API index. The script now carries the fragment over, but always re-verify the anchor still exists on the new page - a reorganized page keeps its URL and renames its headings.
  7. Replace longest-first. When one reported URL is a strict prefix of another, replacing the short one first eats the separator of the long one. On the first run .../train/tr11-176B-ml/ was replaced before .../train/tr11-176B-ml/chronicles.md, producing tr11-176B-mlchronicles.md - four 404s created by the fix. The script now warns about overlapping pairs.
  8. After any URL sweep, re-extract every changed URL from git diff and check each one for a non-200. That check is what caught all five self-inflicted breakages; the redirect report alone did not, because a mangled URL 404s without redirecting.
  9. A 000 result is bot mitigation, not death - amd.com, hpe.com, microsoft.com and nasa.gov all reject a bare client. Confirm with the browser user-agent recipe in Sources and citations item 9 before calling anything dead.
  10. Watch the URL extractor itself. Markdown wraps URLs in ways that corrupt a naive regex: a closing paren ends the match, so Hopper_(microarchitecture) truncates and then 404s, and a URL inside backticks picks the backtick up as its tail. Both produced false 404s on the first run and both are handled now, but any new false positive is more likely a defect in the tool than a broken link in the book.
  11. Two moves are invisible to an HTTP check, and build/check-redirects.py now reports both. A <meta http-equiv="refresh"> is markup rather than a status, so curl -L does not follow it and the stale URL answers 200 forever. Concrete failure: the book cited docs.pytorch.org/docs/stable/torch.compiler_troubleshooting.html, which serves a 1KB stub that refreshes to the pinned release, which refreshes again to a reorganized path under user_guide/ - two hops, both silent, and every other check in this repo called it healthy. Chains are why the probe follows more than one hop.
  12. When a rolling alias refreshes to a pinned release, cite neither end of the chain. /stable/ landing on /2.13/ means the target is correct today and wrong at the next release, while the original may also predate a reorganization. Keep the alias and apply the rest of the move - /stable/x.html plus /2.13/user_guide/y.html gives /stable/user_guide/y.html - then confirm it resolves. The script suggests this rather than the raw target.
  13. A 403/429 carrying a large HTML body is usually a JavaScript browser check, not throttling and not death. Read the body before concluding anything: Vercel Security Checkpoint, Just a moment..., cf-browser-verification and Enable JavaScript to continue are the markers, and the script buckets these separately. The right response is the opposite of the one for rate limiting - do not retry, do not add delay, and do not swap user-agent, because the gate wants a JS engine rather than patience. Concrete failure: hud.pytorch.org/benchmark/compilers answers 429 with 33KB of Vercel checkpoint; it was read as self-inflicted rate limiting and retried three times, twice with a browser user-agent, none of which could ever have worked.
  14. Never quote content from a JS-gated page. The link is fine for a reader with a browser, so it can stay in the book, but its contents have not been seen and must not be summarized or cited as verified until someone opens it. See Measured, derived, or assumed.
  15. Keep BROWSER_UA a current and complete browser string. Bot mitigation fingerprints the whole token sequence, so a stale or truncated UA reads as automation: the recipe spent a pass on a 2015 Firefox 39 string, and a Chrome string with (KHTML, like Gecko) omitted was also refused.
  16. When a cited article is withdrawn rather than moved, check the Wayback Machine before concluding the source is unrecoverable - and use the CDX endpoint, not the availability API. archive.org/wayback/available returned non-JSON on 2026-08-07 and that was misread as "no snapshot exists"; web.archive.org/cdx/search/cdx?url=<encoded>&output=json&filter=statuscode:200 answered immediately with 19 captures. Take the most recent statuscode:200 capture, and verify the figures are actually in it rather than assuming the capture is complete - a snapshot can be a partial or error page. Whether the book may cite web.archive.org is a separate open decision, tracked as consistency item 74; this item is only about finding out what is available.
  17. A failed query is not evidence of absence. Two findings this session were briefly recorded as "searched, nothing found" when the truth was "the tool erred": the Wayback lookup above, and a grep | grep -v | cut pipeline whose exit status came from cut, so a || echo "none found" fallback could never fire. Before writing down a negative result, confirm the check itself ran.
  18. A matching number is not a matching claim. When hunting a replacement source, finding the figure on a candidate page proves nothing until the surrounding sentence is read. Concrete near-miss: nvidia.com/en-us/data-center/nvlink/ contains 3.6 TB/s and was briefly treated as a live source for the DGX H100's 3.6TBps system bisection bandwidth. The page's figure is NVLink 6 bandwidth per GPU on Rubin - two generations and two scopes away, the same digits by coincidence. Check the unit, the scope, the generation and the subject, not the digits.
  19. Before replacing a URL, check it is not a substring of another URL in the file. A withdrawn source often already appears inside an archive link elsewhere, so a bare string replace nests one URL inside another. Anchor the match on the enclosing Markdown - ](<url>) - or assert the count is 1 before writing. build/check-links.py now fails on any link whose scheme appears three or more times, which catches the resulting double-wrap on the next local run, but the assert is what stops it being written in the first place. This is the same hazard as the replace-longest-first rule in item 7, in a different disguise.

Cross-vendor hardware tables

  1. Do not force unlike vendor specifications into an artificial normalized schema.
  2. Preserve the vendor's documented reporting scope, such as per SM, per CU, per XCD, or per accelerator.
  3. Do not derive per-accelerator totals from private local caches unless the derivation is explicitly useful, clearly labeled, and approved.
  4. Prefer not disclosed or omission over an unsupported estimate.
  5. Add a brief explanation of how to compare unlike cache or memory resources, including differences in scope, sharing, semantics, and performance.
  6. For new cache-table additions, consider only high-end GPUs.
  7. Research current primary specifications, including newly documented parts such as AMD Instinct MI455X, but propose rows before adding them.
  8. When one table would mix broadly shared cache capacity with private local resources, prefer separate comparison and vendor-native tables.
  9. Availability is expressed by which table a row is in, not by a column. Every comparison table is split in two - identical columns, the same declared sort applied to each, and one shared note list placed after both:
**Generally available:**

| Accelerator \ TFLOPS  | fp32  | ... | Notes |
| NVIDIA GB300 SXM      |  80.0 | ... | 29,30 |
| Google TPU v7x        |     ? | ... |    25 |

**Announced, availability not confirmed:**

| Accelerator \ TFLOPS  | fp32  | ... | Notes |
| AMD MI455X            |     ? | ... |    27 |
| NVIDIA Rubin SXM      | 130.0 | ... |    26 |
  1. This replaced the earlier convention on 2026-08-06 across all 14 tables that had it: a GA column carrying Y/N/? plus a single empty row as a visual break inside one table. The split wins on three counts. Promoting a part is a cut-and-paste with nothing else to edit - no cell to flip, no note to renumber. A reader scanning the first table cannot mistake an announced part for something to reach for, which a break row only weakly signalled. And the column comes back as width: the TFLOPS table went from 12 columns to 11.
  2. Sort each table by its own declared column and direction, and state that before them. A row whose sort key the vendor does not publish parks at the end of its own table, unsorted, because there is no value to order it by - NVIDIA B300 SXM and GB300 SXM sit there in the clock table on not disclosed clocks, in the available table, since they are shipping parts.
  3. Do not add a column restating what table membership already says. The old GA column only existed because both groups shared one table.
  4. "Published spec" is not "available", and the two diverge in more ways than one: a released standard can precede silicon by years (PCIe 6.0 hardware arrived about three years after its specification), a vendor can publish full specs while marking them "Preliminary information ... subject to change" (NVIDIA Rubin), and a part can ship on one bus generation while the same node already uses a newer one elsewhere (accelerators on PCIe Gen5 x16 while ConnectX-8 NICs use Gen6). Decide which table a row belongs in by whether it can be obtained, not by whether numbers exist.
  5. Two different things get written ? and they must not be conflated. A ? in a spec cell means the vendor has not published that number and says nothing about availability - AMD MI355X has ? for tf32, Google TPU v6e for fp32/tf32, and Google TPU v7x for six of its columns; all three are shipping parts in the available table. Only unconfirmed availability moves a row to the second table. Hardware that ships with a partly published spec stays in the first one.
  6. The second table's title has to cover two situations, not one, which is why it is Announced, availability not confirmed rather than "Announced but not generally available". network/README.md note 7 is explicit about the second: "NVIDIA lists ConnectX-9 in its adapter portfolio without a ship date; AMD gives Pollara 400 a partner platform catalog, which implies it ships, but says so nowhere. Neither is claimed here as available or unavailable." A title asserting unavailability would misrepresent exactly those rows. Let a per-row note say which situation applies - vendor says not yet, or vendor says nothing.
  7. So the availability question a row answers is "can this be obtained", not "can this reader obtain it", and where the vendor is silent the silence is recorded rather than resolved by guessing. Do not promote a row because a partner catalog or a product page implies shipping; that inference is what note 7 declines to make.
  8. Geography is never a reason to keep hardware out of the available table, and the restriction runs in every direction. There is no universal reader to be relative to: Huawei Ascend is not generally obtainable outside China, and NVIDIA's high-end parts are not generally obtainable inside it, so a table meaning "obtainable by you" would have to be a different table per reader. Generally available therefore means obtainable somewhere, with the restriction recorded in a note. network/README.md note 5 previously justified ? for Huawei UB Link with "the product page is live but China-only in practice", conflating two things - Huawei publishing no availability at all, which is a real reason, and the restriction to one market, which is not. The note now says so, and records that the row moves up once availability is confirmed, annotated as China-only. insights/ai-battlefield.md already handles it this way in prose - "real scale, but China-only in practice" - noting the restriction rather than dropping the vendor. Keep Book style item 16 in mind: state the market fact, not why it is the case.
  9. A row in the second table needs a note saying why availability is open when the vendor is merely silent, so the reader can tell that case from a dated "not yet". A source citation is not that note - TPU v7x carried only a link to Google's documentation, which said where the numbers came from and not why availability was unresolved, and it was on that basis eventually promoted.
  10. Concrete failure worth remembering, 2026-08-06. Google TPU v7x was added with GA = ?, misplaced inside the sorted body, then flagged by a sort check as a misplaced row, then documented as correctly placed, then moved below the break, and finally promoted to the available table once Google's own wording - "the latest TPU available on Google Cloud", usable through GKE or Compute Engine - was actually read. Five positions for one row. The lesson is that a ? is a research task rather than a resting state: it took one page fetch to resolve, and nobody had done it.

Product sync map

A product's name, specs and availability are spread across many sections, so a single-place edit leaves the book arguing with itself. The failure is not hypothetical: the accelerator tables were given GA columns marking GB200/GB300 as shipping while the chapter's own opening summary still called them "expected", and one list said MI400X while every table said MI455X. When adding a product, renaming one, or changing an availability status, walk the list below and fix or consciously skip each entry.

compute/accelerator/README.md:

  1. ## Bird's eye view on the high end accelerator reality - the per-category lists (GPUs, HPU, TPU, On Pods and racks). This is the section most likely to be forgotten because it is prose, it sits far above the tables, and it is the first thing a reader sees. It also ends with a That's about it as of DATE stamp that must be re-dated whenever the lists change.
  2. ## Glossary - any new abbreviation, in alphabetical position.
  3. #### TFLOPS comparison table - dtype columns, GA, the availability break, and the numbered row notes below it.
  4. #### Maximum Achievable Matmul FLOPS comparison table - measured, so a new product appears here only once someone has run the benchmark. Never carry a spec number into it.
  5. ### Accelerator memory size and speed - capacity, type, bandwidth, GA, break.
  6. ### Caches - both the cross-vendor comparison and the vendor-native tables, plus their sources.
  7. ### Clock speed, ### Power consumption - each with its own GA, break, Notes numbering, and as of DATE line explaining not disclosed / N/A.
  8. ### Cloud accelerators - the per-vendor roadmap lists (NVIDIA, AMD, Intel, Amazon, Google, SambaNova). Status verbs live here, so this is where "supposed to become available mid-2024" rots.
  9. ## Accelerators in detail - the per-vendor deep dives (### NVIDIA, ### AMD, ### Intel Gaudi, ### AWS Trainium, ### Google TPU, ### Huawei Ascend, ### Cerebras, ### SambaNova) and the matching ## API subsections.

network/README.md:

  1. ## Glossary and concepts - new fabric or adapter abbreviations.
  2. ### All-to-all bandwidth, ### Peer-to-peer bandwidth - the intra-node node-level tables; both carry GA and a break.
  3. The scale-up fabric sections a new accelerator lands in: ### PCIe, ### NVLink, ### NVLink-C2C, ### NVSwitch, ### Infinity Fabric / xGMI, ### NeuronLink v3, ### UB Link (UnifiedBus), ### Ultra Accelerator Link (UALink).
  4. ## Inter-node networking - the node table, then ### Network adapters, ### InfiniBand, ### Switch platforms and its #### children, ### Reaching beyond the rack.
  5. The per-vendor scale-out sections: ### EFA, ### Gaudi2 (inter-node), ### Gaudi3 (inter-node), ### HPE Slingshot interconnect, ### GPUDirect-TCPX, ### Omni-Path.

Cross-chapter:

  1. An accelerator's scale-up bandwidth appears in both books' chapters - the accelerator chapter quotes it in prose while the network chapter tables it. Change both.
  2. ## Bird's eye view on the high end accelerator reality in the accelerator chapter and ### Backend networking in the network chapter both quote current typical top speeds. Neither cites the other, so both drift.
  3. Grep the whole repo for the old product name before concluding a rename is done - MI450 survived in exactly one list after every table had moved to MI455X.
  4. After any of this, run make fix-tables, re-check internal anchors, and confirm no table sorts a not-yet-purchasable part above shipping hardware.

Table ordering and source layout

  1. Keep Markdown table source vertically aligned for maintainer readability.
  2. Sort table rows by an explicit column and direction.
  3. State immediately before the table which column controls the ordering and whether the order is ascending or descending.
  4. When adding a row, insert it into the declared order rather than appending it arbitrarily.
  5. If a table has no declared sort order, ask the user which order to use and propose an appropriate column before editing it.
  6. Do not choose a numerical sort that implies comparability between semantically different vendor specifications.
  7. Where practical, use compact source references in the table and place the full live-checked links immediately below it.
  8. When a column header is much wider than its body cells, compact it with <br> inside the single header row, e.g. | Platform/<br>example<br>node |. Never spread a header over several pipe-delimited lines: GFM requires the delimiter row to be the second line of the table, so a multi-line header stops the table from being recognized and GitHub renders the header as literal | text with the continuation segments orphaned beneath it.
  9. Source column width is set by the longest of the full header string and the body cells. Rendered width is set instead by the longest <br>-separated segment, which is why <br> narrows the table for the reader even though it lengthens the source line. Optimize for the rendered width; a long source header line is not a problem.
  10. Prefer concise, unambiguous abbreviations such as Uni-dir. when a full term makes a compact table column unnecessarily wide.
  11. Each table has an independent Ref. namespace starting at 1. Ref columns are left-aligned because reference IDs are categorical and may contain multiple comma-separated values. Ref cells and source numbers are plain numbers without brackets or links; the source descriptions below the table contain the actual links.
  12. Move explanatory qualifiers out of compact table headers and into nearby prose or notes when the qualifier does not distinguish the displayed values.
  13. Format each per-table Sources: block as an explicit numbered list whose item numbers match that table's Ref. values; do not combine multiple sources into one paragraph.
  14. After every table edit, shrink each source column to the minimum width required by its longest header or body cell, while preserving vertical pipe alignment.
  15. Keep rendered tables compact to minimize line wrapping on narrow media. Compact disproportionately wide headers with <br> within the single header row, use concise labels, and move nonessential detail below the table without sacrificing clarity.
  16. After editing a table, run make fix-tables. It joins multi-line headers into one row, inserts a missing blank line before a table, and re-pads misaligned pipes, then cross-checks the source table count against what pandoc renders. It reports file:line for everything it fixed, and flags what it cannot fix - such as ragged cell counts, where there is no way to know which cell is missing.

Glossary sections

  1. Keep each glossary list alphabetically sorted, case-insensitively, so RoCE sorts next to RoE and xGMI lands with the letters rather than after them. Insert a new entry in place; never append to the end.
  2. Sort per list, not across the section. A chapter may hold several lists - for example an abbreviation list and a Speed-related: list - and each is sorted independently.
  3. A list whose order is deliberately pedagogical rather than alphabetical, such as one introducing Unidirectional before Bi-directional, may keep that order. Say so in a note, otherwise the next pass will "fix" it.
  4. When adding an abbreviation to a chapter, add it to that chapter's glossary in the same edit. This applies to anything a reader can't expand on sight - a GA table column, busbw, SuperNIC - and not to vendor names, product model numbers, or terms as widely known as GPU or CPU.
  5. Periodically check both directions: abbreviations used in the body but missing from the glossary, and glossary entries no longer used anywhere in the chapter. Neither is fatal, but the first hurts readers and the second is dead weight.

Source line layout

  1. Keep each prose paragraph on one physical source line; do not wrap prose to a fixed line width.
  2. Keep each Markdown list item on one physical source line unless it contains nested block content.
  3. Preserve intentional blank lines between Markdown blocks.
  4. Only code is subject to a line-width limit, which is 119 characters.
  5. Wrap code according to the syntax and semantics of its language rather than applying prose-style reflow.

Unit formatting

  1. Write a value tight against its unit, with no separating space: 340Gbps, 80GiB, 125TFLOPS, 700W. This is the dominant convention across the book.
  2. Prefer the p-suffixed spelling over the slash spelling: use TBps rather than TB/s.
  3. When quoting a vendor or other external source verbatim, leave the original spelling untouched. The tight rule governs the book's own prose, not quoted material.
  4. Unit spacing is a further exception to Review scope item 2, and a different one from tables: here the whitespace changes the rendered text, not just the source.
  5. Re-check this periodically across the whole book and fix any drift. Spaced forms reappear as new material is added, and TFLOPS was historically spaced in most chapters, so it drifts first.
  6. When fixing units inside a script, change the code and any captured output in the same pass so the two continue to agree. Prose chapters may be fixed independently of scripts.
  7. After changing a unit inside a table, restore vertical pipe alignment and re-shrink the affected columns as required by Table ordering and source layout.