{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "TypeDefinition",
"type": "object",
"properties": {
"boundaries": {
"type": "array",
"default": [],
"items": {
"type": "string"
}
},
"constraints": {
"description": "Declared keep-health constraints (the constraint vocabulary —\nsee [`ConstraintDef`]). Empty default: a schema declaring no\nconstraints behaves byte-identically to before the vocabulary\nexisted.",
"type": "array",
"items": {
"$ref": "#/$defs/ConstraintDef"
}
},
"description": {
"type": "string"
},
"due": {
"description": "The type's declared due axis (see [`DueAxis`]) — absent for\ntypes without deadline semantics; a schema without any `due:`\ndeclaration behaves byte-identically to before the axis\nexisted.",
"anyOf": [
{
"$ref": "#/$defs/DueAxis"
},
{
"type": "null"
}
]
},
"edge_weight_overrides": {
"type": "object",
"additionalProperties": {
"type": "number",
"format": "float"
},
"default": {}
},
"exemplar": {
"description": "One canonical, ENGINE-VALIDATED exemplar entity for this type\n(agent-trust plan 09) — the few-shot material an authoring\nagent actually learns from. Validated against this very type\nthrough the real create path (`dry_run`) at schema\ninstall/seal time: a package whose exemplar does not conform\nrefuses with a typed error naming the type and the defect —\nthere is no warn-and-carry mode, so an exemplar can never\ndrift into teaching the wrong shape. Served at\n`verbosity: full` only (the lite skeleton stays unchanged).\nOptional per type; the built-in reference schemas are complete.",
"anyOf": [
{
"$ref": "#/$defs/Exemplar"
},
{
"type": "null"
}
]
},
"health_required_fields": {
"type": "array",
"items": {
"type": "string"
}
},
"hierarchy_relationship": {
"type": "string"
},
"leaf": {
"description": "Terminal-by-construction marker: entities of this type are\nleaves — they carry no edges BY DESIGN, so health's orphan\naxis exempts their edge-less entities and reports them as a\nseparate leaf population instead (visible, never vanished).\nLeaf means \"no edges required\", not \"edges forbidden\": a\nleaf-typed entity WITH edges stays legal, and every other\nhealth axis, search, and traversal treats leaf entities\nexactly like any other. Declarative per-type flag (the sixth\ndeclarative form the agent-toolbox constraint vocabulary\nanticipated), served at both schema verbosity levels.",
"type": "boolean"
},
"metadata_fields": {
"type": "array",
"items": {
"$ref": "#/$defs/MetadataFieldDef"
}
},
"must_reach": {
"description": "Declared reachability obligations (see [`MustReach`]): entities\nof this type must reach at least one entity of a named terminal\ntype, following edges of a named relation set in a named\ndirection, within an optional maximum depth. Health-path only,\nalways warn-tier (the loader refuses `block`: a transitive\nproperty is established by writes on OTHER entities, so a\nwrite-time refusal would punish the wrong mutation). Empty\ndefault keeps current behaviour.",
"type": "array",
"items": {
"$ref": "#/$defs/MustReach"
}
},
"name": {
"type": "string"
},
"no_self_loop_relationships": {
"description": "Rel-types on which `memstead_relate` refuses a SELF-LOOP\n(from == to) when this type is the source. That refusal is this\nfield's ONLY effect — it propagates nothing, implies no\nevidence obligation (real impact propagation is the\n`status_propagation` constraint). Renamed from the misleading\n`propagating_relationships` (agent-trust plan 06): the old key\nrefuses at authoring/install load with a typed error naming\nthis one; sealed content (built-ins, installed refs) loads\nwith the old key translated.",
"type": "array",
"items": {
"type": "string"
}
},
"required_outgoing": {
"description": "Outgoing-edge invariants the schema asserts for this type.\nEach entry names a list of relationship names plus a cardinality\nconstraint. The engine evaluates these on every `memstead_create` /\n`memstead_update` (post-application of inline `relations:` / patches)\nand surfaces unsatisfied blocks as a single\n`MISSING_REQUIRED_OUTGOING` warning per entity. Tier-2 (warn,\nnever block). Empty default — types without `required_outgoing`\nkeep current behaviour.",
"type": "array",
"items": {
"$ref": "#/$defs/RequiredOutgoing"
}
},
"sections": {
"type": "array",
"items": {
"$ref": "#/$defs/SectionDef"
}
},
"signals": {
"description": "Declared aggregate signals (see [`SignalDef`]): exact,\nparameter-free counts with declared thresholds, computed at\nread time and served with their evidence — never scored,\nnever blocking, never stored. Empty default keeps every\nresponse byte-identical.",
"type": "array",
"items": {
"$ref": "#/$defs/SignalDef"
}
},
"staleness_threshold_days": {
"type": "integer",
"format": "uint32",
"minimum": 0
},
"system_message": {
"type": [
"string",
"null"
],
"default": null
},
"text_fields": {
"type": "array",
"items": {
"type": "string"
}
},
"title_weight": {
"type": "number",
"format": "float"
},
"updatable_fields": {
"type": "array",
"items": {
"type": "string"
}
},
"when_to_use": {
"type": "string"
},
"write_rules": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"name",
"description",
"when_to_use",
"sections",
"metadata_fields",
"title_weight",
"text_fields",
"hierarchy_relationship",
"updatable_fields",
"health_required_fields",
"staleness_threshold_days",
"write_rules"
],
"$defs": {
"ConstraintDef": {
"description": "One declared keep-health constraint on a type — the constraint\nvocabulary (agent-toolbox plan 07). Declarations travel sealed with\nthe schema package and are rendered on the `memstead_schema`\nresponse at BOTH verbosity levels (a hidden legality condition is a\ndefect class of its own). The `kind` tag is closed: an unknown kind\nfails deserialization, so no declaration can load and be silently\nignored. Forms land vertically — a form is only declarable once the\nengine evaluates it.",
"oneOf": [
{
"description": "Form 1 — conditional requirement: `field` (a metadata field or\nsection key of this type) is required whenever `when_field`\nholds `when_value` (\"`status: checked` requires `checked_by`\").",
"type": "object",
"properties": {
"field": {
"description": "The field or section that becomes required.",
"type": "string"
},
"kind": {
"type": "string",
"const": "requires_when"
},
"severity": {
"$ref": "#/$defs/ConstraintSeverity",
"default": "warn"
},
"when_field": {
"description": "The metadata field whose value triggers the requirement.",
"type": "string"
},
"when_value": {
"description": "The triggering value (validated against `when_field`'s\nenum, when it declares one).",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"kind",
"field",
"when_field",
"when_value"
]
},
{
"description": "Form 2 — uniqueness: the tuple of metadata-field values named\nin `fields` is unique among entities of this type within one\nmem. Entities missing any of the fields carry no tuple and are\nnot compared. Defaults to `block` — the whole point of the\ndeclaration is preventing the duplicate at write time.",
"type": "object",
"properties": {
"fields": {
"description": "The metadata fields forming the unique tuple (each must be\na declared metadata field of this type).",
"type": "array",
"items": {
"type": "string"
}
},
"kind": {
"type": "string",
"const": "unique"
},
"severity": {
"$ref": "#/$defs/ConstraintSeverity",
"default": "block"
}
},
"additionalProperties": false,
"required": [
"kind",
"fields"
]
},
{
"description": "Form 3 — enum-from-neighbour: the legal values of `field` are\nthe bullet-list entries (`- value` lines) of the `section`\nsection on the entity reached from this one via a `rel_type`\nedge. A set value with no backing entry in any reached\nneighbour's section — including the no-neighbour and\nmissing-section cases, where nothing can back it — is a\nviolation.",
"type": "object",
"properties": {
"field": {
"description": "The metadata field whose values the neighbour enumerates.",
"type": "string"
},
"kind": {
"type": "string",
"const": "enum_from_neighbour"
},
"rel_type": {
"description": "The outgoing rel-type that reaches the enumerating entity.",
"type": "string"
},
"section": {
"description": "The section key on the reached entity whose bullet entries\nare the legal values.",
"type": "string"
},
"severity": {
"$ref": "#/$defs/ConstraintSeverity",
"default": "warn"
}
},
"additionalProperties": false,
"required": [
"kind",
"field",
"rel_type",
"section"
]
},
{
"description": "Form 5 — status propagation: when `field` on an entity of this\ntype holds `value` (the terminal value), every entity reaching\nit — transitively — via `rel_type` edges in `direction` is\ntainted; tainted entities surface as health findings naming\ntheir tainting ancestor. Always warn-tier: the taint arises\nfrom the ancestor's *later* change, so it can never refuse the\ndescendant's historical write (the loader refuses a `block`\ndeclaration on this form rather than accepting a promise the\nengine will not keep).",
"type": "object",
"properties": {
"direction": {
"description": "Which direction reaches the dependents: `incoming` taints\nthe entities whose edges point at the terminal entity (and\ntheir dependents, transitively); `outgoing` the entities\nthe terminal entity points at.",
"$ref": "#/$defs/PropagationDirection"
},
"field": {
"description": "The status metadata field on this (the tainting) type.",
"type": "string"
},
"kind": {
"type": "string",
"const": "status_propagation"
},
"rel_type": {
"description": "The single rel-type the taint travels along. Exactly one\nof `rel_type` / `rel_types` per declaration — the loader\nrefuses both-present and neither-present.",
"type": [
"string",
"null"
]
},
"rel_types": {
"description": "The relation SET the taint travels along — the union\nsubgraph, so a taint crosses rel-type boundaries. Inline\nlist of declared names, per the bundle-wide convention.",
"type": [
"array",
"null"
],
"items": {
"type": "string"
}
},
"severity": {
"$ref": "#/$defs/ConstraintSeverity",
"default": "warn"
},
"value": {
"description": "The terminal value that starts the taint (validated\nagainst `field`'s enum, when it declares one).",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"kind",
"field",
"value",
"direction"
]
}
]
},
"ConstraintSeverity": {
"description": "Uniform severity for the constraint vocabulary — one model across\nevery constraint form, never five ad-hoc ones. `warn` produces a\nhealth finding only; `block` additionally refuses at write time\n(and still surfaces pre-existing violations in health). Severity\napplies to every write surface uniformly — operator-mode bypasses\nallowlists, never validation.",
"oneOf": [
{
"description": "Health finding only (and, where a write-time warning exists,\nthat warning). The default for every form except uniqueness.",
"type": "string",
"const": "warn"
},
{
"description": "Write-time refusal plus health finding for pre-existing\nviolations.",
"type": "string",
"const": "block"
}
]
},
"DueAxis": {
"description": "A type's declared **due axis** (first-author-path plan 08): which\nof its fields carry deadline semantics, so the engine's due-brief\n(`memstead due`) can render \"what is due next\" without knowing any\ndomain vocabulary. Validated at schema load: `date_field` must be\na date-typed metadata field of the type, `status_field` an\nenum-typed one, every `open_values` entry a member of that enum,\nand `lead_section` (optional — rendered as \"what must happen\nfirst\") a declared section key. The axis is rendering-only: it\nnever enforces anything (constraints own enforcement) and the\nengine never advances a date (the agent loop is the runtime).",
"type": "object",
"properties": {
"date_field": {
"description": "Date-typed metadata field holding the deadline.",
"type": "string"
},
"lead_section": {
"description": "Optional section key whose content renders with each entry as\n\"what must happen first\".",
"type": [
"string",
"null"
]
},
"open_values": {
"description": "The `status_field` values under which the entity counts as\nstill open (due-relevant). Every entry must be declared in the\nfield's `enum_values`.",
"type": "array",
"items": {
"type": "string"
}
},
"status_field": {
"description": "Enum-typed metadata field holding the lifecycle status.",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"date_field",
"status_field",
"open_values"
]
},
"Exemplar": {
"description": "One canonical exemplar entity for a type — a complete entity in the\nmem markdown shape: title, metadata overrides, section bodies, and\nrelationship entries with placeholder targets. Engine-validated at\nschema install/seal through the real create path, so it can never\nteach a shape the validator would refuse.",
"type": "object",
"properties": {
"metadata": {
"description": "Metadata overrides, keyed by declared field key — validated\nlike a real create's metadata (enums included). Engine-stamped\nfields (`created_date`, …) are omitted; the engine fills them.",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"relations": {
"description": "Relationship entries with PLACEHOLDER targets: each `to` is a\nbare slug (no `mem--` prefix — an exemplar lives outside any\nmem); validation checks rel-type legality and shape, never\ntarget existence.",
"type": "array",
"items": {
"$ref": "#/$defs/ExemplarRelation"
}
},
"sections": {
"description": "Section bodies keyed by section key. Required sections must all\nbe present — the validator enforces it like any create.",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"title": {
"description": "The exemplar entity's title (drives the id slug exactly as a\nreal create would).",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"title"
]
},
"ExemplarRelation": {
"description": "One relationship entry on an [`Exemplar`].",
"type": "object",
"properties": {
"description": {
"description": "Optional per-edge description — validated against the\nrel-type's `per_edge_description` posture.",
"type": [
"string",
"null"
]
},
"to": {
"description": "Placeholder target: a bare slug, scoped to the exemplar's own\n(virtual) mem at validation time.",
"type": "string"
},
"type": {
"description": "Relationship type (UPPER_SNAKE_CASE; validated against the\nschema's declared vocabulary).",
"type": "string"
}
},
"additionalProperties": false,
"required": [
"to",
"type"
]
},
"FieldType": {
"type": "string",
"enum": [
"string",
"number",
"date",
"boolean"
]
},
"Filterable": {
"type": "string",
"enum": [
"none",
"equality",
"range"
]
},
"MetadataFieldDef": {
"description": "A metadata (frontmatter) field.",
"type": "object",
"properties": {
"auto_timestamp": {
"type": "boolean",
"default": false
},
"default_value": {
"type": [
"string",
"null"
],
"default": null
},
"description": {
"type": "string"
},
"enum_values": {
"type": [
"array",
"null"
],
"default": null,
"items": {
"type": "string"
}
},
"field_type": {
"$ref": "#/$defs/FieldType"
},
"filterable": {
"$ref": "#/$defs/Filterable",
"default": "none"
},
"init_timestamp": {
"type": "boolean",
"default": false
},
"key": {
"type": "string"
},
"required": {
"description": "Whether an entity must carry this field — **absence means\noptional**, the same rule sections follow. `required: true`\nrefuses a create that leaves the field unset\n(`REQUIRED_FIELD_UNSET`); a required field with a\n`default_value` (or an `init_timestamp`) is auto-filled and\ntherefore never refused — required-with-default means \"always\npresent\", not \"caller must type it\". Replaces the retired\n`optional:` key (opposite polarity): sealed schemas carrying\n`optional` keep loading with inverted-but-equivalent\nsemantics; authoring refuses it naming this key.",
"type": [
"boolean",
"null"
]
},
"serialization": {
"$ref": "#/$defs/Serialization",
"default": "default"
}
},
"additionalProperties": false,
"required": [
"key",
"description",
"field_type"
]
},
"MustReach": {
"description": "One reachability obligation on a type definition. The obligated\nentity must reach at least one non-stub entity whose type is in\n`terminal_types`, walking edges whose rel-type is in\n`relationships` (an inline relation set), in `direction`, within\n`max_depth` hops when bounded. Evaluated on the health sweep only\n(`constraints` axis), never on the write path — no single write\ncompletes a transitive absence. The incoming direction with\n`max_depth: 1` covers the required-incoming-edge case.",
"type": "object",
"properties": {
"direction": {
"description": "`out` follows edges pointing away from the walked entity, `in`\nfollows edges pointing at it — the same vocabulary the store\nand `memstead_search` speak.",
"$ref": "#/$defs/ReachDirection"
},
"max_depth": {
"description": "Maximum number of hops a conforming path may take. Absent =\nunbounded. Zero refuses at load (nothing is reachable in zero\nhops).",
"type": [
"integer",
"null"
],
"format": "uint32",
"minimum": 0
},
"relationships": {
"description": "Edge names the walk follows — any name in the set continues the\npath. Loader validates each against the schema's relationship\nvocabulary.",
"type": "array",
"items": {
"type": "string"
}
},
"severity": {
"description": "Always `warn` — the loader refuses `block` on this form.",
"$ref": "#/$defs/ConstraintSeverity",
"default": "warn"
},
"terminal_types": {
"description": "Type names that satisfy the obligation when reached. Loader\nvalidates each against the schema's declared types.",
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"relationships",
"direction",
"terminal_types"
]
},
"PropagationDirection": {
"description": "Traversal direction for [`ConstraintDef::StatusPropagation`].",
"type": "string",
"enum": [
"incoming",
"outgoing"
]
},
"ReachDirection": {
"description": "Walk direction for [`MustReach`] — wire literals `out` / `in`,\nmatching the store's relationship rendering and `memstead_search`'s\n`direction` parameter.",
"type": "string",
"enum": [
"out",
"in"
]
},
"RequiredCardinality": {
"description": "Required-cardinality variants. `AtLeastOne` is the only variant\nshipped initially; `ExactlyOne` is the obvious next variant but is\nnot yet wired.",
"type": "string",
"enum": [
"at_least_one"
]
},
"RequiredOutgoing": {
"description": "One outgoing-edge requirement block on a type definition. Lists one\nor more relationship names and a cardinality constraint they must\njointly satisfy. The schema author groups multiple alternative\nrelationships into a single block when \"any of these\" satisfies the\nrule (e.g. `[CHOSEN, REJECTED]` together with `at_least_one` would\nrequire at least one outgoing edge across both names — but the\nplanning schema lists each as its own block instead, so each block\ngets its own warning entry).",
"type": "object",
"properties": {
"cardinality": {
"$ref": "#/$defs/RequiredCardinality"
},
"relationships": {
"description": "Edge names the rule applies to. Loader validates each against\nthe schema's declared relationship vocabulary; unknown names\nraise `SchemaLoadError::UndeclaredRelationship`.",
"type": "array",
"items": {
"type": "string"
}
},
"severity": {
"description": "Constraint severity (form 4 of the constraint vocabulary):\n`warn` (the historical default — health finding +\n`MISSING_REQUIRED_OUTGOING` write-time warning) or `block`\n(write-time refusal when a create/update would land, or a\nrelate-remove would leave, the entity below cardinality).",
"$ref": "#/$defs/ConstraintSeverity",
"default": "warn"
},
"when_field": {
"description": "Optional condition: the block applies only when this metadata\nfield of the entity holds `when_value`. The same two keys\n`requires_when` uses — one vocabulary for one idea. The loader\nrequires the pair to appear together, `when_field` to name a\ndeclared metadata field of this type carrying `enum_values`,\nand `when_value` to be a member. Absent pair = unconditional\nblock = long-standing behaviour.",
"type": [
"string",
"null"
]
},
"when_value": {
"description": "The triggering value (see `when_field`).",
"type": [
"string",
"null"
]
}
},
"additionalProperties": false,
"required": [
"relationships",
"cardinality"
]
},
"SectionDef": {
"description": "A section within an entity (e.g. \"Claim\", \"Evidence\").",
"type": "object",
"properties": {
"catch_all": {
"type": "boolean",
"default": false
},
"content": {
"description": "Declared markdown shape (section-format vocabulary, plan 08):\na flat content expression over the mdast block vocabulary —\nsee [`crate::content_expr::ContentExpr`]. Absent = free-form,\nexactly the pre-declaration behavior. Validated and compiled\nat schema load ([`SectionDef::compiled_content`]).",
"type": [
"string",
"null"
]
},
"description": {
"type": [
"string",
"null"
],
"default": null
},
"example": {
"description": "One conforming snippet, echoed verbatim in every format\nrefusal — for an agent, a conforming example outperforms any\ngrammar string.",
"type": [
"string",
"null"
]
},
"format_severity": {
"description": "Severity of format violations (plan 07's uniform model).\nDefault `block`: a shape violation is deterministic and\none-round-trip repairable (the enum-value analogy) — `warn`\nstays available per section.",
"$ref": "#/$defs/ConstraintSeverity"
},
"heading": {
"type": "string"
},
"item_pattern": {
"description": "Regex applied to the repeating unit of the declared `content`\n(list items with lazy continuation joined; paragraph source\nlines). Implicitly anchored `^…$`; named capture groups name\nthe parts in refusal payloads. Legal only when `content`\ncontains exactly one of `list` / `paragraph`.",
"type": [
"string",
"null"
]
},
"key": {
"type": "string"
},
"load_bearing": {
"description": "Whether this section is **load-bearing** for the entity's claim:\nthe part of the entity a dependent conclusion rests on, as\nopposed to notes, context, or bookkeeping. Consumed by the\n`entity-load-bearing` preparation (`memstead-base::preparation`):\nan entity-grain anchor's prepared form is the stable\nserialization of the type's load-bearing sections, so a notes-only\nedit never breaks a dependent's prepared hash while a load-bearing\nedit always does. **Absence means undeclared**: when NO section of\na type declares this flag, the type's required sections are its\nload-bearing set (and a type with no required sections falls back\nto every section). Declaring `load_bearing: false` on a required\nsection is legal and excludes it once any section of the type\ndeclares the flag.",
"type": [
"boolean",
"null"
]
},
"required": {
"description": "Whether an entity must carry this section — **absence means\noptional**, the same rule metadata fields follow. `required:\ntrue` refuses a create without the section\n(`MISSING_REQUIRED_SECTION`).",
"type": "boolean",
"default": false
},
"search_weight": {
"type": "number",
"format": "float"
},
"table": {
"description": "Table contract — only legal when `content` contains `table`.",
"anyOf": [
{
"$ref": "#/$defs/TableFormat"
},
{
"type": "null"
}
]
},
"write_rules": {
"type": "array",
"default": [],
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"key",
"heading",
"search_weight"
]
},
"Serialization": {
"type": "string",
"enum": [
"default",
"csv_array",
"omit_when_falsy"
]
},
"SignalDef": {
"description": "One declared aggregate signal on a type definition. This wave\nships one kind, `edge_load`: count the edges of a named rel-type\nset, in a named direction, on entities of this type, optionally\nrestricted to edges whose counterpart entity holds a named enum\nvalue. Thresholds map counts to levels; below the first threshold\nthe served level is `none`. Values are computed at read time in\nO(degree), never stored, never part of `_hash`; a signal may not\nreference another signal, and nothing multiplies, averages, or\ndecays — a count and a threshold are the whole vocabulary.",
"type": "object",
"properties": {
"direction": {
"description": "`in` counts edges pointing at the entity, `out` edges pointing\naway — the same vocabulary the store and search speak.",
"$ref": "#/$defs/ReachDirection"
},
"kind": {
"description": "Closed kind enum — one member in this wave.",
"$ref": "#/$defs/SignalKind"
},
"name": {
"description": "Unique per type, `[a-z][a-z0-9_]*` — the stable name prose\nand consumers bind guidance to.",
"type": "string"
},
"neighbour_field": {
"description": "Optional counterpart filter, whole or not at all: count only\nedges whose counterpart entity holds `neighbour_value` in\n`neighbour_field`. A counterpart lacking the field or holding\nanother value simply does not count.",
"type": [
"string",
"null"
]
},
"neighbour_value": {
"type": [
"string",
"null"
]
},
"relationships": {
"description": "Edge names the count covers (inline relation set; loader\nvalidates each against the vocabulary).",
"type": "array",
"items": {
"type": "string"
}
},
"thresholds": {
"description": "Non-empty, strictly increasing `at_least` values.",
"type": "array",
"items": {
"$ref": "#/$defs/SignalThreshold"
}
}
},
"additionalProperties": false,
"required": [
"name",
"kind",
"relationships",
"direction",
"thresholds"
]
},
"SignalKind": {
"description": "Closed signal-kind vocabulary. Adding a member is a\nformat-generation event.",
"type": "string",
"enum": [
"edge_load"
]
},
"SignalLevel": {
"description": "Signal levels — deliberately NOT [`ConstraintSeverity`]: a signal\nlevel is the output of a threshold, not the severity of a\nviolation. `warn` participates in `health --strict` like a\nwarn-tier constraint finding; `notice` never does — that is the\nwhole difference between the two.",
"type": "string",
"enum": [
"notice",
"warn"
]
},
"SignalThreshold": {
"description": "One threshold step of a signal declaration.",
"type": "object",
"properties": {
"at_least": {
"type": "integer",
"format": "uint64",
"minimum": 0
},
"level": {
"$ref": "#/$defs/SignalLevel"
}
},
"additionalProperties": false,
"required": [
"at_least",
"level"
]
},
"TableFormat": {
"description": "The table contract of a format-declared section: `columns` pins\nheader names and order; `column_patterns` maps column name → regex\nper cell (implicitly anchored). Column-count enforcement is ours by\ndecision — GFM silently pads/truncates short or long rows, so a\nrow with the wrong cell count is *our* refusal, not the parser's.",
"type": "object",
"properties": {
"column_patterns": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"columns": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"required": [
"columns"
]
}
}
}