LearnNewsExamplesServices
Frontmatter
id12735
titleRelease-note SEO routes emit mutable /blob/dev/ links that 404 on file move
stateClosed
labels
bugdocumentationaibuild
assigneesneo-gpt
createdAtJun 8, 2026, 6:49 AM
updatedAtJun 8, 2026, 10:59 AM
githubUrlhttps://github.com/neomjs/neo/issues/12735
authorneo-opus-vega
commentsCount2
parentIssue12696
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 8, 2026, 10:59 AM

Release-note SEO routes emit mutable /blob/dev/ links that 404 on file move

Closed v13.0.0/archive-v13-0-0-chunk-17 bugdocumentationaibuild
neo-opus-vega
neo-opus-vega commented on Jun 8, 2026, 6:49 AM

Context

Surfaced by a cross-PR interaction during v13 nightshift review:

  • #12728 (recursive-glob fix) restores chunked release notes to sitemap.xml + llms.txt, making historical release-note pages live, SEO-indexed routes.
  • #12732 retires .github/WORKING_WITH_AGENTS.md into a redirect stub and moves primary guidance to learn/agentos/StrategicWorkflows.md. The historical release note link still resolves today, but its target semantics drifted from the original guide to a retired redirect page.

That intersection is the live proof of a broader latent class: mutable branch links embedded in historical release notes can drift, become stale, or become dangling as files move or retire.

Live latest-open sweep (2026-06-08, 30 latest open issues): no equivalent ticket.

The Problem

Historical release notes link to mutable /blob/dev/<path> GitHub URLs. V-B-A:

rg -n "https://github.com/neomjs/neo/blob/dev/" resources/content/release-notes
-> 31 links across 12 distinct release-note files

Targets include movable paths: src/component/MagicMoveText.mjs, learn/guides/**, .github/AI_QUICK_START.md, .github/WORKING_WITH_AGENTS.md, resources/content/sandman_handoff.md, learn/blog/**, etc.

Before #12728, chunked historical release notes were not emitted as indexed release-note routes. After #12728, they are included in sitemap.xml + llms.txt, so a moved, retired, or deleted target becomes stale or dangling on a live, crawled, SEO-discoverable page. This directly undercuts the discovery/legibility goal the SEO routes exist to serve.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
Active release-note source (resources/content/release-notes/**, excluding resources/content/archive/**) Release-note markdown files and release version filenames Do not keep mutable https://github.com/neomjs/neo/blob/dev/... links in active release-note content that is emitted as an SEO route. Prefer immutable release tags or repo-relative/current documentation targets per file context. If a historical target cannot be safely pinned or remapped, leave a narrow documented exception and file a follow-up rather than guessing. PR body plus inline code comments only if a validator is added. Scan active release notes for /blob/dev/ links before and after the change.
SEO route generation (buildScripts/docs/seo/generate.mjs, sitemap.xml, llms.txt) #12728 route-surface expansion and current SEO generator contract Generated release-note route artifacts must not silently publish mutable /blob/dev/ links from active release-note content. Chosen first pass: source-content cleanup plus a local generation/validation guard; generation-time hidden URL rewriting is deferred unless source cleanup proves insufficient. If route generation cannot validate body links cheaply, add a dedicated release-note link scan script and wire it into the relevant check path. PR body. Generated output or validator fixture showing mutable links fail before publication.
Link target stability GitHub URL semantics and release-note historical context Links in historical release notes should resolve to stable targets for the release context, not to a moving branch head. For retired docs, point to the current canonical successor when that is more truthful than pinning the retired page. Use an explicit exception list only when neither a stable tag nor a canonical successor exists. PR body. Spot-check representative historical links and the #12732 retired-doc instance.
#12732 live instance PR #12732 diff and current .github/WORKING_WITH_AGENTS.md redirect stub Do not leave the indexed historical release-note route pointing at a retired guide as if it were still the primary guide. Resolve consistently with the selected cleanup strategy. If the redirect stub is intentionally retained as the historical target, document why it remains acceptable despite the broader guard. PR body / issue comments. The v11.0.0 release-note route no longer exposes a misleading mutable blob/dev link for this target.
Archived content boundary #12735 out-of-scope clause Do not mutate resources/content/archive/** snapshots as part of this fix. File a separate archive-policy ticket if archive rewrites become necessary. Issue body. Diff excludes archive paths.

Fix Direction

Preferred first pass: one-time active release-note content cleanup + a local guard.

  • Rewrite or remap the 31 active release-note /blob/dev/ links so active release-note SEO routes no longer publish moving branch URLs.
  • Add a guard that fails when active release-note content contains github.com/neomjs/neo/blob/dev/, excluding archived snapshots.
  • Keep generation-time hidden rewriting out of the first pass unless cleanup cannot express the correct historical target.

Acceptance Criteria

  • Active release-note content emitted through SEO routes contains no https://github.com/neomjs/neo/blob/dev/ links.
  • A local test or validation script fails on new active release-note /blob/dev/ links before publication.
  • The #12732 retired-guide instance is resolved consistently with the chosen cleanup strategy.
  • resources/content/archive/** remains untouched.

Out of Scope

  • Archived content under resources/content/archive/ — immutable snapshots; leave their original refs.
  • The #12728 recursive-glob fix itself (correct as-is; this is a follow-up to its new surface).
  • Network-crawling every GitHub URL in CI; this lane can stay local and deterministic unless a later ticket explicitly expands it.

Related

  • Amplified by #12728 / #12727 (SEO routes for chunk-N release notes)
  • Live instance: #12732 (WORKING_WITH_AGENTS.md retirement into redirect stub)
  • v13 epic context: #12696 (non-blocking follow-up — does not gate the release)

Origin: nightshift cross-PR review (@neo-opus-vega). Authored by Claude Opus 4.8. Contract Ledger aligned by GPT-5 (Codex Desktop) after live V-B-A on 2026-06-08.

tobiu referenced in commit ee96fda - "fix(seo): pin release-note github links (#12735) (#12739)" on Jun 8, 2026, 10:59 AM
tobiu closed this issue on Jun 8, 2026, 10:59 AM