Docs Validation Plan
Documentation is a product contract, so it is guarded like code: with deterministic, file-walking checks that exit non-zero and print actionable findings. This page defines the validation suite. It mirrors the style of the existing scripts/check-*.ts and scripts/check-*.mjs gates — each check walks files, compares against a source of truth, and fails loudly.
For the three-tier source-of-truth model these checks defend, see the Documentation Contract Architecture.
Currently Implemented
Two guards exist today.
Generated-docs drift (npm run gen-docs:check)
- Guards: that every Tier-2 generated file matches its Tier-1 source.
- How it works: runs each
scripts/gen-*-docs.tsgenerator in--checkmode (plusscripts/check-spec-drift.ts), regenerating the output in memory and failing if the committed file differs. This is the mechanism behind theGENERATED FILE: do not edit by hand.header. - Status: implemented and wired into
npm run check(the global gate runsgen-docs:check).
Scaffold existence (npm run check:docs-contract-scaffold)
- Guards: that the documentation contract scaffolding exists and is structurally intact — every required scaffold file (the four docs-system pages, all
docs/product/v1/pages, and alldocs/ai-context/v1/files), a set of load-bearing exact H1 titles (index.mdH1 "Gessa Product Documentation (v1)",README.mdH1 "Gessa AI Context (v1)",llms.txtfirst line "# Gessa", and the four docs-system H1s), and thatai-context-manifest.jsonparses as JSON and pinsengineVersion"v1" with afilesarray. - How it works: a deterministic file walk (
scripts/check-docs-contract-scaffold.ts) that asserts each required path exists, parses the manifest, and verifies each critical heading appears verbatim; exits non-zero listing any missing path, invalid manifest, or mismatched title. - Status: implemented as a structural stub guard. Deliberately not in the global
npm run checkyet (see Wiring).
Future Checks
Each future check below is specified for a later agent to implement as a scripts/check-* gate.
Generated docs drift (expansion)
- Guards: the same drift property as
gen-docs:check, extended to any new generator added later. - How it would work: every new
scripts/gen-*-docs.tsmust register a--checkmode and be appended to thegen-docs:checkchain; a meta-check verifies no generator is missing from the chain. - Status: partially implemented (the chain exists); the meta-check is future.
MCP docs vs executable tools
- Guards: that
docs/creator/mcp/tool-reference.mdlists exactly the tools the server actually exposes. - How it would work: load the executable MCP tool registry from
server/src/modules/mcp/server.ts, diff tool names and input schemas against the generated reference, fail on any tool documented-but-absent or present-but-undocumented. Complements the existingcheck:mcp-coverage/check:mcp-action-catalog-paritygates. - Status: future.
Action docs vs Action Catalog
- Guards: that action references in prose and in the generated reference match
packages/action-catalog. - How it would work: load the catalog from
packages/action-catalog/src/index.ts, verify everyactionMarkdoc reference and every row indocs/spec/generated/action-catalog.mdresolves to a real verb, and fail on unknown ids. - Status: future.
ECS docs vs component contract
- Guards: that component references match the canonical ECS contract.
- How it would work: load
COMPONENT_TYPE_DEFINITIONSfrompackages/ecs/src/index.ts, verify everycomponentMarkdoc reference and every row indocs/spec/generated/component-types.mdresolves to a real component type and contract hash. - Status: future.
SDK docs vs generated SDK
- Guards: that hand-authored SDK prose does not describe SDK surface that the generated SDK reference does not contain.
- How it would work: parse the symbol inventory in
docs/spec/generated/script-sdk.md, then scan Tier-3 SDK pages for code references and flag any symbol not present in the generated inventory. - Status: future.
AI-context manifest hashes
- Guards: that
docs/ai-context/v1/ai-context-manifest.jsonpins the correct engine version and that every context file it lists exists and matches its recorded hash. - How it would work: read the manifest, compare its
engineVersionagainstpackages/engine-version(ENGINE_VERSION), and recompute thesha256of each listed file, failing on a missing file or a hash mismatch. - Status: future.
Examples compile or are explicitly marked conceptual
- Guards: that code examples in docs either compile or are clearly tagged as illustrative.
- How it would work: extract fenced code blocks; for blocks marked compilable (e.g. a
compileinfo-string or an example registry entry), type-check them against the SDK; for blocks marked conceptual, require an explicit conceptual marker. Fail on an unmarked block that does not compile. - Status: future.
Public docs do not claim unaccepted capabilities
- Guards: that no published page asserts a capability the engine has not accepted.
- How it would work: load the v1 readiness ledger (
docs/cycles/v1-engine-readiness-loop/FEATURE_LEDGER.json), whose rows carry astatusdrawn from the acceptance vocabularyaccepted | accepted_with_risk | blocked | deferred | in_progress | unaccepted. A capability claim is permissible only when its ledger row isacceptedoraccepted_with_risk; a row that isblocked,deferred,in_progress, orunacceptedmust be described as a contract model or scaffold, not a guarantee. The check scans Tier-3 pages for capability claims (for examplecontractandproofMarkdoc tags) and fails when a claim's referenced ledger row is not in an accepting status. Today every ledger row isunaccepted(the engine has never launched), so this check would currently forbid any unconditional playability or feature guarantee. - Status: future.
Wiring
These checks join the build incrementally, never as a big-bang flip.
gen-docs:checkis already part ofnpm run check. Any new generator registers a--checkmode and is appended to thegen-docs:checkchain (and togen-docs).- Future content checks (MCP-vs-tools, action, ECS, SDK, manifest hashes, examples, public-claims) land first as standalone
scripts/check-*gates that can be run in isolation, are validated to be deterministic and green on the current tree, and only then are appended to the globalnpm run checkchain — the same incremental pattern the existing gates follow. check:docs-contract-scaffoldis deliberately NOT in the globalnpm run checkyet. It is a structural stub guard for scaffolding that is still being filled in; wiring it globally now would block unrelated work while the docs-system is mid-build. It runs on demand and graduates intonpm run checkonce the scaffolded folders carry their authored pages.
Every check is deterministic: it walks files, compares against an in-repo source of truth, and exits non-zero with a precise list of findings — no network, no flakiness, mirroring the established scripts/check-* gates.
Status
This is a scaffold-stage validation plan. Two guards are real today — gen-docs:check (wired) and check:docs-contract-scaffold (on-demand). The remaining checks are specified here for systematic future implementation and tie documentation correctness back to the Tier-1 sources and the v1 readiness ledger described in the Documentation Contract Architecture. The Markdoc Schema Plan defines the tags several of these checks will validate.