Skip to content

docs: restructure the compatibility page and correct platform data - #12529

Merged
dagil-nvidia merged 47 commits into
mainfrom
dagil/release-support-matrix
Aug 10, 2026
Merged

docs: restructure the compatibility page and correct platform data#12529
dagil-nvidia merged 47 commits into
mainfrom
dagil/release-support-matrix

Conversation

@dagil-nvidia

@dagil-nvidia dagil-nvidia commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two things the current support matrix cannot express, and one it states wrongly.

status conflated two different facts. Ubuntu 24.04 and Ubuntu 22.04 both read "Supported", but only 24.04 is a shipped container base (cuda-dl-base 25.11-cuda13.x-devel-ubuntu24.04, per container/context.yaml). 22.04 works because the wheels are manylinux_2_28 — there is no container for it. A reader choosing a host OS cannot tell those apart. Replaced status with scope: "Containers and wheels" vs "Wheels only".

The wheel-validation claim was inaccurate. It said wheels are "validated on CentOS Stream 9 and Ubuntu 22.04/24.04". They are built in a manylinux_2_28 environment (AlmaLinux 8, glibc 2.28+) and validated on Ubuntu 22.04 and 24.04 only. Corrected, and the CentOS Stream 9 row dropped rather than left claiming a validation that does not happen.

67 near-identical rows behind one accordion. The generated table repeated Dynamo/Backend/CUDA/Driver/Note per release, with Note empty on almost every row. The signal a reader wants — CUDA 12 vs 13 — was a number buried mid-row. ReleaseSupportMatrix makes the CUDA major the visual anchor and groups by minor line.

What changed

  • ReleaseSupportMatrix.tsx — new component, rows derived from CUDA_HISTORY and RELEASES in releases.data.ts; nothing transcribed. Native <details>/<summary> for disclosure, so no client JS.
  • releases.data.tsstatusscope, CentOS row removed, wheel note corrected.
  • gen_llms_tables.py — the human-facing accordion generator is removed; the <llms-only> twin still emits the same rows as a flat markdown table, so the agent-facing export loses nothing.
  • FeatureInteractions.tsx — new component rendering the pairwise matrices in the FeatureHeatmap visual vocabulary, from FEATURE_INTERACTIONS in releases.data.ts.
  • releases.data.ts — gains FEATURE_INTERACTIONS: the matrices used to live only in hand-authored JSX, so no pairwise status reached Fern's agent exports. gen_llms_tables.py now emits them into the <llms-only> twin from the same source.
  • InteractionStatus.tsx and its .dynref-interaction* rules in ReferenceStyles.tsx are removed, superseded by the above.

Verification

  • gen_llms_tables.py --check: all outputs unchanged.
  • fern check: 0 errors, 1292 warnings (matches the pre-existing baseline).
  • pre-commit: all applicable hooks pass.
  • fern docs broken-links: all checks passed.
  • The 165 authored interaction cells were migrated mechanically and diffed against the original JSX: 18 differences, all of them the intended LoRA fix.

One fix worth calling out. The component originally used <style>{RSM_CSS}</style>. A text child is escaped on render, so the > child combinator in its CSS would have become &gt; and been dropped silently in production — the failure that took the Home page down in #12402. Switched to dangerouslySetInnerHTML, matching RecipeStyles.tsx, with the reason recorded in the header. ReferenceStyles keeps the text-child form because it still has zero child combinators.

Notes

Rebased across #12373, which renamed every docs path. Five conflict hunks, all resolved toward the new paths.

Update: absorbed #12241

#12241 was a second PR editing compatibility.mdx and gen_llms_tables.py,
and the two conflicted in both files. Landing them in sequence would have
meant resolving that conflict blind on the second rebase, so it was folded
here instead and #12241 is closed.

Carried over: the driver-floor table, which inverts the support matrix so a
reader can start from a driver they already have. <ReleaseSupportMatrix />
renders only the forward view, so this stays a generated span, now placed
beside the component it inverts. Also the SGLang multimodal and router prose
corrections, the v1.3.0 release-note and release-history fixes, the
UpgradePanel change, test_gen_llms_tables.py with its pytest.ini and
pre-commit hook, and the CUDA compatibility link now resolving without a
redirect hop.

Dropped as superseded: the generated support-matrix accordion and its
renderer, replaced by <ReleaseSupportMatrix />, and the raw
feature-interaction markdown tables, replaced by <FeatureInteractions />.
Their per-cell notes live in releases.data.ts.

The fold exposed a factual error. FEATURE_INTERACTIONS marked the SGLang
Multimodal x KV-Aware Routing cell "no" ("This feature combination is not
supported"), while the merged feature table on the same page described it as
supported with a fallback. The page contradicted itself.
multimodal-kv-routing.md is the authority and says supported: hash
forwarding is upstream in SGLang 0.5.13+ and Dynamo pins 0.5.16. The cell is
now "yes", noting that a custom build without the patch degrades to
text-prefix routing.

Validation: gen_llms_tables.py --check clean; check_agent_twins.py clean on
all three governed pages with its self-test at 14/14; test_gen_llms_tables.py
14 passed; ruff clean. Confirmed the corrected note reaches the agent twin.


Open in Devin Review

Summary by CodeRabbit

  • New Features
    • Added a release support matrix with CUDA, driver, toolkit, backend, and related compatibility details.
    • Added release statistics for versions v0.6.0–v0.9.0 and expanded release history information.
    • Added interactive, keyboard-accessible tooltips for feature and interaction support details.
  • Documentation
    • Clarified Ubuntu container and wheel support, manylinux requirements, and validated environments.
    • Updated compatibility guidance and related links.
    • Refined TensorRT-LLM known-issue documentation and cancellation guidance.
  • Bug Fixes
    • Removed outdated CentOS Stream and AWS/Amazon Linux platform references.

The Find a Compatible Release picker asked readers to state their backend
and driver generation before showing anything. Replace it with the matrix
itself, collapsed in a native Fern Accordion, so the CUDA toolkit and
minimum driver requirements are scannable across releases in one view.

This also closes a nav gap: the full CUDA-and-driver-by-release table was
reachable only from reference/releases-data.mdx (hidden from the sidebar)
and the llms-only twin, neither of which a browsing reader will find.

gen_llms_tables.py grows support for more than one generated span per
page, keyed by marker name, and emits the accordion from CUDA_HISTORY so
the numbers stay tied to releases.data.ts at every release bump. The new
span fails closed when its markers are absent rather than appending
itself, keeping placement under human control.

Mainline is read as the stable minor lines (v1.3.0 down to v0.7.0);
CUDA_NOTES already records that patch releases inherit the CUDA support
of their base version, so their rows would only restate the mainline row.

RunsWhereWizard.tsx is left in place -- compatibility.mdx was its only
consumer, but deleting the component is the PR author's call.

Signed-off-by: Daniel Gil <dagil@nvidia.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
The accordion listed only the stable minor lines, on the reasoning that
patch rows restate their base version. That drops real information: a
reader running v1.2.1 had to infer their row from v1.2.0. Cover every
released line instead -- stable releases and their patches -- taking the
matrix from 29 rows to all 60 in CUDA_HISTORY.

Platform previews and model-specific builds stay out. CUDA_HISTORY
carries no rows for them today, so filtering on kind is currently a
no-op, but the filter is expressed on kind rather than on the data
happening to be clean, so a future -dev entry cannot leak in unnoticed.

The accordion and the llms-only twin now emit the same 60 rows. Keeping
both is deliberate: the twin exists because component output may be
dropped from the agent-facing exports, and <Accordion> is a component.
The local dev server does not serve the .md export, so this could not be
verified here; losing the matrix for agents is a worse failure than
repeating it. Comment records the intent so it is not pruned blindly.

Signed-off-by: Daniel Gil <dagil@nvidia.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
The widened matrix runs 60 rows. In a collapsed accordion a single flat
run pushes its header off screen almost immediately, so the reader loses
track of which column is which. Split it into one captioned table per
minor line (1.3.x down to 0.7.x, largest group 15 rows) inside the same
single <Accordion> -- the header repeats every few rows and there is
still only one panel to open.

Separate tables rather than printing the version once and blanking the
repeats: blank leading cells are ambiguous once the page is flattened
into the agent-facing markdown export.

The agent twin keeps the matrix as one flat table. The human and agent
spans are now genuinely different renderings -- grouped for scanning,
flat for parsing -- so carrying both is justified on the merits rather
than on uncertainty about whether <Accordion> children survive the
export.

Signed-off-by: Dan Gil <dagil@nvidia.com>
[kv-routing] pointed at ../user-guides/kv-cache-aware-routing.md. No
user-guides/ directory exists under docs/fern and no file ever lived at
that path in this repo's history, so the reference resolved nowhere and
failed fern broken-links twice (once per docs variant).

The note it sources -- SGLang multimodal plus KV-aware routing is not
supported -- is mirrored from docs/fern/backends/sglang/README.md, which
compatibility.mdx names as its source for the SGLang matrix. That README
carries the identical note and cites components/router/README.md, whose
multimodal section documents image routing for the TRT-LLM and vLLM
router paths only. Pointing at the same target keeps the two pages
citing one authority instead of diverging.

reference/ broken-link errors go 2 -> 0. One pre-existing error remains
in kubernetes/api-reference.md, untouched here.

Signed-off-by: Dan Gil <dagil@nvidia.com>
One conflict, on the [kv-routing] link definition in compatibility.mdx.
#12243 repointed it at ../kubernetes/kv-aware-routing.md; this branch had
repointed it at ../components/router/README.md. Kept this branch's target:
#12241 introduces a separate [mm-kv-routing] reference for the multimodal
claims and keeps [kv-routing] on the router README, so taking the other
side would re-conflict one PR later. Both targets exist; the link resolves.

Also regenerated releases-data.mdx, which went stale on a dependency bump
(nixl 1.1.0 -> 1.3.1).

check_reference.sh: all 5 gates pass, 0 broken links in reference/.

Signed-off-by: Dan Gil <dagil@nvidia.com>
One conflict, in docs/fern/reference/releases-data.mdx. That file is
generated by gen_llms_tables.py, which auto-merged, so the conflict was
resolved by regenerating rather than hand-merging the markers.

gen_llms_tables.py --check is idempotent afterwards, and fern broken-links
reports 0 errors in reference/.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Resolve conflicts:
- docs/fern/pages/reference/general/compatibility.mdx: keep main's relocated
  reference paths under developer-guide/knowledge-base and use-cases.
- docs/fern/scripts/gen_llms_tables.py: preserve this PR's Block/support-matrix
  architecture (support-matrix + llms-tables markers) and adopt main's current
  generated filename releases-machine-readable.mdx (was releases-data.mdx).

Regenerate outputs; compatibility.mdx accordion now links to
releases-machine-readable.mdx.

Signed-off-by: Daniel Gil <dagil@nvidia.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
Signed-off-by: Daniel Gil <dagil@nvidia.com>
The column was mixing two incompatible quantities. Most cells came from
the release bodies, but the bodies themselves are not uniform: v1.1.0's
figure counted only external contributors, from a list its own wording
calls partial ("first-time external contributors ... include"). GitHub's
New Contributors lists answer a third question -- first-ever merged PR
over the compare range -- and put the pre-v1.0.0 releases at 11 where
their announcements say 20 and 14.

Settle on the bodies, which is what every other column in this table
already uses, and require the figure to be release-wide and complete.
v1.1.0 fails both tests and becomes a dash rather than an undercount.

v1.3.0 moves 23 -> 24. The published body states 24 and enumerates 24;
23 came from a pre-release draft. @Change72 was raised as a name that
should not be on that list, on the grounds that PR #10157 predates the
v1.2.1 tag. It does by date, but release/1.2.x was cut from main on
2026-05-12 and #10157 merged 2026-06-02, so it is absent from v1.2.1 and
first ships in v1.3.0 -- inside the compare range, which makes them a
genuine first-timer here. Left in place.

Footnote the empty cells on the rendered page too. They are permanent
now rather than pending, so a reader deserves to know why they are empty
and that first-timers are counted release-wide.

Signed-off-by: Dan Gil <dagil@nvidia.com>
The compatibility matrix, the SGLang backend README, and the data behind
the agent-facing twin all said multimodal plus KV-aware routing was not
supported on SGLang. The code says otherwise, and has since the upstream
interop patch landed.

decode_handler.py probes engine.async_generate once at startup for the
mm_hashes argument. When it is there, per-image hashes are forwarded and
SGLang builds the same pad_value the router used, so image identity
participates in cache overlap. When it is absent the request still
completes and routing falls back to text-prefix overlap alone.

So the honest answer is neither "supported" nor "not supported": it is
supported on Dynamo's SGLang image, which carries the patch, and
degrades rather than fails on a custom build without it. State that
everywhere the claim appears, including the router README, whose
"documented TRT-LLM and vLLM router paths" wording implied SGLang was
excluded outright. The SGLang multimodal guide describes the hash
forwarding but never said what happens without it; it does now.

The support matrix in multimodal-kv-routing.md already had this right.

Signed-off-by: Dan Gil <dagil@nvidia.com>
The matrix answers "what does this release require". A reader who
already has a driver installed is asking the inverse, and the only way
to answer it from the matrix is to scan every row deciding which floors
their driver clears.

Add a small generated table above the accordion that inverts it: one row
per driver floor, one column per backend, each cell the newest release
that backend runs on that driver. Read it as "at least this version" --
a 580 driver satisfies the 575 and 570 floors too, so those releases
stay runnable and the cell reflects that rather than showing only what
requires exactly 580.

Floors and backends are both derived from CUDA_HISTORY, so a fourth
floor or a fourth backend appears without touching this code. Driver
versions parse to integers before they are compared; the retired wizard
compared strings like "580.xx+", which is right only for as long as
every floor has three digits.

TensorRT-LLM has no build that runs on a 570 or 575 driver. That is the
most useful cell in the table, so it says None rather than rendering an
ambiguous dash.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Same coincidence as the from-candidate filter, one layer down.
buildReadingChips tested RELEASE_STATS membership before emitting a chip
that deep-links to a per-release section of the Deprecations or Known
Issues page. Those sections exist only for releases with a notes page;
stats membership stood in for that, and only matched because
RELEASE_STATS held nothing older than v1.0.0.

Backfilling the pre-v1.0.0 rows ended that. It is not currently
reachable with a bad version, because the caller now filters
from-candidates on notesHref, but ReadingListFooter is exported and the
guard is one import away from being wrong again. Test the condition the
hrefs actually depend on so both layers agree.

Signed-off-by: Dan Gil <dagil@nvidia.com>
The bare directory URL 301s to /latest/, and the link checker counts a
redirect as a failure. Only this one use was bare; the deep links
elsewhere already resolve directly.

Signed-off-by: Dan Gil <dagil@nvidia.com>
copyright-checks rejects any .py under the repo that does not open with
the Apache header block. The new generator test file started at its
docstring, so the job failed on this one path. Match the header
gen_llms_tables.py already carries.

Signed-off-by: Dan Gil <dagil@nvidia.com>
The hand-authored Per-Backend Detail tab still said multimodal was not
compatible with KV-aware routing, so the page contradicted the Feature
Interactions note and the generated per-release table a few hundred
lines away. Same wording as the generated table: supported on Dynamo's
SGLang image, text-prefix fallback on a build without the patch.

Signed-off-by: Dan Gil <dagil@nvidia.com>
The ingested page was taken from a pre-release draft: 23 first-timers,
and @jooe0824 missing from both the New Contributors list and the SK
Telecom line. The published v1.3.0 body says 24 and enumerates 24,
which is the figure the release table now carries, so the page was the
only thing still saying 23.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Rebuild the Release Support Matrix as a React component and move it to the
bottom of the page, so CUDA 12 and CUDA 13 render as distinct sub-cards with
per-major driver requirements instead of being buried in table cells. Older
minor lines collapse behind a summary showing which CUDA majors they ship.

Render feature interactions as per-backend tabs with hover notes, replacing
glyph tables and superscript footnotes. A cell that was blank but footnoted
"Not supported" now reads as an explicit unsupported marker.

Correct stale platform data at its source in releases.data.ts rather than in
the rendered prose, so the hero chips, the agent-facing export, and the
machine-readable page all agree. Ubuntu 24.04 and 22.04 now carry distinct
scopes, separating what containers are built on from what the manylinux
wheels run on. Drop CentOS Stream 9, which no CI, test matrix, or base image
supports, and drop the Amazon Linux 2023 support claim, which has no evidence
in the tree.

Correct the TensorRT-LLM --network host caveat, which attributed the hang to
a confirmed mpi4py defect. The upstream thread is open and undiagnosed, and
maintainers there point at the backend MPI implementation instead.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia
dagil-nvidia requested a review from a team as a code owner August 1, 2026 05:10
@github-actions github-actions Bot added documentation Improvements or additions to documentation docs labels Aug 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

Open in Devin Review

Comment thread docs/fern/pages/reference/general/compatibility.mdx Outdated
Comment thread docs/fern/components/FeatureHeatmap.tsx
Comment thread docs/fern/components/releases.data.ts
Comment thread docs/fern/components/InteractionStatus.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc81bcf383

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/fern/pages/reference/general/compatibility.mdx Outdated
Comment thread docs/fern/components/ReleaseSupportMatrix.tsx Outdated
Comment thread docs/fern/components/ReleaseSupportMatrix.tsx Outdated
Comment thread docs/fern/pages/reference/general/compatibility.mdx Outdated
Comment thread docs/fern/components/releases.data.ts
[kv-routing] and [mm-vllm] have no remaining references on the page -- the
multimodal citations moved to [mm-kv-routing] and the KV-routing citation
went with the accordion. Both were kept by mistake when resolving the
rebase against the #12373 path rename, which carried HEAD's full definition
list rather than the narrower set this commit intends.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 6640164

The 11 (now 14) tests for gen_llms_tables.py were only reachable by hand: the
root pytest config carries --ignore-glob=docs/*, and neither check_reference.sh,
pre-commit, nor any workflow invoked the file. Add a local hook scoped to the
generator, its tests, and releases.data.ts.

Markers cannot come from the root config for the same ignore-glob reason, so a
standalone pytest.ini beside the tests registers pre_merge / gpu_0 / unit and
turns on --strict-markers for this file.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Two accuracy fixes on the compatibility page.

Driver floors: the table filtered CUDA_HISTORY on an exact version match, so
post trains -- which deliberately carry no CUDA_HISTORY row because CUDA_NOTES
states they inherit their base release's CUDA support -- never appeared. The
570.xx+ row named vLLM 0.7.0 when v0.7.0.post1 is the newest release that runs
there. Resolve each cell through the newest release sharing that base.

SGLang fallback note: the note claimed Dynamo drops image identity from the
routing key when the startup probe finds no mm_hashes kwarg. It does not.
_resolve_mm_hashes_supported only gates the kwarg passed to
engine.async_generate in the SGLang decode handler; the frontend keeps building
image-aware routing keys via gather_mm_exact_routing_info, so the worker's
internally computed hashes never align and only the text prefix overlaps. The
distinction matters when diagnosing KV events on a custom image. Same note on
the SGLang overview page, corrected identically.

Three tests cover the post-train inheritance.

Signed-off-by: Dan Gil <dagil@nvidia.com>
Base automatically changed from dagil-nvidia/compatibility-page-cleanup to main August 1, 2026 18:38
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test ff0098f

Scope was one page because expanding it meant reading components I had not
read. Mapping every component to its pages showed only three carry a twin at
all, so those three are the live invariant and the rest are a different
question: whether a page should have a twin, which is not this check to
decide. release-artifacts and model-early-access-builds are now governed.

Their expectations were verified before being added, not after. ARTIFACTS
covers 24 of 24 in its twin and MODEL_EA_BUILDS 9 of 9, so both are
all-or-nothing. Deriving from RELEASES once failed a correct twin because I
skipped that step.

FeatureHeatmap keeps its margin. It also sits at full coverage, but the twin
names features in prose as well as in a table, where an exact count breaks
on a rewording that loses nothing.

The structural check asserted shape and not content: keeping the interactions
heading and the backend markers while deleting every row under them passed.
Row labels from INTERACTION_FEATURES are now required inside that section,
scoped past the heading because the same labels appear in the feature table
above and would otherwise satisfy it.

Validation: gutting the interaction rows now fires, as does removing one
backend, deleting the section, and adding an artifact or an early-access
model the twin lacks. Self-test 14/14, three governed pages clean.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 9394214

#12241 and this PR both rewrote compatibility.mdx and gen_llms_tables.py and
conflicted in both. Landing them in sequence would have meant resolving that
conflict blind on the second rebase; folding resolves it once with both sides
in hand. #12241 is closed in favour of this.

Carried over from #12241:

  * The driver-floor table, which inverts the support matrix -- read across
    from a driver you already have to the newest release each backend runs on
    it. <ReleaseSupportMatrix /> renders only the forward view (release -> min
    driver), so this stays a generated span, now placed beside the component
    it inverts.
  * The SGLang multimodal and router prose corrections, the v1.3.0 release
    note and release-history fixes, and the UpgradePanel change.
  * test_gen_llms_tables.py (14 tests) with its pytest.ini and pre-commit hook.
  * The CUDA compatibility link, now pointing at /latest/ so it resolves
    without a redirect hop.

Dropped from #12241, superseded here:

  * The generated support-matrix accordion and its render_support_matrix
    renderer. <ReleaseSupportMatrix /> replaces that rendering, and the data
    still reaches agents through the llms-tables twin.
  * The raw feature-interaction markdown tables, replaced by
    <FeatureInteractions />. Their per-cell notes live in releases.data.ts.

Corrects a factual error this fold exposed. FEATURE_INTERACTIONS marked the
SGLang Multimodal x KV-Aware Routing cell "no" ("This feature combination is
not supported"), while the merged feature table on the same page described it
as supported with a fallback -- the page contradicted itself. multimodal-kv-
routing.md is the authority and says supported: hash forwarding is upstream in
SGLang 0.5.13+ and Dynamo pins 0.5.16. The cell is now "yes", noting that a
custom build without the patch degrades to text-prefix routing.

Not carried over: the RecipeStyles, ReferenceStyles and TerminalDemo comment
fixes, which are #12388's and stay there. Those three files are byte-identical
to main on this branch.

Validation: gen_llms_tables.py --check clean; check_agent_twins.py clean on all
three governed pages with its self-test at 14/14; pytest test_gen_llms_tables.py
14 passed; ruff clean. Verified the corrected note reaches the agent twin.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test de97c69

@harryskim harryskim left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved

@dagil-nvidia
dagil-nvidia enabled auto-merge (squash) August 9, 2026 01:09

@dmitry-tokarev-nv dmitry-tokarev-nv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed with a DevOps focus — the pre-commit wiring and the two scripts it gates. No blockers. Everything below is a gap in the new gates rather than something that breaks the build, and the four .pre-commit-config.yaml comments are all the same shape: the hooks are scoped more narrowly than the code they are meant to guard.

The two I'd most want addressed before merge:

  • check-agent-twins fires on 1 of the 3 pages its own IN_SCOPE list governs, so two of the three twins this PR is built to protect are ungated — and a rename of either throws the hard-fail onto an unrelated PR later.
  • gen-llms-tables runs the tests but never --check, so releases.json and every generated span can silently go stale. Nothing else in the repo checks it.

One item that has no diff line to hang off: minor_line (L690) and group_by_minor_line (L701) in gen_llms_tables.py are now dead — their only caller, render_support_matrix, is deleted in this PR. Nothing under docs/ or .github/ references them.

Validated locally at de97c69

  • check_agent_twins.py → exit 0; --test → 14/14 passed
  • gen_llms_tables.py --check → all 7 outputs unchanged
  • pytest -c docs/fern/scripts/pytest.ini ... test_gen_llms_tables.py → 14 passed
  • driver_floor_table output hand-checked against CUDA_HISTORY: the None cells for TensorRT-LLM at the 570/575 floors and the 0.7.0.post1 post-train substitution are both correct
  • check_style_components.py run manually against ReleaseSupportMatrix.tsx and FeatureInteractions.tsx → clean (so the scoping comment is about coverage, not a live defect)

The 40% coverage figure in the check_agent_twins.py comment is measured, not estimated: I deleted the CUDA table from the twin and re-ran the check.

Nice work on the twin gate generally — the _interactions_segment scoping and the "cases that have actually failed here" self-test are the right instincts. Most of this is asking for those same instincts applied one level wider.

Comment thread .pre-commit-config.yaml Outdated
Comment thread .pre-commit-config.yaml
Comment thread .pre-commit-config.yaml Outdated
Comment thread .pre-commit-config.yaml
Comment thread docs/fern/scripts/check_agent_twins.py
Comment thread docs/fern/scripts/check_agent_twins.py Outdated
Comment thread docs/fern/scripts/check_agent_twins.py Outdated
Comment thread docs/fern/scripts/gen_llms_tables.py
Comment thread docs/fern/scripts/gen_llms_tables.py Outdated
All findings from @dmitry-tokarev-nv, each reproduced before and after.

The twin hook fired on one of the three pages IN_SCOPE governs. A commit
deleting the twin from release-artifacts.mdx or model-early-access-builds.mdx
ran no hook at all, and renaming either would have thrown the script's
hard-fail onto the next unrelated PR. The pattern now covers all three, with a
note that it has to stay in step with IN_SCOPE.

The generated tables were tested but never checked. gen-llms-tables ran the
test suite and never gen_llms_tables.py --check, and nothing else in the repo
did either, so editing releases.data.ts without regenerating left releases.json
and every span stale. Added gen-llms-tables-check.

The release-coverage search was unscoped. Bare versions appear in the
backend-pins table in the same twin, so deleting every release row still
scored 40 percent. _releases_segment bounds the search to the release section,
mirroring _interactions_segment. Gutting the rows now reports 0 percent and
fails. Added as a self-test case; the release fixtures gained the heading,
since a fixture without it models a page that scores zero.

_interaction_features swallowed two intervening exports. Splitting on the next
"export const" ran past a type and an interface and admitted backend names from
a union: 12 names, 2 of them backends, and inconsistently, since the uppercase
filter kept SGLang and TensorRT-LLM but dropped vLLM. Bounded on the array
literal instead. Returns 10 row labels, no backends.

The self-test wrote to a fixed /tmp path, so concurrent runs collided and a
read-only TMPDIR failed the hook. Uses a private temp dir.

PLATFORM rows were published with an unconditional "Supported". The premise
did not hold: the CentOS Stream row this PR removes carried "Experimental".
Nothing is misrepresented today, but the next preview or restricted scope
would have been published to releases.json as supported. SCOPE_STATUS maps it
explicitly and raises TSParseError on an unmapped scope.

An unknown interaction status raised a bare KeyError, surfacing as
"KeyError('preview')" with no indication of which map or how to fix it. Raises
TSParseError like feature_cell.

minor_line and group_by_minor_line were dead once render_support_matrix went.
Removed.

One suggestion adjusted rather than taken. Widening the style hook to
components/.*\.tsx fails on three existing components -- FeatureHeatmap,
ModelEABuildCards and TerminalDemo -- all of which interpolate legitimately.
The check forbids interpolation, which is right for a pure CSS literal and
wrong for ordinary TSX, and its LITERAL regex matches every template literal
rather than only CSS ones. The two new CSS-holding components are named
explicitly instead, in both the hook and the argless default, so the concern
is covered without reddening files that were never in scope.

Validation: check_agent_twins clean on all three pages, self-test 15/15;
check_style_components covers 6 components clean; gen_llms_tables --check
clean; test_gen_llms_tables 14 passed; ruff clean; config parses; all three
IN_SCOPE pages verified against the hook pattern.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 98425e2

@dmitry-tokarev-nv dmitry-tokarev-nv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed at 98425e2. All nine are addressed and the threads are already resolved, so nothing is outstanding from the first pass — this is three new items, none of them blockers.

On the one you adjusted

Your pushback on the style-hook scoping is right, and my suggestion was wrong: LITERAL matches every const X = \…`literal rather than only CSS ones, and forbidding${` is correct for a pure CSS literal and wrong for ordinary TSX. Naming the two components is the right call.

One correction to the count, which matters for the follow-up you floated: it is four components, not three. TagLookup.tsx:118 also fails — and it is the interesting one, because TG_CSS is a real CSS literal that interpolates legitimately (${ENTRIES.map((_, i) => …)}). So a rule that distinguishes CSS literals from ordinary template literals would still not let the glob widen; TagLookup would need the interpolation rule relaxed, not the CSS detection improved. Worth knowing before that follow-up gets scoped.

Verified at 98425e2

  • check_agent_twins.py → exit 0 on all three pages; --test → 15/15
  • gen_llms_tables.py --check → all 7 outputs unchanged; test_gen_llms_tables.py → 14 passed
  • _releases_segment re-tested destructively against the real page, not just the fixture: gutting the release table under the heading now reports 0% of what ReleaseSupportMatrix renders, below 100% and exits 1. That was 40% and passing before, so the scoping does what it claims on the live twin, not only in the self-test.
  • _interaction_features → 10 row labels, no backends
  • Style hook covers 6 components clean; the argless default matches the hook pattern
  • minor_line / group_by_minor_line gone, no residual references

The self-test case you added for the unscoped search — versions in a backend-pins position, heading present, rows deleted — is exactly the shape that was slipping through. Good addition.

Comment thread docs/fern/scripts/check_style_components.py
Comment thread .pre-commit-config.yaml Outdated
Comment thread docs/fern/scripts/gen_llms_tables.py Outdated
Three follow-ups from @dmitry-tokarev-nv's re-review, all reproduced.

check_style_components could not report a defect. check() built its diagnostic
with an unguarded path.relative_to(REPO), and pre-commit passes repo-relative
paths, so the call raised ValueError before the message printed. The gate still
blocked, which is why it stayed hidden: clean files are unaffected and the
failure only appears on the one run that matters, where the author got a
pathlib traceback instead of "raw backtick inside RSM_CSS". Guarded the same
way check_agent_twins guards both of its calls. Verified with relative and
absolute paths.

releases-atom.xml was generated but not gated. --check covers it, and the
hook's pattern listed releases.json beside it but not the feed, so a hand-edit
to the Atom output was the one generated artifact that could drift unnoticed --
the same shape as the gap the hook was added to close. Pattern now matches
both; confirmed it matches neither an unrelated asset.

The status docstring still carried the premise the fix disproved. It said
status was "re-emitted with the value those rows always carried", which the
CentOS Stream row contradicted. Rewritten to describe SCOPE_STATUS and why
deriving fails closed.

Correction to my own note on the previous commit: widening the style hook
fails on four components, not three. TagLookup is the fourth and the
instructive one -- TG_CSS is genuinely CSS and interpolates legitimately, a
generated selector list containing a nested backtick. So improving CSS
detection would not let the glob widen; TagLookup needs the interpolation rule
relaxed. Worth having recorded before that follow-up is scoped.

Validation: check_agent_twins clean, self-test 15/15; check_style_components
6 components clean and now printing its diagnostic; gen_llms_tables --check
clean; test_gen_llms_tables 14 passed; ruff clean; config parses.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test f020845

The section claimed 'Every stable release and patch', and named its exclusions
as platform previews and model-specific builds. Both stable v0.6.0 and v0.6.1
have no CUDA_HISTORY row, and neither do five post-releases across v0.6.1,
v0.7.0 and v0.8.1, so the matrix silently omitted seven releases the prose
promised.

The component derives from CUDA_HISTORY deliberately -- that is what the rows
are -- so the fix is the claim, not the data. Rewritten to say the matrix
covers releases with recorded CUDA data, and to name the ones that predate
that tracking rather than leave a reader to notice the gap.

Closes a finding dynamo-review-agent raised on 2026-08-01 that survived the
restructure.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 632fc97

632fc97 was wrong. I compared RELEASES against CUDA_HISTORY at the data level,
found seven stable and patch releases with no CUDA rows, and concluded the
matrix omitted them. It does not: ReleaseSupportMatrix iterates RELEASES
filtered by kind (L218), and releaseLines falls back to unrecordedLines when a
release has no CUDA rows (L328), so those seven render with their toolkit and
driver marked 'Not recorded'.

Verified: all seven are kind stable or patch, so they pass the filter, and the
matrix renders 22 releases in total.

The original claim was accurate and is restored. Added one sentence naming the
'Not recorded' treatment, which the prose never explained and which is the
thing a reader meeting those rows would otherwise wonder about.

The finding this chased -- dynamo-review-agent, 2026-08-01 -- was already fixed
by the restructure that introduced unrecordedLines. Caught by coderabbitai on
re-review; my error was reading the data rather than the rendering path.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test b874ce5

#12388 merged and moved main, conflicting on .pre-commit-config.yaml. Both
sides append to the same hook list: this branch adds gen-llms-tables and
gen-llms-tables-check, main adds check-component-imports and its self-test.
Different hooks, no overlap, so the resolution is the union. Taking either
side alone would have silently dropped a gate nobody would notice missing.

Resolving surfaced a real defect in this branch's own hook.
gen-llms-tables-check was missing 'pass_filenames: false', so pre-commit
appended the matched filenames to the command and gen_llms_tables.py --check
rejected them as unrecognized arguments. The hook therefore failed on any
commit touching releases.data.ts or its outputs -- which is precisely when it
is supposed to run, so the gate was inert exactly when it mattered. Its
sibling gen-llms-tables already sets the flag; this one did not. Running
--check by hand passes because no filenames are appended, which is why it went
unnoticed.

Everything else auto-merged, including releases.data.ts and the artifacts
generated from it. An auto-merged generated file is not trustworthy merely
because git emitted no marker, so freshness was verified rather than assumed.

Validation: full pre-commit run passes; 32 hooks parse with all four present
and no conflict markers; gen_llms_tables --check confirms releases.json and
every generated span still match the merged source.

Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 7dc4547

@dmitry-tokarev-nv dmitry-tokarev-nv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for addressing comments.
Docs changes are low risk.
LGTM from DevOps perspective.

@dmitry-tokarev-nv

Copy link
Copy Markdown
Contributor

Approved. One correction to something I asserted earlier, since it is wrong on the record and is the kind of claim that gets reused.

On the check-agent-twins scoping thread I wrote that a rename of an IN_SCOPE page would throw the script's hard-fail "onto the next unrelated PR that touches any components/*.tsx", and the commit message repeats that framing. That scenario does not occur. pre-merge.yml runs pre-commit/action with no arguments, which is run --all-files, so every hook in this config executes on every PR and every push to main regardless of its files: pattern. I confirmed the behaviour rather than inferring it — pre-commit run check-agent-twins-selftest --all-files reports Passed, not Skipped, despite its pattern naming a single file.

The practical difference: a files: pattern does not scope which PRs a hook can break. It scopes which files get passed to the hook, and which local git commit runs invoke it. So a rename trips the check on the renaming PR itself, with ::error::in-scope page not found naming the file — it fails closed and self-reports to the person who caused it, which is the right behaviour and not the deferred landmine I described.

Widening the pattern to all three IN_SCOPE pages was still worth doing: it is what makes the hook fire on a local git commit that touches release-artifacts.mdx or model-early-access-builds.mdx, and it keeps the pattern honest about what the script governs. The fix stands; only my rationale for it was wrong.

For the record, on the CI and security surface, since this config gates both PR and post-merge:

  • The pre-commit job on 7dc4547 took 130s against its timeout-minutes: 3 cap. Recent main runs: 134s, 98s, 92s, 99s. The three added hooks run in under 0.1s each, so this sits inside main's existing variance. (That the cap is already at ~74% on main is worth its own look, unrelated to this PR.)
  • All new hooks are under the existing repo: local block running repo-local scripts; no new external pre-commit repo or third-party Action, and pre-commit/action stays SHA-pinned. No eval, exec, subprocess, or network call in any of the three scripts.
  • Nothing outside .pre-commit-config.yaml and docs/fern/** is touched, so no core code or functional test is in scope.

No action needed on any of this.

@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

Thanks — confirmed your correction independently before relying on it. pre-merge.yml passes no extra_args to pre-commit/action@v3.0.1, so it is run --all-files, and pre-commit run check-agent-twins-selftest --all-files reports Passed here too, not Skipped. A files: pattern scopes which filenames reach a hook and which local git commit invokes it — not which PRs it can break. Nothing in the tree encodes the old framing; it lived only in that thread and a commit message.

While checking that, I found a worse error of my own in the same area, so putting it on the record too.

The merge commit 7dc4547 claims it fixed a pre-existing defect: gen-llms-tables-check missing pass_filenames: false. That is wrong. The hook already had the flag at b874ce5. My conflict resolution dropped it — the conflict boundary cut through that hook's definition, and the union I applied kept HEAD's block only up to files:, leaving the flag behind. I then hit the failure locally, diagnosed it as a branch defect, and "fixed" what I had just broken one step earlier.

Two things follow. The file is correct now, so there is nothing to re-fix — pass_filenames: false is present and the full pre-commit run passes. But the commit message misattributes the cause, and pre-commit was green on b874ce5, which is the evidence I should have checked before claiming a pre-existing defect rather than after.

The lesson generalises past this hook: a regex union across conflict markers is not safe when the boundary falls inside a block, because it silently truncates the block rather than failing. Verifying the resolved file against the pre-merge version — not just that it parses — is what would have caught it.

No action needed from you; your approval stands on the file state, which is right.

🤖 Addressed by Claude Code

Clean auto-merge, no conflicts. Brings the branch up to date and produces a
fresh head, which also escapes a wedged CI run: the previous head's PR
workflow sat queued for 90 minutes with every job skipped except
deploy-cleanup, so deploy-status-check -- a required context -- never
reported and the PR could not merge despite being approved with every other
required check green.

Hooks verified against both parents rather than assumed, after a regex union
silently truncated one earlier on this branch: 32 hooks before and after, none
lost, no attribute drift, and gen-llms-tables-check still carries
pass_filenames: false.

Validation: gen_llms_tables --check and check_agent_twins both exit 0.
Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 0155c4b

@dagil-nvidia
dagil-nvidia merged commit d1b7c31 into main Aug 10, 2026
100 checks passed
@dagil-nvidia
dagil-nvidia deleted the dagil/release-support-matrix branch August 10, 2026 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs documentation Improvements or additions to documentation size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants