Skip to content

docs: realign agent guides with the tab structure and add a docs lint job - #12528

Merged
dagil-nvidia merged 26 commits into
mainfrom
dagil-nvidia/docs-agent-guides-and-lint
Sep 1, 2026
Merged

docs: realign agent guides with the tab structure and add a docs lint job#12528
dagil-nvidia merged 26 commits into
mainfrom
dagil-nvidia/docs-agent-guides-and-lint

Conversation

@dagil-nvidia

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

Copy link
Copy Markdown
Collaborator

Summary

The tab restructure (#10855) moved docs content from docs/<section>/ to docs/fern/pages/<tab>/, but the agent-facing guides were never updated. They still described a two-tab site, told authors to create files at docs/<subdirectory>/<file>.md, and pointed at three paths that no longer exist. This realigns them and closes the enforcement gap that let the drift happen silently.

Two halves. Add a blocking Docs Lint job, and clean the docs tree to zero errors so that job gates all of docs/ rather than only changed files. The second half is what makes the first meaningful: a gate scoped to changed files would grandfather every existing violation, so the tree is cleared first and the job blocks from day one.

New: docs/fern/pages/AGENTS.md. A placement guide for the content tree: the nine tabs and the directory each is rooted at (the nav key and directory differ for the two guide tabs), the Kubernetes/CLI split, a tab-selection ladder, the nav grammar, and the URL model. Placement is the decision worth getting right, because fixing it later costs a move plus a redirect.

docs/fern/AGENTS.md becomes the mechanics guide. Every original rule is kept; it gains a pointer to the new file, a map of docs/fern/ separating content from site config, and the sync_site_css.py and docs-website gates.

The dynamo-docs skill is corrected throughout: content paths, nav grammar (tabs: map, path: relative to docs/fern/), the tab table and Kubernetes/CLI split, the URL join rule, the translations path and its ../ depth, the assets path, and the Key References table.

docs/fern/templates/ cleanup is no longer part of this PR. It originally deleted twelve stale flat template files describing a taxonomy the restructure removed. #13138 has since deleted the same files on main and replaced them with a tab-aligned directory structure, so that half is redundant and has dropped out of the diff. Scope is now 20 files.

The enforcement gap

Both docs/fern/AGENTS.md and the skill claimed a "Dynamo Docs Bot" enforced the structural rules pre-merge. No such workflow existed. Real enforcement was fern check, fern docs broken-links, and repo-wide lychee, which cover nav structure and link resolution but not SPDX headers, body # H1, or internal references. Authors were told CI would catch things it never looked at.

This adds docs/fern/scripts/docs_lint.py and wires it as the Docs Lint job in pre-merge.yml, which runs on every pull_request alongside its sibling Fern jobs, and registers it in pre-merge-status-check so it actually gates merge. That token is read-only, so the job reports through inline annotations on the offending line plus a job summary rather than a PR comment.

The linter's navigation check had been a silent no-op: it looked for docs/index.yml, which the restructure replaced, and returned early when absent. It now reads the real nav and resolves every path: against docs/fern/.

What the linter found

Running it surfaced two pages that were live on the docs site:

  • pages/kubernetes/installation/model-storage/overview.md was 4 bytes containing the word TODO, shipping as "Overview" under Kubernetes Guide → Installation → Model Storage.
  • pages/reference/general/examples.md was 0 bytes, empty, shipping as "Examples" under Reference → General.

Both are removed from the nav and deleted, along with the dangling <Card> that pointed at the first. The remaining baseline is cleaned to zero so the job gates the whole docs/ tree rather than only changed files: ten relative links that escaped docs/ converted to github.com URLs, one missing SPDX header, and one comment-only frontmatter fixed in deploy/operator/docs/header.md so regeneration keeps it.

Rebased on main

Merged main on 2026-08-22. Two conflicts, both resolved toward the newer intent: the
pre-merge.yml needs list takes main's, which dropped the snapshot job, and keeps
docs-lint; docs/fern/AGENTS.md keeps both sides, since main added the reviewer note on
curated Kubernetes pages while this branch added the regenerate-before-merge guidance and
the Validate section.

One adaptation was required. #13556 stopped committing the Python and Rust API references
and gitignored both trees, so they are generated at publish time and absent from a clean
checkout. The linter did not know that and reported 29 errors against nav entries and links
targeting them, which would have made this gate fail on its first run. docs_lint.py now
treats pages/reference/api/{python,rust} as satisfied for nav and link resolution, with a
keep-in-sync note against docs/fern/.gitignore.

That left two genuine errors, both in pages/recipes/model-recipes/qwen-3-8-2-4t-a95b-fp8.mdx:
a ../kubernetes/quickstart.mdx link that resolves nowhere, where every sibling recipe page
uses ../../kubernetes/getting-started/quickstart.mdx. Fixed. The linter catching real drift
on its first run against a tree it had not seen is the argument for the job.

Validation

python3 docs/fern/scripts/docs_lint.py --scan docs   # 0 errors, 450 files
cd docs/fern && fern check                 # 0 errors
python3 scripts/validate_skills.py .       # validated 17 skills: OK
pre-commit run --all-files                 # clean

The nav check was verified to actually fire by injecting a dangling path: into index.yml: it reported the correct file and line and exited 1. Both linter output paths were exercised against a scratch tree, confirming the annotation format, the job summary table, and the exit codes. The translations ../ depth rule stated in the skill was checked against all nine translated files (depth 2 uses 5, depth 4 uses 7).

Follow-up

examples/ and recipes/ carry a separate backlog of 32 missing SPDX headers and one broken link, so the job scans docs/ only for now. Widening --scan should land with those fixes, in a PR scoped to those owners.

🤖 Generated with Claude Code


Open in Devin Review

Summary by CodeRabbit

  • Documentation

    • Updated documentation guidance for improved organization, navigation, localization, and authoring workflows.
    • Removed outdated navigation entries, templates, placeholders, and obsolete page references.
    • Improved sidebar labeling and corrected links across the documentation.
    • Clarified recipe placement and publishing requirements.
  • Quality Improvements

    • Added automated documentation validation for links, metadata, navigation, headings, licensing, and internal references.
    • Documentation checks now run automatically during pre-merge validation.

dagil-nvidia and others added 2 commits July 31, 2026 23:49
The docs claimed a "Dynamo Docs Bot" enforced the structural rules pre-merge.
No such workflow existed, so SPDX headers, frontmatter, body H1s, link scope,
and internal references went unchecked while the docs told authors CI would
catch them.

Add scripts/docs_lint.py and wire it as the Docs Lint job in pre-merge.yml,
which runs on every pull_request alongside fern-check and fern-broken-links.
The token there is read-only, so the job reports through inline annotations on
the offending line plus a job summary rather than a pull request comment.
Register it in pre-merge-status-check so it actually gates merge.

The linter's navigation check had been a silent no-op: it looked for
docs/index.yml, which the tab restructure replaced with docs/fern/index.yml,
and returned early when absent. It now reads the real nav and resolves every
path: against docs/fern/.

Clean the docs/ baseline to zero so the job can gate the whole tree rather than
only changed files:

- Convert ten relative links that escaped docs/ to github.com URLs.
- Add the missing SPDX header to the flash-indexer tools README.
- Give the generated Kubernetes API reference a real frontmatter key, fixed in
  deploy/operator/docs/header.md so regeneration keeps it.
- Drop two pages that shipped unfinished: model-storage/overview.md contained
  the word TODO and reference/general/examples.md was empty. Both were in the
  nav and live on the site. Remove the dangling Card pointing at the first.

examples/ and recipes/ carry a separate 32-header backlog, so the job scans
docs/ only for now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
The tab restructure (#10855) moved content from docs/<section>/ to
docs/fern/pages/<tab>/, but the agent-facing guides were never updated. They
still described a two-tab site, told authors to create files at
docs/<subdirectory>/<file>.md, and pointed at three paths that no longer exist
(docs/README.md, docs/documentation-style-guide.md, docs/assets/).

Add docs/fern/pages/AGENTS.md, a placement guide for the content tree: the nine
tabs and the directory each is rooted at, the Kubernetes/CLI split, a tab
selection ladder, the nav grammar, and the URL model. Placement is the decision
worth getting right, because fixing it later costs a move plus a redirect.

Refresh docs/fern/AGENTS.md as the mechanics guide. Every original rule is kept;
it gains a pointer to the new file, a map of docs/fern/ separating content from
site config, and the sync_site_css.py and docs-website gates.

Update the dynamo-docs skill throughout: content paths, the nav grammar
(tabs: map, path: relative to docs/fern/), the tab table and Kubernetes/CLI
split, the URL join rule, the translations path and its ../ depth (three plus
the page's depth under pages/, verified against all nine translated files), the
assets path, and the Key References table.

Correct the style guide's Navigation and placement section, which still listed
the pre-restructure directories, plus its translations and images paths.

Delete docs/fern/templates/. Twelve files, no inbound references anywhere in the
repo, describing a taxonomy (docs/components/, docs/backends/) that the
restructure removed, and naming template files that do not exist. The three
restructure PRs moved them mechanically without updating them. The skill's
Add a Page section already carries the frontmatter skeleton.

Fix the recipe catalog README, which pointed at pages/recipes/<slug>.mdx rather
than pages/recipes/model-recipes/<slug>.mdx.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia
dagil-nvidia requested review from a team as code owners August 1, 2026 05:02
@github-actions github-actions Bot added docs documentation Improvements or additions to documentation deployment::k8s Relates to dynamo deployment in kubernetes actions labels Aug 1, 2026
@datadog-official

datadog-official Bot commented Aug 1, 2026

Copy link
Copy Markdown

Pipelines  Tests

⚠️ Warnings

🚦 2 Pipeline jobs failed

PR | DGDR Deploy Test / CPU / profiling   View in Datadog   GitHub Actions

See error Deployment failed due to missing required inputs 'repository' and 'operator_tag' for the operator image during Helm upgrade.

PR | deploy-status-check   View in Datadog   GitHub Actions

ℹ️ Info

🔄 Datadog auto-retried 1 job - 0 passed on retry View in Datadog

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 48.27% (-5.90%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 91466e9 | Docs | Datadog PR Page | Give us feedback!

@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 6 potential issues.

Open in Devin Review

Comment thread .github/workflows/pre-merge.yml Outdated
Comment thread docs/fern/index.yml Outdated
Comment thread docs/fern/AGENTS.md Outdated
Comment thread .agents/skills/dynamo-docs/SKILL.md Outdated
Comment thread scripts/docs_lint.py Outdated
Comment thread docs/fern/scripts/docs_lint.py
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The PR adds a deterministic documentation linter, runs it in pre-merge checks, updates Fern documentation guidance, removes obsolete templates and navigation entries, and revises affected links, metadata, and page-placement instructions.

Changes

Fern documentation tooling and structure

Layer / File(s) Summary
Documentation linter
scripts/docs_lint.py
Adds checks for SPDX headers, frontmatter, duplicate H1 headings, relative links, internal references, TODO markers, hosts, and Fern navigation. It supports local, JSON, and GitHub Actions output.
Pre-merge lint integration
.github/workflows/pre-merge.yml
Adds a conditional docs-lint job and makes the pre-merge status check wait for it.
Fern authoring guidance
.agents/skills/dynamo-docs/SKILL.md, AGENTS.md, docs/fern/AGENTS.md, docs/fern/pages/AGENTS.md, docs/fern/pages/community/contributing/documentation/documentation-style-guide.md
Updates repository and page-authoring rules for Fern tabs, navigation, assets, translations, versioned pages, redirects, and validation commands.
Navigation and page alignment
docs/fern/index.yml, docs/fern/pages/kubernetes/getting-started/introduction.mdx, docs/fern/pages/recipes/_catalog/README.md, docs/fern/pages/reference/kubernetes-api/additional-resources/api-reference-k8s.md, deploy/operator/docs/header.md, docs/fern/templates/*
Removes obsolete navigation entries and templates, moves model recipe guidance under model-recipes/, removes the model storage card, and adds the Kubernetes API sidebar title.
Repository link and license cleanup
docs/fern/pages/developer-guide/..., docs/fern/pages/recipes/feature-benchmarks/embedding-cache.md, docs/fern/pages/blog/_assets/flash-indexer/tools/README.md
Replaces repository-relative links with GitHub URLs and adds copyright and Apache-2.0 SPDX metadata to the tool README.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description gives detailed scope and validation, but it omits the required Related Issues section and formal issue-link or no-issue confirmation. Add the required Related Issues section and select either the applicable issue-closing statement or the confirmed no-related-issue checkbox.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly describes the primary documentation-guide updates and the addition of the docs lint job.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 8

🧹 Nitpick comments (3)
scripts/docs_lint.py (3)

334-336: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Default --scan value scans trees the PR does not clean up yet.

The PR objectives state the linter currently scans docs/ only, and CI invokes python3 scripts/docs_lint.py --scan docs --github. The default here is still "docs,examples,recipes", so a local contributor running the script with defaults (per the docstring's own usage example at line 16) will hit pre-existing findings in examples//recipes/ unrelated to their change, since those trees were not part of this PR's baseline cleanup.

Consider defaulting --scan to "docs" until examples//recipes/ are cleaned up, matching the CI invocation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/docs_lint.py` around lines 334 - 336, Update the --scan argument
definition in the argument parser to default to "docs" instead of
"docs,examples,recipes", matching the documented and CI scan scope while
preserving explicit user-provided scan trees.

275-286: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Prune .git/node_modules from os.walk instead of skipping after descent.

for dirpath, _, names in os.walk(root): discards dirnames, so the continue at line 282 only skips file collection once already inside .git or node_modulesos.walk still recurses into every subdirectory of these trees before the skip takes effect. This wastes time scanning large .git object stores or node_modules trees (e.g., a local docs/fern/node_modules/ from Fern site tooling) on every run. Prune dirnames in place to stop the walk from entering these directories at all.

⚡ Proposed fix
-        for dirpath, _, names in os.walk(root):
-            if "/.git" in dirpath or "/node_modules" in dirpath:
-                continue
+        for dirpath, dirnames, names in os.walk(root):
+            dirnames[:] = [d for d in dirnames if d not in (".git", "node_modules")]
             for n in names:
                 if n.endswith(exts):
                     files.append(os.path.join(dirpath, n))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/docs_lint.py` around lines 275 - 286, Update gather to retain the
mutable dirnames value from os.walk and remove .git and node_modules entries
from it before recursion. Keep collecting only the existing extensions and
preserve the current file filtering behavior while preventing traversal into
excluded directories.

1-413: 📐 Maintainability & Code Quality | 🔵 Trivial

Consider adding unit tests for the new linter.

scripts/docs_lint.py is a new, CI-blocking tool with non-trivial regex and traversal logic (frontmatter parsing, link resolution, fence blanking). No test file is included in this review. Per the applicable path instruction, tests for .py files should follow the repository's pytest guidelines.
[recommended_refactor]

As per path instructions, **/{pyproject.toml,*.py,*.pyi}: "Read .ai/pytest-guidelines.md and .ai/test-model-size-guardrails.md before writing tests, and follow their pytest and model-size constraints."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/docs_lint.py` around lines 1 - 413, Add pytest coverage for
scripts/docs_lint.py, following the repository’s pytest and model-size
guidelines in .ai/pytest-guidelines.md and .ai/test-model-size-guardrails.md.
Exercise the core helpers—frontmatter and blank_code parsing, SPDX/frontmatter
validation, link resolution, internal-content detection, navigation checks, and
the main scan flow—using temporary files and focused cases for valid and invalid
inputs.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/dynamo-docs/SKILL.md:
- Line 170: Update the deletion workflow in the skill instructions around the
git rm command to require explicit user confirmation immediately before
executing git rm, and only run the command after confirmation is received.
- Line 170: Update the page-removal instructions around the git rm command to
support both .md and .mdx files. In the removal workflow, use the actual
extension of the page being deleted and apply the same extension when removing
its navigation entry, rather than always targeting <filename>.md.
- Around line 154-160: Update the redirect guidance in
.agents/skills/dynamo-docs/SKILL.md lines 154-160 to require redirects only when
a tab, section, page label, or explicit slug changes the public URL; do not
require them for file-only moves. Apply the same condition in
docs/fern/pages/AGENTS.md lines 95-111 while retaining its prohibition on
unversioned and Latest redirects.

In `@docs/fern/pages/AGENTS.md`:
- Around line 38-45: Update the directory-tree code fence in the documentation
around the shown Kubernetes and CLI listings to include the text language tag on
its opening fence, resolving the MD040 markdownlint violation while leaving the
example content unchanged.
- Around line 124-133: Add python3 scripts/docs_lint.py --scan docs to the
Validate command list in the AGENTS.md checklist, and update the surrounding
statement so it accurately identifies Docs Lint, fern check, and broken-links as
pre-merge checks while keeping the catalog validator as a manual-only check.

In `@scripts/docs_lint.py`:
- Around line 230-254: Update check_internal to call blank_code once on the
complete text, then iterate raw lines alongside the corresponding blanked lines
and apply TODO_RE to the blanked line while preserving raw-line checks and
original line numbers for all other rules.
- Around line 1-20: Add scripts/docs_lint.py to the docs filter in
.github/filters.yaml, preferably by including scripts/** so this script is
covered. The .github/workflows/pre-merge.yml lines 86-101 require no direct
change; the filter update will ensure its fern-check, docs-lint, and
fern-broken-links jobs run for this change.
- Line 52: Update the JIRA_RE pattern used by check_internal to include the OPS
project prefix, so references such as OPS-1234 are recognized and produce the
expected INTERNAL finding while preserving existing project matches.

---

Nitpick comments:
In `@scripts/docs_lint.py`:
- Around line 334-336: Update the --scan argument definition in the argument
parser to default to "docs" instead of "docs,examples,recipes", matching the
documented and CI scan scope while preserving explicit user-provided scan trees.
- Around line 275-286: Update gather to retain the mutable dirnames value from
os.walk and remove .git and node_modules entries from it before recursion. Keep
collecting only the existing extensions and preserve the current file filtering
behavior while preventing traversal into excluded directories.
- Around line 1-413: Add pytest coverage for scripts/docs_lint.py, following the
repository’s pytest and model-size guidelines in .ai/pytest-guidelines.md and
.ai/test-model-size-guardrails.md. Exercise the core helpers—frontmatter and
blank_code parsing, SPDX/frontmatter validation, link resolution,
internal-content detection, navigation checks, and the main scan flow—using
temporary files and focused cases for valid and invalid inputs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 65c76208-06a0-4dab-8f18-bc88470a943f

📥 Commits

Reviewing files that changed from the base of the PR and between d84042e and 28aa087.

📒 Files selected for processing (30)
  • .agents/skills/dynamo-docs/SKILL.md
  • .github/workflows/pre-merge.yml
  • AGENTS.md
  • deploy/operator/docs/header.md
  • docs/fern/AGENTS.md
  • docs/fern/index.yml
  • docs/fern/pages/AGENTS.md
  • docs/fern/pages/blog/_assets/flash-indexer/tools/README.md
  • docs/fern/pages/community/contributing/documentation/documentation-style-guide.md
  • docs/fern/pages/developer-guide/additional-resources/runtime-development-guide.md
  • docs/fern/pages/developer-guide/knowledge-base/modular-components/router/router-testing.md
  • docs/fern/pages/kubernetes/getting-started/introduction.mdx
  • docs/fern/pages/kubernetes/installation/model-storage/overview.md
  • docs/fern/pages/recipes/_catalog/README.md
  • docs/fern/pages/recipes/feature-benchmarks/embedding-cache.md
  • docs/fern/pages/reference/general/examples.md
  • docs/fern/pages/reference/kubernetes-api/additional-resources/api-reference-k8s.md
  • docs/fern/templates/README.md
  • docs/fern/templates/backend-guide.md
  • docs/fern/templates/backend-readme.md
  • docs/fern/templates/component-design.md
  • docs/fern/templates/component-examples.md
  • docs/fern/templates/component-guide.md
  • docs/fern/templates/component-readme.md
  • docs/fern/templates/feature-backend.md
  • docs/fern/templates/feature-readme.md
  • docs/fern/templates/incode-readme.md
  • docs/fern/templates/infrastructure-readme.md
  • docs/fern/templates/integration-readme.md
  • scripts/docs_lint.py
💤 Files with no reviewable changes (15)
  • docs/fern/templates/incode-readme.md
  • docs/fern/templates/infrastructure-readme.md
  • docs/fern/templates/integration-readme.md
  • docs/fern/templates/feature-readme.md
  • docs/fern/pages/kubernetes/installation/model-storage/overview.md
  • docs/fern/templates/feature-backend.md
  • docs/fern/pages/kubernetes/getting-started/introduction.mdx
  • docs/fern/templates/component-design.md
  • docs/fern/templates/README.md
  • docs/fern/index.yml
  • docs/fern/templates/backend-readme.md
  • docs/fern/templates/component-readme.md
  • docs/fern/templates/component-guide.md
  • docs/fern/templates/component-examples.md
  • docs/fern/templates/backend-guide.md

Comment thread .agents/skills/dynamo-docs/SKILL.md Outdated
Comment thread .agents/skills/dynamo-docs/SKILL.md Outdated
Comment thread docs/fern/pages/AGENTS.md Outdated
Comment thread docs/fern/pages/AGENTS.md Outdated
Comment thread docs/fern/scripts/docs_lint.py
Comment thread scripts/docs_lint.py Outdated
Comment thread docs/fern/scripts/docs_lint.py

@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: 28aa087002

ℹ️ 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 .github/workflows/pre-merge.yml Outdated
Comment thread docs/fern/scripts/docs_lint.py
Comment thread docs/fern/scripts/docs_lint.py Outdated
Comment thread .agents/skills/dynamo-docs/SKILL.md Outdated
Comment thread docs/fern/AGENTS.md Outdated
Comment thread .github/workflows/pre-merge.yml Outdated
Comment thread scripts/docs_lint.py Outdated
Comment thread docs/fern/pages/AGENTS.md Outdated
Comment thread docs/fern/scripts/docs_lint.py
changed-files gates 100% filter coverage and scripts/docs_lint.py matched no
filter, so the job failed and every dependent check cascaded — including the
Docs Lint job this branch adds, which skipped on the PR that introduces it.

Put the linter in `docs` rather than `ignore`. The `ignore` precedent set by
scripts/dco_check.py and scripts/validate_skills.py works because the
pre-commit job is ungated and runs on every PR. The docs-lint job is gated on
needs.changed-files.outputs.docs, so a filter that excludes the linter would
skip the job that runs it and let a broken linter merge untested.

.github/FILTERS.md also matched no filter: `**` skips dotfile directories, so
the existing `**/*.md` rule never covered it. Editing it to correct the stale
"docs triggers nothing" note would have reproduced the same failure, so cover
it too.

Verified with .github/scripts `npm run coverage`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
Comment thread scripts/docs_lint.py Outdated
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 1f43c8b

dagil-nvidia and others added 2 commits August 1, 2026 13:23
Review findings on #12528, each verified against the head tree:

- check_spdx reported the body-`# SPDX` H1 line relative to the body, not the
  file, so the GitHub annotation landed above the real line. Add the frontmatter
  offset the way check_frontmatter already does.
- check_internal called blank_code() one line at a time. FENCE_RE needs both
  markers in the same string, so a line inside a multi-line fence was never
  blanked and a `# TODO:` in a code example raised a false positive. Blank the
  whole file once and walk raw and blanked lines together.
- Frontmatter-less markdown passed on SPDX-License-Identifier alone. Require
  SPDX-FileCopyrightText too, matching the code/config branch.
- OPS is a live Linear prefix in this repo (tests/fault_tolerance,
  tests/gpu_memory_service). Add it to JIRA_RE.
- Flag hardcoded docs.nvidia.com self-links, which the style guide bans, before
  the generic external-URL skip. Dated archives (blog, release notes) pin their
  links deliberately and are exempt. Found one real drift: the zh-CN knowledge-base
  overview pointed at an unversioned /dynamo/components/kvbm URL while the English
  page used a relative path.
- check_nav only walked nav to file. Add the reverse pass so a page file with no
  `path:` entry is reported as unreachable (warn: three pre-existing cases).

Verified: python3 scripts/docs_lint.py --scan docs -> 0 errors across 394 files,
plus targeted fixtures for each rule above.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
Review findings on #12528:

- docs/fern/AGENTS.md still listed `templates/`, which this branch deletes. Drop
  the row.
- Both guides said a directory-only move changes no URL, then required a redirect
  "either way". Require one only when a tab, section, label, or explicit slug
  changes the URL, or when a page is deleted. A file-only git mv needs none.
- Deleting the empty Examples stub left two redirects in docs.yml pointing at
  /dynamo/dev/reference/examples with nothing behind it. Retarget both to the
  recipes catalog and add dev redirects for the two removed URLs
  (reference/examples and kubernetes/installation/model-storage/overview).
- The skill still described the Examples page as nav-reachable. Say it is gone
  and where its URL now lands.
- The removal workflow assumed .md and skipped the redirect sweep, so it produced
  exactly the dangling redirects above. Add the sweep, take the real extension,
  and confirm before the git rm.
- docs/fern/pages/AGENTS.md omitted Docs Lint from Validate while claiming the
  list mirrored pre-merge, and its directory-tree fence had no language tag.
- Both guides presented body `# H1` and TODO/FIXME as blocking. They are
  annotated but do not fail the job: the generated Kubernetes API reference gets
  its H1 from the crd-ref-docs template. Split the rule table into blocking and
  advisory and state that the CI job scans docs/ only.

Verified: docs_lint --scan docs -> 0 errors / 394 files; fern check -> 0 errors;
pre-commit on all changed files -> pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 583ec96

CODEOWNERS routes `scripts/**` to dynamo-ops and `docs/fern/scripts/**` to
dynamo-docs. At scripts/docs_lint.py the linter that encodes the documentation
style guide was reviewed by ops, while the docs owners whose rules it enforces
were not required reviewers on changes to it. Its siblings already sit in the
right place: sync_site_css.py and the recipe catalog validator both live under
docs and both route to docs.

Moving it also removes the filters.yaml workaround. `docs/**` is already in the
`docs` filter, so the explicit `scripts/docs_lint.py` entry added earlier in
this branch is no longer needed — the changed-files failure that entry fixed
was a symptom of the file being in the wrong tree. The `.github/FILTERS.md`
entry stays, since `**` skips dotfile directories.

Update the four call sites (pre-merge.yml, docs/fern/AGENTS.md,
docs/fern/pages/AGENTS.md, the dynamo-docs skill) and, critically, REPO_ROOT:
it walked two directories up from __file__ and now needs four. Verified by
running the linter from /tmp, where a cwd-derived root would fail.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 728bf2c

@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.

lgtm

@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test 299f323

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

# Conflicts:
#	.github/workflows/pre-merge.yml
#	docs/fern/templates/component-readme.md
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test ba8b713

This PR requested review from nine teams. Four of them were on it for a
single file each -- backend-sglang for one examples/backends/sglang README,
backend-trtllm and backend-vllm likewise, frontend for
examples/chat_templates -- and performance for seventeen recipes/*/README.md.
None of those owners has a stake in the change; CODEOWNERS was routing
correctly to a sweep that had no business being here.

The sweep was an artifact of how the linter was run, not of what CI checks.
The Docs Lint job runs:

    docs_lint.py --scan docs --github

while the script's own default is --scan docs,examples,recipes. Running it
bare produced findings across examples/ and recipes/ that no gate examines,
and those got committed alongside the real change.

Twenty-nine files reverted to main, +135/-2, almost entirely SPDX headers on
files outside the gated scope. What remains is the agent guides, docs_lint.py
itself, the filters and pre-merge wiring, and the docs/ pages the job does
check.

Reverted by reverse-applying the merge-base diff for exactly those paths, then
confirming each is byte-identical to main rather than trusting the apply.

Validation: docs_lint.py --scan docs (what CI runs) exits 0.
Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test ee00518

The previous commit reverted deploy/operator/docs/header.md as part of
dropping the example/recipe sweep, but that file was never part of the sweep.
It is the input half of a generated pair: 'make generate-api-docs'
concatenates header.md with the crd-ref-docs output and footer.md to produce
pages/reference/kubernetes-api/additional-resources/api-reference-k8s.md.

This PR adds 'sidebar-title: API Reference (K8s)' to that generated file so
Fern has a nav title for it. With header.md reverted and the generated file
left changed, the committed output claimed a line its input could no longer
produce -- the next regeneration would silently drop it, and the operator job
caught the drift.

Restored header.md. Verified the two agree rather than assuming: both carry
the sidebar-title line, and the generated file still begins with the header
verbatim.

This is the failure mode AGENTS.md warns about in this same PR, arrived at
from the other direction -- not hand-editing the artifact, but reverting its
source without regenerating.

Validation: docs_lint.py --scan docs exits 0; input and output confirmed
consistent.

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

Copy link
Copy Markdown
Collaborator Author

/ok to test 00fdbcc

@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.

Thanks for addressing findings.
Approving to unblock.
Nothing here touches core, functional/perf tests, or any gate other than the docs jobs.
Any docs related issues can be fixed later.

#12388 merged and moved main, conflicting on .github/filters.yaml and
.github/FILTERS.md.

filters.yaml is a union: this branch rewrites the comment above the docs
filter to record why the repo-wide catch-alls moved to `ignore`, main adds a
new fern_components filter. Different concerns, both kept.

FILTERS.md was not a union -- the two sides contradict on what `docs` gates.
This branch says four jobs; main says "Nothing (classification only)". Checked
against the workflow rather than picking a side: in the merged pre-merge.yml,
outputs.docs gates Docs Lint, Fern Configuration Check, Docs Website
Composition Check, and Fern Broken Links Check. Four jobs, so this branch's
row is right.

Main's row is already wrong on main, where its own workflow keys three jobs on
docs while the table claims none. Taking this branch's row plus main's new
fern_components row fixes that drift as a side effect, and is the same defect
Dmitry flagged earlier on this PR -- a hand-maintained table drifting from the
workflow it describes.

Validation: both files parse; filters.yaml carries 26 keys with docs,
fern_components and ignore all present; docs_lint --scan docs exits 0.

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

Copy link
Copy Markdown
Collaborator Author

/ok to test 7af69c1

#12110 landed the generated language references and moved main, conflicting on
two files this branch also rewrites.

pre-merge.yml is a union of the aggregator's needs list: this branch adds
docs-lint, main adds api-docs. Dropping either would leave the status check
green while a required job never gated it. Verified every one of the 11 entries
resolves to a defined job rather than trusting the merge.

docs/fern/AGENTS.md was not a union. This branch replaces the one-line "Docs
Bot enforces the deterministic subset" with the blocking/advisory rule table,
the directory map, and a Validate section, while main gained the Generated API
references section from #12110 -- written against the older one-line file, so
the two sides restructure the same region. Kept this branch's expansion and
spliced the generated-references section in ahead of Validate, where the rest
of the machinery documentation lives. Nothing from either side was dropped.

Validation: 0 conflict markers; the workflow parses and all 11 needs entries
name defined jobs, docs-lint and api-docs included; AGENTS.md keeps all five
sections in reading order; docs_lint --scan docs exits 0.

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

Copy link
Copy Markdown
Collaborator Author

/ok to test 99813a2

Clean auto-merge. Picks up #12985, which unbroke the two stale generated
artifacts on main -- this PR was failing pre-commit on those rather than on
its own content.

Validation: docs_lint --scan docs exits 0; the aggregator needs list still
resolves all 11 entries to defined jobs.

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

Copy link
Copy Markdown
Collaborator Author

/ok to test 6cf2786

@sttts sttts 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.

For operator.

Resolves three CI-config conflicts as a union of two orthogonal changes:
main added a Recipe Check job gated on the `examples` filter, this branch
adds a Docs Lint job gated on `docs`.

- pre-merge.yml: `needs:` carries both `recipe-check` and `docs-lint`.
- FILTERS.md: neither `docs` nor `examples` is classification-only now;
  the note names the jobs each one gates.
- filters.yaml: keeps this branch's classification-only block and folds
  main's comment on `.github/FILTERS.md` into it.

Clears the 26 docs-lint errors that landed on main while this sat: 25
missing SPDX headers under examples/ and recipes/, and a broken relative
link in the Kimi K2.5 TokenSpeed recipe that pointed at a nonexistent
trtllm/agg/nvidia/ at the wrong depth.

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

Copy link
Copy Markdown
Collaborator Author

/ok to test 5324137

…eanup

The `Docs Lint` job already ran `--scan docs`, but the linter's default was
`docs,examples,recipes`. A local run therefore failed on 26 pre-existing
violations under examples/ and recipes/ that no job gates and that this
branch never touched.

Make the default `docs`, matching the job, and revert the 25 SPDX headers and
the relative-link fix added only to satisfy the wider local scan. The wider
scan stays available behind an explicit `--scan docs,examples,recipes`.

Keeps this PR to the Fern docs tree and the agent guides.

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

Copy link
Copy Markdown
Collaborator Author

/ok to test 91466e9

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

# Conflicts:
#	.github/workflows/pre-merge.yml
#	docs/fern/AGENTS.md
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test ab0cc26

Resolve four conflicts and repair the gate failures the merge surfaced.

Conflicts:
- .github/FILTERS.md: union of the docs-filter job list, keeping main's
  Fern preview or publish entry and adding Docs Lint.
- .github/FILTERS.md: keep main's Note, which is accurate that sidecar
  gates sidecar-build in pr.yaml, and add the docs and examples sentences.
- AGENTS.md: keep main's new fork-PR signature bullet alongside the
  generalized generated-artifact bullet that subsumes main's narrower
  CODEOWNERS wording.
- zh-CN knowledge-base overview: take main's line. The English source no
  longer mentions KVBM or AIBrix, and a translation must mirror it.

Repairs:
- Add docs/fern/pages/CLAUDE.md. The sibling AGENTS.md landed on this
  branch without it, which the current validator rejects.
- Exempt CLAUDE.md from the docs-lint SPDX rule. Satisfying it would
  violate validate_agent_instructions.py, which pins the file's exact
  bytes, so the two gates contradicted each other.
- Correct three relative links in the Kubernetes TLS page, which pointed
  two levels above the docs root. Caught by the new linter on its first
  contact with the page.

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

Copy link
Copy Markdown
Collaborator Author

/ok to test 2af874d

@dagil-nvidia
dagil-nvidia removed request for a team September 1, 2026 18:47
One conflict, AGENTS.md, same file as the previous sync because it changes
constantly and this branch has been open five weeks.

Resolved as the union, which is different from last time. Main's CODEOWNERS
bullet is no longer a subset of this branch's generalized one: it has gained
the who_owns.py invocation, the recipe for a failing codeowners check, external
contributor co-ownership, and the repo-codeowners skill. Both bullets are kept,
with the CODEOWNERS example dropped from the general one so the two do not
restate each other.

Validation: docs lint 0 errors, 42 agent instruction scopes OK.
Signed-off-by: Dan Gil <dagil@nvidia.com>
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

/ok to test d99da1b

@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

Merging with --admin, past a red deploy-status-check. Recording why.

The three DGDR Deploy Test / CPU failures are an admission webhook rejection that has nothing to
do with this PR:

vdynamographdeploymentrequest.kb.io denied the request:
spec.runtimeVersionOverride: Required value: is required when
spec.image has no parseable semantic-version tag

CI tags its images ci-<run-id>-<hash>, which carries no semantic version, and
tests/deploy/test_dgdr.py never sets runtimeVersionOverride. Every DGDR create returns 422. It
is deterministic rather than flaky, so it does not clear on a re-run, and it is failing on #14117 as
well, which is unrelated to this work.

This PR changes documentation, agent guides, and adds the Docs Lint job. It touches no operator
code, no CRD, no deploy test, and no image tagging. Every other required context is green: DCO,
codeowners, copyright-checks, dynamo-status-check, and pre-merge-status-check.

The DGDR break needs the operator owners, not this branch. Either the DGDR tests set
runtimeVersionOverride for CI-tagged images, or the webhook tolerates a non-semver tag on a CI
build.

@dagil-nvidia
dagil-nvidia merged commit cc0eec1 into main Sep 1, 2026
123 of 130 checks passed
@dagil-nvidia
dagil-nvidia deleted the dagil-nvidia/docs-agent-guides-and-lint branch September 1, 2026 22:50
@dagil-nvidia

Copy link
Copy Markdown
Collaborator Author

Admin merge note for the audit trail: this PR was approved with every executed check green. The remaining required contexts are path-filtered for this change set and never report, so the merge gate cannot clear on its own - the override bypasses only the non-reporting contexts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

actions backend::sglang Relates to the sglang backend backend::trtllm Relates to the trtllm backend backend::vllm Relates to the vllm backend deployment::k8s Relates to dynamo deployment in kubernetes docs documentation Improvements or additions to documentation size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants