T-R733-site-manifest-routes-ownership
Status: closed/done · Impact: high · Complexity: large
Build the substrate every other M-0005 phase stands on: the
site/site.yaml manifest contract, the single route registry that
makes naming collisions a hard failure, and the whole-content-root
ownership sweep that makes the site provably generator-owned.
D-0010-deterministic-site-assembly §1–§2.
| Location | Role today |
|---|---|
plugin/lib/services/docs/site.ts | Generates reference/glossary/references/data-model pages; orphan sweep limited to generated subdirectories; no route registry, no collision detection |
site/src/content/docs/ | Holds seven undeclared hand-written pages beside generated output; nothing fails on collision |
Proposed
Section titled “Proposed”Per D-0010 §2: manifest.ts (Zod schema + loader — landing: plus
ordered nav: slots of generated: keys, file: pages, and
two-level group: entries with mixed children), routes.ts (every
placement registers its content-root-relative route; duplicate
routes, supplemental routes inside reserved generated namespaces, and
duplicate same-level nav labels error with NAMESPACE_CONFLICT,
exit 7), and the §1 ownership sweep (post-placement walk of the whole
content root: bannered stragglers deleted loudly, unbannered files a
hard error naming the file and the fix). Existing generated families
register their routes; their page content is unchanged.
Approach
Section titled “Approach”manifest.ts: Zod schema, loader, validation errors (unknown keys, missing files, danglinggenerated:keys, depth > 2, undeclared supplemental files).routes.ts: registry, reserved-namespace table, label-uniqueness check;NAMESPACE_CONFLICTerror wired to exit 7.- Thread registration through the existing page emitters in
site.ts. - Widen the orphan sweep to the whole content root with the banner-split classification.
- Tests: manifest fixtures (valid/invalid), collision fixtures, foreign-file fixtures, idempotency two-pass.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
plugin/lib/services/docs/site/manifest.ts | new | Schema + loader |
plugin/lib/services/docs/site/routes.ts | new | Registry + collisions |
plugin/lib/services/docs/site.ts | modify | Registration threading; whole-root sweep |
site/site.yaml | new | Born minimal: current nav order as slots |
plugin/lib/services/docs/tests/ | modify | New suites per Approach 5 |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: A manifest placing a supplemental page at a route already claimed by a generated page fails with exit 7 naming both claimants.
- AC-2: An unbannered file dropped into the content root fails the pass naming the file and the move-and-declare fix; a bannered stale file is deleted and logged.
- AC-3: A nav entry nested three levels deep is a manifest schema error.
- AC-4: Re-running the pass against unchanged sources produces no diff.
Out of scope
Section titled “Out of scope”- Nav emission (T-G5ND-site-generated-sidebar) and the supplemental mirror step (T-9LZ4-site-supplemental-migration) — this task validates and registers; it moves no content.
Dependencies
Section titled “Dependencies”- T-7D9E-design-deterministic-site — D-0010 accepted.
Discovery context
Section titled “Discovery context”Extracted from D-0010-deterministic-site-assembly Migration Phase 1.
Depends on
Section titled “Depends on”T-7D9E-design-deterministic-site