LearnNewsExamplesServices
Frontmatter
id12727
titleRestore chunked release notes in SEO outputs
stateClosed
labels
bugairegressionbuild
assigneesneo-gpt
createdAtJun 8, 2026, 5:24 AM
updatedAtJun 8, 2026, 11:01 AM
githubUrlhttps://github.com/neomjs/neo/issues/12727
authorneo-gpt
commentsCount0
parentIssue12696
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 8, 2026, 11:01 AM

Restore chunked release notes in SEO outputs

Closed v13.0.0/archive-v13-0-0-chunk-17 bugairegressionbuild
neo-gpt
neo-gpt commented on Jun 8, 2026, 5:24 AM

Context

While recovering after context compaction and surveying the v13 release-note ingestion/SEO surface under #12696, I checked whether the v13 release note was visible in the portal release index and SEO outputs.

The v13 note is visible, but the check exposed a wider regression: the SEO generator currently only sees top-level release-note markdown files. Historical release notes now live under resources/content/release-notes/chunk-N/, so generated sitemap and llms.txt release-note sections contain only v13.0.0 while releases.json still contains the full historical set.

Live latest-open sweep: checked the latest 30 open issues on 2026-06-08; no equivalent open ticket found. Live duplicate searches for release notes sitemap chunked and llms release notes chunked returned no open issues. Exact local sweep found the closed prior sitemap contract #9592 and the closed release-index chunking repair #12176 / #11405, but no active ticket for the SEO collector regression. KB ticket sweep for release notes sitemap chunked collectReleaseRoutes SEO generator tickets #9592 #12176 surfaced #9592 as the closed source contract and no open duplicate.

The Problem

buildScripts/docs/seo/generate.mjs says it collects all release notes, but collectReleaseRoutes() uses a non-recursive glob:

  • buildScripts/docs/seo/generate.mjs:524-528 uses fg('resources/content/release-notes/*.md', ...).
  • Current file-count probe: resources/content/release-notes/**/*.md = 167 files; resources/content/release-notes/*.md = 1 file; 166 release notes are invisible to this collector.
  • apps/portal/sitemap.xml:1338 contains https://neomjs.com/news/releases/13.0.0, but the sitemap release route count is 1; it does not include 12.1.0, 11.13.0, or 8.13.0.
  • apps/portal/llms.txt:191-195 has a Release Notes section with only v13.0.0.

This contradicts the closed #9592 contract that release notes should be dynamically parsed into /news/releases/[version] sitemap URLs, and it regresses after release notes were chunked.

The Architectural Reality

The portal release navigation is already chunk-aware through a separate generator:

  • buildScripts/docs/index/release.mjs:44-62 explicitly documents recursive scanning of resources/content/release-notes including chunk-N/, then uses fg('**/*.md', { cwd: inputDir, absolute: true }).
  • apps/portal/resources/data/releases.json includes v13, 13.0.0, and historical chunked paths like resources/content/release-notes/chunk-2/v12.1.0.md.

The broken substrate is the SEO generator only. The fix should align collectReleaseRoutes() with the release-index generator instead of adding release-specific exceptions for v13.

The Fix

Update buildScripts/docs/seo/generate.mjs so collectReleaseRoutes() recursively scans release-note markdown files, derives the route version from the basename, and preserves the existing /news/releases/${version} route shape.

Regenerate and commit the SEO outputs that are source-controlled consumers of the generator:

  • apps/portal/sitemap.xml
  • apps/portal/llms.txt

Add or adjust focused test coverage for the recursive release-note collector if an existing SEO-generator test seam exists. If there is no existing test seam, add a minimal deterministic script-level test or document the verification commands in the PR body.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
collectReleaseRoutes() in buildScripts/docs/seo/generate.mjs #9592 plus buildScripts/docs/index/release.mjs recursive release-note ingestion Discover top-level and chunk-N/ release-note markdown files If no files exist, keep current empty release-route behavior Existing JSDoc should be corrected if needed Unit/script probe shows recursive count matches release-note markdown count
apps/portal/sitemap.xml release-note URLs SEO generator output Include all release-note routes as /news/releases/[version] Existing sitemap lastmod fallback remains unchanged generated output Count includes 167 release routes; spot-check 13.0.0, 12.1.0, 11.13.0, 8.13.0
apps/portal/llms.txt Release Notes section SEO generator output Include all release-note raw links, not only top-level files Existing latest-updates section remains unchanged generated output Release Notes section includes historical chunked releases

Decision Record impact

Aligned with ADR 0004 chunking behavior and the closed #9592 sitemap contract. No new ADR required.

Acceptance Criteria

  • collectReleaseRoutes() recursively discovers resources/content/release-notes/**/*.md while preserving route ids of the form /news/releases/${version}.
  • Generated apps/portal/sitemap.xml includes historical chunked release routes such as /news/releases/12.1.0, /news/releases/11.13.0, and /news/releases/8.13.0, plus /news/releases/13.0.0.
  • Generated apps/portal/llms.txt Release Notes section includes historical chunked release raw links in addition to v13.
  • Verification evidence records the recursive markdown count and the generated release-route count.
  • The fix avoids changing portal release navigation behavior; apps/portal/resources/data/releases.json is already the correct shape for this issue.

Out of Scope

  • Rewriting the v13 release-note prose.
  • Changing the raw route serving contract.
  • Reworking the release-note directory layout.
  • Changing seo.json; route-specific release-note metadata is not part of the current SEO service contract because nested release routes fall back to /news/releases.

Avoided Traps

  • Do not special-case v13.0.0; it only exposed the regression because it is the one top-level release note.
  • Do not mutate releases.json to solve this; it already recursively sees chunked notes.
  • Do not broaden this into a general SEO overhaul. The release-blocking fix is the collector mismatch plus regenerated outputs.

Related

  • Parent epic: #12696
  • Prior closed sitemap contract: #9592
  • Prior closed release-index chunking repair: #12176 / #11405

Origin Session ID: e8f07ef9-ef7e-4815-8ff4-7abe13720621

Handoff Retrieval Hints: release notes sitemap chunked collectReleaseRoutes, v13 release-note ingestion SEO survey, apps/portal/llms.txt Release Notes only v13

tobiu referenced in commit 42be96a - "fix(seo): restore chunked release note routes (#12727) (#12728)" on Jun 8, 2026, 11:01 AM
tobiu closed this issue on Jun 8, 2026, 11:01 AM