docs: clean up nav-validator and redirect-lint baselined violations#21845
Merged
Conversation
Two deterministic lint scripts in docs/public-docs/scripts/lint/ make docs.json navigation and redirects CI-guarded artifacts (Option A slice 2 of the canonical-homes docs plan): - validate-nav.ts: every .mdx on disk is in nav or allowlisted with a reason; no duplicate nav entries; no nav entries without a file. - validate-redirects.ts: a page deleted or moved in a PR must gain a redirect in the same PR; no chained redirects; no dead redirect targets; no duplicate redirect sources; no redirect source shadowing a live page; no dead internal links. CI wiring follows the shell-check precedent: docs-lint runs in the main workflow and gates merge via ci-gate's terminal requires; the docs-only fast path runs the same job inside ci-gate-skip, whose ci-gate now verifies it instead of always succeeding. Pre-existing violations on develop (11 orphans, 1 duplicate nav entry, 1 shadowed redirect source, 24 dead internal links) are grandfathered in committed shrink-only allowlist/baseline files, so the checks pass on current develop and block only NEW violations; the cleanup lands as a follow-up PR. Tracks ethereum-optimism/solutions#955 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBBBR8m2V8LjzMvuG7Go2L
Fixes the pre-existing nav/redirect violations grandfathered when the guardrails were introduced, and prunes their allowlist/baseline entries in the same PR (stale entries are lint errors by design): - Re-home 4 orphans into the nav: op-stack/features/preinstalls and op-stack/features/experimental/alt-da-mode (OP Stack > Features), node-operators/tutorials/node-from-docker-simple-optimism-node (Node Operators > Archive, alongside the other op-geth-era pages), rust/kona/glossary (Kona - Introduction). - Delete 5 superseded pages, each covered by a redirect in this tree: op-deployer usage/upgrade stub (redirect to the deprecation notice already existed; also resolves the shadowed redirect source), rust/kona/run (superseded by rust/kona/node/run/*), rust/kona/sdk/fpp-dev/io (empty title-only stub), and the two stale op-reth CLI pages for the renamed db settings set receipts/transaction_senders subcommands. - Remove the duplicate rust/op-reth/cli/op-reth nav entry. - Keep sequencer-defined-metering allowlisted as deliberately hidden (frontmatter hidden: true, feature not yet live) and code-setup allowlisted pending the Option C slice C1 tutorial-repair PR. Tracks ethereum-optimism/solutions#955 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBBBR8m2V8LjzMvuG7Go2L
Both docs-lint invocations (main workflow and ci-gate-skip) were bare, unlike every other checkout-with-mise job in this file. Follow the contracts-bedrock-tests-heavy-fuzz-modified precedent for jobs that diff against origin/develop and attach circleci-repo-readonly-authenticated- github-token to both, so mise tool installs and any GitHub API access run authenticated instead of anonymously rate-limited. No fetch step is needed: the blobless checkout is a full-ref clone (git clone --filter=blob:none), and the redirect lint's merge-base against origin/develop already resolved on this PR's own pipeline. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBBBR8m2V8LjzMvuG7Go2L
Wiz SAST flagged the path.join/path.resolve uses in the docs lint scripts as potential CWE-22 path traversal. All inputs are repo-controlled (docs.json, committed baseline files, directory walks), but add cheap containment hardening anyway: a shared resolveInside() helper resolves each candidate path and verifies the result stays inside the docs root before any fs call. Escaping paths are reported (lint error for the link-scan read, setup error for fixed config files, skip for walk entries) instead of read. Dependency-free and behavior-identical for all legitimate inputs; both lints still pass under bun and tsx, and a synthetic dead-link violation still fails the redirect lint. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBBBR8m2V8LjzMvuG7Go2L
Contributor
Author
|
The |
5 tasks
Revert all .circleci changes to the merge-base state per reviewer feedback (CI config is a shared hotspot). The nav validator and redirect lint scripts stay; enforcement moves to a Mintlify automation (review-gated content-update trigger) plus local runs documented in DOCS_CONTRIBUTING.md. Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # docs/public-docs/scripts/lint/nav-allowlist.json # docs/public-docs/scripts/lint/redirect-lint-baseline.json
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
sbvegan
previously approved these changes
Jul 17, 2026
sbvegan
reviewed
Jul 17, 2026
sbvegan
left a comment
Contributor
There was a problem hiding this comment.
While we're doing this, let's clear out all these archived pages in this section
Removes the Node Operators Archive nav group and deletes its five pages (op-geth-config, op-geth-json-rpc, node-from-docker-simple-optimism-node, management/snap-sync, features/snap-sync). Each removed URL gets a redirect to its nearest live equivalent, and all inbound links now point at the redirect targets directly. Co-Authored-By: Claude
sbvegan
approved these changes
Jul 17, 2026
sbvegan
approved these changes
Jul 17, 2026
sbvegan
approved these changes
Jul 17, 2026
claude Bot
pushed a commit
that referenced
this pull request
Jul 17, 2026
Merge-skew resolution alongside the #21845 lint tooling/cleanup now on develop: - nav-allowlist.json: remove the create-l2-rollup/code-setup orphan entry — this branch nav-lists the page, so the allowlist handoff entry is now covered - redirect-lint-baseline.json: prune two dead-link entries (troubleshooting.mdx -> op-reth-setup, index.mdx -> create-l2-rollup) that this branch's tutorial repair turned into live links - docs.json: drop the /app-developers/quickstarts/get-started -> interop redirect that shadowed the live quickstart page this branch re-created Both lints pass: validate-nav.ts, validate-redirects.ts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBBBR8m2V8LjzMvuG7Go2L
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Matthew Cruz · Slack thread
What / why
The cleanup half of Option A slice 2 (CI guardrails) of the canonical-homes plan: fixes the nav/redirect violations that were grandfathered when the validators landed, and prunes the corresponding allowlist/baseline entries in the same PR (stale entries are lint errors by design).
The validator tooling merged as #21843. This PR now sits directly on
develop, and the diff is cleanup-only: grandfather-file prunes, nav re-homes, and 5 page deletions with redirect coverage.docs.json lane: this PR holds the docs.json nav/redirects serialization slot; both predecessors in the lane (#21841, #21843) have merged, so there is no remaining merge-order constraint.
Tracks ethereum-optimism/solutions#955
Before / After
rust/op-reth/cli/op-reth)/chain-operators/tools/op-deployer/usage/upgrade)lint:nav/lint:redirectsOrphans re-homed into the nav (4)
op-stack/features/preinstalls→ OP Stack > Features (two live redirects already point at this page)op-stack/features/experimental/alt-da-mode→ OP Stack > Features (a live redirect points at it)node-operators/tutorials/node-from-docker-simple-optimism-node→ Node Operators > Archive, alongside the other op-geth-era pages — the page's own warning says simple-optimism-node defaults to end-of-support op-geth and steers new deployments to the docker-compose tutorialrust/kona/glossary→ Rust > Kona - Introduction (6 live kona pages deep-link its anchors)Orphans deleted, with redirect coverage in this tree (5 pages / 4 redirects)
chain-operators/tools/op-deployer/usage/upgrade.mdx— a 12-line stub whose entire content is a warning pointing at/notices/op-deployer-upgrade-deprecation; the redirect to that notice already existed (it was the shadowed-source violation — one deletion resolves both findings, keep-redirect-drop-page)rust/kona/run.mdx— older, shorter duplicate of therust/kona/node/run/*chapter, zero inbound links → new redirect to/rust/kona/node/run/overviewrust/kona/sdk/fpp-dev/io.mdx— empty title-only stub, zero inbound links → new redirect to/rust/kona/sdk/fpp-dev/introrust/op-reth/cli/op-reth/db/settings/set/receipts_in_static_files.mdxand..._transaction_senders_in_static_files.mdx— stale generated pages for the since-renamedreceipts/transaction_senderssubcommands (the renamed pages are on disk and in the nav); new redirects to the renamed pagesDuplicate nav entry (1)
rust/op-reth/cli/op-rethentry directly under "op-reth - CLI Reference"; the page keeps its home as the first entry of the nestedop-rethgroup.Remaining allowlist entries (2, both with terminal reasons — not grandfathered violations)
chain-operators/tutorials/create-l2-rollup/code-setup— handed off to Option C slice C1 (homepage router / flagship-tutorial repair), which owns re-homing it; the C1 PR removes the entry when its nav fix lands.chain-operators/guides/features/sequencer-defined-metering— kept out of the nav deliberately: the page carrieshidden: truefrontmatter and documents a feature that is not yet live (expected with the Lagoon hardfork). Nav-listing it would announce an unshipped feature; the allowlist reason says to add it to Chain Operators > Guides > Features when the feature ships. This is the one deviation from "empty allowlist" — flagged for reviewer judgment.Dead internal links: left baselined on purpose
The 24 baselined dead internal links (19 files) are not touched here: they are content-level link repairs that belong to the Option B slice B2 cross-repo link policy + mechanical sweep, which is held until the B2 linter PR merges. Fixing them piecemeal here would collide with that sweep and bloat this docs.json-lane PR.
Verification
pnpm lint:nav— OK: 398 pages on disk, 396 distinct nav entries, 2 allowlisted orphanspnpm lint:redirects— OK: 465 redirects, 402 files scanned, 22 grandfathered violations remaining (all dead-link baseline)docs.jsonparses; every nav entry maps to a file on disk (validator check N2)Reviewer checklist
sequencer-defined-meteringhidden-by-design is the right callMore context: projects/docs-improver/README.md
🤖 Drafted by the docs-improver agent — review before merge.
🤖 Generated with Claude Code
https://claude.ai/code/session_01EBBBR8m2V8LjzMvuG7Go2L
Generated by Claude Code