Skip to content

T-QGYW-waypost-docs-site-build-in-no-ci-gate

State: closed/done · Impact: high · Complexity: small

Put the waypost docs-site build behind CI. The site is mirrored out with the source, so a build that fails is a broken page in someone else’s repository, and today nothing in the repository builds it.

Nothing reaches the site build.

LocationRole today
packages/ts/waypost/docs-site/An Astro Starlight site with a TypeDoc pass over detect-runners. Has package.json scripts but no moon.yml, so it is not a moon project.
.moon/workspace.ymlProject globs stop at packages/ts/*; nothing descends to a nested docs-site.
.github/workflows/ci.ymlRuns moon run :check :test --affected, which can only reach registered projects — and excludes layer: application besides.
sites/df-docs/moon.ymlThe one docs site that IS registered. The model to copy: thin tasks shelling to the same commands the package scripts run.

An earlier draft of this task claimed the site build was the only lane that typechecks test files, and that is wrong. Both packages/ts/detect-runners/tsconfig.json and packages/ts/waypost/tsconfig.json carry tests/** in include, so moon run <pkg>:check typechecks them and CI already runs it. Verified by injecting a type error into tests/cache.test.ts: detect-runners:check failed on it. The escapes that motivated this task happened to people running a bare bunx tsc --noEmit from the repository root, which resolves the ROOT tsconfig and a different include — a false green from the wrong command, not a hole in CI.

What the site build does catch, and nothing else does, is the site. Verified by injecting a malformed MDX expression into a guide page: every package check stayed green and waypost-docs:build failed. That class — an unparseable page, a sidebar entry pointing at a page that no longer exists, a TypeDoc entryPoints or tsconfig path that stopped resolving — reaches the public mirror today with no gate at all.

.moon/workspace.yml already argues this case against itself, about crates:

A hand-kept list is the failure this whole block exists to close: a crate lands, nobody remembers to add its sources: line, and it silently has no fmt-check, no clippy and no test target while moon run :check :test reports green.

Three docs sites are in exactly that state: waypost, intersect (T-94S0-intersect-docs-site-build-in-no-ci-gate) and flowline (T-MYD5-flowline-docs-site-build-in-no-ci-gate).

packages/ts/waypost/docs-site is a registered moon project whose build runs in CI on every push, as an explicit step.

Registration is by explicit sources:, not a glob. A packages/ts/*/docs-site glob cannot work: all three sites are directories named docs-site, so moon’s folder-derived ids would collide silently — the trap .moon/workspace.yml already documents for pumice-core and polish. The same file records that on moon 2.4 a nested glob additionally registers a phantom parent project. The json-canvas-demo entry is the precedent: a project nested inside a package that the packages/ts/* glob stops one level above, which is exactly this shape.

Registration alone is not enough. CI’s affected step queries projectLayer!=application, and these are Astro applications. A registered docs-site project would still never run. The Nuxt-product steps exist for this same reason and their comment carries the argument: a gate that reported green while checking the wrong files must not be given a step that can silently skip itself. So the site gets an unconditional step, if: always() so a sibling’s failure cannot hide it, and one step per site because moon run is fail-fast with no --no-bail.

The gate is the full build rather than TypeDoc alone. Install dominates the cost either way — typedoc lives in the site’s own node_modules — so the astro pass on top is a couple of seconds for link and content coverage the TypeDoc run does not give.

  1. Add packages/ts/waypost/docs-site/moon.yml modelled on sites/df-docs/moon.yml: install (its own Bun root), build, dev. Project id waypost-docs, set by the workspace sources: key. No dependsOn — moon’s javascript toolchain syncs project dependencies into package.json as workspace:*, which cannot resolve from a directory outside the repo’s workspaces and makes bun install fail outright.
  2. Add three sources: entries to .moon/workspace.yml, with a comment giving both reasons a glob is wrong.
  3. Add the CI step, beside the Nuxt-product steps and documented against them.
  4. Prove the gate: break a guide page, watch moon run waypost-docs:build fail while every package check stays green, revert. A gate that has never failed has not been shown to work, and a gate that only duplicates an existing one is not worth its wall time.
  5. Update packages/ts/waypost/CLAUDE.md, whose documentation table tells the reader to run the build by hand.
LocationKindChange
packages/ts/waypost/docs-site/moon.ymlnewRegister the site; install, build, dev tasks.
.moon/workspace.ymlmodifyThree explicit sources: entries, with the reasoning.
.github/workflows/ci.ymlmodifyOne unconditional build step per site.
packages/ts/waypost/CLAUDE.mdmodifyIts docs table says to run the build by hand; say CI now does.
  • AC-1: moon run waypost-docs:build succeeds from a clean checkout.
  • AC-2: A break the package checks do not see — a malformed page — fails waypost-docs:build, demonstrated by introducing one and reverting it.
  • AC-3: moon query projects lists waypost-docs exactly once and registers no phantom parent project.
  • AC-4: CI wall time on a docs-only change grows by under a minute.
  • The link check across SITE_BASE values. Worth gating later; it needs a built site and a decision about which bases to sweep.
  • The sibling sites’ own project files, which their tasks carry.
  • none

Found while answering “what is left for waypost” on 2026-08-31. The immediate trigger was the excludePaths branch (#1615), where the site build rejected a Fingerprint test fixture that a bare bunx tsc --noEmit had passed. That looked like a CI hole and was written up as one; checking it during implementation showed it was a wrong command run locally — moon run detect-runners:check catches the same fixture, because the package tsconfig includes tests/**. The task survives on the narrower and true claim above: the published site is built by nothing.

Originally drafted as WP-0002 under docs/packages/ts/waypost/planning/tasks in #1616, outside the registry; moved here so it is indexed and swept like everything else.


← Back to Tasks