Migrate documentation to Fern platform#1578
Conversation
- fern/convert_docs.py: Python script that converts all 62 Sphinx/RST docs to Fern MDX, handles pandoc 2.9 note/warning divs → Fern callout components, resolves literalinclude → embedded code blocks, rewrites image paths to flat fern/docs/images/, strips Sphinx-only directives (toctree, install-selector, autodoc, breathe). - fern/docs.yml: full navigation tree auto-generated from RST toctrees, with NVIDIA green accent colors and API Reference section. - fern/fern.config.json: org=nvidia-cuopt, version=5.67.1. - fern/docs/pages/**: 62 converted MDX pages. - fern/docs/images/**: all doc images copied flat. - .github/workflows/fern-docs.yml: CI that re-converts RST→MDX on push and runs fern check; publishes on docs-fern-migration branch merges. - C/C++ Doxygen reference stubbed pending Fern C++ library support. fern check: 0 errors, 2 warnings (auth redirect + minor color contrast). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fern/generators.yml: register OpenAPI spec (openapi/cuopt_spec.yaml) so fern check and fern generate --docs can serve the REST API reference - fern/openapi/cuopt_spec.yaml: committed spec generated from FastAPI app without GPU (10 endpoints, 23 validated examples) - fern/docs.yml: replace stub open-api page with a proper "api: REST API" nav entry that Fern renders as an interactive API reference - fern/extract_python_api.py: AST-based Python docstring extractor (no imports, no GPU) generating MDX for routing, LP/QP, and MIP APIs; mirrors the classes/functions listed in the Sphinx autoclass:: directives - fern/convert_docs.py: call OpenAPI generation + Python extraction from the main convert script so one command rebuilds everything - .github/workflows/fern-docs.yml: add Python deps install step for OpenAPI spec generation; watch python/ source paths for changes fern check: 0 errors, 8 warnings (7 are pre-existing OpenAPI example mismatches in the FastAPI source; 1 is WCAG contrast auto-adjusted by Fern). C/C++ Doxygen reference still stubbed pending Fern C++ library support. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The custom .. install-selector:: Sphinx directive is now fully supported
in Fern by reusing the existing vanilla JS + CSS widget unchanged:
- fern/docs/scripts/install-selector.{js,css}: copied from Sphinx _static/
- fern/docs/scripts/cuopt-install-version.js: generated at build time by
convert_docs.py from cuopt_server version (replaces the Sphinx conf.py
build-time injection of window.CUOPT_INSTALL_VERSION)
- fern/docs.yml: css/js entries load the widget and version script on
every page so the selector is available wherever the div is placed
- fern/convert_docs.py: preprocessor now emits
<div id="cuopt-install-selector" data-default-iface="..."> via RST
raw:: html instead of a plain-text note stub; version script generation
added alongside the OpenAPI spec generation
Result: install.mdx and all 4 quick-start pages (python/c/server/cli)
render the full interactive install selector with correct version numbers
and interface pre-selection, identical to the Sphinx site.
fern check: 0 errors, 8 warnings (unchanged).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ersion - Fix <Note> inside list items: un-indent opening tag to break out of list item context (MDX can't parse JSX inside list items when closing tag is at column 0) - Convert .. dropdown:: RST directives to <Accordion> MDX components in preprocessor (was becoming <div class="dropdown"> which broke fenced code blocks inside) - Add postprocessor fallback converting <div class="dropdown"> to <Accordion> for any that slip through pandoc - Add libraries: section in docs.yml and DOCS_YML_HEADER for Fern C++ (cuopt-c-api) and Python (cuopt-python-api) library docs - Add Doxyfile.fern to cpp/ (Fern's input.path for C++ parsing) - Include generated Fern Python library docs (static/python-docs) as "Python Distance Engine" folder in API Reference nav section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
MDX's JSX parser is stricter than CommonMark and fails on patterns that
are valid in plain Markdown. All 62+ pages now pass the MDX parser.
Fixes applied in convert_docs.py post-processor and extract_python_api.py:
- Angle-bracket autolinks: <https://...> and <email@...> → proper links
- Comparison operators: `<=` in text → `<=` (MDX parses `<` as JSX)
- Curly-brace math notation: {<=, =, >=} → \{...\}
- Placeholder tags in code blocks: <CUOPT_IMAGE>, <ip> → HTML entities
- Shell redirects in code blocks: `</dev/null` → `< /dev/null`
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fern's server-side acorn processor rejects { } even inside fenced code
blocks, causing 500 errors on convex-features.mdx and milp-features.mdx.
- RST pre-processor (step 13): convert {<=, =, >=} math notation to
(<=, =, >=) parenthesis form before pandoc — eliminates all { } from
generated MDX
- Post-processor: simplify _escape_lt_outside_code now that { } are
handled at the RST level
- Fix angle-bracket autolinks and email addresses → proper MD links
- All 62 MDX pages pass both MDX parse and Fern's acorn validation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…enAPI fixes - Python API: prefix classes with 'class', methods/functions with 'def'; use <hr /> separators between entries for visual scanning - C API: extract_c_api.py now generates real content from headers (211 symbols); typedef entries labeled with 'typedef'; functions show bare prototype (no 'function' prefix — matches cppreference/Doxygen convention); <hr /> separators - Nav: index pages inside sections renamed to 'Overview' to eliminate duplicate section-name / page-name entries in the left nav - REST API Reference moved under Server → Server API → Server API Overview - OpenAPI spec post-processing: relax IdModel additionalProperties, fix health-endpoint examples (add error_result), fix incumbents examples (null cost/bound); prevents fern docs dev from exiting with code 1 - NVIDIA cuOpt logo SVGs added (dark/light variants) - MutationObserver-based install selector widget for Next.js SPA timing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Converts the Sphinx/RST documentation to the Fern docs platform on the
docs-fern-migration branch. Key changes across this session:
Conversion pipeline (fern/convert_docs.py, extract_*.py):
- Fix brace corruption: remove step 13 ({}→() broad replacement) and add
prose-only { escaping that skips fenced code blocks and inline code spans
- Fix duplicate page headings: strip pandoc H1 BEFORE prepending frontmatter
so the ^# regex anchors at the start of pandoc output, not after ---
- Fix inspect.cleandoc vs textwrap.dedent for Python docstring parsing so
Parameters/Returns/Raises sections render correctly
- Fix .. dropdown:: dedent (textwrap.dedent instead of hardcoded 3-space strip)
so list items inside Accordion blocks are flat, not nested
- Remove explicit H1 from extract_python_api.py and extract_c_api.py output
(frontmatter title: is the heading; duplicate H1 caused double rendering)
Nav / docs.yml:
- Add _inject_nav_after, _rename_page, _remove_page helpers so curated nav
fixes survive regeneration: REST API Reference after Server CLI, Settings
pages under Python API, duplicate section/page names resolved, Swagger stub
removed
- Split navigation into docs-v26-08.yml (required by Fern when versions is set)
- Add version switcher with all archived versions (26.06–25.05) pointing to
archive.docs.nvidia.com via JS redirect pages
Install selector widget (fern/docs/scripts/install-selector.js):
- Full rewrite with lazy resolveVersion() and polling loop (150 ms, ~10 s)
to survive Next.js async script injection race; pushState/replaceState hooks
set up unconditionally
Python source (python/cuopt/cuopt/linear_programming/io/parser.py):
- Add NumPy-style docstring to toDict so it appears in the Python API reference
CI (.github/workflows/fern-docs.yml):
- Add cpp/**/*.h and cpp/**/*.hpp to path triggers (C API extractor reads headers)
build.sh:
- Replace old Sphinx/Doxygen docs target with Fern pipeline:
checks for pandoc/node/jq, auto-installs pinned fern-api, runs
convert_docs.py + fern check, prints fern docs dev command for preview
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add fern/requirements-docs.txt (fastapi, pydantic, pyyaml) as the single source of truth for Python docs dependencies; both build.sh and CI now install from it instead of inlining package names - Update dependencies.yaml docs group: replace old Sphinx/Doxygen packages with Fern toolchain deps (jq, nodejs, pandoc, pyyaml, fastapi, pydantic) so conda environments include what ./build.sh docs actually needs - build.sh: add npm presence check alongside node (npm is separate on some distros), with install hint pointing to nodejs.org and conda Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ./build.sh docs now runs convert_docs.py + fern check then launches fern docs dev (localhost:3000 preview) instead of just printing the command - Add --publish-docs flag to publish to Fern cloud (nvidia-cuopt.docs.buildwithfern.com) via fern generate --docs; requires FERN_TOKEN env var, checked before running - Add --publish-docs to VALIDARGS and help text Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- On every run: upload generated fern/docs.yml, docs-v*.yml, docs/pages/, and openapi/ as a GitHub Actions artifact (14-day retention) so reviewers can download and inspect exactly what will be published - On pull_request: run fern generate --docs --preview to publish a temporary Fern preview URL that doesn't affect the live site; requires FERN_TOKEN secret, skipped silently if absent Note: Fern has no native static HTML export — it is a Next.js SPA served via Fern cloud. The artifact above contains the MDX source; the preview URL gives a fully rendered browser view for sharing during PR review. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New non-blocking link-check job runs after convert-and-check, concurrently with publish (continue-on-error: true so broken external links don't block the live site update — check the job summary for failures) - Skips fern/docs/pages/versions/ (JS redirect stubs, no real links) - fern/.lycheeignore excludes hosts that reliably cause false positives in CI: localhost, YouTube (429), LinkedIn (bot block), NGC catalog (auth required), Azure Maps sample (401), raw.githubusercontent.com (429 bursts) - --accept 429 treats rate-limit responses as passing (not a dead link) - Uploads lychee-report.md as a 14-day artifact on every run Note: fern check validates config schema only; it does not check URLs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers prerequisites, ./build.sh docs local preview, manual publish with
FERN_TOKEN, and a table of what each CI trigger does — addresses the gap
Andrew pointed out ("samples in the readme").
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-links - Add `global-theme: nvidia` to docs.yml (mandatory for NVIDIA Fern branding) - Add GitHub navbar link to docs.yml header - Fix accentPrimary light color to match NVIDIA green (#76B900) - CI: split PR preview into two stages so FERN_TOKEN is never exposed to fork PRs; stage 2 runs via workflow_run in base-branch context - CI: add `fern docs broken-links` step for internal link checking - CI: stage 1 saves PR metadata artifact so stage 2 can post preview comment - README: document fern login requirement, how to get FERN_TOKEN, custom domain requirement, and two-stage PR preview security model Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
MDX pages are now the source of truth. Removes: - fern/convert_docs.py, extract_python_api.py, extract_c_api.py - fern/requirements-docs.txt (pandoc, pyyaml, fastapi, pydantic) - All conversion steps from build.sh and CI - RST/C++/Python path triggers from CI (no longer affect docs) - lychee link-check job (not needed for hand-edited MDX) - pandoc/pyyaml/fastapi/pydantic from dependencies.yaml docs group CI now: fern check + fern docs broken-links + PR preview + publish. build.sh docs now: install fern CLI → fern check → fern docs dev. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OpenAPI spec, Python API reference, and C API reference are derived from code and regenerated by fern/generate_api_docs.py on every docs build. RST→MDX conversion is still gone; hand-edited MDX pages are not touched. - Restore fern/extract_python_api.py and fern/extract_c_api.py - Add fern/generate_api_docs.py (orchestrates the three dynamic outputs) - Restore fern/requirements-docs.txt (fastapi, pydantic, pyyaml) - build.sh docs: run generate_api_docs.py before fern check - CI: install Python deps, run generate_api_docs.py, then fern check - Re-add C++/Python source paths to CI triggers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ci/build_docs.sh: replace Sphinx build with Fern pipeline (conda env already provides jq, nodejs, pyyaml, fastapi, pydantic via rapids-dependency-file-generator; Fern CLI installed via npm at pinned version) Generates API docs, runs fern check, then publishes (preview on PR, production on branch/nightly) - build.sh docs: skip pip install when packages already present (conda); fall back to pip only when importing fails - build.yaml / pr.yaml: remove Sphinx html artifact upload; switch to cpu node type (no GPU needed for docs) - Remove .github/workflows/fern-docs.yml (superseded by existing docs-build jobs) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds explicit trigger to AGENTS.md so CI/workflow changes clearly map to skills/cuopt-developer/ — surfacing the "prefer extending existing scripts" rule before new workflow files or pip installs are created. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Python API: keep AST walking (no imports needed) but pipe docstrings through numpydoc.docscrape.NumpyDocString, giving properly structured Parameters / Returns / Raises / Examples sections in the generated MDX. C API: replace fragile regex header parser with Doxygen XML pipeline. Doxyfile targets the two public headers; XML is parsed with ElementTree and rendered to MDX. Picks up 211 symbols vs ~80 before, handles @param, @return, @brief, and enum values correctly. Add numpydoc to requirements-docs.txt and dependencies.yaml docs group. Add doxygen to dependencies.yaml docs group. Gitignore cpp/build_split/ and fern/.doxygen-xml/ build directories. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2081988 to
6b157a0
Compare
…tom parsers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Python API: replace hardcoded file paths with PAGE_SOURCES config — each entry lists directories to scan non-recursively. New .py files added to a configured directory appear in the docs automatically without editing the script. C API: replace RST parser with fern/c_api_config.yaml for section organization. Doxygen XML is still the symbol source; the YAML controls section groupings and prose. Symbols not in the config auto-appear in an "Uncategorized" section on the designated catchall page so new header additions are never silently dropped. Added previously uncategorized symbols (hyper diving/heuristic params, scaling constants, presolve constants, deprecated quad create functions). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copies example source files from docs/cuopt/source/ into fern/docs/pages/*/examples/ so they live alongside the MDX pages that reference them. The old docs/ tree is left intact for now. Adds fern/embed_examples.py which embeds example files as fenced code blocks into the *-examples.mdx pages using idempotent <!-- embed: examples/file --> / <!-- /embed --> markers. First run upgrades bare link stubs; subsequent runs refresh code content within the markers without disturbing surrounding prose. Rewrites the C API example pages (convex-examples.mdx, mip-examples.mdx) to use clean standalone link patterns and removes the repetitive Sphinx-era "It is necessary to have the path..." boilerplate. embed_examples.py is called from generate_api_docs.py on every build. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove: - fern/.lycheeignore (lychee CI job was deleted) - cpp/Doxyfile.fern and fern/Doxyfile.fern (remnants of abandoned fern docs md generate --local approach, superseded by fern/Doxyfile) - fern/static/python-docs/ (auto-generated by fern docs md generate; replaced by extract_python_api.py) - libraries: block from fern/docs.yml (referenced the deleted files) Add distance_engine/ to the routing PAGE_SOURCES in extract_python_api.py so WaypointMatrix is covered in the generated routing-api.mdx. Remove the folder: ./static/python-docs nav entry from docs-v26-08.yml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@CodeRabbit review |
✅ Action performedReview finished.
|
✅ Action performedReview finished.
|
📝 WalkthroughWalkthroughThe documentation system is migrated to Fern, with CI publishing, generated C/Python/OpenAPI references, extensive API and deployment content, runnable examples, version navigation, installation commands, and local preview support. ChangesDocumentation platform and publishing
Estimated code review effort: 5 (Critical) | ~120 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
🟠 Major comments (35)
fern/docs/scripts/install-selector.js-372-382 (1)
372-382: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winNo user-facing fallback if the install widget never resolves.
poll()gives up silently after ~10s ifwindow.CUOPT_INSTALL_VERSIONnever becomes available, leaving#cuopt-install-selectorempty.install-selector.cssalready defines a.cuopt-install-errorstate (border/background) that is never applied anywhere in this file.🔧 Proposed fix: render an error state when polling gives up
function poll(gen, remaining) { if (gen !== _pollGen) return; if (!isRendered()) render(); if (isRendered() && remaining > 20) { remaining = 20; } if (remaining > 0) { _pollTimer = setTimeout(function () { poll(gen, remaining - 1); }, 150); + } else if (!isRendered()) { + var root = document.getElementById("cuopt-install-selector"); + if (root) { + root.innerHTML = + '<div class="cuopt-install-selector-wrap cuopt-install-error">' + + "<code>Unable to load the install selector. Please refresh the page.</code></div>"; + } } }🤖 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 `@fern/docs/scripts/install-selector.js` around lines 372 - 382, Update the poll function so that when remaining reaches zero and the install widget still has not rendered or resolved, it applies the existing cuopt-install-error state to `#cuopt-install-selector`. Preserve the current polling and rendering behavior for successful resolution, and only show the fallback after polling is exhausted.fern/docs/scripts/install-selector.js-200-239 (1)
200-239: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winSilent CUDA-version substitution for the 12.x + UBI10 combination.
containerLibnever defines acu12-ubi10variant, so selecting CUDA=12.x with the UBI10 variant silently falls back to thecu13-ubi10command (Line 205'sfallbackKey) while the UI still shows "12.x" checked — the user gets a CUDA 13 command with no indication of the substitution.🐛 Proposed fix: disable CUDA 12.x when UBI10 variant is selected
function updateVisibility(COMMANDS) { var method = getSelectedValue("cuopt-method"); var iface = getSelectedValue("cuopt-iface"); var allowed = SUPPORTED_METHODS[iface] || []; + var variant = getSelectedValue("cuopt-variant"); + var cu12Radio = document.querySelector('input[name="cuopt-cuda"][value="cu12"]'); + if (cu12Radio) { + var forceUbi10 = method === "container" && variant === "ubi10"; + cu12Radio.disabled = forceUbi10; + if (forceUbi10 && cu12Radio.checked) { + var cu13Radio = document.querySelector('input[name="cuopt-cuda"][value="cu13"]'); + if (cu13Radio) cu13Radio.checked = true; + } + }🤖 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 `@fern/docs/scripts/install-selector.js` around lines 200 - 239, Update the container selection logic around `cudaKey`, `fallbackKey`, and the `cuopt-variant` value so CUDA 12.x cannot remain selected when `variant === "ubi10"`; disable or otherwise remove the CUDA 12.x option in the UI when UBI10 is selected, and ensure command generation does not silently substitute `cu13-ubi10` while displaying CUDA 12.x.build.sh-462-470 (1)
462-470: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winKeep local documentation prerequisites consistent across the script and README.
The Fern generator requires a complete Python/Doxygen toolchain, but the script can skip or partially bootstrap it while the README does not tell contributors to install it.
build.sh#L462-L470: Require Python and the complete generator toolchain, including Doxygen and numpydoc, before runningfern check; use the selected interpreter’s pip.README.md#L33-L40: Document those prerequisites or direct contributors to the reproducible conda docs environment.🤖 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 `@build.sh` around lines 462 - 470, Update build.sh lines 462-470 to require Python and validate the complete Fern generator toolchain, including Doxygen and numpydoc, before running fern check or generate_api_docs; bootstrap dependencies through the selected interpreter’s pip and do not silently proceed with missing prerequisites. Update README.md lines 33-40 to document these prerequisites or direct contributors to the reproducible conda documentation environment.fern/generate_api_docs.py-88-90 (1)
88-90: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winFail the build when OpenAPI generation fails.
The broad catch only prints a warning, so the build continues with stale
cuopt_spec.yamland installation-version data. This can publish artifacts from different cuOpt versions. Propagate the failure after adding actionable context.🤖 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 `@fern/generate_api_docs.py` around lines 88 - 90, Update the exception handler in the OpenAPI generation flow to preserve the actionable context message while propagating the original failure instead of continuing after the error. Ensure generation failures cause the build to stop, preventing stale cuopt_spec.yaml and installation-version data from being used.fern/extract_c_api.py-191-195 (1)
191-195: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winFail generation when a target Doxygen XML file cannot be parsed.
Skipping the file creates a partial symbol table; configured symbols then become “documentation not found” placeholders and the command still exits successfully. Raise with the XML filename so incomplete C API references cannot be published.
Proposed fix
try: tree = ET.parse(xml_file) except ET.ParseError as e: - print(f" [WARN] XML parse error in {xml_file.name}: {e}") - continue + raise RuntimeError( + f"Failed to parse Doxygen XML {xml_file.name}: {e}" + ) from eAlso applies to: 373-376
🤖 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 `@fern/extract_c_api.py` around lines 191 - 195, Update the ET.parse error handling in the XML extraction flow to raise on ET.ParseError instead of printing a warning and continuing, including the affected XML filename in the raised error. Apply the same behavior to the additional parse-error handling block noted in the comment so generation fails rather than publishing an incomplete symbol table.fern/generate_api_docs.py-100-113 (1)
100-113: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winComplete the public contracts for the new documentation-generator entry points.
fern/generate_api_docs.py#L100-L113: add-> None; document generated artifacts and propagated failures.fern/embed_examples.py#L122-L129: add-> None; document updated files and I/O failures.fern/extract_c_api.py#L168-L180: precisely type the symbol map and document Doxygen/XML errors.fern/extract_c_api.py#L504-L525: add-> None; document generated pages and YAML/Doxygen/I/O errors.fern/extract_python_api.py#L421-L442: add-> None; document all parameters, file writes, and failures.fern/extract_python_api.py#L477-L490: add-> None; document generated pages and failures.As per coding guidelines, “Require type hints on new public Python functions and classes” and “Document new public Python APIs with meaningful docstring content covering parameters, returns, and raises.”
🤖 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 `@fern/generate_api_docs.py` around lines 100 - 113, Complete the public contracts for the six documented entry points: add -> None and meaningful docstrings to main in fern/generate_api_docs.py, embed_all in fern/embed_examples.py, the symbol-map function and page-generation function in fern/extract_c_api.py, and the two public functions in fern/extract_python_api.py. Document parameters where applicable, generated or updated artifacts, and propagated YAML, Doxygen/XML, I/O, file-write, and subprocess failures; precisely type the extract_c_api symbol map. Affected sites: fern/generate_api_docs.py lines 100-113, fern/embed_examples.py lines 122-129, fern/extract_c_api.py lines 168-180 and 504-525, and fern/extract_python_api.py lines 421-442 and 477-490.Source: Coding guidelines
fern/embed_examples.py-90-110 (1)
90-110: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winReject unclosed embed blocks instead of truncating the page.
If
<!-- /embed -->is absent, Line 97 reaches EOF and Line 99 advances beyond it. The script then writes only the prefix, deleting the rest of the MDX page. Raise before consuming or writing the file.Proposed fix
i += 1 while i < len(lines) and lines[i].rstrip("\n") != _CLOSE: i += 1 + if i >= len(lines): + raise ValueError( + f"Unclosed embed marker for examples/{rel} in {mdx_path}" + ) i += 1 # skip the closing marker line🤖 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 `@fern/embed_examples.py` around lines 90 - 110, Update the existing embed-marker handling around `_OPEN_RE.match` to detect when `_CLOSE` is not found before end of file. Raise an error before consuming the remainder or writing output, and only advance past the closing marker and replace the block when the closing marker exists.fern/openapi/cuopt_spec.yaml-171-188 (1)
171-188: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDocument the binary solver-log response formats
/cuopt/log/{id}acceptsapplication/vnd.msgpackandapplication/zlib, but the200response infern/openapi/cuopt_spec.yamlonly advertises JSON. Add the missing media types to the response content and regenerate the spec.🤖 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 `@fern/openapi/cuopt_spec.yaml` around lines 171 - 188, Update the 200 response content for the /cuopt/log/{id} operation to advertise application/vnd.msgpack and application/zlib alongside application/json, reusing the LogResponseModel schema for the binary formats, then regenerate the OpenAPI spec.fern/extract_python_api.py-285-390 (1)
285-390: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPreserve parsed numpydoc sections. The
numpydocpath drops sections it doesn’t render today:Attributesand other supported sections in public docstrings (for example inpython/cuopt/cuopt/linear_programming/problem.py) disappear oncehas_contentis true instead of falling back or being emitted.🤖 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 `@fern/extract_python_api.py` around lines 285 - 390, Update the numpydoc rendering flow around the parsed section handling in the doc conversion function to preserve Attributes and every other supported section, rather than silently dropping them when has_content is true. Include those sections in the content detection and emit them in the generated MDX using the existing section-formatting conventions; retain fallback to _doc_to_mdx only when no supported parsed content exists.fern/openapi/cuopt_spec.yaml-1175-1200 (1)
1175-1200: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winReconcile the LP example with
SolutionData. The example putsreduced_costonsolution, butSolutionDatadoesn’t define it and hasadditionalProperties: false; add it to the schema (or move it underlp_statistics) or remove it from the example.🤖 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 `@fern/openapi/cuopt_spec.yaml` around lines 1175 - 1200, Reconcile the LP response example with the SolutionData schema: either define reduced_cost in SolutionData with the correct type, move it under lp_statistics if that is the intended model, or remove it from the example. Ensure the final example contains no properties rejected by SolutionData’s additionalProperties: false.fern/docs/pages/cuopt-cli/quick-start.mdx-11-15 (1)
11-15: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winInclude the help command.
This says the next step displays CLI options, but no command is shown. Add a fenced
cuopt_cli --helpinvocation before the explanatory sentence.🤖 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 `@fern/docs/pages/cuopt-cli/quick-start.mdx` around lines 11 - 15, Add a fenced command block containing the cuopt_cli --help invocation immediately before the sentence explaining that the complete list of command-line arguments will be displayed, preserving the surrounding quick-start guidance.fern/docs/pages/cuopt-c/mip/mip-c-api.mdx-35-61 (1)
35-61: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDocument the complete callback typedef signatures.
The reference lists only typedef names and parameter descriptions, not the callable C declarations. Add both full
typedef void (*...)(...)signatures so users can implement compatible callbacks.Based on supplied upstream contract in
cpp/include/cuopt/mathematical_optimization/cuopt_c.h:776-845, both callback typedefs have required pointer qualifiers and avoidreturn type.🤖 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 `@fern/docs/pages/cuopt-c/mip/mip-c-api.mdx` around lines 35 - 61, Add the complete C callback declarations for cuOptMIPGetSolutionCallback and cuOptMIPSetSolutionCallback, using typedef void (*...)(...) and preserving the upstream parameter order, pointer qualifiers, and void return type. Place each signature with its corresponding typedef documentation before the parameter descriptions, without changing the existing parameter semantics.fern/docs/pages/cuopt-server/server-api/server-cli.mdx-1-5 (1)
1-5: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd the actual Server CLI reference. This page is just an intro today; add the command syntax, option list, env-var mapping, or a link to an authoritative generated reference so operators can find the supported flags.
🤖 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 `@fern/docs/pages/cuopt-server/server-api/server-cli.mdx` around lines 1 - 5, Add the actual cuOpt Server CLI reference to the “cuOpt Server CLI” page: document the command syntax and supported options with their corresponding environment-variable mappings, or link to an authoritative generated reference. Replace the introductory-only content while preserving the page’s existing title and scope.fern/docs/pages/cuopt-grpc/advanced.mdx-46-104 (1)
46-104: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd the missing walkthrough commands
The TLS, private-CA, Docker, and client setup sections only contain prose and headings. Add the fenced command examples for each flow so the page can be followed end to end.
🤖 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 `@fern/docs/pages/cuopt-grpc/advanced.mdx` around lines 46 - 104, Add fenced, executable command examples to the walkthrough sections in advanced.mdx: create the private CA, issue client and server certificates, start the TLS server, configure an authorized client, run the Docker gRPC server with a certificate volume, bypass the entrypoint, and set the client environment variables. Ensure examples use the documented flags and variables and form an end-to-end flow.fern/docs/pages/cuopt-grpc/quick-start.mdx-23-73 (1)
23-73: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftRestore the missing executable commands.
The page describes verification, bare-metal/Docker startup, remote environment exports, and Python/CLI execution, but none of those sections includes a command. This leaves the quick start non-actionable.
🤖 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 `@fern/docs/pages/cuopt-grpc/quick-start.mdx` around lines 23 - 73, Restore the executable shell commands throughout the cuOpt gRPC quick-start: add the binary verification command, bare-metal and Docker server launch commands, client remote environment exports, and Python/cuopt_cli run commands for both repository-checkout and downloaded-file workflows. Ensure the commands match the surrounding instructions, use the documented ports and image placeholder, and include the local-run unset commands.fern/docs/pages/cuopt-python/routing/examples/smoke_test_example.sh-37-49 (1)
37-49: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRegister the task locations before solving.
task_locationsis never passed todm, so the documented tasks at locations 1, 2, and 3 are not modeled. Calldm.set_order_locations(task_locations)after configuring the cost matrix.🤖 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 `@fern/docs/pages/cuopt-python/routing/examples/smoke_test_example.sh` around lines 37 - 49, Update the DataModel setup in the routing example to register task_locations before solving by calling set_order_locations on dm after configuring the cost and transit-time matrices. Preserve the existing task_locations values and vehicle configuration.fern/docs/pages/cuopt-python/convex/examples/mps_example.py-22-33 (1)
22-33: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy liftDocument and annotate the new public example functions.
All new non-underscore module-level functions need type hints and meaningful docstrings covering parameters, returns, and raised errors.
fern/docs/pages/cuopt-python/convex/examples/mps_example.py#L22-L33: annotate and documentmain.fern/docs/pages/cuopt-python/convex/examples/solution_example.py#L31-L63: annotatemainand expand its docstring with return/error behavior.fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py#L52-L60: annotate and documentbuild_cost_matrix.fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py#L63-L91: annotate and documentbuild_orders.fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py#L94-L98: annotate and documentbuild_fleet.fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py#L101-L151: annotate and documentbuild_data_model.fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py#L154-L180: annotate and documentprint_schedule.fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py#L183-L205: annotate and documentmain.fern/docs/pages/cuopt-python/routing/examples/tsp_batch_example.py#L13-L19: annotate and documentcreate_tsp_cost_matrix.fern/docs/pages/cuopt-python/routing/examples/tsp_batch_example.py#L22-L51: annotate and documentmain.As per coding guidelines, “Require type hints on new public Python functions and classes” and “Document new public Python APIs with meaningful docstring content covering parameters, returns, and raises.”
🤖 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 `@fern/docs/pages/cuopt-python/convex/examples/mps_example.py` around lines 22 - 33, All listed public example functions lack required API annotations and documentation. In fern/docs/pages/cuopt-python/convex/examples/mps_example.py:22-33, annotate and document main; in fern/docs/pages/cuopt-python/convex/examples/solution_example.py:31-63, annotate main and document its return and raised-error behavior; in fern/docs/pages/cuopt-python/routing/examples/intra_factory_example.py:52-60, 63-91, 94-98, 101-151, 154-180, and 183-205, annotate and add meaningful docstrings to build_cost_matrix, build_orders, build_fleet, build_data_model, print_schedule, and main; and in fern/docs/pages/cuopt-python/routing/examples/tsp_batch_example.py:13-19 and 22-51, annotate and document create_tsp_cost_matrix and main. Ensure every signature has appropriate parameter and return type hints, and each docstring covers parameters, returns, and raised errors where applicable.Source: Coding guidelines
fern/docs/pages/cuopt-python/mip/mip-api.mdx-5-5 (1)
5-5: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winPopulate the MIP Python API page from existing symbols
fern/extract_python_api.pyonly scanspython/cuopt/cuopt/linear_programming/mip, which doesn’t exist here, so this page falls back to the empty note. Point the MIP page at the actual Python modules that expose MIP APIs, or remove the nav entry if a separate MIP reference isn’t intended.🤖 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 `@fern/docs/pages/cuopt-python/mip/mip-api.mdx` at line 5, Update the MIP API page configuration to scan the existing Python modules that expose MIP APIs instead of the nonexistent linear_programming/mip directory, so fern/extract_python_api.py discovers and renders their public symbols. If no standalone MIP reference is intended, remove the page’s navigation entry instead.fern/docs/pages/cuopt-python/convex/examples/production_planning_example.py-39-40 (1)
39-40: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winType and document the public entry point.
Add
-> Noneand document the return contract (and expected raises, if applicable), or make this a private script helper.As per coding guidelines, “Require type hints on new public Python functions and classes” and “Document new public Python APIs with meaningful docstring content covering parameters, returns, and raises.”
🤖 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 `@fern/docs/pages/cuopt-python/convex/examples/production_planning_example.py` around lines 39 - 40, Update the public main entry point to include a -> None return annotation and expand its docstring to document the return contract and any applicable exceptions; retain it as public unless converting it to a private script helper is more appropriate.Sources: Coding guidelines, Path instructions
fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx-13-25 (1)
13-25: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRestore the missing runnable client examples.
This page promises a server command plus direct JSON and file-based requests, but provides no commands or payloads. It cannot currently guide a user through building a thin client.
🤖 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 `@fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx` around lines 13 - 25, Complete the “Invoking cuOpt Service” section with runnable server-start and client-request examples: add the command to run the server, a direct JSON request including a representative payload, and a file-based JSON request showing the required file and invocation. Ensure the examples target the /cuopt/request endpoint and reflect the documented shared data and result directories.fern/docs/pages/cuopt-server/nim-operator/configuration.mdx-46-46 (1)
46-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDo not conflate replica count with external exposure.
A
LoadBalancercan expose a single-replica service externally; scaling capability is unrelated. Rephrase this as a deployment-option decision rather than calling it unnecessary.🤖 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 `@fern/docs/pages/cuopt-server/nim-operator/configuration.mdx` at line 46, Revise the LoadBalancer note in the cuOpt service configuration documentation to separate replica count from external exposure: state that the service currently supports one pod instance while presenting LoadBalancer as an optional deployment choice, not as unnecessary because scaling is unavailable.fern/docs/pages/cuopt-server/nim-operator/index.mdx-9-14 (1)
9-14: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDo not advertise scaling for this deployment.
This contradicts
configuration.mdxLine 56, which says cuOpt supports only a single pod per service. Remove “scaling” or explicitly state that this workload is single-replica.🤖 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 `@fern/docs/pages/cuopt-server/nim-operator/index.mdx` around lines 9 - 14, Update the NIM Operator deployment overview to remove the claim that the operator handles scaling, or explicitly describe the cuOpt workload as single-replica. Keep the remaining lifecycle-management capabilities unchanged and align the wording with the single-pod constraint documented in configuration.mdx.fern/docs/pages/cuopt-server/nim-operator/configuration.mdx-32-34 (1)
32-34: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReconcile the persistent-storage requirement.
One page says storage is optional for HTTP requests, while the other says it is required. State that storage is optional and document the specific filesystem dataset workflow that needs it.
fern/docs/pages/cuopt-server/nim-operator/configuration.mdx#L32-L34: retain the conditional requirement and identify the storage-backed workflow.fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx#L39-L42: replace the unconditional requirement with the same conditional guidance.🤖 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 `@fern/docs/pages/cuopt-server/nim-operator/configuration.mdx` around lines 32 - 34, The persistent-storage documentation is inconsistent across the Nim operator pages. In fern/docs/pages/cuopt-server/nim-operator/configuration.mdx lines 32-34, retain the optional requirement and explicitly identify the filesystem-based dataset workflow that needs storage; in fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx lines 39-42, replace the unconditional storage requirement with the same conditional guidance.fern/docs/pages/faq.mdx-222-225 (1)
222-225: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftReconcile the routing-capacity guidance.
This claims standard CVRPTW instances can “easily” reach 15K locations on A100/H100, while Line 337 calls 10,000 the maximum on H100. Publish one validated, versioned benchmark envelope before users size deployments from this page.
🤖 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 `@fern/docs/pages/faq.mdx` around lines 222 - 225, Reconcile the conflicting cuOpt capacity claims in the FAQ by replacing the unqualified “easily” 15K-location statement near the cuOpt resource estimates accordion and the 10,000-location guidance near the existing H100 limit with one validated, versioned benchmark envelope. Ensure the published guidance consistently states the supported location limit, GPU assumptions, and relevant constraints rather than presenting contradictory maxima.fern/docs/pages/license.mdx-1-3 (1)
1-3: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRestore the license content.
This published page has only a title, so users cannot determine cuOpt’s license terms. Add the license text or a canonical-license link.
🤖 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 `@fern/docs/pages/license.mdx` around lines 1 - 3, Restore the license content in the cuOpt License page by adding the complete license text or a canonical link to the license. Keep the existing title and ensure the published page provides accessible license terms.fern/docs/pages/cuopt-python/convex/examples/rotated_socp_example.py-28-56 (1)
28-56: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winDocument and annotate the new public entry points.
fern/docs/pages/cuopt-python/convex/examples/rotated_socp_example.py#L28-L56: changemaintodef main() -> Noneand add a meaningful docstring documenting its return behavior.fern/docs/pages/cuopt-python/convex/examples/simple_lp_example.py#L32-L62: changemaintodef main() -> Noneand extend its docstring with return behavior.As per coding guidelines, “Require type hints on new public Python functions and classes” and “Document new public Python APIs with meaningful docstring content covering parameters, returns, and raises.”
🤖 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 `@fern/docs/pages/cuopt-python/convex/examples/rotated_socp_example.py` around lines 28 - 56, Update main in fern/docs/pages/cuopt-python/convex/examples/rotated_socp_example.py lines 28-56 to return None explicitly in its type hint and add a meaningful docstring documenting that it returns no value. Apply the same changes to main in fern/docs/pages/cuopt-python/convex/examples/simple_lp_example.py lines 32-62, extending its existing docstring with the return behavior; no parameters or raises documentation is needed unless applicable.Sources: Coding guidelines, Path instructions
fern/docs/pages/convex-features.mdx-59-121 (1)
59-121: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftRestore the equations and examples lost during migration.
Lines 61-63 omit the quadratic-objective formula, and Lines 77-121 omit each quadratic/SOCP form and both promised Python examples. RST remnants such as
:c,.note:, and double-backtick markup will also render incorrectly in MDX. Restore the source equations/examples and convert the directives to Fern MDX.🤖 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 `@fern/docs/pages/convex-features.mdx` around lines 59 - 121, Restore the missing quadratic-objective, quadratic-constraint, second-order cone, and rotated-cone equations, along with both promised Python examples, in the documentation section around “Quadratic Objectives” and “Quadratic Constraints.” Convert remaining RST syntax such as :c references, .note blocks, and double-backtick markup to valid Fern MDX while preserving the documented API references and constraint semantics.fern/docs/pages/cuopt-python/routing/routing-api.mdx-1200-1213 (1)
1200-1213: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse the defined
distancevariable in all three examples.Each snippet defines
distancebut passesdistancestocudf.DataFrame, causing an immediateNameError.Also applies to: 1233-1247, 1269-1281
🤖 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 `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 1200 - 1213, The routing examples around routing.Solve define the matrix as distance but incorrectly reference distances; update all three affected cudf.DataFrame constructions to use the existing distance variable consistently.fern/docs/pages/cuopt-python/routing/routing-api.mdx-1122-1129 (1)
1122-1129: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDefine
data_modelbefore using it.This example declares locations, vehicles, and prizes but calls
data_model.set_order_prizes(...)without constructing arouting.DataModel.🤖 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 `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 1122 - 1129, Update the routing example before the set_order_prizes call to construct data_model as a routing.DataModel using the declared locations and vehicles, preserving the existing prizes setup and API usage.fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c-139-143 (1)
139-143: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winCheck allocation before passing the buffer to cuOpt.
Both examples pass a potentially null
solution_valuespointer tocuOptGetPrimalSolution.
fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c#L139-L143: check for null, setstatus = CUOPT_OUT_OF_MEMORY, and jump to cleanup.fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c#L148-L152: apply the same allocation guard.🤖 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 `@fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c` around lines 139 - 143, Add a null-allocation guard after assigning solution_values in the solution retrieval flow: in fern/docs/pages/cuopt-c/convex/examples/lp_file_example.c lines 139-143 and fern/docs/pages/cuopt-c/convex/examples/mps_file_example.c lines 148-152, set status to CUOPT_OUT_OF_MEMORY and jump to DONE before calling cuOptGetPrimalSolution when allocation fails.fern/docs/pages/cuopt-c/convex/convex-examples.mdx-7-13 (1)
7-13: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winCorrect the local-build paths relative to the examples directory.
Both snippets point to paths that do not reach the repository’s
cpp/directory whenmakeruns beside this Makefile.
fern/docs/pages/cuopt-c/convex/convex-examples.mdx#L7-L13: use absolute repository-root paths or explicitly state the required working directory.fern/docs/pages/cuopt-c/convex/examples/Makefile#L37-L39: use paths such as../../../../../../cpp/includeand../../../../../../cpp/build.🤖 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 `@fern/docs/pages/cuopt-c/convex/convex-examples.mdx` around lines 7 - 13, The local-build instructions and Makefile use paths relative to the wrong working directory. Update fern/docs/pages/cuopt-c/convex/convex-examples.mdx lines 7-13 to use repository-root paths or explicitly require running from the repository root, and update fern/docs/pages/cuopt-c/convex/examples/Makefile lines 37-39 to reference the cpp directory via paths such as ../../../../../../cpp/include and ../../../../../../cpp/build.fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c-167-170 (1)
167-170: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReturn an error when solution allocation fails.
statusstill equalsCUOPT_SUCCESSon this path, somainprints “Test completed successfully” aftermallocfails.Proposed correction
if (solution_values == NULL) { printf("Error allocating solution values\n"); + status = CUOPT_OUT_OF_MEMORY; goto DONE; }🤖 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 `@fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c` around lines 167 - 170, Update the solution_values allocation failure branch in main so it assigns a non-success CUOPT status before jumping to DONE. Preserve the existing error message and cleanup flow, ensuring main does not report successful completion when malloc fails.fern/docs/pages/cuopt-c/convex/examples/Makefile-56-69 (1)
56-69: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRun
check-pathsfor direct example targets too.
make simple_lp_exampleis advertised, but onlyalldepends oncheck-paths. With empty variables,-Iand-Lconsume subsequent flags and produce misleading compiler/linker failures.Proposed correction
-.PHONY: all clean help list +.PHONY: all clean help list check-paths ... -%: %.c +%: %.c | check-paths🤖 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 `@fern/docs/pages/cuopt-c/convex/examples/Makefile` around lines 56 - 69, Ensure direct executable targets built by the pattern rule also depend on check-paths, not only the all target. Update the pattern rule so invoking targets such as simple_lp_example validates required paths before compilation, while preserving the existing build command and output behavior.fern/docs/pages/convex-settings.mdx-146-146 (1)
146-146: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse
CUOPT_SAVE_BEST_PRIMAL_SO_FARhere. The current name doesn’t match the C API constant, so copying it as written will lead to a compile error.🤖 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 `@fern/docs/pages/convex-settings.mdx` at line 146, Update the documented parameter name in the PDLP settings description from CUOPT_SAVE_BEST_PRIMAL_SOLUTION to CUOPT_SAVE_BEST_PRIMAL_SO_FAR, preserving the surrounding explanation and behavior details.fern/docs/pages/cuopt-python/routing/routing-api.mdx-73-98 (1)
73-98: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse the documented solver API here. Import
routingforrouting.DataModel, but keep solving viacuopt.Solver/solver.solve();routing.SolveandDataModel.set_min_vehiclesdon’t match the documented API. Remove the duplicateset_min_vehiclesandget_routecalls.🤖 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 `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 73 - 98, Update the routing example to import and use the documented routing namespace for routing.DataModel while retaining cuopt.Solver and solver.solve() for solving. Remove any routing.Solve usage and DataModel.set_min_vehicles calls, and delete the duplicate solver.set_min_vehicles and solution.get_route invocations.
🧹 Nitpick comments (2)
fern/docs/scripts/install-selector.js (1)
285-297: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider the modern Clipboard API.
document.execCommand("copy")is deprecated;navigator.clipboard.writeText()(with this as a fallback for older browsers) would be more future-proof.🤖 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 `@fern/docs/scripts/install-selector.js` around lines 285 - 297, Update copyToClipboard to use navigator.clipboard.writeText(out.value) when available, while retaining document.execCommand("copy") as the fallback for older browsers. Preserve the existing button text update and restoration behavior after a successful copy.fern/docs/pages/versions/v26-04.mdx (1)
1-8: 📐 Maintainability & Code Quality | 🔵 TrivialConsider a shared redirect template instead of per-version duplication.
Content is correct and internally consistent. This boilerplate (title, inline redirect script, fallback link) is duplicated almost verbatim across
v26-06.mdx(and likely the other archived-version pages). See consolidated comment below.
[medium]🤖 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 `@fern/docs/pages/versions/v26-04.mdx` around lines 1 - 8, Replace the duplicated redirect markup in the archived-version page represented by v26-04.mdx with a shared redirect template or reusable component, parameterized by the version-specific archive URL and title. Update the other archived-version pages, including v26-06.mdx, to use the same shared implementation while preserving each page’s destination and fallback link.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: a05f0a1e-1240-476d-b4c0-5495d08cb89f
⛔ Files ignored due to path filters (52)
fern/docs/images/add_role.pngis excluded by!**/*.pngfern/docs/images/aws1.pngis excluded by!**/*.pngfern/docs/images/aws2.pngis excluded by!**/*.pngfern/docs/images/aws3.pngis excluded by!**/*.pngfern/docs/images/aws4.pngis excluded by!**/*.pngfern/docs/images/azure1.pngis excluded by!**/*.pngfern/docs/images/azure2.pngis excluded by!**/*.pngfern/docs/images/azure3.pngis excluded by!**/*.pngfern/docs/images/azure4.pngis excluded by!**/*.pngfern/docs/images/azure5.pngis excluded by!**/*.pngfern/docs/images/azure6.pngis excluded by!**/*.pngfern/docs/images/cloud_functions.pngis excluded by!**/*.pngfern/docs/images/cost_matrix.pngis excluded by!**/*.pngfern/docs/images/cuOpt-managed.pngis excluded by!**/*.pngfern/docs/images/cuOpt-self-hosted.pngis excluded by!**/*.pngfern/docs/images/cuOpt_Collections_Image.pngis excluded by!**/*.pngfern/docs/images/cuOpt_Stack.pngis excluded by!**/*.pngfern/docs/images/cuopt_feature_diag.jpgis excluded by!**/*.jpgfern/docs/images/cuopt_landing_page.pngis excluded by!**/*.pngfern/docs/images/faq-01.pngis excluded by!**/*.pngfern/docs/images/generate-personal-key.pngis excluded by!**/*.pngfern/docs/images/genms_cuopt.pngis excluded by!**/*.pngfern/docs/images/grpc-job-states.pngis excluded by!**/*.pngfern/docs/images/grpc-process-model.pngis excluded by!**/*.pngfern/docs/images/image1.pngis excluded by!**/*.pngfern/docs/images/image2.pngis excluded by!**/*.pngfern/docs/images/image3.pngis excluded by!**/*.pngfern/docs/images/image4.pngis excluded by!**/*.pngfern/docs/images/image5.pngis excluded by!**/*.pngfern/docs/images/invite_user.pngis excluded by!**/*.pngfern/docs/images/ms_cuopt.pngis excluded by!**/*.pngfern/docs/images/nav-cloud-functions.pngis excluded by!**/*.pngfern/docs/images/nav-landing-page.pngis excluded by!**/*.pngfern/docs/images/nvidia-cuopt-logo-dark.svgis excluded by!**/*.svgfern/docs/images/nvidia-cuopt-logo-light.svgis excluded by!**/*.svgfern/docs/images/options_cuopt.pngis excluded by!**/*.pngfern/docs/images/organization.pngis excluded by!**/*.pngfern/docs/images/overview_cuopt.pngis excluded by!**/*.pngfern/docs/images/route_map.pngis excluded by!**/*.pngfern/docs/images/service_key_creation.pngis excluded by!**/*.pngfern/docs/images/service_keys.pngis excluded by!**/*.pngfern/docs/images/sh-cuOpt-stack.pngis excluded by!**/*.pngfern/docs/images/shared_functions.pngis excluded by!**/*.pngfern/docs/images/soft_stack.pngis excluded by!**/*.pngfern/docs/images/users.pngis excluded by!**/*.pngfern/docs/images/waypoint_graph.pngis excluded by!**/*.pngfern/docs/pages/cuopt-c/convex/examples/qp_sample.mpsis excluded by!**/*.mpsfern/docs/pages/cuopt-c/convex/examples/sample.lpis excluded by!**/*.lpfern/docs/pages/cuopt-c/convex/examples/sample.mpsis excluded by!**/*.mpsfern/docs/pages/cuopt-c/convex/examples/socp_sample.mpsis excluded by!**/*.mpsfern/docs/pages/cuopt-c/mip/examples/mip_sample.mpsis excluded by!**/*.mpsfern/docs/pages/cuopt-python/convex/examples/sample.mpsis excluded by!**/*.mps
📒 Files selected for processing (127)
.github/workflows/build.yaml.github/workflows/pr.yaml.gitignoreAGENTS.mdREADME.mdbuild.shci/build_docs.shdependencies.yamlfern/Doxyfilefern/c_api_config.yamlfern/docs-v25-05.ymlfern/docs-v25-08.ymlfern/docs-v25-12.ymlfern/docs-v26-02.ymlfern/docs-v26-04.ymlfern/docs-v26-06.ymlfern/docs-v26-08.ymlfern/docs.ymlfern/docs/pages/convex-features.mdxfern/docs/pages/convex-settings.mdxfern/docs/pages/cuopt-c-api-reference.mdxfern/docs/pages/cuopt-c/convex/convex-c-api.mdxfern/docs/pages/cuopt-c/convex/convex-examples.mdxfern/docs/pages/cuopt-c/convex/examples/Makefilefern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.cfern/docs/pages/cuopt-c/convex/examples/lp_file_example.cfern/docs/pages/cuopt-c/convex/examples/mps_file_example.cfern/docs/pages/cuopt-c/convex/examples/rotated_socp_example.cfern/docs/pages/cuopt-c/convex/examples/simple_lp_example.cfern/docs/pages/cuopt-c/convex/examples/simple_qp_example.cfern/docs/pages/cuopt-c/convex/examples/simple_socp_example.cfern/docs/pages/cuopt-c/convex/index.mdxfern/docs/pages/cuopt-c/index.mdxfern/docs/pages/cuopt-c/mip/examples/Makefilefern/docs/pages/cuopt-c/mip/examples/milp_mps_example.cfern/docs/pages/cuopt-c/mip/examples/simple_milp_example.cfern/docs/pages/cuopt-c/mip/index.mdxfern/docs/pages/cuopt-c/mip/mip-c-api.mdxfern/docs/pages/cuopt-c/mip/mip-examples.mdxfern/docs/pages/cuopt-c/quick-start.mdxfern/docs/pages/cuopt-cli/cli-examples.mdxfern/docs/pages/cuopt-cli/index.mdxfern/docs/pages/cuopt-cli/quick-start.mdxfern/docs/pages/cuopt-grpc/advanced.mdxfern/docs/pages/cuopt-grpc/api.mdxfern/docs/pages/cuopt-grpc/examples.mdxfern/docs/pages/cuopt-grpc/grpc-server-architecture.mdxfern/docs/pages/cuopt-grpc/index.mdxfern/docs/pages/cuopt-grpc/quick-start.mdxfern/docs/pages/cuopt-python/convex/convex-api.mdxfern/docs/pages/cuopt-python/convex/convex-examples.mdxfern/docs/pages/cuopt-python/convex/examples/expressions_constraints_example.pyfern/docs/pages/cuopt-python/convex/examples/general_quadratic_example.pyfern/docs/pages/cuopt-python/convex/examples/mps_example.pyfern/docs/pages/cuopt-python/convex/examples/pdlp_warmstart_example.pyfern/docs/pages/cuopt-python/convex/examples/production_planning_example.pyfern/docs/pages/cuopt-python/convex/examples/qp_matrix_example.pyfern/docs/pages/cuopt-python/convex/examples/rotated_socp_example.pyfern/docs/pages/cuopt-python/convex/examples/simple_lp_example.pyfern/docs/pages/cuopt-python/convex/examples/simple_qp_example.pyfern/docs/pages/cuopt-python/convex/examples/simple_socp_example.pyfern/docs/pages/cuopt-python/convex/examples/solution_example.pyfern/docs/pages/cuopt-python/convex/index.mdxfern/docs/pages/cuopt-python/index.mdxfern/docs/pages/cuopt-python/mip/examples/incumbent_solutions_example.pyfern/docs/pages/cuopt-python/mip/examples/semi_continuous_example.pyfern/docs/pages/cuopt-python/mip/examples/simple_milp_example.pyfern/docs/pages/cuopt-python/mip/index.mdxfern/docs/pages/cuopt-python/mip/mip-api.mdxfern/docs/pages/cuopt-python/mip/mip-examples.mdxfern/docs/pages/cuopt-python/quick-start.mdxfern/docs/pages/cuopt-python/routing/examples/intra_factory_example.pyfern/docs/pages/cuopt-python/routing/examples/smoke_test_example.shfern/docs/pages/cuopt-python/routing/examples/tsp_batch_example.pyfern/docs/pages/cuopt-python/routing/index.mdxfern/docs/pages/cuopt-python/routing/routing-api.mdxfern/docs/pages/cuopt-python/routing/routing-examples.mdxfern/docs/pages/cuopt-server/client-api/index.mdxfern/docs/pages/cuopt-server/client-api/sh-cli-api.mdxfern/docs/pages/cuopt-server/client-api/sh-cli-build.mdxfern/docs/pages/cuopt-server/csp-guides/csp-aws.mdxfern/docs/pages/cuopt-server/csp-guides/csp-azure.mdxfern/docs/pages/cuopt-server/csp-guides/index.mdxfern/docs/pages/cuopt-server/examples/index.mdxfern/docs/pages/cuopt-server/examples/lp-examples.mdxfern/docs/pages/cuopt-server/examples/milp-examples.mdxfern/docs/pages/cuopt-server/examples/routing-examples.mdxfern/docs/pages/cuopt-server/index.mdxfern/docs/pages/cuopt-server/nim-operator/configuration.mdxfern/docs/pages/cuopt-server/nim-operator/deployment.mdxfern/docs/pages/cuopt-server/nim-operator/index.mdxfern/docs/pages/cuopt-server/nim-operator/prerequisites.mdxfern/docs/pages/cuopt-server/quick-start.mdxfern/docs/pages/cuopt-server/server-api/index.mdxfern/docs/pages/cuopt-server/server-api/server-cli.mdxfern/docs/pages/faq.mdxfern/docs/pages/index.mdxfern/docs/pages/install.mdxfern/docs/pages/introduction.mdxfern/docs/pages/license.mdxfern/docs/pages/milp-features.mdxfern/docs/pages/mip-settings.mdxfern/docs/pages/open-api.mdxfern/docs/pages/release-notes.mdxfern/docs/pages/resources.mdxfern/docs/pages/routing-features.mdxfern/docs/pages/system-requirements.mdxfern/docs/pages/thirdparty_modeling_languages/index.mdxfern/docs/pages/transition.mdxfern/docs/pages/versions/v25-05.mdxfern/docs/pages/versions/v25-08.mdxfern/docs/pages/versions/v25-12.mdxfern/docs/pages/versions/v26-02.mdxfern/docs/pages/versions/v26-04.mdxfern/docs/pages/versions/v26-06.mdxfern/docs/scripts/cuopt-install-version.jsfern/docs/scripts/install-selector.cssfern/docs/scripts/install-selector.jsfern/embed_examples.pyfern/extract_c_api.pyfern/extract_python_api.pyfern/fern.config.jsonfern/generate_api_docs.pyfern/generators.ymlfern/openapi/cuopt_spec.yamlfern/requirements-docs.txtpython/cuopt/cuopt/linear_programming/io/parser.py
📝 WalkthroughWalkthroughThe pull request migrates cuOpt documentation from the existing build flow to Fern. It adds CI publishing, generated C/Python/OpenAPI references, extensive guides and examples, navigation and version redirects, an installation selector, and supporting documentation tooling. ChangesFern documentation migration
Estimated code review effort: 5 (Critical) | ~120 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
fern/docs/pages/cuopt-python/quick-start.mdx (1)
21-24: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winEmbed the smoke test or correct the instructions.
The page provides only a link and an empty “Example Response” section, so users cannot copy a script directly from this guide as stated. Embed the command and output, or reword this as a link to the script.
🤖 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 `@fern/docs/pages/cuopt-python/quick-start.mdx` around lines 21 - 24, Update the quick-start section around the smoke_test_example.sh reference so it matches the stated usage: either embed the complete smoke-test command and a representative example response, or reword the text to clearly direct users to the linked script instead of claiming it can be copied directly from the guide.
🟠 Major comments (30)
fern/c_api_config.yaml-58-64 (1)
58-64: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winCorrect the standard second-order cone formula.
The standard SOC is
sum(x_i^2) <= x_0^2withx_0 >= 0; the current text documents a different constraint.🤖 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 `@fern/c_api_config.yaml` around lines 58 - 64, Update the quadratic-constraint documentation note for cuOptAddQuadraticConstraint so the standard second-order cone formula uses sum of the squared non-leading variables bounded by x_0 squared, with x_0 nonnegative. Leave the convex and rotated second-order cone descriptions unchanged.fern/docs/pages/cuopt-c/convex/convex-examples.mdx-382-406 (1)
382-406: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winCheck termination status before reading a primal solution.
These examples accept arbitrary files but unconditionally request the objective and primal vector. Mirror
milp_mps_example.c: computehas_primal_solution, only access solution data when true, and checkmallocbefore callingcuOptGetPrimalSolution.Also applies to: 593-615
🤖 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 `@fern/docs/pages/cuopt-c/convex/convex-examples.mdx` around lines 382 - 406, The example must verify termination status before accessing solution data. Mirror milp_mps_example.c by computing has_primal_solution, conditionally calling cuOptGetObjectiveValue and cuOptGetPrimalSolution only when true, and checking solution_values allocation before using it; preserve the existing error handling and result output for valid primal solutions.build.sh-462-470 (1)
462-470: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDo not continue with stale generated API pages.
If Python is unavailable, this proceeds through validation and even publishing without regenerating the references. Also, bare
pipmay install dependencies for a different interpreter. Require${PY}and install with"${PY}" -m pip.Proposed fix
PY=${PYTHON:-python3} if command -v "${PY}" &>/dev/null; then if ! "${PY}" -c "import fastapi, pydantic, yaml" 2>/dev/null; then - pip install --quiet -r "${REPODIR}/fern/requirements-docs.txt" + "${PY}" -m pip install --quiet -r "${REPODIR}/fern/requirements-docs.txt" fi "${PY}" "${REPODIR}/fern/generate_api_docs.py" else - echo " [WARN] Python not found; skipping API doc generation." + echo "ERROR: Python is required to generate API documentation." + exit 1 fi🤖 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 `@build.sh` around lines 462 - 470, Update the API documentation generation block around PY so missing Python causes the build to fail instead of continuing to validation or publishing. Replace bare pip installation with the selected interpreter’s “${PY} -m pip”, and preserve dependency installation and generate_api_docs.py execution through that same interpreter.fern/docs/pages/cuopt-c/convex/convex-c-api.mdx-127-127 (1)
127-127: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReplace
CUOPT_ERRORwith a documented status code
CUOPT_ERRORis not in the public status-code list on this page. Use one of the documented error constants, or add and documentCUOPT_ERRORif it is meant to be part of the API. (Also applies to line 183.)🤖 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 `@fern/docs/pages/cuopt-c/convex/convex-c-api.mdx` at line 127, Update the return documentation at both affected locations to use a status constant already listed in the public API documentation, or add CUOPT_ERROR to that documented status-code list if it is an intended public constant; keep the success/error return description consistent.fern/docs/pages/cuopt-c/convex/convex-c-api.mdx-108-108 (1)
108-108: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftRestore the missing equations and API details in the convex C reference The four constructor entries are missing their optimization formulations,
CUOPT_ERRORis missing from the status-code list, andcuOptGetErrorStatus/cuOptGetErrorString/cuOptGetPrimalSolutionhave no descriptive content.🤖 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 `@fern/docs/pages/cuopt-c/convex/convex-c-api.mdx` at line 108, The convex C API reference is incomplete: update the four constructor entries following “Create an optimization problem of the form” with their optimization equations, add CUOPT_ERROR to the status-code list, and provide descriptions for cuOptGetErrorStatus, cuOptGetErrorString, and cuOptGetPrimalSolution. Preserve the existing reference structure and terminology.fern/docs/pages/convex-features.mdx-61-121 (1)
61-121: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRestore the missing quadratic formulas and replace the legacy RST syntax. The equations after the “of the form” lines are still blank, and the
:c\``/.note:markup won’t render as intended in this MDX page. The#simple-qp-example-python,#simple-qp-example-c, and#generic-example-with-normal-and-batch-mode` links also point to slugs that don’t exist here.🤖 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 `@fern/docs/pages/convex-features.mdx` around lines 61 - 121, The quadratic objective and constraint sections in the MDX page are missing their formulas; restore the displayed equations for each “of the form” statement, including convex, concave, second-order cone, and rotated cone definitions. Replace legacy `:c\`` and `.note:` RST markup with valid MDX/Markdown equivalents, and update the referenced example links to anchors that exist in this page, including the generic normal/batch example.fern/docs/pages/cuopt-python/convex/examples/mps_example.py-22-33 (1)
22-33: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAdd a return annotation to the new entry point.
mainis a new non-private function and should declare-> None.Proposed fix
-def main(): +def main() -> None:🤖 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 `@fern/docs/pages/cuopt-python/convex/examples/mps_example.py` around lines 22 - 33, Update the new main function to declare an explicit None return annotation, preserving its existing execution and output behavior.Source: Coding guidelines
fern/docs/pages/cuopt-grpc/quick-start.mdx-23-71 (1)
23-71: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftRestore the omitted gRPC command blocks. The migration retained introductory text but lost the executable commands required by all three guides.
fern/docs/pages/cuopt-grpc/quick-start.mdx#L23-L71: add binary verification, server launch, Docker, client-export, and example-run commands.fern/docs/pages/cuopt-grpc/advanced.mdx#L11-L104: add flags, TLS/mTLS, CA, Docker, and client-configuration commands.fern/docs/pages/cuopt-grpc/examples.mdx#L5-L9: add the required remote host and port exports.🤖 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 `@fern/docs/pages/cuopt-grpc/quick-start.mdx` around lines 23 - 71, Restore the omitted executable command blocks in fern/docs/pages/cuopt-grpc/quick-start.mdx (lines 23-71) for binary verification, bare-metal and Docker server launch, client environment exports, and Python/CLI example runs. Add the documented flags, TLS/mTLS and CA commands, Docker commands, and client configuration commands in fern/docs/pages/cuopt-grpc/advanced.mdx (lines 11-104). Add the required remote host and port exports in fern/docs/pages/cuopt-grpc/examples.mdx (lines 5-9), preserving the surrounding guidance and documented command behavior.fern/docs/pages/cuopt-python/convex/convex-api.mdx-33-33 (1)
33-33: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftFix the API doc generator before publishing this page. Several generated sections still leak literal
:py:meth:/:py:class:roles, escape<=inside examples, flatten.. deprecated::into prose, and drop exception names in**Raises**; regenerate after fixing the renderer.🤖 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 `@fern/docs/pages/cuopt-python/convex/convex-api.mdx` at line 33, Fix the API documentation renderer before regenerating this page: resolve literal :py:meth: and :py:class: roles into proper links, preserve <= in example blocks, render .. deprecated:: as a directive, and retain exception names in **Raises** sections. Locate the renderer components responsible for these generated sections, then regenerate the cuOpt Python API documentation.Source: Coding guidelines
fern/docs/pages/cuopt-python/routing/routing-api.mdx-71-99 (1)
71-99: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winImport
routingin both Assignment examples. Both snippets callrouting.DataModelwithout definingrouting, so they fail immediately.
fern/docs/pages/cuopt-python/routing/routing-api.mdx#L71-L99: addfrom cuopt import routingbefore constructing the data model.fern/docs/pages/cuopt-python/routing/routing-api.mdx#L169-L201: add the same import before constructing the data model.🤖 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 `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 71 - 99, Import the routing module in both Assignment examples before their routing.DataModel calls: update fern/docs/pages/cuopt-python/routing/routing-api.mdx lines 71-99 and 169-201 with the same cuopt routing import. No other changes are needed.fern/docs/pages/cuopt-python/routing/routing-api.mdx-1201-1207 (1)
1201-1207: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse the declared matrix variable in both matching examples. Each example defines
distancebut passes undefineddistances.
fern/docs/pages/cuopt-python/routing/routing-api.mdx#L1201-L1207: passcudf.DataFrame(distance)toadd_cost_matrix.fern/docs/pages/cuopt-python/routing/routing-api.mdx#L1233-L1240: passcudf.DataFrame(distance)toadd_cost_matrix.🤖 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 `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 1201 - 1207, The routing API examples use the undefined variable distances instead of the declared distance matrix. Update both affected examples in fern/docs/pages/cuopt-python/routing/routing-api.mdx (lines 1201-1207 and 1233-1240) so add_cost_matrix uses distance in cudf.DataFrame, preserving the rest of each example.fern/docs/pages/cuopt-python/routing/routing-api.mdx-1123-1128 (1)
1123-1128: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winInitialize
data_modelbefore using it.Line 1128 raises
NameError; this fenced example never creates arouting.DataModel.🤖 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 `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 1123 - 1128, Initialize a routing.DataModel instance before the set_order_prizes call in the example, using the existing locations and vehicles context as required by its constructor. Ensure data_model is defined before cudf.Series(prizes) is passed to data_model.set_order_prizes.fern/docs/pages/cuopt-server/examples/lp-examples.mdx-63-65 (1)
63-65: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winPoint the abort links to the MILP examples page.
These are same-page fragments, but neither target exists here. Link to the corresponding headings in
milp-examples.mdxinstead.Also applies to: 101-103
🤖 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 `@fern/docs/pages/cuopt-server/examples/lp-examples.mdx` around lines 63 - 65, Update the aborting-job references in the LP examples, including the occurrence around the alternate abort section, to link to the corresponding headings in milp-examples.mdx rather than using same-page fragment links. Preserve the existing link text and point each reference at its matching MILP heading.fern/docs/pages/cuopt-python/routing/routing-api.mdx-209-243 (1)
209-243: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winFix the non-runnable re-routing example.
Line 237 has an unterminated
"service_time"key, and Line 241 passesdistances, which is never defined. The snippet cannot be copied or executed as written.🤖 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 `@fern/docs/pages/cuopt-python/routing/routing-api.mdx` around lines 209 - 243, Fix the construct_rerouting_model example by closing the service_time key string in new_order_data and passing the defined new_distances variable instead of the undefined distances name. Keep the example’s remaining parameters and flow unchanged so it is directly runnable.fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx-17-29 (1)
17-29: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winAdd the missing request and server-start examples.
The guide announces commands and direct-string/file examples, but none are present. Include runnable HTTP requests with endpoint, headers, payload/file handling, and the asynchronous response shape.
🤖 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 `@fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx` around lines 17 - 29, Add the missing runnable server-start command and request examples in the CLI guide section around the `/cuopt/request` documentation: include the endpoint, required headers, a direct JSON payload example, a file-upload example with data/result directory handling, and the asynchronous response shape. Ensure the examples match the documented `-d` and `-r` server options and are executable as presented.fern/docs/pages/cuopt-server/nim-operator/index.mdx-9-14 (1)
9-14: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMake the scaling contract consistent.
fern/docs/pages/cuopt-server/nim-operator/index.mdxLines 9-14: qualify scaling as a generic operator capability.fern/docs/pages/cuopt-server/nim-operator/configuration.mdxLines 46-56: state that cuOpt currently supports only one pod and does not support service scaling.🤖 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 `@fern/docs/pages/cuopt-server/nim-operator/index.mdx` around lines 9 - 14, Make the scaling documentation consistent across both sites: in fern/docs/pages/cuopt-server/nim-operator/index.mdx lines 9-14, qualify automated scaling as a generic NIM Operator capability rather than a cuOpt-supported feature; in fern/docs/pages/cuopt-server/nim-operator/configuration.mdx lines 46-56, explicitly state that cuOpt currently supports only one pod and does not support service scaling.fern/docs/pages/cuopt-server/examples/routing-examples.mdx-19-25 (1)
19-25: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMake initial-solution support consistent.
fern/docs/pages/cuopt-server/examples/routing-examples.mdxLines 19-25: document the actual acceptance/rejection behavior for initial solutions.fern/docs/pages/faq.mdxLines 243-245: update the FAQ to match the supported behavior.🤖 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 `@fern/docs/pages/cuopt-server/examples/routing-examples.mdx` around lines 19 - 25, Update the initial-solution documentation to accurately describe the actual acceptance and rejection behavior, replacing the incorrect claim that the example solution is rejected because the problem is too small. Apply the corresponding consistency update in fern/docs/pages/faq.mdx lines 243-245; both documented locations must describe the same supported behavior.fern/docs/pages/faq.mdx-222-225 (1)
222-225: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winResolve the contradictory routing capacity claims.
The FAQ says cuOpt can easily solve 15K locations on A100/H100, but later describes 10,000 locations as the maximum on an H100 SXM. Clarify the workload assumptions or replace one of the figures with a consistent, qualified estimate.
Also applies to: 335-339
🤖 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 `@fern/docs/pages/faq.mdx` around lines 222 - 225, Resolve the conflicting capacity statements in the cuOpt resource-estimates FAQ by aligning the 15K-location claim with the later H100 SXM 10,000-location maximum. Clarify the workload or hardware assumptions for each estimate, or replace the figures with one consistent, explicitly qualified capacity statement.fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx-87-94 (1)
87-94: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winDo not echo the NGC API key.
echo $NGC_API_KEYprints the secret to terminal logs and CI output. Replace it with a non-disclosing presence check such astest -n "${NGC_API_KEY:-}".🤖 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 `@fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx` around lines 87 - 94, Update the NGC API key prerequisite check in the deployment verification list to avoid printing the secret. Replace the echo command with a non-disclosing presence check using NGC_API_KEY that succeeds only when the variable is set and non-empty.fern/docs/pages/cuopt-server/nim-operator/configuration.mdx-32-34 (1)
32-34: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMake the storage requirement consistent.
fern/docs/pages/cuopt-server/nim-operator/configuration.mdxLines 32-34: explain that persistent storage is optional for HTTP-based data transfer.fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdxLines 39-42: remove the unconditional requirement or document the exact cases requiring storage.🤖 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 `@fern/docs/pages/cuopt-server/nim-operator/configuration.mdx` around lines 32 - 34, Align the storage guidance across both documentation sites: in fern/docs/pages/cuopt-server/nim-operator/configuration.mdx lines 32-34, retain that persistent storage is optional when data is transferred over HTTP; in fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx lines 39-42, remove the unconditional storage requirement or explicitly limit it to deployments that pass datasets through the filesystem.fern/docs/pages/cuopt-server/quick-start.mdx-17-60 (1)
17-60: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy liftRestore the omitted documentation content across the migration. Multiple pages retain empty placeholders where commands, outputs, API references, or configuration examples are required.
fern/docs/pages/cuopt-server/quick-start.mdxLines 17-60: restore container and smoke-test commands.fern/docs/pages/cuopt-server/examples/routing-examples.mdxLines 13-49: restore response and HTTPS examples.fern/docs/pages/cuopt-server/nim-operator/configuration.mdxLines 22-80: add actual configuration values and manifests.fern/docs/pages/cuopt-server/nim-operator/deployment.mdxLines 7-75: add deployment, verification, and testing commands.fern/docs/pages/cuopt-server/nim-operator/index.mdxLines 32-44: add quick-start commands and navigation.fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdxLines 25-68: add installation and verification commands.fern/docs/pages/cuopt-server/server-api/index.mdxLine 5: add API navigation/content.fern/docs/pages/cuopt-server/server-api/server-cli.mdxLine 5: add the CLI reference.fern/docs/pages/faq.mdxLines 102-108, 125-165, 195-200, and 439-449: restore troubleshooting commands and examples.🤖 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 `@fern/docs/pages/cuopt-server/quick-start.mdx` around lines 17 - 60, The migration removed required documentation content across multiple cuOpt pages; restore the omitted commands, outputs, references, configuration values, manifests, and examples. Update fern/docs/pages/cuopt-server/quick-start.mdx (17-60) with container and smoke-test commands; examples/routing-examples.mdx (13-49) with response and HTTPS examples; nim-operator/configuration.mdx (22-80) with configuration values and manifests; deployment.mdx (7-75) with deployment, verification, and testing commands; index.mdx (32-44) with quick-start commands and navigation; prerequisites.mdx (25-68) with installation and verification commands; server-api/index.mdx (5) with API navigation/content; server-cli.mdx (5) with the CLI reference; and faq.mdx (102-108, 125-165, 195-200, 439-449) with the troubleshooting commands and examples.fern/docs/pages/cuopt-server/nim-operator/configuration.mdx-46-46 (1)
46-46: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReplace the RST directive with Fern/MDX syntax.
.. note::is an RST directive and will not render as a Fern note in this MDX page. Use Fern’s<Note>component or standard Markdown.🤖 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 `@fern/docs/pages/cuopt-server/nim-operator/configuration.mdx` at line 46, Update the LoadBalancer guidance in the cuOpt configuration page to replace the RST `.. note::` directive with Fern-supported MDX syntax, preferably the `<Note>` component, while preserving the existing message.fern/docs/pages/cuopt-python/convex/examples/production_planning_example.py-39-40 (1)
39-40: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winAdd the required public-function contract.
mainis a new public Python function but has no return annotation, and its docstring does not document the return/raise contract.Proposed fix
-def main(): - """Run the production planning example.""" +def main() -> None: + """Run the production planning example. + + Returns: + None. + """🤖 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 `@fern/docs/pages/cuopt-python/convex/examples/production_planning_example.py` around lines 39 - 40, Update the public function main to declare its return type as None and expand its docstring to document the return and raise contract, following the repository’s established public-function documentation conventions.Source: Coding guidelines
fern/docs/pages/system-requirements.mdx-62-68 (1)
62-68: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winCorrect the CUDA 12.9 driver floor.
CUDA 12.9 GA requires Linux driver
575.51.03+, not570.42.01+. The current value can direct users to an unsupported runtime combination. (docs.nvidia.com)- - CUDA 12.9 with Driver 570.42.01+ + - CUDA 12.9 with Driver 575.51.03+🤖 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 `@fern/docs/pages/system-requirements.mdx` around lines 62 - 68, Update the CUDA 12.9 entry in the “CUDA & NVIDIA Driver combinations” list to require Linux driver 575.51.03 or newer instead of 570.42.01, leaving the other version requirements unchanged.fern/docs/scripts/install-selector.css-6-8 (1)
6-8: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winIncrease the copy-button text contrast.
White on
#76b900is approximately 2.41:1, below WCAG’s 4.5:1 normal-text minimum and even its 3:1 large-text minimum. (w3.org)Proposed fix
`#cuopt-copy-btn.cuopt-install-copy-btn` { - color: `#fff` !important; + color: `#000` !important; }Also applies to: 152-173
🤖 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 `@fern/docs/scripts/install-selector.css` around lines 6 - 8, Update the copy-button color variables around --cuopt-nvidia-green and its hover/active variants so the button background provides sufficient contrast with its white text, meeting at least WCAG 4.5:1 for normal text across all interactive states.fern/extract_python_api.py-438-441 (1)
438-441: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDo not HTML-escape operators inside fenced code.
This global replacement changes generated signatures and examples from
x <= ytox <= y, making displayed and copied Python code incorrect. Escape only prose/MDX text, not fenced regions.🤖 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 `@fern/extract_python_api.py` around lines 438 - 441, Update the content transformation after joining lines so the <= replacement applies only outside fenced code blocks. Preserve operators inside fenced regions unchanged while continuing to escape them in prose/MDX text, then write the selectively transformed content through the existing dest.write_text call.fern/generate_api_docs.py-88-90 (1)
88-90: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winMake documentation generation fail closed.
Generation errors currently produce stale or incomplete API documentation while the pipeline continues successfully.
fern/generate_api_docs.py#L88-L90: re-raise OpenAPI/version generation failures.fern/extract_c_api.py#L191-L195: fail if any Doxygen XML file cannot be parsed.fern/extract_python_api.py#L85-L89: fail instead of treating an unparsable module as empty.🤖 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 `@fern/generate_api_docs.py` around lines 88 - 90, Make documentation generation fail closed: in fern/generate_api_docs.py around the OpenAPI/version generation exception handler, re-raise the failure after reporting it; in fern/extract_c_api.py around the Doxygen XML parsing handler, propagate any file parse error instead of continuing; and in fern/extract_python_api.py around module parsing, fail on unparsable modules rather than treating them as empty.fern/embed_examples.py-90-103 (1)
90-103: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winFail before truncating an unterminated embed block.
When
<!-- /embed -->is missing, this loop reaches EOF and replaces everything from the opening marker onward. Raise an error before writing the MDX file.Proposed fix
i += 1 while i < len(lines) and lines[i].rstrip("\n") != _CLOSE: i += 1 + if i >= len(lines): + raise ValueError( + f"{mdx_path}: missing {_CLOSE!r} for examples/{rel}" + ) i += 1 # skip the closing marker line🤖 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 `@fern/embed_examples.py` around lines 90 - 103, Update the existing embed-marker handling around _OPEN_RE and _CLOSE so it detects when the closing marker is not found before EOF, raises an error, and aborts before modifying or writing the MDX output; only skip and replace the block when _CLOSE is present.fern/docs/scripts/install-selector.js-201-206 (1)
201-206: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDo not silently map CUDA 12 + UBI10 to a CUDA 13 image.
cu12-ubi10is absent, so the fallback emitscu13-ubi10while the UI still says CUDA 12.x. Disable that combination, select CUDA 13 explicitly, or report it as unsupported.Minimal correctness fix
var baseCuda = cuda || "cu12"; var cudaKey = baseCuda + (variant === "ubi10" ? "-ubi10" : ""); - var fallbackKey = (variant === "ubi10") ? "cu13-ubi10" : "cu12"; - var c = data[release][cudaKey] || data[release][fallbackKey]; + if (variant === "ubi10" && baseCuda !== "cu13") { + return "# UBI10 images require CUDA 13.x. Select CUDA 13.x."; + } + var c = data[release][cudaKey] || data[release].cu12;🤖 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 `@fern/docs/scripts/install-selector.js` around lines 201 - 206, Update the fallback logic around `cudaKey`, `fallbackKey`, and `data[release]` so selecting CUDA 12 with the `ubi10` variant never resolves to `cu13-ubi10`. Treat that combination as unsupported or require an explicit CUDA 13 selection, while preserving valid image resolution for other CUDA and variant combinations.fern/openapi/cuopt_spec.yaml-3797-3801 (1)
3797-3801: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winUse object defaults for
DroppedTasks, and fix thevehicle_breaksexample
dropped_tasksis aDroppedTasksobject, but it defaults to[]in multiple response schemas. Use{}(or remove the default) so the spec matches the schema.- The third
vehicle_breaksexample omits requiredlocations; add it or make the field optional if omission is intended.🤖 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 `@fern/openapi/cuopt_spec.yaml` around lines 3797 - 3801, Update every response schema property referencing DroppedTasks, including dropped_tasks, to use an object default ({}) or remove the default instead of [] while preserving the DroppedTasks schema type. Correct the third vehicle_breaks example by adding the required locations field, unless the schema is intentionally changed to make locations optional.
🧹 Nitpick comments (1)
fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c (1)
118-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the non-deprecated quadratic-objective flow.
The page says this example uses
cuOptCreateProblempluscuOptSetQuadraticObjective, but the source teaches deprecatedcuOptCreateQuadraticProblem. Update the source and regenerate the embedded MDX.🤖 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 `@fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c` around lines 118 - 134, Update the simple QP example to use the non-deprecated cuOptCreateProblem flow, then apply the quadratic objective through cuOptSetQuadraticObjective instead of calling cuOptCreateQuadraticProblem. Regenerate the embedded MDX so the documented example matches the updated source and stated API usage.
🤖 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 `@ci/build_docs.sh`:
- Around line 40-52: Update ci/build_docs.sh so fern/generate_api_docs.py and
fern check run without repository secrets, and remove Fern publishing from this
secret-bearing script. Move fern generate --docs --preview into a trusted
workflow_run or base-branch job, and ensure production fern generate --docs is
gated by an explicit trusted branch or event.
---
Outside diff comments:
In `@fern/docs/pages/cuopt-python/quick-start.mdx`:
- Around line 21-24: Update the quick-start section around the
smoke_test_example.sh reference so it matches the stated usage: either embed the
complete smoke-test command and a representative example response, or reword the
text to clearly direct users to the linked script instead of claiming it can be
copied directly from the guide.
---
Major comments:
In `@build.sh`:
- Around line 462-470: Update the API documentation generation block around PY
so missing Python causes the build to fail instead of continuing to validation
or publishing. Replace bare pip installation with the selected interpreter’s
“${PY} -m pip”, and preserve dependency installation and generate_api_docs.py
execution through that same interpreter.
In `@fern/c_api_config.yaml`:
- Around line 58-64: Update the quadratic-constraint documentation note for
cuOptAddQuadraticConstraint so the standard second-order cone formula uses sum
of the squared non-leading variables bounded by x_0 squared, with x_0
nonnegative. Leave the convex and rotated second-order cone descriptions
unchanged.
In `@fern/docs/pages/convex-features.mdx`:
- Around line 61-121: The quadratic objective and constraint sections in the MDX
page are missing their formulas; restore the displayed equations for each “of
the form” statement, including convex, concave, second-order cone, and rotated
cone definitions. Replace legacy `:c\`` and `.note:` RST markup with valid
MDX/Markdown equivalents, and update the referenced example links to anchors
that exist in this page, including the generic normal/batch example.
In `@fern/docs/pages/cuopt-c/convex/convex-c-api.mdx`:
- Line 127: Update the return documentation at both affected locations to use a
status constant already listed in the public API documentation, or add
CUOPT_ERROR to that documented status-code list if it is an intended public
constant; keep the success/error return description consistent.
- Line 108: The convex C API reference is incomplete: update the four
constructor entries following “Create an optimization problem of the form” with
their optimization equations, add CUOPT_ERROR to the status-code list, and
provide descriptions for cuOptGetErrorStatus, cuOptGetErrorString, and
cuOptGetPrimalSolution. Preserve the existing reference structure and
terminology.
In `@fern/docs/pages/cuopt-c/convex/convex-examples.mdx`:
- Around line 382-406: The example must verify termination status before
accessing solution data. Mirror milp_mps_example.c by computing
has_primal_solution, conditionally calling cuOptGetObjectiveValue and
cuOptGetPrimalSolution only when true, and checking solution_values allocation
before using it; preserve the existing error handling and result output for
valid primal solutions.
In `@fern/docs/pages/cuopt-grpc/quick-start.mdx`:
- Around line 23-71: Restore the omitted executable command blocks in
fern/docs/pages/cuopt-grpc/quick-start.mdx (lines 23-71) for binary
verification, bare-metal and Docker server launch, client environment exports,
and Python/CLI example runs. Add the documented flags, TLS/mTLS and CA commands,
Docker commands, and client configuration commands in
fern/docs/pages/cuopt-grpc/advanced.mdx (lines 11-104). Add the required remote
host and port exports in fern/docs/pages/cuopt-grpc/examples.mdx (lines 5-9),
preserving the surrounding guidance and documented command behavior.
In `@fern/docs/pages/cuopt-python/convex/convex-api.mdx`:
- Line 33: Fix the API documentation renderer before regenerating this page:
resolve literal :py:meth: and :py:class: roles into proper links, preserve <= in
example blocks, render .. deprecated:: as a directive, and retain exception
names in **Raises** sections. Locate the renderer components responsible for
these generated sections, then regenerate the cuOpt Python API documentation.
In `@fern/docs/pages/cuopt-python/convex/examples/mps_example.py`:
- Around line 22-33: Update the new main function to declare an explicit None
return annotation, preserving its existing execution and output behavior.
In `@fern/docs/pages/cuopt-python/convex/examples/production_planning_example.py`:
- Around line 39-40: Update the public function main to declare its return type
as None and expand its docstring to document the return and raise contract,
following the repository’s established public-function documentation
conventions.
In `@fern/docs/pages/cuopt-python/routing/routing-api.mdx`:
- Around line 71-99: Import the routing module in both Assignment examples
before their routing.DataModel calls: update
fern/docs/pages/cuopt-python/routing/routing-api.mdx lines 71-99 and 169-201
with the same cuopt routing import. No other changes are needed.
- Around line 1201-1207: The routing API examples use the undefined variable
distances instead of the declared distance matrix. Update both affected examples
in fern/docs/pages/cuopt-python/routing/routing-api.mdx (lines 1201-1207 and
1233-1240) so add_cost_matrix uses distance in cudf.DataFrame, preserving the
rest of each example.
- Around line 1123-1128: Initialize a routing.DataModel instance before the
set_order_prizes call in the example, using the existing locations and vehicles
context as required by its constructor. Ensure data_model is defined before
cudf.Series(prizes) is passed to data_model.set_order_prizes.
- Around line 209-243: Fix the construct_rerouting_model example by closing the
service_time key string in new_order_data and passing the defined new_distances
variable instead of the undefined distances name. Keep the example’s remaining
parameters and flow unchanged so it is directly runnable.
In `@fern/docs/pages/cuopt-server/client-api/sh-cli-build.mdx`:
- Around line 17-29: Add the missing runnable server-start command and request
examples in the CLI guide section around the `/cuopt/request` documentation:
include the endpoint, required headers, a direct JSON payload example, a
file-upload example with data/result directory handling, and the asynchronous
response shape. Ensure the examples match the documented `-d` and `-r` server
options and are executable as presented.
In `@fern/docs/pages/cuopt-server/examples/lp-examples.mdx`:
- Around line 63-65: Update the aborting-job references in the LP examples,
including the occurrence around the alternate abort section, to link to the
corresponding headings in milp-examples.mdx rather than using same-page fragment
links. Preserve the existing link text and point each reference at its matching
MILP heading.
In `@fern/docs/pages/cuopt-server/examples/routing-examples.mdx`:
- Around line 19-25: Update the initial-solution documentation to accurately
describe the actual acceptance and rejection behavior, replacing the incorrect
claim that the example solution is rejected because the problem is too small.
Apply the corresponding consistency update in fern/docs/pages/faq.mdx lines
243-245; both documented locations must describe the same supported behavior.
In `@fern/docs/pages/cuopt-server/nim-operator/configuration.mdx`:
- Around line 32-34: Align the storage guidance across both documentation sites:
in fern/docs/pages/cuopt-server/nim-operator/configuration.mdx lines 32-34,
retain that persistent storage is optional when data is transferred over HTTP;
in fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx lines 39-42,
remove the unconditional storage requirement or explicitly limit it to
deployments that pass datasets through the filesystem.
- Line 46: Update the LoadBalancer guidance in the cuOpt configuration page to
replace the RST `.. note::` directive with Fern-supported MDX syntax, preferably
the `<Note>` component, while preserving the existing message.
In `@fern/docs/pages/cuopt-server/nim-operator/index.mdx`:
- Around line 9-14: Make the scaling documentation consistent across both sites:
in fern/docs/pages/cuopt-server/nim-operator/index.mdx lines 9-14, qualify
automated scaling as a generic NIM Operator capability rather than a
cuOpt-supported feature; in
fern/docs/pages/cuopt-server/nim-operator/configuration.mdx lines 46-56,
explicitly state that cuOpt currently supports only one pod and does not support
service scaling.
In `@fern/docs/pages/cuopt-server/nim-operator/prerequisites.mdx`:
- Around line 87-94: Update the NGC API key prerequisite check in the deployment
verification list to avoid printing the secret. Replace the echo command with a
non-disclosing presence check using NGC_API_KEY that succeeds only when the
variable is set and non-empty.
In `@fern/docs/pages/cuopt-server/quick-start.mdx`:
- Around line 17-60: The migration removed required documentation content across
multiple cuOpt pages; restore the omitted commands, outputs, references,
configuration values, manifests, and examples. Update
fern/docs/pages/cuopt-server/quick-start.mdx (17-60) with container and
smoke-test commands; examples/routing-examples.mdx (13-49) with response and
HTTPS examples; nim-operator/configuration.mdx (22-80) with configuration values
and manifests; deployment.mdx (7-75) with deployment, verification, and testing
commands; index.mdx (32-44) with quick-start commands and navigation;
prerequisites.mdx (25-68) with installation and verification commands;
server-api/index.mdx (5) with API navigation/content; server-cli.mdx (5) with
the CLI reference; and faq.mdx (102-108, 125-165, 195-200, 439-449) with the
troubleshooting commands and examples.
In `@fern/docs/pages/faq.mdx`:
- Around line 222-225: Resolve the conflicting capacity statements in the cuOpt
resource-estimates FAQ by aligning the 15K-location claim with the later H100
SXM 10,000-location maximum. Clarify the workload or hardware assumptions for
each estimate, or replace the figures with one consistent, explicitly qualified
capacity statement.
In `@fern/docs/pages/system-requirements.mdx`:
- Around line 62-68: Update the CUDA 12.9 entry in the “CUDA & NVIDIA Driver
combinations” list to require Linux driver 575.51.03 or newer instead of
570.42.01, leaving the other version requirements unchanged.
In `@fern/docs/scripts/install-selector.css`:
- Around line 6-8: Update the copy-button color variables around
--cuopt-nvidia-green and its hover/active variants so the button background
provides sufficient contrast with its white text, meeting at least WCAG 4.5:1
for normal text across all interactive states.
In `@fern/docs/scripts/install-selector.js`:
- Around line 201-206: Update the fallback logic around `cudaKey`,
`fallbackKey`, and `data[release]` so selecting CUDA 12 with the `ubi10` variant
never resolves to `cu13-ubi10`. Treat that combination as unsupported or require
an explicit CUDA 13 selection, while preserving valid image resolution for other
CUDA and variant combinations.
In `@fern/embed_examples.py`:
- Around line 90-103: Update the existing embed-marker handling around _OPEN_RE
and _CLOSE so it detects when the closing marker is not found before EOF, raises
an error, and aborts before modifying or writing the MDX output; only skip and
replace the block when _CLOSE is present.
In `@fern/extract_python_api.py`:
- Around line 438-441: Update the content transformation after joining lines so
the <= replacement applies only outside fenced code blocks. Preserve operators
inside fenced regions unchanged while continuing to escape them in prose/MDX
text, then write the selectively transformed content through the existing
dest.write_text call.
In `@fern/generate_api_docs.py`:
- Around line 88-90: Make documentation generation fail closed: in
fern/generate_api_docs.py around the OpenAPI/version generation exception
handler, re-raise the failure after reporting it; in fern/extract_c_api.py
around the Doxygen XML parsing handler, propagate any file parse error instead
of continuing; and in fern/extract_python_api.py around module parsing, fail on
unparsable modules rather than treating them as empty.
In `@fern/openapi/cuopt_spec.yaml`:
- Around line 3797-3801: Update every response schema property referencing
DroppedTasks, including dropped_tasks, to use an object default ({}) or remove
the default instead of [] while preserving the DroppedTasks schema type. Correct
the third vehicle_breaks example by adding the required locations field, unless
the schema is intentionally changed to make locations optional.
---
Minor comments:
In `@fern/c_api_config.yaml`:
- Around line 27-30: Update the “Status Codes” intro in c_api_config.yaml to
qualify that status codes apply only to fallible or status-returning C API
functions, excluding generated destroy functions with no return value.
- Line 8: Update both MIP C API link references in the relevant documentation to
use the sibling-directory target ../mip/mip-c-api instead of mip-c-api, then
regenerate the affected page.
In `@fern/docs-v26-08.yml`:
- Around line 1-200: Update the release-version configuration associated with
docs-v26-08 so the documentation site continues to use 26.06 as the Latest
version until launch. Do not promote 26.08 in the Latest pointer; preserve the
existing 26.08 documentation navigation content.
In `@fern/docs/pages/convex-features.mdx`:
- Line 69: Update the links in the convex features documentation: replace the
broken Python and C anchors with the specified cuOpt page paths and anchors, and
update the self-hosted references near the “simple-qp” examples to target the
cuOpt server LP examples page and its generic normal/batch mode anchor.
In `@fern/docs/pages/convex-settings.mdx`:
- Around line 144-146: Update the “Save Best Primal So Far” section for
CUOPT_SAVE_BEST_PRIMAL_SOLUTION by adding a paragraph before the four conditions
and converting the escaped asterisks into Markdown bullet items. Preserve the
existing condition text and ensure Fern renders four separate list entries.
- Around line 172-178: The precision documentation has contradictory default
values: the `default` mode is defined as `-1`, but the Note says the default is
`0` (`single`). Update the Note to state `-1` and consistently identify it as
the default precision mode.
In `@fern/docs/pages/cuopt-c/convex/convex-c-api.mdx`:
- Around line 809-819: Update the source comments for cuOptGetErrorStatus,
cuOptGetErrorString, and cuOptGetPrimalSolution so their generated API
documentation includes behavior descriptions, parameter documentation, and
return-value documentation; keep the existing signatures unchanged.
In `@fern/docs/pages/cuopt-c/convex/convex-examples.mdx`:
- Line 1119: Update the Convex Features links in the affected documentation
entries to use the correct relative target ../../convex-features from this
directory, including both occurrences, while preserving the surrounding text.
In `@fern/docs/pages/cuopt-c/convex/examples/general_quadratic_example.c`:
- Around line 167-170: In general_quadratic_example.c at lines 167-170, set
main()’s status to a non-success value before jumping to DONE when
solution_values allocation fails. In lp_file_example.c at lines 139-140 and
mps_file_example.c at lines 148-149, check solution_values for NULL before
calling cuOptGetPrimalSolution and set the failure status before cleanup,
preserving the existing success path for valid allocations.
In `@fern/docs/pages/cuopt-c/convex/examples/Makefile`:
- Around line 59-69: Update the Makefile’s pattern rule for executable targets
so every compilation target also depends on the check-paths validation target,
ensuring direct builds and parallel builds wait for check-paths before invoking
the compiler. Preserve the existing build commands and all target behavior.
- Around line 37-39: Update the commented INCLUDE_PATH and LIBCUOPT_LIBRARY_PATH
examples in the Makefile to use repository-relative paths that correctly reach
the root-level cpp directory from this examples directory, while preserving the
existing local-build guidance.
In `@fern/docs/pages/cuopt-c/convex/examples/simple_lp_example.c`:
- Around line 190-193: Set status to CUOPT_OUT_OF_MEMORY before each
solution-buffer allocation failure jumps to DONE, preserving the error status
for main: fern/docs/pages/cuopt-c/convex/examples/simple_lp_example.c:190-193,
simple_qp_example.c:183-186, and simple_socp_example.c:167-170. Apply the same
fix to the rotated-SOCP and general-quadratic embedded sources at
fern/docs/pages/cuopt-c/convex/convex-examples.mdx:1285-1288 and 1498-1501, and
the simple-MILP source at fern/docs/pages/cuopt-c/mip/mip-examples.mdx:190-193,
then regenerate the embedded examples.
In `@fern/docs/pages/cuopt-cli/quick-start.mdx`:
- Around line 11-15: Restore the missing CLI workflow snippets: in
fern/docs/pages/cuopt-cli/quick-start.mdx:11-15, add the cuopt_cli --help
command beneath the introduction; in
fern/docs/pages/cuopt-cli/cli-examples.mdx:16-34, add the commands and
representative output blocks for the documented examples, or remove claims that
output follows if no output is shown.
In `@fern/docs/pages/cuopt-python/convex/convex-examples.mdx`:
- Line 84: Remove or populate the empty generated-output placeholders: in
fern/docs/pages/cuopt-python/convex/convex-examples.mdx at lines 84-84, populate
or remove every repeated “response is as follows” section; in
fern/docs/pages/cuopt-python/mip/mip-examples.mdx at lines 84-84, populate or
remove all three empty response sections; and in
fern/docs/pages/cuopt-python/routing/routing-examples.mdx at lines 308-308, add
the promised batch sample output or remove its heading.
- Line 285: Update the “Convex Features” link in the rotated second-order cone
example to target the root feature page at the correct relative path, rather
than resolving under cuopt-python/convex. Keep the link text and surrounding
explanation unchanged.
In `@fern/docs/pages/cuopt-python/convex/examples/pdlp_warmstart_example.py`:
- Around line 54-55: Update the public main() entrypoint with a -> None return
annotation and expand its docstring to describe its behavior, including that it
returns None and which relevant errors may propagate. Keep the documentation
aligned with the function’s actual parameters and execution flow.
In `@fern/docs/pages/cuopt-python/convex/examples/qp_matrix_example.py`:
- Line 30: Annotate the public main entry points with explicit None return
types: update main in
fern/docs/pages/cuopt-python/convex/examples/qp_matrix_example.py at lines 30-30
and main in fern/docs/pages/cuopt-python/convex/examples/simple_socp_example.py
at lines 30-30 to include -> None.
In `@fern/docs/pages/cuopt-python/convex/examples/simple_lp_example.py`:
- Around line 32-33: Update the simple LP example’s main function to annotate a
None return type and expand its docstring to explicitly document that it returns
None.
In `@fern/docs/pages/cuopt-python/mip/examples/incumbent_solutions_example.py`:
- Around line 46-62: Update IncumbentCallback.__init__ and get_solution with
type annotations matching the GetSolutionCallback contract, including the
callback inputs and None return type. Expand the IncumbentCallback class
docstring to document the constructor arguments and state that get_solution
returns None.
In `@fern/docs/pages/cuopt-python/mip/mip-api.mdx`:
- Line 5: Update the MIP API page to reference the shared linear-programming API
documentation instead of rendering the empty API placeholder. Configure the page
to use the existing linear-programming reference and preserve the intended MIP
API symbols if they are defined there.
In `@fern/docs/pages/cuopt-server/csp-guides/csp-aws.mdx`:
- Around line 41-43: Update the self-hosted quickstart links in
fern/docs/pages/cuopt-server/csp-guides/csp-aws.mdx (lines 41-43) and
fern/docs/pages/cuopt-server/csp-guides/csp-azure.mdx (lines 47-49) to target
the “Container from NVIDIA NGC” heading in
fern/docs/pages/cuopt-server/quick-start.mdx, replacing the fragment-only
anchors with the correct page-relative link.
In `@fern/docs/pages/cuopt-server/examples/lp-examples.mdx`:
- Line 15: Correct the heading text in the LP examples documentation from
“Genric” to “Generic,” leaving the rest of the heading unchanged.
In `@fern/docs/pages/cuopt-server/nim-operator/index.mdx`:
- Line 30: Fix the broken documentation links across all listed sites: in
fern/docs/pages/cuopt-server/nim-operator/index.mdx lines 30-30, link to
prerequisites; in deployment.mdx lines 104-106, link to configuration; in
prerequisites.mdx lines 96-98, link to deployment; in
examples/routing-examples.mdx lines 53-75, link to the actual aborting sections
or pages; and in faq.mdx lines 343-375, link to convex-features#batch-mode.
In `@fern/docs/pages/introduction.mdx`:
- Line 63: Correct the spelling of “perfomed” to “performed” in the PDLP
description while leaving the rest of the text unchanged.
In `@fern/docs/pages/license.mdx`:
- Around line 1-3: Update the license page front matter section so the page
includes the applicable cuOpt license terms or a link to the canonical license
material, rather than only displaying the “cuOpt License” title. Preserve the
existing page title and ensure the published content is accessible from this
page.
In `@fern/docs/pages/milp-features.mdx`:
- Around line 53-65: Update both the “Incumbent Example” and “Logging Callback
Example” links in the MILP features documentation to target
cuopt-server/examples/milp-examples#incumbent-and-logging-callback instead of
resolving against milp-features.mdx.
In `@fern/docs/pages/routing-features.mdx`:
- Around line 34-37: Update the time-window note near the “All time windows”
statement to make the UTC January 1970–2038 conversion conditional on values
being Unix seconds. Clarify that for minutes or other caller-selected units, the
int32 range remains [0, 2^31-1] in that chosen unit.
In `@fern/openapi/cuopt_spec.yaml`:
- Around line 2037-2043: Update the third vehicle_breaks example entry in both
example blocks to include the required locations field, using null or a valid
list consistent with the surrounding example data.
In `@README.md`:
- Around line 56-82: Update the Fern documentation instructions to accurately
describe ./build.sh docs: API documentation generation, fern check, and fern
generate --docs or --preview, without claiming it starts a localhost:3000
server. Replace the CI workflow reference with ci/build_docs.sh, and align the
surrounding CI/publishing description with the implemented pipeline.
---
Nitpick comments:
In `@fern/docs/pages/cuopt-c/convex/examples/simple_qp_example.c`:
- Around line 118-134: Update the simple QP example to use the non-deprecated
cuOptCreateProblem flow, then apply the quadratic objective through
cuOptSetQuadraticObjective instead of calling cuOptCreateQuadraticProblem.
Regenerate the embedded MDX so the documented example matches the updated source
and stated API usage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| rapids-logger "Generate dynamic API docs (OpenAPI spec, Python API, C API)" | ||
| python fern/generate_api_docs.py | ||
|
|
||
| rapids-logger "Validate docs (fern check)" | ||
| fern check | ||
|
|
||
| if [[ "${RAPIDS_BUILD_TYPE:-branch}" == "pull-request" ]]; then | ||
| rapids-logger "Publishing Fern preview for PR review" | ||
| fern generate --docs --preview | ||
| else | ||
| rapids-logger "Publishing Fern docs to production" | ||
| fern generate --docs | ||
| fi |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## File map"
git ls-files 'ci/build_docs.sh' 'ci/*' 'pr.yaml' 'build.yaml' | sed 's#^`#-` #'
echo
echo "## Outline of relevant files"
for f in ci/build_docs.sh pr.yaml build.yaml; do
if [[ -f "$f" ]]; then
echo "### $f"
wc -l "$f"
sed -n '1,220p' "$f" | cat -n
echo
fi
done
echo "## Search for Fern and related gating"
rg -n --hidden --no-ignore-vcs -S 'FERN_TOKEN|fern generate|fern check|workflow_run|pull-request|branch|build_docs\.sh|generate_api_docs\.py' ci pr.yaml build.yaml .github 2>/dev/null || trueRepository: NVIDIA/cuopt
Length of output: 24037
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "## Relevant workflow files"
fd -a -t f 'build.yaml|pr.yaml|build_docs.sh' . ci .github 2>/dev/null || true
echo
echo "## Search for CI invocations and secrets"
rg -n -S 'build_docs\.sh|FERN_TOKEN|fern generate|fern check|workflow_run|pull_request|pull-request|secrets\.' ci .github pr.yaml build.yaml 2>/dev/null || trueRepository: NVIDIA/cuopt
Length of output: 12462
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for f in ci/build_docs.sh pr.yaml build.yaml; do
if [[ -f "$f" ]]; then
echo "### $f"
nl -ba "$f" | sed -n '1,220p'
echo
fi
doneRepository: NVIDIA/cuopt
Length of output: 211
🌐 Web query:
RAPIDS ci pr.yaml build.yaml RAPIDS_BUILD_TYPE Fern docs build_docs.sh
💡 Result:
In the RAPIDS ecosystem, pr.yaml and build.yaml serve as the primary GitHub Actions workflow entry points, managing CI jobs for pull requests and main/release branches respectively [1]. These workflows orchestrate build processes by invoking various CI scripts, such as those located in the ci/ directory, and by utilizing standardized shared workflows [2][3][4][5]. Key components related to your query include: RAPIDS_BUILD_TYPE: This environment variable is used to specify the context of a build, typically taking values such as branch, nightly, or pull-request [3][6]. It is passed into CI jobs to configure build parameters, artifact handling, and other environment-specific logic [2][3]. Fern and Documentation Builds: RAPIDS has been migrating its documentation infrastructure from Sphinx to Fern [7][8]. This transition involves the following key components: fern/build_docs.sh: A wrapper script introduced to handle Fern-based documentation workflows, supporting modes such as check, preview, publish, and dev [7][8]. It manages the generation of API references and runs validation checks (e.g., fern check) [7][9]. ci/build_docs.sh: While previously used to run Sphinx-based documentation builds [5][10], this script has been updated in many repositories to integrate with or be replaced by the Fern-based documentation flow, ensuring documentation is correctly built and validated during CI [7][8]. build.sh: A local build script often updated to set relevant environment variables (like FERN_DOCS_DIR) and invoke fern/build_docs.sh [7][8][11]. These components together enable a standardized, reproducible CI process where documentation validation and builds are integrated alongside code builds and testing [7][8][12].
Citations:
- 1: https://docs.rapids.ai/resources/github-actions/
- 2: https://github.com/rapidsai/shared-workflows/blob/b5de46f0bb78115af9a4c80645faad3bb72b12be/.github/workflows/conda-cpp-build.yaml
- 3: https://github.com/rapidsai/rmm/blob/main/.github/workflows/build.yaml
- 4: https://github.com/rapidsai/rapids-cli/blob/cc9c97ab38fe6844028c7b473d3ecbfbc538b446/.github/workflows/pr.yaml
- 5: https://github.com/rapidsai/rmm/blob/branch-23.12/.github/workflows/pr.yaml
- 6: https://github.com/rapidsai/cudf/blob/cc699204bc43a03f18b86d2a105eb6ef27c534d5/.github/workflows/build.yaml
- 7: [Docs] Convert Sphinx docs to Fern cuvs#2067
- 8: [Docs] Convert Sphinx docs to Fern rapidsai/rmm#2411
- 9: https://docs.nvidia.com/cuvs/installation
- 10: https://github.com/EMinsight/cudf/blob/99b580cf2265d975f472efa4b3cc9c15b2ae18ba/ci/build_docs.sh
- 11: https://github.com/rapidsai/cuvs/blob/main/build.sh
- 12: https://docs.rapids.ai/resources/reproducing-ci/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for f in .github/workflows/build.yaml .github/workflows/pr.yaml; do
echo "### $f"
sed -n '200,260p' "$f" | cat -n
echo
done
echo "### build.yaml docs-related context"
sed -n '210,245p' .github/workflows/build.yaml | cat -n
echo "### pr.yaml docs-related context"
sed -n '425,450p' .github/workflows/pr.yaml | cat -nRepository: NVIDIA/cuopt
Length of output: 8248
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "### build.yaml trigger + top-level permissions"
sed -n '1,120p' .github/workflows/build.yaml | cat -n
echo
echo "### pr.yaml trigger + top-level permissions"
sed -n '1,120p' .github/workflows/pr.yaml | cat -nRepository: NVIDIA/cuopt
Length of output: 10198
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "### build.yaml docs job"
sed -n '215,235p' .github/workflows/build.yaml | cat -n
echo
echo "### pr.yaml docs job"
sed -n '432,446p' .github/workflows/pr.yaml | cat -nRepository: NVIDIA/cuopt
Length of output: 1686
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -S 'FERN_TOKEN|fern-api|fern config|fern/fern.config.json|preview|publish.*Fern|Fern preview|Fern docs' .github/workflows ci . 2>/dev/null || trueRepository: NVIDIA/cuopt
Length of output: 3145
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for f in .github/workflows/build.yaml .github/workflows/pr.yaml; do
echo "### $f"
awk 'NR>=210 && NR<=245 {printf "%4d %s\n", NR, $0}' "$f"
echo
doneRepository: NVIDIA/cuopt
Length of output: 3249
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "### build.yaml: trigger + permissions"
awk 'NR>=1 && NR<=80 {printf "%4d %s\n", NR, $0}' .github/workflows/build.yaml
echo
echo "### pr.yaml: trigger + permissions"
awk 'NR>=1 && NR<=90 {printf "%4d %s\n", NR, $0}' .github/workflows/pr.yamlRepository: NVIDIA/cuopt
Length of output: 7067
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "### workflow_run / Fern docs references"
rg -n -S 'workflow_run|FERN_TOKEN|Fern preview|publish.*Fern|buildwithfern|preview' .github/workflows README.md build.sh ci/build_docs.sh fern 2>/dev/null || true
echo
echo "### README docs section"
awk 'NR>=24 && NR<=90 {printf "%4d %s\n", NR, $0}' README.mdRepository: NVIDIA/cuopt
Length of output: 5200
Separate Fern generation from secret-bearing publish jobs. .github/workflows/build.yaml and .github/workflows/pr.yaml call ci/build_docs.sh with secrets: inherit, so fern/generate_api_docs.py runs with repository secrets available. Keep generation secretless and run fern generate --docs --preview from a trusted workflow_run/base-branch job; gate production publishing on an explicit trusted branch/event too.
🤖 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 `@ci/build_docs.sh` around lines 40 - 52, Update ci/build_docs.sh so
fern/generate_api_docs.py and fern check run without repository secrets, and
remove Fern publishing from this secret-bearing script. Move fern generate
--docs --preview into a trusted workflow_run or base-branch job, and ensure
production fern generate --docs is gated by an explicit trusted branch or event.
Sources: Coding guidelines, Path instructions
|
Superseded by #1582 which implements the custom AST-based generator approach instead of the Fern native |
Migrates cuOpt documentation from Sphinx/RST to the Fern platform. MDX pages in `fern/` are now the source of truth and edited directly.
What's included
Before going to production