Problem
The three Helm stacks under deploy/stacks/ (self-managed, nvcf-compute-plane, observability) were level-set to 1.0.0 and now release independently from release-deploy/stacks/<stack>/vX.Y branches (#1959, #1963, #1965). The documentation model has not caught up:
- The Fern site has a single global version dropdown. Each published docs version is a QA-qualified tuple of all three stack versions (
cp-X-compute-Y-obs-Z), so releasing docs for one stack requires qualifying all three together.
- Every docs version is a full deep copy of
docs/user/ (about 90 pages). Cutting observability docs copies the self-managed and compute-plane pages too, even when they did not change.
- There is no compatibility matrix. The only cross-stack version statement is a three-row "Stack release set" table in
manifest.md.
tools/docs-version-sync still models a single qualified release set (--qualification-version cp-X-compute-Y-obs-Z) and its README describes the retired semver-on-main release flow.
check-doc-version-sync is not wired into any GitHub workflow.
Goal
One docs site with a version dropdown per stack, an always-current compatibility matrix, per-stack frozen copies, and no joint qualification gate.
Design
Use Fern products:. The hierarchy is Products -> Versions -> Tabs -> Navigation; each product carries its own independent versions: list, and versioned and unversioned products may coexist. Verified with fern check on Fern CLI 5.38.0 (the pinned version).
Products:
| Product |
Slug |
Versioned |
Source tree |
| Overview |
overview |
no |
docs/overview/ |
| Self-Managed Stack |
self-managed |
yes |
docs/self-managed/ (dev), docs/self-managed-<train>/ (frozen) |
| Compute Plane Stack |
compute-plane |
yes |
docs/compute-plane/ (dev), docs/compute-plane-<train>/ (frozen) |
| Observability Stack |
observability |
yes |
docs/observability/ (dev), docs/observability-<train>/ (frozen) |
URL shapes: /nvcf/overview/..., /nvcf/<stack>/... (default version), /nvcf/<stack>/<train>/....
Overview holds the compatibility matrix, quickstart, infrastructure sizing, manifest, image mirroring, release-notes index, local development, development docs, and the legacy NGC-managed section. Legacy full-tree versions (0.5, 0.6.0, 0.6.1, cp-0.20.6-compute-0.4.4-obs-0.2.2) attach to the Self-Managed product with a "legacy" label; their trees are not modified.
A page belongs to exactly one product. Cross-product links use absolute site paths because Fern resolves relative links against the rendering product.
Work items (single PR)
- Docs tree split. Move
docs/user/ into docs/overview/, docs/self-managed/, docs/compute-plane/, docs/observability/. Rewrite cross-product links to absolute paths. Add docs/overview/compatibility-matrix.md with a generated block.
- Fern. Replace
versions: in fern/docs.yml with products:. Move version navigation files to fern/products/<product>/<version>.yml. Add redirects for every moved slug and for legacy version prefixes. fern check must pass with broken-links: error.
- docs-version-sync. Allow generated outputs under the four product trees. Add a
compatibility: catalog block and a compatibility-matrix renderer that emits stack versions, source tags, docs versions, and declared compatible ranges. Replace --qualification-version with per-stack freeze inputs. Update tools/scripts/cut-docs-version.sh to --stack <name> --train <X.Y>, copying only that stack's tree. Fix the README release-flow section. Add tests.
- CI. Run
tools/ci/check-doc-version-sync in fern-docs-ci.yml as a blocking check.
- Stack inventory continuity. Add a
test-github-release.py case proving a tag pushed from a release branch resolves the same publisher and resolved_inventory_asset as before. No behavior change expected; attachment is keyed by tag.
- Policy docs.
RELEASE.md, docs/dev/github-release-process.md, deploy/stacks/AGENTS.md, docs/AGENTS.md: the 1.0.0 level-set, independent trains, the N and N-1 support window as the upgrade-stop rule, and the per-stack docs cut.
Out of scope
- Cutting the first
1.1 frozen docs per stack (follows once each train has a release branch).
- Build-time assembly of frozen docs from release branches instead of committed copies.
- Renaming or re-tagging existing stack releases.
Acceptance
fern check passes.
go test ./... in tools/docs-version-sync passes; tools/ci/check-doc-version-sync passes on the branch.
python3 tools/ci/test-github-release.py passes.
- Preview build shows four products, with independent version dropdowns on the three stack products.
Problem
The three Helm stacks under
deploy/stacks/(self-managed,nvcf-compute-plane,observability) were level-set to 1.0.0 and now release independently fromrelease-deploy/stacks/<stack>/vX.Ybranches (#1959, #1963, #1965). The documentation model has not caught up:cp-X-compute-Y-obs-Z), so releasing docs for one stack requires qualifying all three together.docs/user/(about 90 pages). Cutting observability docs copies the self-managed and compute-plane pages too, even when they did not change.manifest.md.tools/docs-version-syncstill models a single qualified release set (--qualification-version cp-X-compute-Y-obs-Z) and its README describes the retired semver-on-main release flow.check-doc-version-syncis not wired into any GitHub workflow.Goal
One docs site with a version dropdown per stack, an always-current compatibility matrix, per-stack frozen copies, and no joint qualification gate.
Design
Use Fern
products:. The hierarchy is Products -> Versions -> Tabs -> Navigation; each product carries its own independentversions:list, and versioned and unversioned products may coexist. Verified withfern checkon Fern CLI 5.38.0 (the pinned version).Products:
overviewdocs/overview/self-manageddocs/self-managed/(dev),docs/self-managed-<train>/(frozen)compute-planedocs/compute-plane/(dev),docs/compute-plane-<train>/(frozen)observabilitydocs/observability/(dev),docs/observability-<train>/(frozen)URL shapes:
/nvcf/overview/...,/nvcf/<stack>/...(default version),/nvcf/<stack>/<train>/....Overview holds the compatibility matrix, quickstart, infrastructure sizing, manifest, image mirroring, release-notes index, local development, development docs, and the legacy NGC-managed section. Legacy full-tree versions (
0.5,0.6.0,0.6.1,cp-0.20.6-compute-0.4.4-obs-0.2.2) attach to the Self-Managed product with a "legacy" label; their trees are not modified.A page belongs to exactly one product. Cross-product links use absolute site paths because Fern resolves relative links against the rendering product.
Work items (single PR)
docs/user/intodocs/overview/,docs/self-managed/,docs/compute-plane/,docs/observability/. Rewrite cross-product links to absolute paths. Adddocs/overview/compatibility-matrix.mdwith a generated block.versions:infern/docs.ymlwithproducts:. Move version navigation files tofern/products/<product>/<version>.yml. Add redirects for every moved slug and for legacy version prefixes.fern checkmust pass withbroken-links: error.compatibility:catalog block and acompatibility-matrixrenderer that emits stack versions, source tags, docs versions, and declared compatible ranges. Replace--qualification-versionwith per-stack freeze inputs. Updatetools/scripts/cut-docs-version.shto--stack <name> --train <X.Y>, copying only that stack's tree. Fix the README release-flow section. Add tests.tools/ci/check-doc-version-syncinfern-docs-ci.ymlas a blocking check.test-github-release.pycase proving a tag pushed from a release branch resolves the same publisher andresolved_inventory_assetas before. No behavior change expected; attachment is keyed by tag.RELEASE.md,docs/dev/github-release-process.md,deploy/stacks/AGENTS.md,docs/AGENTS.md: the 1.0.0 level-set, independent trains, the N and N-1 support window as the upgrade-stop rule, and the per-stack docs cut.Out of scope
1.1frozen docs per stack (follows once each train has a release branch).Acceptance
fern checkpasses.go test ./...intools/docs-version-syncpasses;tools/ci/check-doc-version-syncpasses on the branch.python3 tools/ci/test-github-release.pypasses.