{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://markup-carve.github.io/carve/ast-schema.json",
  "title": "Carve AST exchange format",
  "description": "The JSON encoding of a parsed Carve document, normative in PART 12 of the grammar (resources/grammar.ebnf). One shape, so a consumer written against one implementation reads another's output: field names and node-type identifiers are spec surface, and an implementation whose internals differ maps on the way out rather than exporting them.\n\nVersion 0.1. Generated JSON is validated against this file over the whole spec corpus by tests/ast-schema.test.mjs.",
  "$ref": "#/$defs/document",
  "$defs": {
    "abbreviation": {
      "type": "object",
      "title": "abbreviation (inline)",
      "required": [
        "type",
        "abbr",
        "expansion"
      ],
      "properties": {
        "type": {
          "const": "abbreviation"
        },
        "abbr": {
          "type": "string"
        },
        "expansion": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "link_reference_definition": {
      "type": "object",
      "title": "link_reference_definition (block)",
      "description": "The `[label]: /url \"title\" {attrs}` definition line. Renders nothing in HTML itself; it feeds every link or image that resolves the label (PART 9R R1). Hoisted to the document like the footnote definition (PART 12 section 7; an abbreviation definition inside a container is not a definition at all, so nothing is hoisted), so a definition authored inside a container is a child of the document and its `pos` still says where it was written.",
      "required": [
        "type",
        "label",
        "href"
      ],
      "properties": {
        "type": {
          "const": "link_reference_definition"
        },
        "label": {
          "type": "string",
          "description": "The reference label as the author wrote it, before case folding. Matching is case-sensitive (PART 9R R1)."
        },
        "href": {
          "type": "string",
          "description": "The destination. Present and non-empty: a definition with an empty destination is not a definition, it is paragraph text."
        },
        "title": {
          "type": "string",
          "description": "The quoted title, unescaped, when the definition carries one."
        },
        "attrs": {
          "$ref": "#/$defs/attrs",
          "description": "A trailing attribute block on the definition line (carve#604). Transfers to every link or image resolving the label, with the reference site's own attributes overriding per key under section 15 A3."
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "abbreviation_def": {
      "type": "object",
      "title": "abbreviation_def (block)",
      "description": "The `*[ABBR]: expansion` definition line. Renders nothing itself; it feeds the inline `abbreviation`.",
      "required": [
        "type",
        "abbr",
        "expansion"
      ],
      "properties": {
        "type": {
          "const": "abbreviation_def"
        },
        "abbr": {
          "type": "string"
        },
        "expansion": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "admonition": {
      "type": "object",
      "title": "admonition (block)",
      "description": "A typed `::: word` container. Its own type rather than a `div` carrying a class, so a profile can deny callouts while allowing generic containers.",
      "required": [
        "type",
        "kind",
        "children"
      ],
      "properties": {
        "type": {
          "const": "admonition"
        },
        "kind": {
          "type": "string"
        },
        "title": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "label": {
          "type": "string",
          "description": "Opener `[label]` grouping id (`::: tab [First]`). Inert in core."
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "attrs": {
      "type": "object",
      "title": "Attribute block",
      "description": "The `{#id .class key=value}` block attached to the node. A boolean attribute (`{disabled}`) is a key with an empty-string value.",
      "properties": {
        "id": {
          "type": "string"
        },
        "classes": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "keyValues": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          }
        },
        "order": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Source-appearance order of the slots: `#id`, `.class`, or a bare key name. Absent on a programmatically built tree."
        }
      },
      "additionalProperties": false
    },
    "autolink": {
      "type": "object",
      "title": "autolink (inline)",
      "description": "Its own type rather than a `link`: it carries no label and shows its own target, so folding it into `link` would lose the authored form.",
      "required": [
        "type",
        "href"
      ],
      "properties": {
        "type": {
          "const": "autolink"
        },
        "href": {
          "type": "string"
        },
        "text": {
          "type": "string",
          "description": "Display text: the raw content between `<` and `>`."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "blockNode": {
      "type": "object",
      "title": "Any block node",
      "description": "Dispatches on `type`. An unlisted type is rejected: PART 9 section 8 makes the identifiers spec surface, and they are `snake_case` always.",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "enum": [
            "abbreviation_def",
            "admonition",
            "block_quote",
            "citation_definition",
            "code_block",
            "comment",
            "definition_description",
            "definition_list",
            "definition_term",
            "div",
            "figure",
            "figure_group",
            "footnote",
            "frontmatter",
            "heading",
            "image",
            "line_block",
            "list",
            "list_item",
            "link_reference_definition",
            "paragraph",
            "raw_block",
            "table",
            "table_cell",
            "table_row",
            "thematic_break"
          ]
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "type": {
                "const": "abbreviation_def"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/abbreviation_def"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "link_reference_definition"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/link_reference_definition"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "admonition"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/admonition"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "block_quote"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/block_quote"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "citation_definition"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/citation_definition"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "code_block"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/code_block"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "comment"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/comment"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "definition_description"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/definition_description"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "definition_list"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/definition_list"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "definition_term"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/definition_term"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "div"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/div"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "figure"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/figure"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "figure_group"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/figure_group"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "footnote"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/footnote"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "frontmatter"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/frontmatter"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "heading"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/heading"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "image"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/image"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "line_block"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/line_block"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "list"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/list"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "list_item"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/list_item"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "paragraph"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/paragraph"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "raw_block"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/raw_block"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "table"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/table"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "table_cell"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/table_cell"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "table_row"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/table_row"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "thematic_break"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/thematic_break"
          }
        }
      ]
    },
    "block_quote": {
      "type": "object",
      "title": "block_quote (block)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "block_quote"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "caption_number": {
      "type": "object",
      "title": "caption_number (inline)",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "caption_number"
        },
        "n": {
          "type": "integer",
          "description": "Assigned during resolution; absent before it. A resolution result, serialized because recomputing it means reimplementing PART 9R."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "citation": {
      "type": "object",
      "title": "Citation item",
      "description": "One `@key` inside a citation group. A plain object, like `definition_item`.",
      "required": [
        "key",
        "suppressAuthor"
      ],
      "properties": {
        "key": {
          "type": "string"
        },
        "prefix": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "locator": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          },
          "description": "Raw inline locator after `, ` (e.g. `p. 33`), kept for byte-stable visible output."
        },
        "locatorLabel": {
          "type": "string",
          "description": "Canonical citeproc locator label parsed from `locator` (e.g. `page`)."
        },
        "locatorValue": {
          "type": "string",
          "description": "Locator value parsed from `locator` (e.g. `33-35, 38`)."
        },
        "suffix": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "suppressAuthor": {
          "type": "boolean",
          "description": "`-@key`: suppress the author in author-date mode."
        },
        "number": {
          "type": "integer",
          "description": "Assigned during resolution in numbered mode."
        },
        "useIndex": {
          "type": "integer",
          "description": "Per-key, document-wide use-site index (1-based); drives back-link anchors."
        }
      },
      "additionalProperties": false
    },
    "citation_definition": {
      "type": "object",
      "title": "citation_definition (block)",
      "description": "The `[@key]: {author= year=} entry` bibliography line (PART 12 section 18). Shaped after `link_reference_definition` rather than after the footnote: a footnote body holds blocks, while a citation definition holds a metadata run plus one line of rendered text. Renders nothing where it sits; the entry's text renders in the references list the Citations extension builds. Tier-2, so a default-profile parse never produces it.",
      "required": [
        "type",
        "key",
        "children"
      ],
      "properties": {
        "type": {
          "const": "citation_definition"
        },
        "key": {
          "type": "string",
          "description": "The citation key as the author wrote it, without the `@`. The same string `citation.key` carries at the use site."
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          },
          "description": "The entry's inline content: what follows the `]: ` separator and the optional metadata block. Required as a field, but may be an empty array: which source lines carry no entry is a separate question PART 12 section 18 does not settle."
        },
        "attrs": {
          "$ref": "#/$defs/attrs",
          "description": "The leading `{author= year=}` metadata block, when the definition carries one. `author` and `year` feed author-date mode."
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "citation_group": {
      "type": "object",
      "title": "citation_group (inline)",
      "required": [
        "type",
        "items",
        "raw"
      ],
      "properties": {
        "type": {
          "const": "citation_group"
        },
        "items": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/citation"
          }
        },
        "raw": {
          "type": "string",
          "description": "Verbatim source `[...]`, for the undefined-key literal fallback."
        },
        "mode": {
          "const": "integral",
          "description": "Set by a leading `+` after `[`. Absent means parenthetical."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "code": {
      "type": "object",
      "title": "code (inline)",
      "required": [
        "type",
        "value"
      ],
      "properties": {
        "type": {
          "const": "code"
        },
        "value": {
          "type": "string",
          "description": "May contain U+E000, the NO-BREAK SPACE SENTINEL. This content is verbatim, so the sentinel here is a U+E000 the author typed rather than one the parser resolved from an escaped space; on the wire the two are the same character and carry the same rule. A consumer MUST map U+E000 to its target's no-break space, or to an ordinary space where the target has none, and MUST NOT emit it. See `text.value` for the full sentinel rule."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "code_block": {
      "type": "object",
      "title": "code_block (block)",
      "required": [
        "type",
        "content"
      ],
      "properties": {
        "type": {
          "const": "code_block"
        },
        "content": {
          "type": "string",
          "description": "May contain U+E000, the NO-BREAK SPACE SENTINEL. This content is verbatim, so the sentinel here is a U+E000 the author typed rather than one the parser resolved from an escaped space; on the wire the two are the same character and carry the same rule. A consumer MUST map U+E000 to its target's no-break space, or to an ordinary space where the target has none, and MUST NOT emit it. See `text.value` for the full sentinel rule."
        },
        "lang": {
          "type": "string"
        },
        "header": {
          "type": "string",
          "description": "Quoted title from the info string (```php \"src/Auth.php\")."
        },
        "label": {
          "type": "string",
          "description": "Bracketed grouping label from the info string (```php [NPM]). Structured metadata, not part of the language class."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "comment": {
      "type": "object",
      "title": "comment (block or inline)",
      "description": "An author comment. Renders nothing, and is serialized because a writer has to reproduce it.",
      "required": [
        "type",
        "block",
        "content"
      ],
      "properties": {
        "type": {
          "const": "comment"
        },
        "block": {
          "type": "boolean",
          "description": "True for the fenced `%%%` block form, false for an inline `%%` or `{% … %}` comment."
        },
        "delimited": {
          "type": "boolean",
          "description": "True for the braced `{% … %}` inline form (PART 9 §21a). Absent means the trailing `%%` form. An author-choice field: the two spell different documents, since `%%` runs to the end of its inline run and the braced form ends at its closer, so a writer has to reproduce the one that was written."
        },
        "content": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "critic_comment": {
      "type": "object",
      "title": "critic_comment (inline)",
      "description": "Its own type rather than a `comment`, so a profile that accepts editorial marks but not side commentary can say so.",
      "required": [
        "type",
        "text"
      ],
      "properties": {
        "type": {
          "const": "critic_comment"
        },
        "text": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "definition_description": {
      "type": "object",
      "title": "definition_description (block)",
      "description": "A `<dd>`: the block content of one `:  definition`. It belongs to the run of terms before it.",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "definition_description"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "definition_list": {
      "type": "object",
      "title": "definition_list (block)",
      "description": "Its items are the `<dt>` / `<dd>` sequence, in document order: a run of `definition_term` nodes followed by the `definition_description` nodes they share. The grouping is not published because it is not a shared fact - two engines that published it grouped the same document differently while rendering the same list - and because a plain object can carry no `pos`, which left a term the only content in a serialized document an editor could not navigate to (PART 12 §4).",
      "required": [
        "type",
        "items"
      ],
      "properties": {
        "type": {
          "const": "definition_list"
        },
        "items": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "$ref": "#/$defs/definition_term"
              },
              {
                "$ref": "#/$defs/definition_description"
              }
            ]
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "definition_term": {
      "type": "object",
      "title": "definition_term (block)",
      "description": "A `<dt>`: the inline content of one `:: term` line. Consecutive terms belong to the descriptions that follow them, which is what the rendered list shows.",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "definition_term"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "delete": {
      "type": "object",
      "title": "delete (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "delete"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "div": {
      "type": "object",
      "title": "div (block)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "div"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "label": {
          "type": "string",
          "description": "Opener `[label]` grouping id. Inert in core."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "document": {
      "type": "object",
      "title": "document (root)",
      "description": "The root carries EXACTLY three fields (PART 12 section 7). Frontmatter and definitions - footnote AND abbreviation alike (PART 12 section 7) - are block nodes in `children`, not root fields, because a root field cannot carry the `pos` section 4 requires of everything else - and both are source an editor navigates to.\n\nThe root is the one node with no `pos`: it spans the whole source by definition.",
      "required": [
        "type",
        "children",
        "srcByteLength"
      ],
      "properties": {
        "type": {
          "const": "document"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "srcByteLength": {
          "type": "integer",
          "minimum": 0,
          "description": "BYTE length of the source - the one field here counted in bytes rather than codepoints. It answers 'how much source was this', not 'where in it'."
        }
      },
      "additionalProperties": false
    },
    "emphasis": {
      "type": "object",
      "title": "emphasis (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "emphasis"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "escaped_text": {
      "type": "object",
      "title": "escaped_text (inline)",
      "description": "A character the author escaped (`\\-`). Its own type because the escape carries intent the character alone does not.",
      "required": [
        "type",
        "value"
      ],
      "properties": {
        "type": {
          "const": "escaped_text"
        },
        "value": {
          "type": "string",
          "description": "The literal character, WITHOUT the backslash."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "figure": {
      "type": "object",
      "title": "figure (block)",
      "required": [
        "type",
        "target",
        "caption"
      ],
      "properties": {
        "type": {
          "const": "figure"
        },
        "target": {
          "description": "The captioned block: an image, block quote, table, code block or paragraph. What a captioned host is called and counted as comes from the caption's label, never from the host (PART 9 §4b); for a quote the HTML Standard also requires the attribution outside the `blockquote`.",
          "oneOf": [
            {
              "$ref": "#/$defs/image"
            },
            {
              "$ref": "#/$defs/block_quote"
            },
            {
              "$ref": "#/$defs/table"
            },
            {
              "$ref": "#/$defs/code_block"
            },
            {
              "$ref": "#/$defs/paragraph"
            }
          ]
        },
        "caption": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "shortCaption": {
          "type": "array",
          "description": "Optional abbreviated navigation caption imported from or destined for a structured publishing format. Carve 0.1 source has no spelling for this field; ordinary renderers ignore it.",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "figure_group": {
      "type": "object",
      "title": "figure_group (block)",
      "description": "A composite figure (PART 9 §4c, carve#1122): one figure-numbering unit whose direct captionable children - ordinary `figure` and `table` nodes among `children`, in source order - are its panels. There is no `panels` array: a consumer derives the panel list the way the renderer does, by type, in order, and non-panel stray content is preserved in place between them. Discriminated by `type` rather than by shape: every `figure` carries a `target`, this node deliberately does not, and probing for the missing field instead of the type string would break the day either shape grows a field. No title, no label, no `shortCaption`, no legend fields - the group's one authored metadata channel is `caption`, and the rest is carve#1118/carve#1121 design space, not claimed here.",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "figure_group"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "caption": {
          "type": "array",
          "description": "The GROUP caption (the `^ ` line after the closing fence). Absent means the group is uncaptioned - no empty-array placeholder.",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "footnote": {
      "type": "object",
      "title": "footnote (block)",
      "description": "A footnote DEFINITION. A child of the document even when authored inside a container (PART 9 section 16); its `pos` still records where it was written.",
      "required": [
        "type",
        "label",
        "children"
      ],
      "properties": {
        "type": {
          "const": "footnote"
        },
        "label": {
          "type": "string",
          "description": "The label as written, without `[^` and `]:` (PART 12 section 7)."
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "footnote_ref": {
      "type": "object",
      "title": "footnote_ref (inline)",
      "description": "A reference to a definition. Split from `inline_footnote` because a profile has to be able to deny one without the other (carve#405).",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "footnote_ref"
        },
        "id": {
          "type": "string",
          "description": "Reference label of `[^label]`, matched against the document's `footnote` definitions."
        },
        "number": {
          "type": "integer",
          "description": "Assigned during resolution, by document reference order."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "frontmatter": {
      "type": "object",
      "title": "frontmatter (block)",
      "description": "Frontmatter as written. The FIRST child when present (PART 12 section 7).",
      "required": [
        "type",
        "format",
        "content"
      ],
      "properties": {
        "type": {
          "const": "frontmatter"
        },
        "format": {
          "type": "string",
          "description": "The info word on the opening fence, or `yaml` when it carries none."
        },
        "content": {
          "type": "string",
          "description": "The text between the fences, VERBATIM. Never a parsed mapping (PART 12 section 7)."
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "hard_break": {
      "type": "object",
      "title": "hard_break (inline)",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "hard_break"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "heading": {
      "type": "object",
      "title": "heading (block)",
      "required": [
        "type",
        "level",
        "children"
      ],
      "properties": {
        "type": {
          "const": "heading"
        },
        "level": {
          "type": "integer",
          "minimum": 1,
          "maximum": 6
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs",
          "description": "`id` holds the heading's id whether the author wrote `{#id}` or it was slugged from the heading text. A GENERATED id is assigned during resolution and is a resolution result under PART 12 §5, serialized because recomputing it means replaying every earlier heading and the dedup suffix rule (`Notes`, then `Notes-2`) - a consumer holding only the tree cannot derive it."
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "heading_ref": {
      "type": "object",
      "title": "heading_ref (inline)",
      "required": [
        "type",
        "target"
      ],
      "properties": {
        "type": {
          "const": "heading_ref"
        },
        "target": {
          "type": "string",
          "description": "Raw id between `</#` and `>`, as the author spelled it. Ids resolve case-insensitively, so this is not necessarily the id it resolved to."
        },
        "href": {
          "type": "string",
          "description": "The resolved destination (`#` + the heading's id), present only where the crossref resolved. PART 12 §3a: the resolution is published beside the authored construct, not in place of it."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "highlight": {
      "type": "object",
      "title": "highlight (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "highlight"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "image": {
      "type": "object",
      "title": "image (block or inline)",
      "description": "Also valid in BLOCK position: a lone image paragraph is a block-level image.",
      "required": [
        "type",
        "src",
        "alt"
      ],
      "properties": {
        "type": {
          "const": "image"
        },
        "src": {
          "type": "string",
          "description": "Source. Carries the RESOLVED destination when the document defines the reference; empty ONLY where nothing resolved it (PART 12 section 3a). `ref`/`rawRef` sit alongside it and record what the author wrote."
        },
        "alt": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "ref": {
          "type": "string",
          "description": "Reference label of `![alt][ref]`, as the reference resolves by - the DERIVED label for the collapsed form `![alt][]`, where the author wrote nothing between the second brackets. Present whenever the author wrote a reference image - resolved or not - because the serialized tree is PRE-RESOLVE (PART 12 section 3a). It is not a transient between parse and resolve."
        },
        "rawRef": {
          "type": "string",
          "description": "Verbatim source of the reference as written, so the construct can be restored. Reachable because the tree is PRE-RESOLVE (PART 12 section 3a); under a post-resolve tree this field would describe something already discarded."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "inlineNode": {
      "type": "object",
      "title": "Any inline node",
      "description": "Dispatches on `type`.",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "enum": [
            "abbreviation",
            "autolink",
            "caption_number",
            "citation_group",
            "code",
            "comment",
            "critic_comment",
            "delete",
            "emphasis",
            "escaped_text",
            "footnote_ref",
            "hard_break",
            "heading_ref",
            "highlight",
            "image",
            "inline_extension",
            "inline_footnote",
            "insert",
            "link",
            "literal_inline",
            "math",
            "mention",
            "raw_inline",
            "smart_punctuation",
            "soft_break",
            "span",
            "strike",
            "strong",
            "subscript",
            "substitution",
            "superscript",
            "symbol",
            "tag",
            "text",
            "underline"
          ]
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "type": {
                "const": "abbreviation"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/abbreviation"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "autolink"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/autolink"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "caption_number"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/caption_number"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "citation_group"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/citation_group"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "code"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/code"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "comment"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/comment"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "critic_comment"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/critic_comment"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "delete"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/delete"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "emphasis"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/emphasis"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "escaped_text"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/escaped_text"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "footnote_ref"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/footnote_ref"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "hard_break"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/hard_break"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "heading_ref"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/heading_ref"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "highlight"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/highlight"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "image"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/image"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "inline_extension"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/inline_extension"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "inline_footnote"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/inline_footnote"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "insert"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/insert"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "link"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/link"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "literal_inline"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/literal_inline"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "math"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/math"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "mention"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/mention"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "raw_inline"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/raw_inline"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "smart_punctuation"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/smart_punctuation"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "soft_break"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/soft_break"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "span"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/span"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "strike"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/strike"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "strong"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/strong"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "subscript"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/subscript"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "substitution"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/substitution"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "superscript"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/superscript"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "symbol"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/symbol"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "tag"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/tag"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "text"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/text"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "underline"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/underline"
          }
        }
      ]
    },
    "inline_extension": {
      "type": "object",
      "title": "inline_extension (inline)",
      "required": [
        "type",
        "name",
        "content"
      ],
      "properties": {
        "type": {
          "const": "inline_extension"
        },
        "name": {
          "type": "string"
        },
        "content": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "inline_footnote": {
      "type": "object",
      "title": "inline_footnote (inline)",
      "description": "`^[content]` - a footnote whose body is written at the point of use.",
      "required": [
        "type",
        "inline"
      ],
      "properties": {
        "type": {
          "const": "inline_footnote"
        },
        "inline": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "number": {
          "type": "integer"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "insert": {
      "type": "object",
      "title": "insert (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "insert"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "line_block": {
      "type": "object",
      "title": "line_block (block)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "line_block"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "link": {
      "type": "object",
      "title": "link (inline)",
      "description": "`href` is the destination field name for every implementation (PART 12 section 3): a consumer must not have to know which engine produced the document.",
      "required": [
        "type",
        "href",
        "children"
      ],
      "properties": {
        "type": {
          "const": "link"
        },
        "href": {
          "type": "string",
          "description": "Destination. Carries the RESOLVED destination when the document defines the reference; empty ONLY where nothing resolved it (PART 12 section 3a). `ref`/`rawRef` sit alongside it and record what the author wrote."
        },
        "title": {
          "type": "string"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "ref": {
          "type": "string",
          "description": "Reference label of `[text][ref]`, as the reference resolves by - the DERIVED label for the collapsed form `[label][]`, where the author wrote nothing between the second brackets. Present whenever the author wrote a reference link - resolved or not - because the serialized tree is PRE-RESOLVE (PART 12 section 3a). It is not a transient between parse and resolve."
        },
        "rawRef": {
          "type": "string",
          "description": "Verbatim source of the reference as written, so the construct can be restored. Reachable because the tree is PRE-RESOLVE (PART 12 section 3a); under a post-resolve tree this field would describe something already discarded."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "list": {
      "type": "object",
      "title": "list (block)",
      "description": "`delim` and `bulletChar` are author-choice fields: a sibling list with a different marker is a DIFFERENT list, so a writer has to reproduce the spelling.",
      "required": [
        "type",
        "ordered",
        "tight",
        "items"
      ],
      "properties": {
        "type": {
          "const": "list"
        },
        "ordered": {
          "type": "boolean"
        },
        "tight": {
          "type": "boolean"
        },
        "items": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/list_item"
          }
        },
        "start": {
          "type": "integer",
          "description": "First number of an ordered list, when it is not 1."
        },
        "olType": {
          "enum": [
            "a",
            "A",
            "i",
            "I"
          ],
          "description": "Ordered-list numbering style; absent means decimal."
        },
        "delim": {
          "enum": [
            ".",
            ")"
          ],
          "description": "Ordered-marker delimiter AS AUTHORED (PART 11 section 6). Absent means the default `.`."
        },
        "bareMarker": {
          "const": true,
          "description": "Ordered list written with the BARE dot marker (`. item`), which carries no number, AS AUTHORED (PART 11 section 6). Absent means the author numbered it. Without this the bare form decodes as `1. item`: `delim` and `bulletChar` carry marker flavor for every other form, and this was the one authored distinction with no field to hold it (carve#480)."
        },
        "bulletChar": {
          "enum": [
            "-",
            "*"
          ],
          "description": "Bullet character AS AUTHORED (PART 11 section 6). Absent means the default `-`."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "list_item": {
      "type": "object",
      "title": "list_item (block)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "list_item"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "checked": {
          "type": "boolean",
          "description": "Present only on a task-list item; absent on a plain bullet."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "literal_inline": {
      "type": "object",
      "title": "literal_inline (inline)",
      "description": "`` !`...` `` - verbatim content emitted by every renderer and escaped on output, unlike raw passthrough.",
      "required": [
        "type",
        "content"
      ],
      "properties": {
        "type": {
          "const": "literal_inline"
        },
        "content": {
          "type": "string",
          "description": "May contain U+E000, the NO-BREAK SPACE SENTINEL. This content is verbatim, so the sentinel here is a U+E000 the author typed rather than one the parser resolved from an escaped space; on the wire the two are the same character and carry the same rule. A consumer MUST map U+E000 to its target's no-break space, or to an ordinary space where the target has none, and MUST NOT emit it. See `text.value` for the full sentinel rule."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "math": {
      "type": "object",
      "title": "math (inline)",
      "required": [
        "type",
        "display",
        "content"
      ],
      "properties": {
        "type": {
          "const": "math"
        },
        "display": {
          "type": "boolean"
        },
        "content": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "mention": {
      "type": "object",
      "title": "mention (inline)",
      "required": [
        "type",
        "user"
      ],
      "properties": {
        "type": {
          "const": "mention"
        },
        "user": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "paragraph": {
      "type": "object",
      "title": "paragraph (block)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "paragraph"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "pos": {
      "type": "object",
      "title": "Source span",
      "description": "A node's span in the source (PART 12 section 4). Lines and columns are 1-based, offsets 0-based, `endColumn` and `endOffset` exclusive, and columns and offsets are counted in UNICODE CODEPOINTS - not bytes, not UTF-16 code units.\n\nSection 4 REQUIRES this on every node except the document root. It is declared optional here because a JSON Schema can only answer 'is this shape valid', and an engine that cannot yet place a node must omit `pos` rather than invent one. Whether a producer places every node is a separate, per-node question, reported by the conformance runner (`scripts/ast-conformance.mjs`) rather than by this schema.",
      "required": [
        "startLine",
        "endLine",
        "startColumn",
        "endColumn",
        "startOffset",
        "endOffset"
      ],
      "properties": {
        "startLine": {
          "type": "integer",
          "minimum": 1
        },
        "endLine": {
          "type": "integer",
          "minimum": 1
        },
        "startColumn": {
          "type": "integer",
          "minimum": 1
        },
        "endColumn": {
          "type": "integer",
          "minimum": 1
        },
        "startOffset": {
          "type": "integer",
          "minimum": 0
        },
        "endOffset": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "raw_block": {
      "type": "object",
      "title": "raw_block (block)",
      "required": [
        "type",
        "format",
        "content"
      ],
      "properties": {
        "type": {
          "const": "raw_block"
        },
        "format": {
          "type": "string"
        },
        "content": {
          "type": "string",
          "description": "Byte-for-byte passthrough to the named target. U+E000 here is NOT the no-break space sentinel that `text.value`, `code.value`, `code_block.content` and `literal_inline.content` carry: raw content is handed to its target unexamined, so a U+E000 in it is a byte the author put there and a consumer MUST leave it alone. Mapping it would corrupt the payload this node exists to carry."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "raw_inline": {
      "type": "object",
      "title": "raw_inline (inline)",
      "required": [
        "type",
        "format",
        "content"
      ],
      "properties": {
        "type": {
          "const": "raw_inline"
        },
        "format": {
          "type": "string"
        },
        "content": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "smart_punctuation": {
      "type": "object",
      "title": "smart_punctuation (inline)",
      "description": "Carries BOTH the resolved sort and the source spelling, so a writer can reproduce the document rather than normalize it.",
      "required": [
        "type",
        "kind",
        "value"
      ],
      "properties": {
        "type": {
          "const": "smart_punctuation"
        },
        "kind": {
          "type": "string",
          "description": "The resolved sort: `ellipsis`, `em_dash`, `left_double_quote`, ..."
        },
        "value": {
          "type": "string",
          "description": "The author's source run, e.g. `...`, `->`, `\"`."
        },
        "glyph": {
          "type": "string",
          "description": "Resolved glyph, present when the parser fixed it (quotes are locale-dependent)."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "soft_break": {
      "type": "object",
      "title": "soft_break (inline)",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "soft_break"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "span": {
      "type": "object",
      "title": "span (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "span"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "strike": {
      "type": "object",
      "title": "strike (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "strike"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "strong": {
      "type": "object",
      "title": "strong (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "strong"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "boldItalic": {
          "const": true,
          "description": "Present when the author wrote the combined `/*...*/` form rather than nesting `*` around `/` (PART 11 section 6)."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "subscript": {
      "type": "object",
      "title": "subscript (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "subscript"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "substitution": {
      "type": "object",
      "title": "substitution (inline)",
      "required": [
        "type",
        "oldText",
        "newText"
      ],
      "properties": {
        "type": {
          "const": "substitution"
        },
        "oldText": {
          "type": "string"
        },
        "newText": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "superscript": {
      "type": "object",
      "title": "superscript (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "superscript"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "symbol": {
      "type": "object",
      "title": "symbol (inline)",
      "required": [
        "type",
        "name"
      ],
      "properties": {
        "type": {
          "const": "symbol"
        },
        "name": {
          "type": "string",
          "description": "The shortcode between the colons, without them."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "table": {
      "type": "object",
      "title": "table (block)",
      "required": [
        "type",
        "rows"
      ],
      "properties": {
        "type": {
          "const": "table"
        },
        "rows": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/table_row"
          }
        },
        "caption": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "shortCaption": {
          "type": "array",
          "description": "Optional abbreviated navigation caption imported from or destined for a structured publishing format. Carve 0.1 source has no spelling for this field; ordinary renderers ignore it.",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "rowGroups": {
          "type": "object",
          "description": "Optional explicit head/body/foot partition of `rows`, imported from or destined for a format whose table model has one. It PARTITIONS `rows` and never repeats them: the counts consume `rows` in order, head first, then each body, then the foot, and they MUST account for every row exactly once. Carve 0.1 source has no spelling for this field; absent means the implicit structure every renderer already derives - the leading run of header rows as the head, everything after it as one body, no foot, no row-head columns. HTML, plain and ANSI output ignore it.",
          "required": [
            "headRows",
            "bodies",
            "footRows"
          ],
          "properties": {
            "headRows": {
              "type": "integer",
              "minimum": 0,
              "description": "Rows at the start of `rows` forming the table head. Stated rather than derived, because a body's own intermediate header rows are header rows too and the leading run alone cannot say where one ends and the other begins."
            },
            "bodies": {
              "type": "array",
              "description": "The body groups, in order, each consuming the next `headRows + bodyRows` rows. An empty array is a table whose rows are all head and foot.",
              "items": {
                "type": "object",
                "required": [
                  "headRows",
                  "bodyRows"
                ],
                "properties": {
                  "headRows": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Rows at the start of this group forming its intermediate header."
                  },
                  "bodyRows": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Rows in this group after its intermediate header."
                  },
                  "rowHeadColumns": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Leading columns of this group's rows that are row headers. Absent means zero. It sits on the group rather than on the table because that is where the exchanged model puts it."
                  },
                  "attrs": {
                    "$ref": "#/$defs/attrs"
                  }
                },
                "additionalProperties": false
              }
            },
            "footRows": {
              "type": "integer",
              "minimum": 0,
              "description": "Rows at the end of `rows` forming the table foot."
            }
          },
          "additionalProperties": false
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "table_cell": {
      "type": "object",
      "title": "table_cell (block)",
      "required": [
        "type",
        "header",
        "children"
      ],
      "properties": {
        "type": {
          "const": "table_cell"
        },
        "header": {
          "type": "boolean"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "span": {
          "enum": [
            "rowspan",
            "colspan"
          ],
          "description": "Set by a `^` (rowspan) or `<` (colspan) continuation cell."
        },
        "align": {
          "enum": [
            "left",
            "right",
            "center"
          ],
          "description": "Explicit per-cell alignment; absent means the cell inherits its column's."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "table_row": {
      "type": "object",
      "title": "table_row (block)",
      "required": [
        "type",
        "cells"
      ],
      "properties": {
        "type": {
          "const": "table_row"
        },
        "cells": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/table_cell"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "tag": {
      "type": "object",
      "title": "tag (inline)",
      "description": "The AST form of `#tag`. Not a profile vocabulary entry - a profile classifies it as `mention`, since `@user` and `#tag` are one trust class.",
      "required": [
        "type",
        "name"
      ],
      "properties": {
        "type": {
          "const": "tag"
        },
        "name": {
          "type": "string"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "text": {
      "type": "object",
      "title": "text (inline)",
      "required": [
        "type",
        "value"
      ],
      "properties": {
        "type": {
          "const": "text"
        },
        "value": {
          "type": "string",
          "description": "May contain U+E000, the NO-BREAK SPACE SENTINEL. Three things put it here: an escaped space (`\\ `), the preserved indentation of a line block (PART 9 section 23), and a U+E000 the author typed. A line block's indentation is a RUN of the sentinel, one per preserved space, so a four-space indent is four U+E000 resolving to four no-break spaces - the source a consumer that has only seen `\\ ` will miss. The sentinel is distinct from a literal U+00A0 in the source, which is published as itself. A consumer MUST map U+E000 to its target's no-break space, or to an ordinary space where the target has none, and MUST NOT emit it. The same sentinel may appear on `code.value`, `code_block.content` and `literal_inline.content`; `raw_block.content` is byte-for-byte passthrough and is deliberately excluded."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "thematic_break": {
      "type": "object",
      "title": "thematic_break (block)",
      "description": "`marker` is an author-choice field: the three spellings render alike, so a writer has to reproduce the one the author wrote.",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "thematic_break"
        },
        "marker": {
          "enum": [
            "-",
            "*",
            "_"
          ],
          "description": "Thematic-break marker character AS AUTHORED (PART 11 section 6). Absent means the default `-`. The CHARACTER only: `***` and `*****` are one spelling and no run length is recorded (carve#1000)."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "underline": {
      "type": "object",
      "title": "underline (inline)",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "underline"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    }
  }
}
