---
title: "Markdoc Schema Plan"
description: "The eleven implemented Gessa Markdoc custom tags, their attributes, intended render, and which tags bind to Tier-2 generated data."
engineVersion: v1.0.234
date: 2026-09-28
license: "(c) Gessa, proprietary. Cite with attribution to https://gessa.ai/docs/. Terms: https://gessa.ai/terms/."
canonical: https://gessa.ai/docs/docs-system/MARKDOC_SCHEMA_PLAN/
---

# Markdoc Schema Plan

Gessa documentation is authored and rendered with [Markdoc](https://markdoc.dev). Markdoc is a superset of Markdown, so every page stays valid Markdown even where a custom tag appears. This page defines the custom tags: their schema, attributes, intended render, and which of them bind to Tier-2 generated data.

There are exactly eleven custom tags: `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 /%}`.

These tags are **implemented**, not planned. The schema is a real, importable module at `scripts/markdoc/tags.ts` (the `TAG_SCHEMAS`, `BINDING_TAGS`, and `buildMarkdocConfig` exports). Two callers consume it: the docs-site build (`scripts/docs-site/build.ts`) renders each tag to semantic HTML, and the validation guard (`scripts/check-docs-markdoc.ts`) checks that every tag used in prose is well-formed and, for a binding tag, resolves into its generated file. The tags exist to keep Tier-3 prose consistent with the three-tier source-of-truth model in the [Documentation Contract Architecture](./DOCUMENTATION_CONTRACT_ARCHITECTURE.md): annotation tags carry contract semantics, and reference tags resolve to Tier-2 generated data instead of copying it.

## Tag Schemas

### `contract`

- **Purpose:** marks a block as a versioned product contract, a promise about engine behavior at a pinned version.
- **Form:** block.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `id` | string | yes | Stable contract identifier (for cross-reference and citation). |
  | `engineVersion` | string | yes | Pinned engine version this contract describes (for example `v1`). |
  | `status` | string | no | Readiness status; should mirror a v1 readiness-ledger acceptance state. |

- **Intended render:** a bordered contract callout with a version badge and an anchor on `id`, signaling "this is a guarantee, not a suggestion".
- **Example:**

  ```markdoc
  {% contract id="world.build.from_prompt" engineVersion="v1" status="unaccepted" %}
  Prompt-to-world build accepts a world spec and returns an executable world.
  {% /contract %}
  ```

### `version`

- **Purpose:** pins and displays the engine version coordinate a page or section documents.
- **Form:** self-closing.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `engineVersion` | string | yes | The docs and engine version (for example `v1`). |
  | `coordinate` | string | no | A specific catalog coordinate from `packages/engine-version`. |
  | `hash` | string | no | The `sha256` hash that immutably pins the coordinate. |

- **Intended render:** an inline version pill, optionally linking to the pinned coordinate's generated source.
- **Example:**

  ```markdoc
  {% version engineVersion="v1" coordinate="action-catalog.v1.ecs-contract-surface-closure" /%}
  ```

### `generated-reference`

- **Purpose:** embeds a thin pointer to a Tier-2 generated file instead of restating its tables.
- **Form:** self-closing.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `file` | string | yes | Repo-relative path to the Tier-2 generated file. |
  | `anchor` | string | no | Heading anchor within the generated file. |
  | `label` | string | no | Display label for the link. |

- **Intended render:** a "Canonical reference" link card pointing at the generated file, with a note that the table is generated and must not be copied.
- **Example:**

  ```markdoc
  {% generated-reference file="docs/spec/generated/component-types.md" label="ECS component inventory" /%}
  ```

### `proof`

- **Purpose:** records the proof obligation or evidence backing a capability claim, tied to the v1 readiness registries.
- **Form:** block.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `class` | string | yes | Proof class (for example `playability`, `renderability`). |
  | `registry` | string | no | Source registry, for example `docs/cycles/v1-engine-readiness-loop/PROOF_REGISTRY.json`. |
  | `status` | string | no | Whether the evidence is `present`, `pending`, or `absent`, or the readiness-row progress it mirrors (`in_progress`, `unaccepted`, `planned`). |

- **Intended render:** an evidence callout listing the required proof and its current state.
- **Example:**

  ```markdoc
  {% proof class="playability" registry="docs/cycles/v1-engine-readiness-loop/PROOF_REGISTRY.json" status="pending" %}
  Requires collision proxy, nav and query proxy, semantic anchor, and a `playability.accepted` receipt.
  {% /proof %}
  ```

### `warning`

- **Purpose:** flags a caution, limitation, or footgun for the reader.
- **Form:** block.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `severity` | string | no | `info`, `caution`, or `critical` (defaults to `info`). |
  | `title` | string | no | Short heading for the warning. |

- **Intended render:** a colored admonition block keyed by `severity`.
- **Example:**

  ```markdoc
  {% warning severity="critical" title="Do not mutate the Project Graph directly" %}
  Use the Action Catalog or semantic authoring; raw graph mutations bypass authority and validation.
  {% /warning %}
  ```

### `ai-context`

- **Purpose:** marks a block as agent-facing operational guidance (what to call, what to avoid).
- **Form:** block.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `audience` | string | no | Target client: `codex`, `claude-code`, `mcp`, `sdk`, `internal`, or `any`. |
  | `priority` | string | no | `must`, `should`, or `avoid`. |

- **Intended render:** an agent-oriented callout, visually distinct from human prose, optionally filtered by audience.
- **Example:**

  ```markdoc
  {% ai-context audience="mcp" priority="avoid" %}
  Do not paste full project snapshots into context; call `agent_get_project_context` for a compact packet.
  {% /ai-context %}
  ```

### `mcp-tool`

- **Purpose:** references a single MCP tool from the generated MCP reference.
- **Form:** self-closing.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `name` | string | yes | The MCP tool name (for example `agent_get_project_context`). |
  | `file` | string | no | Generated MCP reference path; defaults to `docs/creator/mcp/tool-reference.md`. |

- **Intended render:** an inline tool chip linking to the tool's entry in the generated MCP reference.
- **Example:**

  ```markdoc
  {% mcp-tool name="agent_get_project_context" /%}
  ```

### `component`

- **Purpose:** references a single ECS component from the generated component inventory.
- **Form:** self-closing.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `name` | string | yes | The component type name (for example `RigidBodyComponent`). |
  | `file` | string | no | Generated reference path; defaults to `docs/spec/generated/component-types.md`. |

- **Intended render:** an inline component chip linking to the component's row in the generated inventory.
- **Example:**

  ```markdoc
  {% component name="RigidBodyComponent" /%}
  ```

### `action`

- **Purpose:** references a single Action Catalog verb from the generated action reference.
- **Form:** self-closing.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `name` | string | yes | The action id (for example `project.world.create`). |
  | `file` | string | no | Generated reference path; defaults to `docs/spec/generated/action-catalog.md`. |

- **Intended render:** an inline action chip linking to the verb's row in the generated Action Catalog.
- **Example:**

  ```markdoc
  {% action name="project.world.create" /%}
  ```

### `capability`

- **Purpose:** references a single capability or capability pack from the generated capability reference.
- **Form:** self-closing.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `id` | string | yes | The capability or pack id (for example `physics.v1`). |
  | `file` | string | no | Generated reference path; defaults to `docs/spec/generated/capability-catalog.md`. |

- **Intended render:** an inline capability chip linking to the capability's entry in the generated capability reference or pack list.
- **Example:**

  ```markdoc
  {% capability id="physics.v1" file="docs/spec/generated/capability-packs.md" /%}
  ```

### `recipe`

- **Purpose:** marks a reusable, ordered task recipe (a how-to sequence) for humans or agents.
- **Form:** block.
- **Attributes:**

  | Attribute | Type | Required | Description |
  | --- | --- | --- | --- |
  | `id` | string | yes | Stable recipe identifier. |
  | `goal` | string | no | One-line statement of what the recipe accomplishes. |
  | `audience` | string | no | `human`, `agent`, or `both`. |

- **Intended render:** a numbered recipe card with a goal header; pairs naturally with how-to pages.
- **Example:**

  ```markdoc
  {% recipe id="build-from-prompt" goal="Turn a prompt into an executable world" audience="both" %}
  1. Submit the world spec via the World Build Contract.
  2. Validate against the Project Graph.
  3. Collect playability proof receipts before claiming the world is playable.
  {% /recipe %}
  ```

## Tag Data Bindings

The eleven tags split into two groups by where their truth lives. The `BINDING_TAGS` export in `scripts/markdoc/tags.ts` is the authoritative list of which tag resolves into which generated file.

**Tags that bind to Tier-2 generated data** (these resolve identifiers against generated files and must point at the canonical reference rather than restate it):

- `generated-reference` binds by `file` path, which must exist under `docs/spec/generated/` or `docs/creator/`.
- `mcp-tool` binds by `name` into [`docs/creator/mcp/tool-reference.md`](../creator/mcp/tool-reference.md).
- `component` binds by `name` into [`docs/spec/generated/component-types.md`](../spec/generated/component-types.md).
- `action` binds by `name` into [`docs/spec/generated/action-catalog.md`](../spec/generated/action-catalog.md).
- `capability` binds by `id` into [`docs/spec/generated/capability-catalog.md`](../spec/generated/capability-catalog.md) and [`docs/spec/generated/capability-packs.md`](../spec/generated/capability-packs.md).

**Tags that are pure prose annotations** (no binding to generated data; they carry editorial and contract semantics only):

- `contract`, `version`, `proof`, `warning`, `ai-context`, `recipe`.

`version` and `proof` may *reference* pinned coordinates and registries by string, but they do not resolve a row in a generated catalog the way the binding tags do.

## Enforcement Today and Where It Hardens

The Markdoc guard (`scripts/check-docs-markdoc.ts`) runs under `npm run check:docs` and enforces, for every tag used in prose (tags shown inside fenced code blocks are skipped):

- The tag is one of the eleven; unknown tags fail.
- Required attributes are present, unknown attributes fail, and an enumerated attribute value is in range.
- A binding tag's referenced value resolves into its generated file.

The binding resolution is the narrow part: it uses a naive substring `.includes()` over the generated file, so a value that is a substring of unrelated text resolves even when there is no matching table row. The `version` tag's `coordinate` and `hash` are free strings that no check validates against `packages/engine-version`. Both gaps are closed by the [docs program](../cycles/docs-program/SPEC.md), which replaces substring resolution with anchored heading and table-row resolution and binds coordinate references to the version constants.

## Status

The eleven tags, their attributes, intended render, and data bindings are implemented in `scripts/markdoc/tags.ts`, rendered by `scripts/docs-site/build.ts`, and validated by `scripts/check-docs-markdoc.ts`. Every page stays valid Markdown. The remaining gap is resolution strength (substring, not row) and unvalidated `version` coordinates; the [docs program](../cycles/docs-program/SPEC.md) hardens both. See the [Documentation Contract Architecture](./DOCUMENTATION_CONTRACT_ARCHITECTURE.md) for the three-tier model these tags enforce and the [Docs Validation Plan](./DOCS_VALIDATION_PLAN.md) for the full guard suite.
