{
  "$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 CALLOUT: a named `:::` container presenting the blocks written inside it, set apart - note, warning, tip, danger and the like. A container whose kind names generated content is a `directive` instead, and an anonymous or attribute-only one is a `div` (carve#2195).",
      "required": [
        "type",
        "kind",
        "children"
      ],
      "properties": {
        "type": {
          "const": "admonition"
        },
        "kind": {
          "type": "string",
          "minLength": 1,
          "not": {
            "enum": [
              "bibliography",
              "footnotes",
              "glossary",
              "index",
              "references",
              "toc"
            ]
          },
          "description": "The callout kind, as authored. Generated-content kinds (`bibliography`, `footnotes`, `glossary`, `index`, `references`, `toc`) belong on a `directive` instead (carve#2195)."
        },
        "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 a `children` array may hold",
      "description": "Dispatches on `type`. An unlisted type is rejected: PART 9 section 8 makes the identifiers spec surface, and they are `snake_case` always.\n\nA container-internal type is NOT listed here. `table_row`, `table_cell`, `list_item`, `definition_term` and `definition_description` exist only inside the container that owns them - `table.rows`, `table_row.cells`, `list.items` and `definition_list.items` name them directly - so a `children` array holding one is a tree no parser can produce. Listing them here made that payload valid, which left PART 12 section 12(d) unable to refuse it (carve#2189).",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "enum": [
            "abbreviation_def",
            "admonition",
            "block_extension",
            "block_quote",
            "citation_definition",
            "code_block",
            "comment",
            "definition_list",
            "div",
            "directive",
            "figure",
            "figure_group",
            "footnote",
            "frontmatter",
            "heading",
            "image",
            "line_block",
            "list",
            "link_reference_definition",
            "paragraph",
            "raw_block",
            "section",
            "table",
            "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_extension"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/block_extension"
          }
        },
        {
          "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_list"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/definition_list"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "div"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/div"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "directive"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/directive"
          }
        },
        {
          "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": "paragraph"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/paragraph"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "raw_block"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/raw_block"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "section"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/section"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "table"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/table"
          }
        },
        {
          "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"
          }
        },
        "fenced": {
          "description": "True when the quote was authored as a ::: > container rather than with > line markers. The two spellings are one node; this records which one, so the canonical writer can write back what it read. Absent on a >-prefixed quote.",
          "const": true
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "block_extension": {
      "type": "object",
      "title": "block_extension (block)",
      "description": "A block construct an extension owns, carried with a core FALLBACK so a reader that does not implement the extension still has something real to render, write and report. The twin of `inline_extension`, which had no block equivalent, so a Tier-3 block whose payload is not Carve content had to smuggle it through `attrs.keyValues` as strings or lose it (carve#2200). Carve 0.1 source spells no block extension, so a parser produces none.",
      "required": [
        "type",
        "name",
        "fallback"
      ],
      "properties": {
        "type": {
          "const": "block_extension"
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "Globally qualified, so two extensions cannot collide: `org.example.diagram`, not `diagram`."
        },
        "version": {
          "type": "string",
          "description": "The extension's own version, opaque here. Absent means the extension does not version its payload."
        },
        "fallback": {
          "$ref": "#/$defs/blockNode",
          "description": "REQUIRED. The core block a reader that does not implement this extension renders, writes and counts instead. It is not a placeholder: it is what the document MEANS to such a reader, so the renderer, the canonical writer and the loss report all have a defined answer rather than three separate special cases."
        },
        "payload": {
          "type": "object",
          "required": [
            "format"
          ],
          "properties": {
            "format": {
              "type": "string",
              "minLength": 1,
              "description": "A media type naming how `value` is encoded, so a reader can tell whether it can parse it at all."
            },
            "value": {
              "description": "The extension's own data. Opaque to this schema and to every core renderer."
            }
          },
          "additionalProperties": false,
          "description": "The extension's data, which is NOT Carve content and is never rendered by a core target. Subject to the ingest bound of §9 like any other nesting, and to §25's trust rules like any other content a renderer did not produce."
        },
        "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 (inline)",
      "description": "One positioned `@key` node inside a citation group.",
      "required": [
        "type",
        "key",
        "suppressAuthor"
      ],
      "properties": {
        "type": {
          "const": "citation"
        },
        "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."
        },
        "mode": {
          "const": "integral",
          "description": "This item's citation mode. Set from the group's `+` shorthand, which is the only way Carve 0.1 source spells it, so every item of a source-spelled group carries the same value. Absent means parenthetical. It sits on the ITEM because the models a bridge reaches put it there - Pandoc's `CitationMode` is per citation - and a group whose items differ is reachable from an importer even though no Carve source spells one (carve#2203)."
        },
        "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."
        },
        "pos": {
          "$ref": "#/$defs/pos",
          "description": "The complete citation item, from its optional prefix through its optional suffix. Present on a parsed citation; omitted where PART 12 section 4 exempts the node, as on one an importer or an editing API synthesized (carve#2192)."
        }
      },
      "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)",
      "not": {
        "type": "object",
        "required": [
          "mode"
        ],
        "properties": {
          "mode": {},
          "items": {
            "type": "array",
            "contains": {
              "not": {
                "type": "object",
                "required": [
                  "mode"
                ],
                "properties": {
                  "mode": {}
                }
              }
            }
          }
        }
      },
      "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 no group shorthand; each item's mode governs."
        },
        "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": "Literal Unicode content. U+E000 and all other private-use characters are preserved unchanged. Generated nonbreaking spaces use non_breaking_space nodes; no character is an AST sentinel."
        },
        "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": "Literal Unicode content. U+E000 and all other private-use characters are preserved unchanged. Generated nonbreaking spaces use non_breaking_space nodes; no character is an AST sentinel. Literal payload text, including its final LF when present (PART 12 section 3). Empty content, a blank line, and nonempty content with or without a final LF are distinct. Renderers do not append a payload newline."
        },
        "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"
              }
            ]
          }
        },
        "loose": {
          "const": true,
          "description": "The looseness was SPELLED, with PART 9 §17 L7's consumed `loose` boolean, so every description renders its children as blocks. Absent means each description derives its own wrapper from its block count, which is what every other definition list does. Only the spelled fact is published, because only it is underivable: a `<dl>` has no blank-line spelling for a one-block description at any entry count, so a serialized tree could not otherwise say which of the two spellings it came from (carve#1624)."
        },
        "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
    },
    "directive": {
      "type": "object",
      "title": "directive (block)",
      "description": "A generated-content directive: a named `:::` container whose kind asks the renderer to PLACE something the document already contains, rather than to present the blocks written inside it. Split from `admonition` because a table of contents is not a callout, and a consumer deciding whether to draw one had to carry a list of kinds that are not callouts (carve#2195).",
      "required": [
        "type",
        "kind",
        "children"
      ],
      "properties": {
        "type": {
          "const": "directive"
        },
        "kind": {
          "enum": [
            "bibliography",
            "footnotes",
            "glossary",
            "index",
            "references",
            "toc"
          ],
          "description": "Which generated content is placed here. A kind outside this list is an `admonition`, not a directive."
        },
        "title": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          },
          "description": "The opener's quoted title, as `admonition.title` carries it. The opener admits one on every named container, so `::: toc \"Contents\"` spells it here; it does not move the dispatch (carve#2247)."
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          },
          "description": "Blocks written inside the opener. Always published, using [] when empty; a directive's content is usually generated rather than authored."
        },
        "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). The label is spelled `label`, the same name its `footnote` definition uses; an engine that once published `id` may keep decoding that property onto this field under PART 12 section 11's narrow exception (carve#2193).",
      "required": [
        "type",
        "label"
      ],
      "properties": {
        "type": {
          "const": "footnote_ref"
        },
        "label": {
          "type": "string",
          "description": "Reference label of `[^label]`, matched against the document's `footnote` definitions by the same string that node carries in its own `label`."
        },
        "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. This covers the DIRECT spelling `![alt](src)` and both reference spellings, `![alt][ref]` and the collapsed `![alt][]`, once they resolve - a reference that resolves to nothing has no destination and stays inside its paragraph. Read the PUBLISHED tree when checking this: an engine may promote during reference resolution rather than in its block pass, so a parse-only tree can still show the paragraph (carve#1663). Where it does, `paragraph.blockImage` carries the answer - a consumer reads that field rather than re-deriving promotion from the paragraph's contents (PART 12 section 23).",
      "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`.\n\n`citation` is NOT listed. It is a declared node type and `citation_group.items` references it directly, but a citation is only ever an item of a group: PART 7 makes the bracket the unit a source spells, an item's `prefix`, `locator` and `suffix` mean nothing outside one, and no clause defines what a bare citation renders to in any target. Listing it here admitted a shape every engine refuses (carve#2227).",
      "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",
            "non_breaking_space",
            "raw_inline",
            "ruby",
            "small_caps",
            "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": "ruby"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/ruby"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "small_caps"
              }
            },
            "required": [
              "type"
            ]
          },
          "then": {
            "$ref": "#/$defs/small_caps"
          }
        },
        {
          "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"
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "non_breaking_space"
              }
            }
          },
          "then": {
            "$ref": "#/$defs/non_breaking_space"
          }
        }
      ]
    },
    "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"
          }
        },
        "lines": {
          "type": "array",
          "description": "PART 12 §36: the block's LINES as RANGES, parallel to `children` - entry `i` holds the lines of the stanza `children[i]`, so `lines` never spans a stanza. Each entry is an array of RFC 6901 pointers relative to that stanza, one per line and in document order, naming where the line STOPS: the `hard_break` that closes it, or `/children/-`, the past-the-end pointer, for the last line. Line `n` is the content between pointer `n-1` and pointer `n`, excluding both, so a run spanning a boundary is neither re-bracketed nor duplicated. A `hard_break` no pointer names is authored content. Absent means the lines are whatever splitting `children` on `hard_break` yields, which over-counts a trailing break and under-counts a boundary inside a run (carve#2235).",
          "items": {
            "type": "array",
            "minItems": 1,
            "contains": {
              "const": "/children/-"
            },
            "maxContains": 1,
            "items": {
              "type": "string",
              "pattern": "^(?:/(?:[^~/]|~[01])*)+$"
            }
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false,
      "description": "Verse, addresses and anything else whose line breaks are content. `children` carries the blocks as every consumer already reads them; `lines` says where each stanza's lines begin and end, added alongside rather than instead (PART 12 §5)."
    },
    "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."
        },
        "taskState": {
          "enum": [
            " ",
            "x",
            "-",
            "_",
            ">",
            "?"
          ],
          "description": "Task marker character AS AUTHORED (PART 11 section 6g), on a task item whose state is not the default for `checked`: absent means `x` when checked is true and ` ` when it is false. `X` is folded to `x`, which is a case, not a state (carve#1866). The two branches below spell the states rather than negating `x`: an engine validator that skips a keyword it does not implement accepts everything the keyword was added to reject, so this schema stays inside the subset every engine implements."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "allOf": [
        {
          "if": {
            "required": [
              "taskState"
            ],
            "properties": {
              "taskState": {
                "const": "x"
              }
            }
          },
          "then": {
            "required": [
              "checked"
            ],
            "properties": {
              "checked": {
                "const": true
              }
            }
          }
        },
        {
          "if": {
            "required": [
              "taskState"
            ],
            "properties": {
              "taskState": {
                "enum": [
                  " ",
                  "-",
                  "_",
                  ">",
                  "?"
                ]
              }
            }
          },
          "then": {
            "required": [
              "checked"
            ],
            "properties": {
              "checked": {
                "const": false
              }
            }
          }
        }
      ],
      "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": "Literal Unicode content. U+E000 and all other private-use characters are preserved unchanged. Generated nonbreaking spaces use non_breaking_space nodes; no character is an AST sentinel."
        },
        "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"
        },
        "label": {
          "type": "string",
          "minLength": 1,
          "pattern": "^\\S(?:[\\s\\S]*\\S)?$",
          "description": "Authored equation-number label, such as `Equation` or `Eq.`. It selects the numbering bucket and supplies the visible prefix; `attrs.id` is the cross-reference key."
        },
        "number": {
          "type": "integer",
          "minimum": 1,
          "description": "Equation number assigned during resolution. Present only on display math; absent before resolution."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "number": {}
            },
            "required": [
              "number"
            ]
          },
          "then": {
            "required": [
              "label"
            ],
            "properties": {
              "label": {},
              "display": {
                "const": true
              }
            }
          }
        }
      ],
      "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"
          }
        },
        "blockImage": {
          "const": true,
          "description": "Set by the BLOCK-IMAGE PROMOTION phase, and by nothing else (PART 9R R7, PART 12 section 23): this paragraph's whole content resolves to a single image, so it is a block-level image and not a paragraph. Present ONLY as `true` - a paragraph that is not a block image omits the field rather than carrying `false`.\n\nIt is a resolution result published alongside the authored construct, the same added-alongside rule that lets a resolved reference link keep `href` beside `ref` and `rawRef` (section 3a). A consumer READS it instead of re-deriving it: absent means the producer did not run the phase, not that the paragraph is ordinary, and an ingesting consumer runs promotion itself only where the field is absent.",
          "type": "boolean"
        },
        "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
        },
        "file": {
          "type": "string",
          "description": "Identity of the file these coordinates are measured in, when that is NOT the document being parsed: the canonical id of the file an include pulled the node in from (PART 9 section 19). Absent means the top-level document, so a tree with no includes is unchanged. Without it an included span is ambiguous - a child's first paragraph and the parent's first paragraph both report line 1."
        }
      },
      "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": "Verbatim passthrough to the named target, including private-use Unicode characters."
        },
        "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
    },
    "section": {
      "type": "object",
      "title": "section (block)",
      "description": "An explicit sectioning wrapper. Carve 0.1 source has no spelling for one - sectioning is implicit in heading level - so a parser does not produce it and a canonical Carve writer flattens it back to its headings and reports `structure-unspellable` on the conversion-diagnostics channel of PART 11 section 1d. It exists so the nesting a format with explicit sections carries (HTML5 `section`, JATS `sec`, DocBook `section`, DITA, TEI, and Pandoc's `--section-divs`) survives a bridge instead of being flattened and re-derived by every consumer that needs it (carve#2207).",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "section"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "level": {
          "type": "integer",
          "minimum": 1,
          "maximum": 6,
          "description": "The heading level this section corresponds to, where the source format states one. Absent means the level is whatever the nesting implies."
        },
        "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
    },
    "ruby": {
      "type": "object",
      "title": "ruby (inline)",
      "description": "An interchange-only ruby annotation. Carve 0.1 source has no spelling for the paired base and annotation structure.",
      "required": [
        "type",
        "pairs"
      ],
      "properties": {
        "type": {
          "const": "ruby"
        },
        "pairs": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/rubyPair"
          }
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    },
    "rubyPair": {
      "type": "object",
      "title": "ruby base/annotation pair",
      "required": [
        "base",
        "annotation"
      ],
      "properties": {
        "base": {
          "type": "array",
          "minItems": 1,
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "annotation": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        }
      },
      "additionalProperties": false
    },
    "small_caps": {
      "type": "object",
      "title": "small_caps (inline)",
      "description": "An interchange-only small-caps span. Carve 0.1 source has no spelling for this wrapper, so parsers do not produce it and canonical source writers omit the wrapper while preserving attributes on an ordinary attributed span. Conversion APIs with diagnostics should report the loss.",
      "required": [
        "type",
        "children"
      ],
      "properties": {
        "type": {
          "const": "small_caps"
        },
        "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",
        "old",
        "new"
      ],
      "properties": {
        "type": {
          "const": "substitution"
        },
        "old": {
          "type": "array",
          "description": "The deleted half, as inline content.",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "new": {
          "type": "array",
          "description": "The inserted half, as inline content.",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "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"
          }
        },
        "columns": {
          "type": "array",
          "description": "Optional positional column metadata imported from, authored through table-level aligns/valigns/widths attributes, or destined for a richer table model. Entry N describes column N; the array MAY be shorter than the widest row. A cell's explicit value wins over the corresponding column value.",
          "items": {
            "type": "object",
            "properties": {
              "align": {
                "enum": [
                  "left",
                  "right",
                  "center"
                ],
                "description": "Horizontal alignment inherited by cells in this column when they carry no explicit alignment."
              },
              "valign": {
                "enum": [
                  "top",
                  "middle",
                  "bottom"
                ],
                "description": "Vertical alignment inherited by cells in this column when they carry no explicit vertical alignment."
              },
              "width": {
                "type": "number",
                "exclusiveMinimum": 0,
                "maximum": 1,
                "description": "The column's fraction of the table width, in the interval (0, 1]. Widths need not sum to 1."
              }
            },
            "additionalProperties": false
          }
        },
        "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. ListTable can author a leading head, header-led body groups, a foot, and leading row-header columns; pipe-table body-rows, body-header-rows, and body-header-cols preserve arbitrary body partitions. Absent means the implicit structure every renderer already derives.",
          "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."
            },
            "headAttrs": {
              "$ref": "#/$defs/attrs"
            },
            "footAttrs": {
              "$ref": "#/$defs/attrs"
            },
            "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"
      ],
      "properties": {
        "type": {
          "const": "table_cell"
        },
        "header": {
          "type": "boolean"
        },
        "children": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/inlineNode"
          }
        },
        "blocks": {
          "type": "array",
          "description": "Block content, in place of the inline `children`. A cell carries one or the other, never both. Carve 0.1 source has no spelling for a block inside a cell, so a parser does not produce this field; it exists so an HTML `<td>` holding flow content, or a Pandoc `Cell` holding `[Block]`, survives a bridge instead of flattening to text. A canonical Carve writer loses it and reports `field-unspellable` for `table_cell.blocks` on the conversion-diagnostics channel of PART 11 section 1d.",
          "items": {
            "$ref": "#/$defs/blockNode"
          }
        },
        "span": {
          "enum": [
            "rowspan",
            "colspan"
          ],
          "description": "Set by a `^` (rowspan) or `<` (colspan) continuation cell."
        },
        "colspan": {
          "type": "integer",
          "minimum": 2,
          "description": "Resolved number of columns this cell occupies, from the span walk of PART 9 §13 T5. Published on the ORIGIN cell, alongside the `<` markers that extended it rather than instead of them. Absent means 1, and an ingested 1 is normalized away (PART 12 §22)."
        },
        "rowspan": {
          "type": "integer",
          "minimum": 2,
          "description": "Resolved number of rows this cell occupies, from the span walk of PART 9 §13 T5. Published on the ORIGIN cell, alongside the `^` markers that extended it rather than instead of them. Absent means 1, and an ingested 1 is normalized away (PART 12 §22)."
        },
        "align": {
          "enum": [
            "left",
            "right",
            "center"
          ],
          "description": "Explicit per-cell alignment; absent means the cell inherits its column's."
        },
        "valign": {
          "enum": [
            "top",
            "middle",
            "bottom"
          ],
          "description": "Explicit per-cell vertical alignment; absent means the cell inherits its column's."
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false,
      "oneOf": [
        {
          "required": [
            "children"
          ],
          "properties": {
            "children": true,
            "blocks": false
          }
        },
        {
          "required": [
            "blocks"
          ],
          "properties": {
            "blocks": true,
            "children": false
          }
        }
      ],
      "description": "A table cell. Its content is EITHER the inline `children` every source-spelled cell carries, OR the block `blocks` a format bridge needs - exactly one of the two, never both and never neither (carve#2191)."
    },
    "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": "Literal Unicode content. U+E000 and all other private-use characters are preserved unchanged. Generated nonbreaking spaces use non_breaking_space nodes; no character is an AST sentinel."
        },
        "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
    },
    "non_breaking_space": {
      "type": "object",
      "title": "non_breaking_space (inline)",
      "description": "One generated nonbreaking space, from an escaped space or preserved line-block whitespace. Literal Unicode characters remain in text and verbatim fields.",
      "required": [
        "type"
      ],
      "properties": {
        "type": {
          "const": "non_breaking_space"
        },
        "attrs": {
          "$ref": "#/$defs/attrs"
        },
        "pos": {
          "$ref": "#/$defs/pos"
        }
      },
      "additionalProperties": false
    }
  }
}
