feat(reference) Move each port's reference under its own version - #16
Merged
Merged
Conversation
why: /reference/go/ put the Go API outside the Go documentation, above the version it documents, and mixed three separately versioned packages -- the core library, the Workspace Manager and the MCP server -- into one tree. A reference documents one release of one package. what: - referenceUrl(port, version, product) and referenceSegment() build every reference path, and productApiPath spells the product trees the same way: mcp/reference and workspace/reference - The reference route renders inside each port's shell, where Astro's base is already /<port>/<version>/, so its paths carry no port segment and the core tree holds core symbols alone - The Markdown twins and tree.json follow it; the root build keeps the cross-port hub at /reference/ and the A-Z symbol index - referenceHref resolves a cross-port link through the target port's default version, which defaultVersionFor reads from the assembly's LIBTMUX_DOCS_PORT_DEFAULTS
why: A prose mention resolved through api-model, which cannot know which version a port publishes or which package a symbol belongs to, so every cross-reference in prose still named the old path. The intersphinx inventories named it too. what: - MentionContext takes symbolHref and moduleHref; the site passes builders that know the target port version and the three trees, and tooling that only asks whether a span resolves keeps the default - Every resolved mention now routes through productApiHref - A port shell writes its own objects.inv beside its reference; the root build keeps the per-port copies and the combined one, so an external intersphinx mapping still resolves - The assembly points its /api/ redirect stubs at the new location
why: The Workspace Manager's declarations answered under workspace/internals/api and the MCP server's under mcp/api, two spellings for the same thing and neither matching the core library's. A reader who has found one reference should be able to guess the others. what: - The generated pages and their landing page move together: <port>/<version>/workspace/reference/ and .../mcp/reference/ - The workspace reference leaves Internals, because a package's API is not an implementation note; Internals keeps its guides, topics and examples, and workspaceRedirects lifts those alone - A page's own port comes from the build rather than from the second segment of its path, which no longer carries one - Checks read the trees through scripts/reference-trees.mjs, which knows a port publishes one version prefix or two and that each carries three references - Served checks, dev checks and unit expectations follow the new paths
why: Nine checks and eleven suites located the reference by the path it had. Left alone they would measure an empty tree and pass, which is the one failure mode a gate must not have. what: - canonicals, xrefs, type-links and api-fidelity read every port's trees through referenceDirs, which covers both version prefixes and all three products - sidebar-refs asserts the entry is /<port>/<version>/reference/ and still first; its negative fixture drops that link - The canonicals negative case drops a version segment rather than a port segment, which is the collision the new shape can have - The switcher test asserted that no port link may carry a reference path, which is now the shape itself: it asserts each language link offers that port's root and nothing deeper - check-links no longer excuses a whole port tree as vendored output. Only the native `api/` subtree is Sphinx's or docfx's; the reference beside it is ours - Served checks, dev checks, fixtures and the publication smoke test follow the new paths
why: A signature on a core page can name a Workspace Manager or MCP type, and the page built that link from its own root -- 35,092 links to pages that moved. The sidebar tree listed those declarations too, since the nav sidecar covers the whole model. what: - The reference page resolves every symbol through productApiHref, so a product type links into its own package reference - navTree lists what the core reference holds, dropping declarations that belong to a product tree
why: Every mention records the URL it links to, and all 775 moved. what: - gen-mentions --check passes again
why: Thirty-three prose links and three notes named the old path. what: - Each link is rewritten to the tree that holds that symbol: a Workspace Manager type to workspace/reference, an MCP one to mcp/reference, the rest to the core reference under the port version - The parity note and the edge-function example follow
why: The plugin added the site root to an href the injected builders had already rooted, so every module link read /en/en/… -- 320 broken links from prose. Twenty-four pages also pointed at ./api/, the product page that became a reference of its own. what: - Only the package default, which carries no root, gets one added - The relative prose links follow the product reference out of Internals
why: ProseText resolved a mention through api-model and rooted the unversioned default, so a port landing page linked six symbols at the old path. Ten prose links and one component still named ../api/. what: - ProseText injects the same symbolHref and moduleHref the rehype plugin does, so both spell a reference URL one way - The MCP tool page and the last relative links point at the reference beside them
why: The route passed no port to the layout, so every page declared /en/reference/<symbol>/ -- the URL it used to have, which no longer exists. 12,600 pages pointed there. what: - The route passes its port and version, so the canonical is built the way every other port page builds one - check-canonicals asserts the port rule it now follows: a page is canonical to itself under the default version, and another version of it points there
why: The defaults lookup ran above the argument it reads, so check-canonicals threw before it checked anything -- and its negative test is what caught it. what: - The lookup moves below the site directory it depends on
why: The preview build publishes one version per port, so a prose link that spelled /py/stable/reference/ broke there while passing on an assembly that builds both. CI caught it: one broken link in 1,987,189. what: - Every same-port reference link in prose is relative to the page, so it resolves under whichever version prefix the build produced - The type-name ceilings move to the wider basis: the check reads all three trees per port now, where before it read only the core tree and never saw a product page
why: A product reference is a section of its product now, so the assembled suite looked for pages under the path it had, and the structured-data rule named api and tools but not reference. what: - The product section list carries reference beside Internals rather than inside it, and the workspace breadcrumb reads Reference - Seo marks any reference page APIReference, the core tree included, where before only a product api or tools page qualified - The exported metadata assertion follows the same spelling
why: Four files still named workspace/internals/api, and the intersphinx writer looked for an inventory at the root copy alone. what: - check-dev, the font audit and the product suite name the product reference section - add-intersphinx prefers the versioned inventory beside its reference, falling back to nothing rather than to a path that no longer holds one
why: docs.json named /reference/<port>/ for every port, so sixteen manifest entries pointed at pages that no longer exist -- the one file an agent reads first. The native navigation manifest test and the workspace redirect expectations named the old shape too. what: - Each port entry, its Markdown twin and its inventory carry the port's default version, the same one the pages are built under - A product reference is a section of its product, so no legacy twin redirects to it and the sitemap lists it like any other page
why: A product reference hangs directly off its product now, so a symbol page has no Internals level in its breadcrumb, and the search cases named two pages that no longer exist. what: - The breadcrumb assertion pins the product and the page, not the level between them that moved - The search cases name the trees that exist: a product declaration, the core reference, its index and the hub
why: The check counted one tree per port and that tree held everything, duplicates included. It reads the core reference and both product references now, which is every page a port publishes -- so seven ports rise, Python falls, and neither movement is a change in resolution. Python falls because its 627 workspace and MCP declarations left the core tree for product pages. Both render the same ApiEntry, but a core reference page wraps it in examples, related entries and module links, and those carry cross-references the product page has no room for. The duplicates that used to be counted are gone with them. what: - py 13,027 -> 11,925, and the seven that rose take their new counts: dotnet 3,975 -> 4,771, swift 3,298 -> 3,739, rs 3,750 -> 4,330
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.
/en/reference/go/put the Go API outside the Go documentation, above the version it documents, and mixed three separately versioned packages into one tree. Each reference now lives under the port and version it documents, and the Workspace Manager and the MCP server have references of their own./en/reference/go/<symbol>//en/go/latest/reference/<symbol>//en/go/latest/workspace/internals/api/<symbol>//en/go/latest/workspace/reference/<symbol>//en/go/latest/mcp/api/<symbol>//en/go/latest/mcp/reference/<symbol>//en/reference//en/reference/symbols/<letter>/How it works
referenceUrl(port, version, product)andreferenceSegment()are the only place a reference path is spelled.baseis already/<port>/<version>/. The core tree holds core symbols alone, so the 1,732 duplicate product pages that used to render under/reference/and carrynoindexare gone.MentionContextgainedsymbolHrefandmoduleHref. api-model cannot know which version a port publishes, so the site injects builders that do, and both prose linkers use them.objects.invbeside its reference; the root build still writes the per-port copies and the combined one, so external intersphinx keeps resolving.What the assembly caught
Each of these was a real defect, found by rebuilding and fixed at its source:
withRootreturns the locale root, not the shell's base — Astro'sbaseprefixes routes, not strings a component builds/en/en/…ProseTextresolved mentions without those builders; ten prose links and one component still said../api/check-linksalso stopped excusing a whole port tree as vendored generator output. Only the nativeapi/subtree is Sphinx's or docfx's; the reference beside it is ours, and excusing it would have hidden every one of the above.Verification
astro check0 errors, lint clean.check-sidebar-refs,check-api-fidelity,check-xrefsand the negative tests for canonicals, xrefs, type-links and edge extensions all pass.