Skip to content

fix(docs): serve released docs at canonical root - #553

Merged
jeremi merged 3 commits into
mainfrom
agent/v0152-docs-promotion
Jul 29, 2026
Merged

jeremi merged 3 commits into
mainfrom
agent/v0152-docs-promotion

Conversation

@jeremi

@jeremi jeremi commented Jul 29, 2026

Copy link
Copy Markdown
Member

Summary

  • serve the selected released documentation directly at /
  • publish unreleased Main documentation at /dev/ with noindex
  • keep immutable /v/<version>/ archives and mark every archive noindex
  • preserve /preview/ as compatibility redirects to the canonical release routes
  • advance the documentation selector to released v0.15.2 and add validation against future release-selector drift

Root cause

The v0.15.2 release manifest and documentation archive were published, but docsets.yaml still selected v0.13.0. The deployment also treated the root as a redirect surface and made the Main preview the indexable documentation source. This left the public root redirecting to v0.13.0 and did not provide a canonical latest-release copy at /.

Production model

  • /: canonical, indexable copy derived from the selected locked release archive
  • /dev/: unreleased Main documentation, noindex
  • /v/<version>/: immutable release archives, noindex
  • /preview/: legacy noindex redirects to matching canonical root routes

The selected archive tree digest is checked before and after promotion. /v/0.15.2/ remains byte-for-byte locked, and only a deployment-time copy is rewritten for the canonical root namespace.

Validation

  • npm test: 248 passed, 1 intentional skip
  • npm run check: passed end to end
  • python3 -m unittest release/scripts/test_registry_release.py: 99 passed
  • release/scripts/registry-release validate-docsets: passed for 14 versioned docsets
  • production-shape assembly: 18 locked archives restored, 519 files promoted, 186 canonical content routes, 254 legacy redirects
  • built SEO check: 255 canonical root pages, 255 /dev/ pages, 4,296 archive pages, 254 legacy redirects
  • built link check: 736,895 internal links and assets passed
  • built LLM discovery check for /dev/: 199 passed

Existing non-failing documentation warnings remain unchanged: 2 Vale warnings, 14 Redocly warnings, and the existing Astro/Rhai build notices.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Comment thread docs/site/scripts/check-seo.mjs Fixed
Comment thread docs/site/scripts/stage-production-docsets.test.mjs Fixed
jeremi added 2 commits July 29, 2026 11:17
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
@jeremi
jeremi marked this pull request as ready for review July 29, 2026 04:29
@jeremi
jeremi enabled auto-merge (squash) July 29, 2026 04:29
@jeremi
jeremi merged commit 78ed250 into main Jul 29, 2026
29 checks passed
@jeremi
jeremi deleted the agent/v0152-docs-promotion branch July 29, 2026 04:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b055c2db5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

run: node scripts/generate-standard-journeys.mjs --check

- name: Build Main-source preview
- name: Build unreleased Main documentation

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required DCO sign-off

Commit bdd43f39706fd4d548f51367767a7f02b987f085 has no Signed-off-by trailer, so it does not satisfy the repository's mandatory DCO policy; recreate this commit with the required sign-off before merging.

AGENTS.md reference: AGENTS.md:L68-L70

Useful? React with 👍 / 👎.

Comment on lines +590 to +591
if stack.get("status") == "released":
released_manifest_tags.append(docset_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep release validation in a single owning area

Adding this validation under release/ while the same change modifies the docs/site/ deployment and data spans two explicitly separate owning areas. Move the release-tool changes into their own owning-area change, or implement the selector validation within the docs area, so the change remains reviewable under the repository's required ownership boundary.

AGENTS.md reference: AGENTS.md:L76-L78

Useful? React with 👍 / 👎.

Comment on lines +331 to +334
const legacyRedirects = rootRouteEntries.map((entry) => {
const relativeIndex = entry.route === '/'
? 'index.html'
: `${entry.route.slice(1)}index.html`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve legacy non-HTML preview endpoints

When a client follows an existing machine-readable URL such as /preview/llms.txt or /preview/<slug>.md, it now receives a 404: the workflow no longer builds dist/preview, while this compatibility list is derived only from index.html routes and emits only corresponding index.html redirects. These endpoints were served by the previous /preview/ build and matching release files are promoted at the root, so generate compatibility redirects or copies for the non-HTML public routes as well.

Useful? React with 👍 / 👎.

Comment on lines +364 to +368
for (const promoted of promotedFiles) {
await mkdir(dirname(promoted.destination), { recursive: true });
if (textExtensions.has(extname(promoted.relative))) {
const contents = await readFile(promoted.source, 'utf8');
await writeFile(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Generate search for the canonical release copy

Because the selected release is built as an archive, astro.config.mjs sets pagefind: !isArchivedBuild to false and the locked tree contains no Pagefind index. Promoting that tree directly here therefore leaves the new canonical / documentation without site search, while only the unreleased /dev/ build remains searchable. Generate a deployment-time search index for the promoted copy, or build a separate canonical release copy, without changing the immutable /v/<version>/ archive.

Useful? React with 👍 / 👎.

Comment on lines +216 to +219
return `User-agent: *
Allow: /

Sitemap: https://docs.registrystack.org/sitemap-index.xml

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude non-HTML development artifacts from indexing

The /dev/ build publishes per-page .md files and llms*.txt, but those plain-text responses cannot carry the HTML noindex meta added by apply-archive-seo.mjs. Since this root policy explicitly allows every path, crawlers following the development HTML's alternate Markdown links can index unreleased source content even though /dev/ is intended to be search-excluded. Disallow /dev/ here, stop publishing those artifacts in that mount, or arrange an X-Robots-Tag: noindex response policy.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants