Gessa Docs

Documentation

Documentation Contract Architecture

How Gessa documentation is a version-pinned product contract over a single authoritative engine source.
engine v1.0.234since v1Copy for LLM

This document defines how Gessa's documentation is produced, versioned, and validated. It is the spine of the documentation contract system: every other docs-system page, every generated reference, and every hand-authored product page derives its rules from here.

The engine has never launched, so everything described here is v1. The three-tier model, the Markdoc tag schema, the generated reference, the export artifact, and the wired guards described below are real and running today. Where enforcement is still narrower than the rule it defends, this page says so plainly and names the docs program work item that hardens it. When in doubt, describe the contract rule, not a capability guarantee.

Docs as Contract

A Gessa documentation page is a product contract: it states what the engine guarantees at a pinned engine version. Documentation is not aspirational marketing copy and it is not a changelog of intentions. It is a promise about observable engine behavior, scoped to a specific contract snapshot.

Three consequences follow from treating docs as contracts:

  1. The engine repo owns the authoritative source. Canonical contracts live in this repository. Documentation is downstream of code, never the reverse.
  2. A page must not claim a capability the engine has not accepted. The v1 engine-readiness ledger (docs/cycles/v1-engine-readiness-loop/FEATURE_LEDGER.json) is the acceptance authority. A page that asserts a capability whose ledger row is not in an accepting status is making a false contract. See the Docs Validation Plan.
  3. Every contract page pins a version. A page declares which engine contract snapshot it documents, so a reader (human or generative engine) can cite an immutable coordinate rather than a moving target.

Source-of-Truth Rules

Documentation follows a strict three-tier source-of-truth model. Each tier has one job, and content never flows upward.

Tier 1, CODE and REGISTRY, is the source of truth. Canonical contracts live in code:

  • ECS components and fields: packages/ecs
  • Action Catalog verbs: packages/action-catalog
  • Capability Registry and packs: packages/capability-catalog plus runtime capability packs
  • MCP tools: server/src/modules/mcp/server.ts
  • Script SDK: packages/script-sdk
  • Script IR and GessaScript: packages/script-nodes plus packages/script-codegen and the Script IR
  • Semantic authoring: packages/script-semantic-patch
  • World Build Contract: packages/world-build-contract
  • Platform Catalog: packages/platform-catalog
  • Runtime: server runtime modules under server/src/modules/runtime
  • Renderer: renderer modules plus the renderer visual profile (packages/renderer-visual-profiles)
  • Version coordinates and catalog hashes: packages/engine-version

Tier 2, GENERATED REFERENCE, is a derived projection of Tier 1 and is never hand-edited. It carries the header comment GENERATED FILE: do not edit by hand. and lives under docs/spec/generated/ and docs/creator/mcp/. It is produced by the scripts/gen-*-docs.ts generators via npm run gen-docs and verified by npm run gen-docs:check.

Tier 3, HAND-AUTHORED PROSE, is reviewed instructional and explanatory content under docs/product/v1/ and docs/ai-context/v1/. It must link to Tier 2 for canonical tables and must not restate or duplicate generated content. Reference pages are thin pointers plus orientation, not copies of the generated tables.

The cardinal rule: Tier 3 links down to Tier 2; Tier 2 is regenerated from Tier 1; nothing edits a higher tier from a lower one.

Generated vs Hand-Authored Content Rules

The boundary between Tier 2 and Tier 3 is enforced, not advisory.

  • Generated (Tier 2) files are machine-owned. They begin with a GENERATED FILE: do not edit by hand. banner and a Regenerate with npm run gen-docs. note. Each names its Sources: (the exact Tier-1 code paths) and carries catalog versions and sha256 hashes. Do not hand-edit them; change the code, then regenerate. npm run gen-docs:check fails the build if a generated file drifts from its source.
  • Hand-authored (Tier 3) files are human-owned prose. They teach, explain, and orient. When a Tier-3 page needs a canonical fact (the ECS component inventory, the Action Catalog verbs, the MCP tool list) it links to the Tier-2 file rather than copying the table. Copying a generated table into prose creates a second, un-versioned source of truth that silently rots.
  • One fact, one home. If a fact is in a generated table, the prose page references it. If a fact is genuinely editorial (a tutorial's narrative, an explanation of why a contract exists), it lives only in prose and is never generated.

Versioning Model

Docs version equals engine version. Today there is exactly one: v1, aligned to packages/engine-version (the ENGINE_VERSION constants; the engine major reads one). The model is folder-per-version, in the style of Docusaurus versioning:

  • docs/product/v1/ for hand-authored product documentation.
  • docs/ai-context/v1/ for AI-agent context.

A future engine major opens v2/. Do not pre-create it.

A docs version pins engine manifest coordinates: the catalog versions and sha256 hashes from packages/engine-version and the generated reference headers, so a page declares which contract snapshot it documents. This is Stripe-style version pinning: a page is anchored to immutable coordinates, not to "latest".

Honest status of the invariant: docs version equals engine version is enforced nowhere today. The scaffold guard checks only that ai-context-manifest.json carries the literal string v1; nothing yet asserts the docs folder set against ENGINE_VERSION_MAJOR, and no check compares a generated header's engine coordinate against the current ENGINE_VERSION. The docs program closes this: it adds check:docs-version-freeze, which fails when the export manifest, the version archives, and the changelog disagree with ENGINE_VERSION and releases.json, and it derives the docs folder set from ENGINE_VERSION_MAJOR rather than a literal.

Pre-launch, v1 content is edited in place. Post-launch, an accepted behavior change goes through the contract-freeze gate (npm run check:contract-freeze, with npm run contracts:bump to advance coordinates) and may open a new docs version. Never silently rewrite a pinned version to describe new behavior; that breaks the contract promise for anyone who cited the old coordinate. Documentation never uses second-attempt spellings for an engine major; a coordinate reads its major number.

Markdoc Strategy

Authoring and rendering use Markdoc. Markdoc is a superset of Markdown, so every page is valid Markdown even where a custom tag appears and no renderer is present.

The eleven custom tags are implemented, not planned. They live as a real, importable schema in scripts/markdoc/tags.ts and are consumed by two callers: the docs-site build (scripts/docs-site/build.ts), which renders each tag to semantic HTML, and the Markdoc validation guard (scripts/check-docs-markdoc.ts), which checks that every tag used in prose is well-formed and, where it references engine contracts, resolves into the Tier-2 generated reference.

The eleven tags are exactly: contract, version, generated-reference, proof, warning, ai-context, mcp-tool, component, action, capability, recipe. Block tags use {% tag attr="value" %} ... {% /tag %}; self-closing tags use {% tag /%}.

Some tags are pure prose annotations; others point at Tier-2 generated data (component, action, capability, mcp-tool, and generated-reference resolve to entries in generated files). Full schema, attribute tables, intended render, and the map of which tags bind to generated data are defined in the Markdoc Schema Plan.

rune_web Consumption Model

The marketing and web repository ~/rune_web (sibling to this engine repo) is a consumer, never a source of truth for engine contracts. This consumption path exists today.

  • The docs-site build (scripts/docs-site/build.ts) emits a published, version-pinned export: an export manifest that records each page's source path, title, group, and a sha256 over the source Markdown, alongside the rendered internal preview. The manifest is the machine-citeable pinning the architecture promises.
  • ~/rune_web consumes that export one way through scripts/sync-engine-docs.mjs, which copies the pinned artifact into docs/engine-export/ and offers a --check mode that fails on drift. The export boundary is one-directional: ~/rune_web renders and presents; it never edits and never owns engine contracts, and treats the engine repo's published version as immutable input.
  • No engine contract source ever moves to ~/rune_web. The engine repo owns content and version pinning; ~/rune_web owns the eventual public sitemap and canonical tags for the rendered site.

If a contract fact must change, the change happens in Tier 1 in this repo, regenerates Tier 2, rebuilds the pinned export, and only then does ~/rune_web sync it.

AI-Context Strategy

Alongside human product docs, Gessa publishes a dedicated AI-agent context axis so that coding agents and MCP clients can build worlds correctly without dumping the whole engine into a model's context window.

The AI-context surface provides: an llms.txt index (per the llmstxt.org standard), an expanded llms-full.md, per-client operational guides (Codex, Claude Code, and MCP clients), a common-failures-and-repairs runbook, and a machine-readable ai-context-manifest.json that pins the engine version and lists the context files. SDK-user and internal-agent guidance is currently folded into the shared context files; dedicated per-client pages for them are candidate future additions.

AI docs are concise and operational: what to call for world building, what not to call, how to discover ECS components, how to use semantic script authoring, how to use MCP safely, how to avoid raw Project Graph mutations, what proof is required before claiming a world is playable, and how to handle renderer and runtime failures. The full layout lives in Gessa AI Context (v1); its validation rules are in the Docs Validation Plan.

SEO, GEO, and Parsability Strategy

Documentation is built to be citeable by humans, search engines, and generative engines (GEO is Generative Engine Optimization).

  • Stable per-version URLs. docs/product/v1/... and docs/ai-context/v1/... give every fact a durable address that does not move when v2 opens.
  • Semantic heading hierarchy. One H1 per page, descending H2 and H3 that mirror the contract's structure.
  • Front-matter metadata. Each page carries title, description, engineVersion, and canonical.
  • llms.txt for AI discovery. The AI-context index follows the llmstxt.org standard so agents can find the right context file quickly.
  • Generated reference as machine-citeable ground truth. Tier-2 files carry catalog versions and sha256 hashes, and the export manifest hashes each source page, giving generative engines immutable coordinates to cite.

The docs-site build writes a per-page meta description for the internal preview. The broader public SEO and GEO plumbing (sitemap index, canonical tags, structured data, per-page OG images, IndexNow) lives at the ~/rune_web boundary and is delivered by the later phases of the docs program. ~/rune_web owns the eventual public sitemap and canonical tags; the engine repo owns the content and the version pinning those tags point at.

Docs Validation and Drift-Guard Model

Documentation is guarded the same way code is: deterministic, file-walking checks that exit non-zero with findings and never touch the network.

Six guards are wired today. One is the generated-drift guard; the other five run under npm run check:docs, which is part of the global npm run check chain.

  • Generated-docs drift, npm run gen-docs:check. Regenerates each Tier-2 file from its Tier-1 source in memory and fails if the committed output differs. This is the mechanism behind the GENERATED FILE: do not edit by hand. banner and the real drift guard for the whole Tier-2 surface.
  • Scaffold existence, npm run check:docs-contract-scaffold. Asserts every required scaffold file is present, that a set of load-bearing exact H1 titles appear verbatim, and that ai-context-manifest.json parses and carries the literal engineVersion string with a files array. It is a structural existence and shape gate; it does not read the version dynamically.
  • Relative links, npm run check:docs-links. Every relative Markdown link in the hand-authored surface resolves to a real path on disk. External and pure-anchor links are skipped.
  • Markdoc tags, npm run check:docs-markdoc. Every custom tag used in prose is one of the eleven, is well-formed (required attributes present, enumerated values in range), and, for a binding tag, resolves into its generated file. What it enforces today is narrower than the rule: a binding tag resolves by naive substring .includes() over the generated file, so any id that happens to be a substring of unrelated text passes. It does not yet verify a specific table row or heading.
  • Example markers, npm run check:docs-examples. Every fenced ts, tsx, typescript, js, javascript, or json block carries an example:conceptual or example:verbatim source=... marker in the three lines above it. This is a marker-presence check only: it does not compile, type-check, or byte-compare anything against a source file.
  • Public claims, npm run check:docs-claims. Over docs/product/v1 and docs/ai-context/v1, a fixed list of banned over-claim phrases never appears, and a {% contract %} or {% proof %} tag may not carry an accepting status while the readiness ledger has zero accepted rows. The accepting-status rule has an accepted-rows bypass: it auto-relaxes the moment the ledger records its first accepted row, so it protects only the pre-launch window and does not tie a specific claim to a specific ledger row.

The docs program hardens each of these: it replaces the substring binding resolution with anchored heading and row resolution, upgrades the example guard to byte-match verbatim blocks against their cited symbol span and to replay marked examples through preflight, adds check:docs-closure for both closure directions and a typed-count ban, and adds check:docs-version-freeze for the docs-equals-engine invariant that nothing enforces today. Future guards specified for that work are catalogued in the Docs Validation Plan.

Subsystem Mapping

Each subsystem has exactly one Tier-1 canonical owner in code, one generator script, one Tier-2 generated reference, and a Tier-3 product page that links down to the generated reference. This table is the authoritative generator-to-file map.

SubsystemTier-1 canonical owner (code path)Generator scriptTier-2 generated referenceTier-3 product page
ECS componentspackages/ecs/src/index.tsscripts/gen-component-docs.tsdocs/spec/generated/component-types.md (plus docs/spec/COMPONENT_TYPE_DEFINITIONS.md)docs/product/v1/reference/ecs-components.md
Action Catalogpackages/action-catalog/src/index.tsscripts/gen-action-catalog-docs.tsdocs/spec/generated/action-catalog.mddocs/product/v1/reference/action-catalog.md
Capability Registrypackages/capability-catalog plus runtime capability packsscripts/gen-capability-catalog-docs.ts, scripts/gen-capability-pack-docs.tsdocs/spec/generated/capability-catalog.md, docs/spec/generated/capability-packs.md(planned)
MCP toolsserver/src/modules/mcp/server.tsscripts/gen-mcp-docs.tsdocs/creator/mcp/tool-reference.md (plus quickstart.md, security.md, others)docs/product/v1/how-to/use-mcp-tools.md, docs/product/v1/reference/mcp-tools.md
SDKscript SDK source (packages/script-sdk)scripts/gen-sdk-docs.tsdocs/spec/generated/script-sdk.mddocs/product/v1/reference/script-nodes.md (dedicated SDK page planned)
Script IR and GessaScriptpackages/script-nodes plus packages/script-codegen (Script IR)scripts/gen-script-node-docs.tsdocs/spec/generated/script-node-catalog.mddocs/product/v1/reference/script-nodes.md, docs/product/v1/how-to/write-gessascript.md, docs/product/v1/explanation/script-ir-and-gessascript.md
World Build Contractpackages/world-build-contract/src/index.tsscripts/gen-world-build-contract-docs.tsdocs/spec/generated/world-build-contract.md(planned)
Runtimeserver runtime modules (server/src/modules/runtime)no single generator (registries under docs/cycles/v1-engine-readiness-loop/)the v1 readiness registries (FEATURE_LEDGER.json, PROOF_REGISTRY.json, others)docs/product/v1/reference/runtime-playability.md, docs/product/v1/explanation/playability-proofs.md
Rendererrenderer modules plus renderer visual profile (packages/renderer-visual-profiles)scripts/gen-renderer-visual-profile-docs.tsdocs/creator/components/renderer-visual-profiles.md(planned)
Platform Catalogpackages/platform-catalogscripts/gen-platform-catalog-docs.tsdocs/spec/generated/platform-catalog.md(planned)

The Tier-3 column lists the product pages that exist in the current v1 set (mapped in the Information Architecture); rows marked (planned) have no page yet and are candidates for systematic authoring. Every Tier-3 page links down to the Tier-2 file in the same row and never restates its tables.

Status

The three-tier model, the versioning model, and the generator-to-file map are canon and are guarded by gen-docs:check. The eleven Markdoc tags are implemented in scripts/markdoc/tags.ts and rendered by scripts/docs-site/build.ts; the export manifest and the one-way ~/rune_web consumption path exist; six docs guards are wired. Two rules the architecture states are not yet fully enforced: binding tags resolve by substring rather than by row, and docs version equals engine version is enforced nowhere. The docs program hardens both, along with the example and closure guards. Until then, describe the contract rule, not a capability guarantee.

See also: Information Architecture, Markdoc Schema Plan, Docs Validation Plan.

Was this helpful?Report an issueContact support

On this page