Skip to content

Publish durable Sphinx inventories and footer links - #166

Draft
tony wants to merge 19 commits into
mainfrom
sphinx-inventories
Draft

tony wants to merge 19 commits into
mainfrom
sphinx-inventories

Conversation

@tony

@tony tony commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Publish objects-full.inv for the assembled English site and objects.inv at each built port/version root. Sphinx projects can link to documents, APIs, overloads, parameters, MCP objects, schema pointers, headings and table rows through portable labels and registered native aliases.

Renderers own target identities and destinations. Case-safe keys and explicit migration aliases preserve references when pages or names move. Root composition selects published default catalogs, validates their trees before upload, and retains existing inventory mapping bases. The footer offers scoped/full downloads and a keyboard-accessible ? linking to the Intersphinx setup guide.

Python tooling uses pyproject.toml, uv.lock, dependency groups, Ruff lint/format checks and ty. Local and CI installs share the declared three-day package cooldown.

Rebased onto main at 4e891632a66a144bd9dd7747168cf9218eb32710. The branch retains #157's exact head; #157 has merged. All 19 patches replay unchanged, and the complete source tree at 1c99d184aa6b6d0af5fdc9e57f7007744bb379fb matches the previously audited 930a24cc tree.

Addresses #164.

Validation

Fresh local checks at 1c99d184:

  • pnpm lint and pnpm type-check pass, including Ruff lint/format, ty and workspace TypeScript/Astro checks.
  • The focused inventory suites pass 68 tests; seven assembled-output tests are explicitly skipped in the source-only run.
  • Unmodified Sphinx 8.2.3 and 9.1.0 consumers over local HTTP each pass 3,028 strict RST and 3,028 MyST references across 16 catalogs. Both fresh runs use Python 3.12.15.
  • Compiled desktop/phone browser checks pass hover, keyboard focus, Escape, reopening and help navigation. Root, Go, PowerShell and Japanese footer links pass. All sixteen HTTP inventory downloads match the audited archive bytes.
  • Ruby and Lua caller workflow tests each pass four tests. All twelve port diffs contain only the paired docs producer refs in .github/workflows/docs.yml.
  • pnpm test fails because the real-corpus resolver test reaches its five-second timeout. The same test passes in isolation with its original timeout. The resolver and its test match main; the complete outer loop is not a pass.
  • Actionlint 1.7.12 reports exactly the same diagnostics as the pinned bases, with no new messages. Its schema lacks current GitHub job.workflow_repository, job.workflow_sha and concurrency.queue fields; existing Shellcheck messages also remain. See GitHub's job context and concurrency documentation.

The compiled preview above is the exact uploaded successful prior CI artifact, built from the identical source tree at 930a24cc. Its independent complete Sphinx 8/9 audits each passed 780,840 records, 16 catalogs, 40,770 owned documents and all 34 compatibility inventory paths. These artifact results remain distinct from CI for the new commit.

Rollout

Keep this PR and all twelve port PRs as drafts for review. Their build and publication refs now pin this rebased producer. Keep the remote preservation branch sphinx-inventories-producer-205ecacf3 until consumers move to the landed docs commit. Publish every selected default catalog, including Python stable, before composing the canonical root inventory.

Canonical publication and live public verification remain open. The prior default Python urllib preview probe received HTTP 403 / Cloudflare 1010; remote stock Sphinx consumers have not run. The local preview uses committed models and latest defaults. Separate actual-source canonical-default evidence is recorded in the research report; it is not production publication. Current C++ CI excludes native Breathe HTML.

Earlier Ruby, Lua, PowerShell and Julia preview publications failed AWS role assumption, and separate Swift/TypeScript native checks failed in unchanged paths. Those historical failures are distinct from newly triggered CI. Native library matrices were not rerun locally for these workflow-only port changes. Merge and production publication remain for review.

Draft port PRs
Repositories Draft PR
Python tmux-python/libtmux#787
Ruby libtmux/libtmux-ruby#45
Lua libtmux/libtmux-lua#44
PowerShell libtmux/libtmux-powershell#30
Julia libtmux/libtmux-julia#28
TypeScript libtmux/libtmux-ts#84
Rust libtmux/libtmux-rs#84
Go libtmux/libtmux-go#70
Java, Kotlin and Scala libtmux/libtmux-java#80
C# and F# libtmux/libtmux-dotnet#94
C++ libtmux/libtmux-cxx#76
Swift libtmux/libtmux-swift#57

tony added 9 commits October 19, 2026 19:19
why: Intersphinx consumers need correct domains and durable references
across APIs, protocol objects, prose, and versioned documentation.

what:
- Export rendered targets with case-safe keys and explicit migrations
- Compose full and scoped inventories from the selected default trees
- Preserve compatibility exports and expose inventory help in the footer
- Audit real destinations and strict Sphinx and MyST consumers
why: Shared parameter fields omit native qualifiers and companion kinds,
which collapsed distinct C++ constructors and other declarations.

what:
- Prefer native identities and normalized native syntax for signatures
- Preserve keyword names and literal whitespace in structured fallbacks
- Cover copy/move constructors, companions, and named Ruby forms
- Match the footer browser assertion to its TypeScript fixture
why: Reading the rendered estate needlessly builds source positions and
converts every syntax-highlight span into another tree.

what:
- Use the existing parse5 version directly without source positions
- Materialize only inventory attributes and retain HAST for fragment edits

A 71-page, 49 MB sample preserves all 623 targets exactly and takes
5.9 seconds instead of 12.5 seconds in the same process.
why: HTML parsing moves spans out of table rows, so a retired fragment
would land above the table instead of at its configuration entry.

what:
- Place row fragment aliases inside the first cell
- Verify the parsed DOM keeps the alias with its owning row
why: Escape intentionally keeps the tooltip dismissed while its link
remains focused. Each viewport must begin a new focus interaction.
why: Port builds copy parity and translations pages without owning their
identities, which gave the full inventory conflicting destinations.

what:
- Exclude shared page copies from port build ownership
- Audit every owned document against the full or scoped catalog
- Exclude native shell exports that do not contain an article
why: Stripping any index.html suffix turned Sphinx genindex.html into a
nonexistent gen URL.

what:
- Strip only a complete index.html basename
- Cover ordinary Sphinx HTML index filenames
why: Sphinx strips trailing whitespace before parsing inventory records,
which silently dropped manual table anchors with empty display text.

what:
- Emit the standard default-name marker for empty or blank captions
- Use fragment names when rendered headings have no display text
- Cover blank captions and missing heading text
why: A page still owns its document identity when its layout has no main
element. The translations page was missing from the full inventory.

what:
- Export metadata-owned documents independently of fragment regions
- Keep native shell exports out of the published catalog
- Preserve retired document fragments at the body when needed

validation: 60 focused contracts pass. The required outer loop failed an
existing corpus resolver test at its five-second timeout.
tony added 10 commits October 19, 2026 19:19
why: Native Sphinx pages can reuse automatic IDs for heading aliases and
citation links, blocking publication despite unique named destinations.

what:
- Export the named headings and citations without their link controls
- Omit a colliding automatic alias only beside its unique named heading
- Keep duplicate content IDs fatal and preserve native article bytes

validation: Both new regressions fail before the fix. All 62 focused
contracts, workspace types and lint pass. The native compatibility
inventory's 1,747 destinations are present and unique. The required
outer run passes 951 API/model tests but reaches its 60-second deadline.
why: Python audits need reproducible dependencies and the same lint and
type checks used by the other Python projects in this workspace.

what:
- Replace inventory requirements with dependency groups and uv.lock
- Run Ruff, format checks and ty through the existing pnpm and CI gates
- Type the inventory audit and fix unchecked optional helper values
- Lock the C++ Sphinx renderer to its tested Breathe release

validation: Ruff, formatting, ty and focused helper contracts pass.
The outer loop retains the existing five-second prose/resolver corpus
timeouts. Complete publication evidence remains a separate gate.
why: The lockfile records the user's three-day package cooldown.
CI without that global configuration rejects uv sync --locked.

what:
- Declare the same policy in the project manifest and setup guide
- Preserve the locked package versions and stale-lock enforcement
- Verify lock checking and both groups with empty user configuration
  under uv 0.12.0 and CI's uv 0.13.1
why: A selected-source latest build renders a port homepage at the
shared root as well as its version root. Both then claim the same
inventory identity, so composition rejects the two destinations.

what:
- Use the existing version root to exclude pages outside that mount
  from selected-port inventory metadata and the export hook
- Keep API coverage validation mandatory at the actual port mount
- Exercise real layout metadata and hook behavior, including shared,
  preview and near-matching paths and missing mounted declarations
- Pass 155 focused contracts; four assembled-tree checks stay skipped

The outer loop still stops on the existing resolver corpus test's
five-second timeout.
why: The root namespace is reserved for the site's existing sections.
The new Intersphinx guide belongs with the pages about the site.

what:
- Move the guide under meta while retaining its inventory identity
- Update the footer, browser checks, notes and generated mentions
- Pass 166 focused contracts and the fresh browser sample; four
  assembled-output checks remain skipped

Inventory producer and checker files match the source-bound Python
replay audited with Sphinx 8 and 9. That captured fixture predates
this route correction.
why: Linux Ruff rejects shebangs without executable permission. WSL
skips this rule, so local lint alone did not expose it.

what:
- Record executable modes for the four Python CLI scripts
- Preserve every script blob and the existing Ruff rule selection
why: Decorative kind marks must not become configuration names in
Sphinx inventories.

what:
- Exercise configuration aliases through the row renderer
- Verify that hidden nested marks leave the public name unchanged
why: A bare --append under Sphinx's tmuxp load program context cannot
resolve the existing human-readable option name through Intersphinx.

what:
- Add canonical normalized-program.option aliases beside human names
- Omit aliases whose normalized program names have several destinations
- Audit each consumer reference's destination and contextual option roles
- Document the standard program directive with a checked option example

validation: 22 inventory tests, Ruff, formatting, ty and API-model types
pass. Sphinx 8 and 9 each resolve 114 RST and 114 MyST references against
recomposed CI catalogs. The exact guide example passes in both syntaxes.
The full local outer check exits 143 in the site suite at its deadline;
its completed API-model tests and workspace type checks pass.
why: Cached root models can advertise fields absent from the selected
published API, such as Go SubscriptionRequest.Session.

what:
- Build root per-port compatibility exports from default target catalogs
- Use the same selection during local site assembly
- Leave shell-only compatibility exports to final composition
- Cover retained and removed names with version-aware regressions

Validation: 22 focused tests, lint, and workspace type checks pass.
The outer loop exceeds its 60-second budget and terminates site tests.
why: Astro scopes the inventory tooltip styles onto the footer code tag.
The source parser rejected that attribute and accumulated errors until the
output worker exhausted its heap.

what:
- Accept code attributes and cover scoped and plain source tags.
- Stop after forty footer diagnostics while retaining failure status.
@tony
tony force-pushed the sphinx-inventories branch from 930a24c to 1c99d18 Compare October 20, 2026 00:43
@tony
tony deployed to docs-preview October 20, 2026 03:32 — with GitHub Actions Active

This branch was successfully deployed

1 active deployment
docs-preview — 1c99d184 Deployed Oct 20, 2026 by tony via publish-preview / publish #880
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.

1 participant