Skip to main content
Glama

Apply model patch

layerz_patch
Destructive

Applies a batch of mutations to a model: create, replace, update, delete, move, list_create, list_update, list_delete and meta (name, subtitle, finance_md, timelines, formats, number_locale, default_branch, glyph). The batch is all-or-nothing: a validation failure persists nothing and returns every error at once (MODEL_VALIDATION_ERROR, details[]). A create may carry a temp id that later ops of the batch reference (parent, source, target, series, liste_ref, after, $_id in a formula); the result map gives each temp id its UID. replace keeps the item's UID and presentation fields; update is a strict partial merge of the named fields. Root accepts section and dashboard; dashboard accepts widgets only; a formula with both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN); a list-mode item takes timeline_values and rejects value / values; a non-list item takes value / values (a sparse period-keyed timeline_values map merges into values). branch_id routes the value writes onto that branch as an overlay of the cells differing from the base, with no data source; compute returns the computed series of the given UIDs (under compute_branch, default branch_id); dry_run validates and computes without persisting. Persists one version labelled with summary. Not advertised to read-only keys. Modeling patterns and examples: resource modeling-guide://reference.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
opsYesMutation operations. Each op is a discriminated object on a string `op` field (e.g. {op:'create', role:'assumption', name:'Revenue'}; {op:'replace', from_uid:'abc', new_item:{role:'formula', name:'Revenue', formula:'xyz * 12'}}; {op:'update', uid:'abc', value:42}).
computeNoUIDs to compute after mutations
dry_runNoValidates and computes the batch without persisting it.
summaryYesShort note (3–100 chars) describing the change, stored as the label of the resulting version. Examples: "Renamed Revenue to Net Revenue", "Imported 2024 OPEX from Excel".
model_idNoTarget model UUID. Required for user-scoped API keys; validated against the bound model for model-scoped keys.
branch_idNoBranch that receives the value writes of this batch (`update` / `replace` `value`, `values`, `timeline_values` on assumptions): only the cells that differ from the base are stored as that branch's overlay, the same record a value edit makes in the web editor with the branch checked out; no data source is created. Absent or `default`: the base plan. Structural ops and non-value fields apply to the model as a whole; a `create` carrying values under a branch is rejected. An unknown id is rejected.
compute_branchNoBranch whose `[base, branch]` checkout the `compute` values are returned under, instead of the stacked-all view (mirror of `layerz_read` `branch_id`); `default` = the base plan alone. Defaults to `branch_id` when that is set. Requires `compute`.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / ops / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "by_branch": {
      -        "description": "Chart only: one styled series per branch; false reverts to the checked-out view.",
      -        "type": "boolean"
      -      },
      -      "cagr": {
      -        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      -        "type": "boolean"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Flags the line as a control judged on its own value: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. `null` removes the check. Failing periods surface in `layerz_read` under `health`, non-blocking."
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (null clears it)."
      -      },
      -      "compare_to": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "KPI native comparison; null clears it."
      -      },
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      -      },
      -      "name": {
      -        "description": "New display label (also the formula identifier)",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "update",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "New parent UID (null to move to root)"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Change the item role. Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "description": "Chart series UIDs",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch; supersedes `series`.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "uid": {
      -        "description": "Existing item UID to update",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "unit": {
      -        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      -        "enum": [
      -          "none",
      -          "k",
      -          "m",
      -          "auto"
      -        ],
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "by_branch": {
      -        "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      -        "type": "boolean"
      -      },
      -      "cagr": {
      -        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      -        "type": "boolean"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "description": "Flags the line as a control judged on its own value at every period: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals, so a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (\"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health`, non-blocking.",
      -        "properties": {
      -          "tolerance": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -      },
      -      "compare_to": {
      -        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -        "properties": {
      -          "branch_id": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "display": {
      -            "enum": [
      -              "abs",
      -              "pct",
      -              "both"
      -            ],
      -            "type": "string"
      -          },
      -          "mode": {
      -            "enum": [
      -              "branch",
      -              "prev_period",
      -              "prev_year"
      -            ],
      -            "type": "string"
      -          },
      -          "thresholds": {
      -            "properties": {
      -              "green": {
      -                "type": "number"
      -              },
      -              "red": {
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "green",
      -              "red"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "mode"
      -        ],
      -        "type": "object"
      -      },
      -      "default_branch": {
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as one series (a list total charted without a mirror formula).",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -        "properties": {
      -          "assert": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "assert"
      -        ],
      -        "type": "object"
      -      },
      -      "name": {
      -        "description": "Display name",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "create",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart under the value.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "unit": {
      -        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      -        "enum": [
      -          "none",
      -          "k",
      -          "m",
      -          "auto"
      -        ],
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "role",
      -      "name",
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "from_uid": {
      -        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "new_item": {
      -        "description": "Inline payload describing the replacement item",
      -        "properties": {
      -          "aggregation": {
      -            "enum": [
      -              "sum",
      -              "average",
      -              "stock"
      -            ],
      -            "type": "string"
      -          },
      -          "axis": {
      -            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -            "enum": [
      -              "time",
      -              "branches",
      -              "list"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "bridge_config": {
      -            "properties": {
      -              "axis": {
      -                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -                "enum": [
      -                  "time",
      -                  "branches"
      -                ],
      -                "type": "string"
      -              },
      -              "branches": {
      -                "description": "Branch ids compared when axis=branches: [from, to].",
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "contributions": {
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "end_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              },
      -              "endpoint": {
      -                "description": "Single endpoint item (stock/balance) read at start & end periods",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "endpoint_branch": {
      -                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "residual_label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              },
      -              "start_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "endpoint"
      -            ],
      -            "type": "object"
      -          },
      -          "by_branch": {
      -            "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      -            "type": "boolean"
      -          },
      -          "cagr": {
      -            "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      -            "type": "boolean"
      -          },
      -          "chart_type": {
      -            "enum": [
      -              "line",
      -              "bar",
      -              "area",
      -              "bridge"
      -            ],
      -            "type": "string"
      -          },
      -          "check": {
      -            "description": "Flags the line as a control judged on its own value at every period: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals, so a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (\"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health`, non-blocking.",
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "comment": {
      -            "anyOf": [
      -              {
      -                "maxLength": 2000,
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -          },
      -          "compare_to": {
      -            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          "default_branch": {
      -            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "format": {
      -            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "formula": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "inputs": {
      -            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "item_style": {
      -            "enum": [
      -              "normal",
      -              "subtotal",
      -              "total",
      -              "kpi"
      -            ],
      -            "type": "string"
      -          },
      -          "list_mode": {
      -            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as one series (a list total charted without a mirror formula).",
      -            "enum": [
      -              "split",
      -              "total"
      -            ],
      -            "type": "string"
      -          },
      -          "list_total": {
      -            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -            "type": "boolean"
      -          },
      -          "liste": {
      -            "description": "mini_table list whose entries become the columns (axis=list)",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "liste_ref": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "monitor": {
      -            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          "name": {
      -            "description": "Display name",
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "opening_balance": {
      -            "type": "number"
      -          },
      -          "period_window": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  },
      -                  "fit": {
      -                    "enum": [
      -                      "data",
      -                      "full"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      -          },
      -          "position": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "col": {
      -                    "maximum": 11,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "row": {
      -                    "maximum": 400,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  }
      -                },
      -                "required": [
      -                  "col",
      -                  "row"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -          },
      -          "role": {
      -            "description": "Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -            "enum": [
      -              "assumption",
      -              "formula",
      -              "callup",
      -              "balance",
      -              "section",
      -              "chart",
      -              "dashboard",
      -              "kpi",
      -              "mini_table"
      -            ],
      -            "type": "string"
      -          },
      -          "row_break": {
      -            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -            "type": "boolean"
      -          },
      -          "rows": {
      -            "description": "mini_table curated row item UIDs / temp IDs / names",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series_defs": {
      -            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -            "items": {
      -              "properties": {
      -                "branch_id": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "uid": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "uid"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "description": "Callup source UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "span": {
      -            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -            "properties": {
      -              "cols": {
      -                "maximum": 12,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "rows": {
      -                "maximum": 4,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "sparkline": {
      -            "description": "KPI trend mini-chart under the value.",
      -            "type": "boolean"
      -          },
      -          "target": {
      -            "description": "KPI/mini_table target UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "target_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "timeline_ref": {
      -            "enum": [
      -              "constant",
      -              "monthly",
      -              "yearly",
      -              "quarterly"
      -            ],
      -            "type": "string"
      -          },
      -          "timeline_values": {
      -            "additionalProperties": {
      -              "anyOf": [
      -                {
      -                  "anyOf": [
      -                    {
      -                      "type": "number"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ]
      -                },
      -                {
      -                  "items": {
      -                    "anyOf": [
      -                      {
      -                        "type": "number"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ]
      -                  },
      -                  "type": "array"
      -                }
      -              ]
      -            },
      -            "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -            "propertyNames": {
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "unit": {
      -            "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      -            "enum": [
      -              "none",
      -              "k",
      -              "m",
      -              "auto"
      -            ],
      -            "type": "string"
      -          },
      -          "value": {
      -            "anyOf": [
      -              {
      -                "type": "number"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "values": {
      -            "items": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            "type": "array"
      -          },
      -          "variance": {
      -            "description": "mini_table écart columns (axis=branches)",
      -            "properties": {
      -              "abs": {
      -                "type": "boolean"
      -              },
      -              "color": {
      -                "type": "boolean"
      -              },
      -              "pct": {
      -                "type": "boolean"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "role",
      -          "name"
      -        ],
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "preserve_order": {
      -        "type": "boolean"
      -      },
      -      "preserve_parent": {
      -        "type": "boolean"
      -      },
      -      "preserve_presentation": {
      -        "description": "Default true: every presentation / annotation field `new_item` omits (item_style, format, comment, check, span, position, period_window, compare_to, sparkline, series_defs, …) is carried over from the replaced item when the new role can hold it; `false` rebuilds the item from `new_item` alone.",
      -        "type": "boolean"
      -      },
      -      "preserve_style": {
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "from_uid",
      -      "new_item"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "after": {
      -        "description": "UID of item to place after (for ordering)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "move",
      -        "type": "string"
      -      },
      -      "parent": {
      -        "description": "New parent UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to move",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_create",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_update",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "list_delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of list to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "finance_md": {
      -        "anyOf": [
      -          {
      -            "maxLength": 5000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "formats": {
      -        "additionalProperties": {
      -          "properties": {
      -            "display_name": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "excel_format": {
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "name": {
      -              "maxLength": 50,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "excel_format"
      -          ],
      -          "type": "object"
      -        },
      -        "propertyNames": {
      -          "maxLength": 50,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "glyph": {
      -        "anyOf": [
      -          {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      -      },
      -      "name": {
      -        "maxLength": 100,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "number_locale": {
      -        "anyOf": [
      -          {
      -            "enum": [
      -              "en",
      -              "fr",
      -              "de"
      -            ],
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "op": {
      -        "const": "meta",
      -        "type": "string"
      -      },
      -      "subtitle": {
      -        "anyOf": [
      -          {
      -            "maxLength": 160,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "timelines": {
      -        "properties": {
      -          "monthly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "quarterly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "yearly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "by_branch": {
      +        "description": "Chart only: one styled series per branch; false reverts to the checked-out view.",
      +        "type": "boolean"
      +      },
      +      "cagr": {
      +        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +        "type": "boolean"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Flags the line as a control judged on its own value: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. `null` removes the check. Failing periods surface in `layerz_read` under `health`, non-blocking."
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (null clears it)."
      +      },
      +      "compare_to": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "KPI native comparison; null clears it."
      +      },
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      +      },
      +      "name": {
      +        "description": "New display label (also the formula identifier)",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "update",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "New parent UID (null to move to root)"
      +      },
      +      "period_mode": {
      +        "description": "kpi / mini_table period mode. 'ytd' shows the year to date: the cumulative from January through the target period (each column for a time-axis mini_table). Flows are summed, an `average` line averaged, a `stock` line read at the period, and a ratio line (formula `a / b`) recomputed on the cumulated operands. Branch columns, écarts and the KPI comparison follow (prev_year = year to date of the same month a year earlier). Default 'period'.",
      +        "enum": [
      +          "period",
      +          "ytd"
      +        ],
      +        "type": "string"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Change the item role. Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "description": "Chart series UIDs",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch; supersedes `series`.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "uid": {
      +        "description": "Existing item UID to update",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "unit": {
      +        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      +        "enum": [
      +          "none",
      +          "k",
      +          "m",
      +          "auto"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "by_branch": {
      +        "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      +        "type": "boolean"
      +      },
      +      "cagr": {
      +        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +        "type": "boolean"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "description": "Flags the line as a control judged on its own value at every period: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals, so a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (\"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health`, non-blocking.",
      +        "properties": {
      +          "tolerance": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +      },
      +      "compare_to": {
      +        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +        "properties": {
      +          "branch_id": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "display": {
      +            "enum": [
      +              "abs",
      +              "pct",
      +              "both"
      +            ],
      +            "type": "string"
      +          },
      +          "mode": {
      +            "enum": [
      +              "branch",
      +              "prev_period",
      +              "prev_year"
      +            ],
      +            "type": "string"
      +          },
      +          "thresholds": {
      +            "properties": {
      +              "green": {
      +                "type": "number"
      +              },
      +              "red": {
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "green",
      +              "red"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "mode"
      +        ],
      +        "type": "object"
      +      },
      +      "default_branch": {
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as one series (a list total charted without a mirror formula).",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +        "properties": {
      +          "assert": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "assert"
      +        ],
      +        "type": "object"
      +      },
      +      "name": {
      +        "description": "Display name",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "create",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "period_mode": {
      +        "description": "kpi / mini_table period mode. 'ytd' shows the year to date: the cumulative from January through the target period (each column for a time-axis mini_table). Flows are summed, an `average` line averaged, a `stock` line read at the period, and a ratio line (formula `a / b`) recomputed on the cumulated operands. Branch columns, écarts and the KPI comparison follow (prev_year = year to date of the same month a year earlier). Default 'period'.",
      +        "enum": [
      +          "period",
      +          "ytd"
      +        ],
      +        "type": "string"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart under the value.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "unit": {
      +        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      +        "enum": [
      +          "none",
      +          "k",
      +          "m",
      +          "auto"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "role",
      +      "name",
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "from_uid": {
      +        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "new_item": {
      +        "description": "Inline payload describing the replacement item",
      +        "properties": {
      +          "aggregation": {
      +            "enum": [
      +              "sum",
      +              "average",
      +              "stock"
      +            ],
      +            "type": "string"
      +          },
      +          "axis": {
      +            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +            "enum": [
      +              "time",
      +              "branches",
      +              "list"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "bridge_config": {
      +            "properties": {
      +              "axis": {
      +                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +                "enum": [
      +                  "time",
      +                  "branches"
      +                ],
      +                "type": "string"
      +              },
      +              "branches": {
      +                "description": "Branch ids compared when axis=branches: [from, to].",
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "contributions": {
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "end_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              },
      +              "endpoint": {
      +                "description": "Single endpoint item (stock/balance) read at start & end periods",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "endpoint_branch": {
      +                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "residual_label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              },
      +              "start_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "endpoint"
      +            ],
      +            "type": "object"
      +          },
      +          "by_branch": {
      +            "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      +            "type": "boolean"
      +          },
      +          "cagr": {
      +            "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +            "type": "boolean"
      +          },
      +          "chart_type": {
      +            "enum": [
      +              "line",
      +              "bar",
      +              "area",
      +              "bridge"
      +            ],
      +            "type": "string"
      +          },
      +          "check": {
      +            "description": "Flags the line as a control judged on its own value at every period: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals, so a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (\"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health`, non-blocking.",
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "comment": {
      +            "anyOf": [
      +              {
      +                "maxLength": 2000,
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +          },
      +          "compare_to": {
      +            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          "default_branch": {
      +            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "format": {
      +            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "formula": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "inputs": {
      +            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "item_style": {
      +            "enum": [
      +              "normal",
      +              "subtotal",
      +              "total",
      +              "kpi"
      +            ],
      +            "type": "string"
      +          },
      +          "list_mode": {
      +            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as one series (a list total charted without a mirror formula).",
      +            "enum": [
      +              "split",
      +              "total"
      +            ],
      +            "type": "string"
      +          },
      +          "list_total": {
      +            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +            "type": "boolean"
      +          },
      +          "liste": {
      +            "description": "mini_table list whose entries become the columns (axis=list)",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "liste_ref": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "monitor": {
      +            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          "name": {
      +            "description": "Display name",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "opening_balance": {
      +            "type": "number"
      +          },
      +          "period_mode": {
      +            "description": "kpi / mini_table period mode. 'ytd' shows the year to date: the cumulative from January through the target period (each column for a time-axis mini_table). Flows are summed, an `average` line averaged, a `stock` line read at the period, and a ratio line (formula `a / b`) recomputed on the cumulated operands. Branch columns, écarts and the KPI comparison follow (prev_year = year to date of the same month a year earlier). Default 'period'.",
      +            "enum": [
      +              "period",
      +              "ytd"
      +            ],
      +            "type": "string"
      +          },
      +          "period_window": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  },
      +                  "fit": {
      +                    "enum": [
      +                      "data",
      +                      "full"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      +          },
      +          "position": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "col": {
      +                    "maximum": 11,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "row": {
      +                    "maximum": 400,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "col",
      +                  "row"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +          },
      +          "role": {
      +            "description": "Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +            "enum": [
      +              "assumption",
      +              "formula",
      +              "callup",
      +              "balance",
      +              "section",
      +              "chart",
      +              "dashboard",
      +              "kpi",
      +              "mini_table"
      +            ],
      +            "type": "string"
      +          },
      +          "row_break": {
      +            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +            "type": "boolean"
      +          },
      +          "rows": {
      +            "description": "mini_table curated row item UIDs / temp IDs / names",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series_defs": {
      +            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +            "items": {
      +              "properties": {
      +                "branch_id": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "uid": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "uid"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "description": "Callup source UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "span": {
      +            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +            "properties": {
      +              "cols": {
      +                "maximum": 12,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "rows": {
      +                "maximum": 4,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "sparkline": {
      +            "description": "KPI trend mini-chart under the value.",
      +            "type": "boolean"
      +          },
      +          "target": {
      +            "description": "KPI/mini_table target UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "target_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "timeline_ref": {
      +            "enum": [
      +              "constant",
      +              "monthly",
      +              "yearly",
      +              "quarterly"
      +            ],
      +            "type": "string"
      +          },
      +          "timeline_values": {
      +            "additionalProperties": {
      +              "anyOf": [
      +                {
      +                  "anyOf": [
      +                    {
      +                      "type": "number"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ]
      +                },
      +                {
      +                  "items": {
      +                    "anyOf": [
      +                      {
      +                        "type": "number"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "type": "array"
      +                }
      +              ]
      +            },
      +            "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +            "propertyNames": {
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "unit": {
      +            "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      +            "enum": [
      +              "none",
      +              "k",
      +              "m",
      +              "auto"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "values": {
      +            "items": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "type": "array"
      +          },
      +          "variance": {
      +            "description": "mini_table écart columns (axis=branches)",
      +            "properties": {
      +              "abs": {
      +                "type": "boolean"
      +              },
      +              "color": {
      +                "type": "boolean"
      +              },
      +              "pct": {
      +                "type": "boolean"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "role",
      +          "name"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "preserve_order": {
      +        "type": "boolean"
      +      },
      +      "preserve_parent": {
      +        "type": "boolean"
      +      },
      +      "preserve_presentation": {
      +        "description": "Default true: every presentation / annotation field `new_item` omits (item_style, format, comment, check, span, position, period_window, compare_to, sparkline, series_defs, …) is carried over from the replaced item when the new role can hold it; `false` rebuilds the item from `new_item` alone.",
      +        "type": "boolean"
      +      },
      +      "preserve_style": {
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "from_uid",
      +      "new_item"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "UID of item to place after (for ordering)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "move",
      +        "type": "string"
      +      },
      +      "parent": {
      +        "description": "New parent UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to move",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_create",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_update",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "list_delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of list to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "finance_md": {
      +        "anyOf": [
      +          {
      +            "maxLength": 5000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "formats": {
      +        "additionalProperties": {
      +          "properties": {
      +            "display_name": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "excel_format": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "name": {
      +              "maxLength": 50,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "excel_format"
      +          ],
      +          "type": "object"
      +        },
      +        "propertyNames": {
      +          "maxLength": 50,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "glyph": {
      +        "anyOf": [
      +          {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      +      },
      +      "name": {
      +        "maxLength": 100,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "number_locale": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "en",
      +              "fr",
      +              "de"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "op": {
      +        "const": "meta",
      +        "type": "string"
      +      },
      +      "subtitle": {
      +        "anyOf": [
      +          {
      +            "maxLength": 160,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "timelines": {
      +        "properties": {
      +          "monthly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "quarterly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "yearly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Changed6 schema fields changed
    • addedInput schema / properties / branch_id
      Added value: +{
      +  "description": "Branch that receives the value writes of this batch (`update` / `replace` `value`, `values`, `timeline_values` on assumptions): only the cells that differ from the base are stored as that branch's overlay, the same record a value edit makes in the web editor with the branch checked out; no data source is created. Absent or `default`: the base plan. Structural ops and non-value fields apply to the model as a whole; a `create` carrying values under a branch is rejected. An unknown id is rejected.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • changedInput schema / properties / compute_branch / description
      Previous value: -"Return the `compute` values under a single branch's `[base, branch]` checkout instead of the stacked-all view (mirror of `layerz_read` `branch_id`). Pass `default` to audit the base plan alone — e.g. verify a base correction without a live import layer polluting the result. Requires `compute`. Does not change where the write lands (always the base)."New value: +"Branch whose `[base, branch]` checkout the `compute` values are returned under, instead of the stacked-all view (mirror of `layerz_read` `branch_id`); `default` = the base plan alone. Defaults to `branch_id` when that is set. Requires `compute`."
    • changedInput schema / properties / dry_run / description
      Previous value: -"Validate and compute the batch without persisting it"New value: +"Validates and computes the batch without persisting it."
    • changedInput schema / properties / model_id / description
      Previous value: -"Target model UUID. Required for user-scoped API keys; ignored (or validated against scope) for model-scoped keys."New value: +"Target model UUID. Required for user-scoped API keys; validated against the bound model for model-scoped keys."
    • changedInput schema / properties / ops / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "by_branch": {
      -        "description": "Chart only: one styled series per branch; false reverts to the checked-out view.",
      -        "type": "boolean"
      -      },
      -      "cagr": {
      -        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      -        "type": "boolean"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (null clears it)."
      -      },
      -      "compare_to": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "KPI native comparison; null clears it."
      -      },
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      -      },
      -      "name": {
      -        "description": "New display label (also the formula identifier)",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "update",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "New parent UID (null to move to root)"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "description": "Chart series UIDs",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch; supersedes `series`.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "uid": {
      -        "description": "Existing item UID to update",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "unit": {
      -        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are never divided",
      -        "enum": [
      -          "none",
      -          "k",
      -          "m",
      -          "auto"
      -        ],
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "by_branch": {
      -        "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      -        "type": "boolean"
      -      },
      -      "cagr": {
      -        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      -        "type": "boolean"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -        "properties": {
      -          "tolerance": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -      },
      -      "compare_to": {
      -        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -        "properties": {
      -          "branch_id": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "display": {
      -            "enum": [
      -              "abs",
      -              "pct",
      -              "both"
      -            ],
      -            "type": "string"
      -          },
      -          "mode": {
      -            "enum": [
      -              "branch",
      -              "prev_period",
      -              "prev_year"
      -            ],
      -            "type": "string"
      -          },
      -          "thresholds": {
      -            "properties": {
      -              "green": {
      -                "type": "number"
      -              },
      -              "red": {
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "green",
      -              "red"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "mode"
      -        ],
      -        "type": "object"
      -      },
      -      "default_branch": {
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -        "properties": {
      -          "assert": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "assert"
      -        ],
      -        "type": "object"
      -      },
      -      "name": {
      -        "description": "Display name",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "create",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart under the value.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "unit": {
      -        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are never divided",
      -        "enum": [
      -          "none",
      -          "k",
      -          "m",
      -          "auto"
      -        ],
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "role",
      -      "name",
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "from_uid": {
      -        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "new_item": {
      -        "description": "Inline payload describing the replacement item",
      -        "properties": {
      -          "aggregation": {
      -            "enum": [
      -              "sum",
      -              "average",
      -              "stock"
      -            ],
      -            "type": "string"
      -          },
      -          "axis": {
      -            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -            "enum": [
      -              "time",
      -              "branches",
      -              "list"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "bridge_config": {
      -            "properties": {
      -              "axis": {
      -                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -                "enum": [
      -                  "time",
      -                  "branches"
      -                ],
      -                "type": "string"
      -              },
      -              "branches": {
      -                "description": "Branch ids compared when axis=branches: [from, to].",
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "contributions": {
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "end_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              },
      -              "endpoint": {
      -                "description": "Single endpoint item (stock/balance) read at start & end periods",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "endpoint_branch": {
      -                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "residual_label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              },
      -              "start_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "endpoint"
      -            ],
      -            "type": "object"
      -          },
      -          "by_branch": {
      -            "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      -            "type": "boolean"
      -          },
      -          "cagr": {
      -            "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      -            "type": "boolean"
      -          },
      -          "chart_type": {
      -            "enum": [
      -              "line",
      -              "bar",
      -              "area",
      -              "bridge"
      -            ],
      -            "type": "string"
      -          },
      -          "check": {
      -            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "comment": {
      -            "anyOf": [
      -              {
      -                "maxLength": 2000,
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -          },
      -          "compare_to": {
      -            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          "default_branch": {
      -            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "format": {
      -            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "formula": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "inputs": {
      -            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "item_style": {
      -            "enum": [
      -              "normal",
      -              "subtotal",
      -              "total",
      -              "kpi"
      -            ],
      -            "type": "string"
      -          },
      -          "list_mode": {
      -            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -            "enum": [
      -              "split",
      -              "total"
      -            ],
      -            "type": "string"
      -          },
      -          "list_total": {
      -            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -            "type": "boolean"
      -          },
      -          "liste": {
      -            "description": "mini_table list whose entries become the columns (axis=list)",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "liste_ref": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "monitor": {
      -            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          "name": {
      -            "description": "Display name",
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "opening_balance": {
      -            "type": "number"
      -          },
      -          "period_window": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  },
      -                  "fit": {
      -                    "enum": [
      -                      "data",
      -                      "full"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -          },
      -          "position": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "col": {
      -                    "maximum": 11,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "row": {
      -                    "maximum": 400,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  }
      -                },
      -                "required": [
      -                  "col",
      -                  "row"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -          },
      -          "role": {
      -            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -            "enum": [
      -              "assumption",
      -              "formula",
      -              "callup",
      -              "balance",
      -              "section",
      -              "chart",
      -              "dashboard",
      -              "kpi",
      -              "mini_table"
      -            ],
      -            "type": "string"
      -          },
      -          "row_break": {
      -            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -            "type": "boolean"
      -          },
      -          "rows": {
      -            "description": "mini_table curated row item UIDs / temp IDs / names",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series_defs": {
      -            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -            "items": {
      -              "properties": {
      -                "branch_id": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "uid": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "uid"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "description": "Callup source UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "span": {
      -            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -            "properties": {
      -              "cols": {
      -                "maximum": 12,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "rows": {
      -                "maximum": 4,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "sparkline": {
      -            "description": "KPI trend mini-chart under the value.",
      -            "type": "boolean"
      -          },
      -          "target": {
      -            "description": "KPI/mini_table target UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "target_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "timeline_ref": {
      -            "enum": [
      -              "constant",
      -              "monthly",
      -              "yearly",
      -              "quarterly"
      -            ],
      -            "type": "string"
      -          },
      -          "timeline_values": {
      -            "additionalProperties": {
      -              "anyOf": [
      -                {
      -                  "anyOf": [
      -                    {
      -                      "type": "number"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ]
      -                },
      -                {
      -                  "items": {
      -                    "anyOf": [
      -                      {
      -                        "type": "number"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ]
      -                  },
      -                  "type": "array"
      -                }
      -              ]
      -            },
      -            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -            "propertyNames": {
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "unit": {
      -            "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are never divided",
      -            "enum": [
      -              "none",
      -              "k",
      -              "m",
      -              "auto"
      -            ],
      -            "type": "string"
      -          },
      -          "value": {
      -            "anyOf": [
      -              {
      -                "type": "number"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "values": {
      -            "items": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            "type": "array"
      -          },
      -          "variance": {
      -            "description": "mini_table écart columns (axis=branches)",
      -            "properties": {
      -              "abs": {
      -                "type": "boolean"
      -              },
      -              "color": {
      -                "type": "boolean"
      -              },
      -              "pct": {
      -                "type": "boolean"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "role",
      -          "name"
      -        ],
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "preserve_order": {
      -        "type": "boolean"
      -      },
      -      "preserve_parent": {
      -        "type": "boolean"
      -      },
      -      "preserve_presentation": {
      -        "description": "Default true: every presentation / annotation field `new_item` omits (item_style, format, comment, check, span, position, period_window, compare_to, sparkline, series_defs, …) is carried over from the replaced item when the new role can hold it. Pass false to rebuild the item from `new_item` alone.",
      -        "type": "boolean"
      -      },
      -      "preserve_style": {
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "from_uid",
      -      "new_item"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "after": {
      -        "description": "UID of item to place after (for ordering)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "move",
      -        "type": "string"
      -      },
      -      "parent": {
      -        "description": "New parent UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to move",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_create",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_update",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "list_delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of list to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "finance_md": {
      -        "anyOf": [
      -          {
      -            "maxLength": 5000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "formats": {
      -        "additionalProperties": {
      -          "properties": {
      -            "display_name": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "excel_format": {
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "name": {
      -              "maxLength": 50,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "excel_format"
      -          ],
      -          "type": "object"
      -        },
      -        "propertyNames": {
      -          "maxLength": 50,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "glyph": {
      -        "anyOf": [
      -          {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      -      },
      -      "name": {
      -        "maxLength": 100,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "number_locale": {
      -        "anyOf": [
      -          {
      -            "enum": [
      -              "en",
      -              "fr",
      -              "de"
      -            ],
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "op": {
      -        "const": "meta",
      -        "type": "string"
      -      },
      -      "subtitle": {
      -        "anyOf": [
      -          {
      -            "maxLength": 160,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "timelines": {
      -        "properties": {
      -          "monthly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "quarterly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "yearly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "by_branch": {
      +        "description": "Chart only: one styled series per branch; false reverts to the checked-out view.",
      +        "type": "boolean"
      +      },
      +      "cagr": {
      +        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +        "type": "boolean"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Flags the line as a control judged on its own value: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. `null` removes the check. Failing periods surface in `layerz_read` under `health`, non-blocking."
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (null clears it)."
      +      },
      +      "compare_to": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "KPI native comparison; null clears it."
      +      },
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      +      },
      +      "name": {
      +        "description": "New display label (also the formula identifier)",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "update",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "New parent UID (null to move to root)"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Change the item role. Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "description": "Chart series UIDs",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch; supersedes `series`.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "uid": {
      +        "description": "Existing item UID to update",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "unit": {
      +        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      +        "enum": [
      +          "none",
      +          "k",
      +          "m",
      +          "auto"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "by_branch": {
      +        "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      +        "type": "boolean"
      +      },
      +      "cagr": {
      +        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +        "type": "boolean"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "description": "Flags the line as a control judged on its own value at every period: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals, so a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (\"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health`, non-blocking.",
      +        "properties": {
      +          "tolerance": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +      },
      +      "compare_to": {
      +        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +        "properties": {
      +          "branch_id": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "display": {
      +            "enum": [
      +              "abs",
      +              "pct",
      +              "both"
      +            ],
      +            "type": "string"
      +          },
      +          "mode": {
      +            "enum": [
      +              "branch",
      +              "prev_period",
      +              "prev_year"
      +            ],
      +            "type": "string"
      +          },
      +          "thresholds": {
      +            "properties": {
      +              "green": {
      +                "type": "number"
      +              },
      +              "red": {
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "green",
      +              "red"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "mode"
      +        ],
      +        "type": "object"
      +      },
      +      "default_branch": {
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as one series (a list total charted without a mirror formula).",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +        "properties": {
      +          "assert": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "assert"
      +        ],
      +        "type": "object"
      +      },
      +      "name": {
      +        "description": "Display name",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "create",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart under the value.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "unit": {
      +        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      +        "enum": [
      +          "none",
      +          "k",
      +          "m",
      +          "auto"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "role",
      +      "name",
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "from_uid": {
      +        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "new_item": {
      +        "description": "Inline payload describing the replacement item",
      +        "properties": {
      +          "aggregation": {
      +            "enum": [
      +              "sum",
      +              "average",
      +              "stock"
      +            ],
      +            "type": "string"
      +          },
      +          "axis": {
      +            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +            "enum": [
      +              "time",
      +              "branches",
      +              "list"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "bridge_config": {
      +            "properties": {
      +              "axis": {
      +                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +                "enum": [
      +                  "time",
      +                  "branches"
      +                ],
      +                "type": "string"
      +              },
      +              "branches": {
      +                "description": "Branch ids compared when axis=branches: [from, to].",
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "contributions": {
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "end_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              },
      +              "endpoint": {
      +                "description": "Single endpoint item (stock/balance) read at start & end periods",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "endpoint_branch": {
      +                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "residual_label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              },
      +              "start_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "endpoint"
      +            ],
      +            "type": "object"
      +          },
      +          "by_branch": {
      +            "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      +            "type": "boolean"
      +          },
      +          "cagr": {
      +            "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +            "type": "boolean"
      +          },
      +          "chart_type": {
      +            "enum": [
      +              "line",
      +              "bar",
      +              "area",
      +              "bridge"
      +            ],
      +            "type": "string"
      +          },
      +          "check": {
      +            "description": "Flags the line as a control judged on its own value at every period: a plain amount passes when within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals, so a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (\"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health`, non-blocking.",
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "comment": {
      +            "anyOf": [
      +              {
      +                "maxLength": 2000,
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +          },
      +          "compare_to": {
      +            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          "default_branch": {
      +            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "format": {
      +            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is rejected with code UNKNOWN_FORMAT listing what is available (`percent` is the current name of the legacy `\"%\"`). Full catalog with each excel_format and rendered positive/negative/zero examples (`default` = dash-for-zero accounting style, `integer` = plain 0): MCP resource `format-spec://reference`.",
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "formula": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "inputs": {
      +            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "item_style": {
      +            "enum": [
      +              "normal",
      +              "subtotal",
      +              "total",
      +              "kpi"
      +            ],
      +            "type": "string"
      +          },
      +          "list_mode": {
      +            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as one series (a list total charted without a mirror formula).",
      +            "enum": [
      +              "split",
      +              "total"
      +            ],
      +            "type": "string"
      +          },
      +          "list_total": {
      +            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +            "type": "boolean"
      +          },
      +          "liste": {
      +            "description": "mini_table list whose entries become the columns (axis=list)",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "liste_ref": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "monitor": {
      +            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          "name": {
      +            "description": "Display name",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "opening_balance": {
      +            "type": "number"
      +          },
      +          "period_window": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  },
      +                  "fit": {
      +                    "enum": [
      +                      "data",
      +                      "full"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. `null` clears it (back to fit-to-data)."
      +          },
      +          "position": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "col": {
      +                    "maximum": 11,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "row": {
      +                    "maximum": 400,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "col",
      +                  "row"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +          },
      +          "role": {
      +            "description": "Role of the item. assumption: a typed input (value / values / timeline_values), the only role a branch overlays. formula: a computed transformation (formula). formula with no expression and children: an aggregator that sums its children (a subtotal value; a nested section is structural grouping with no value). callup: a typed mirror of one source whose value flows into its parent (source): balance flows, a value surfaced in a section or subtotal; a formula references its source directly instead. balance: a rolling stock (opening_balance) that sums its callup-child flows. section: structural container, no value. dashboard / chart / kpi / mini_table: presentational. A formula carrying both an expression and children is rejected (FORMULA_EXPR_AND_CHILDREN). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +            "enum": [
      +              "assumption",
      +              "formula",
      +              "callup",
      +              "balance",
      +              "section",
      +              "chart",
      +              "dashboard",
      +              "kpi",
      +              "mini_table"
      +            ],
      +            "type": "string"
      +          },
      +          "row_break": {
      +            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +            "type": "boolean"
      +          },
      +          "rows": {
      +            "description": "mini_table curated row item UIDs / temp IDs / names",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series_defs": {
      +            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +            "items": {
      +              "properties": {
      +                "branch_id": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "uid": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "uid"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "description": "Callup source UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "span": {
      +            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +            "properties": {
      +              "cols": {
      +                "maximum": 12,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "rows": {
      +                "maximum": 4,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "sparkline": {
      +            "description": "KPI trend mini-chart under the value.",
      +            "type": "boolean"
      +          },
      +          "target": {
      +            "description": "KPI/mini_table target UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "target_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "timeline_ref": {
      +            "enum": [
      +              "constant",
      +              "monthly",
      +              "yearly",
      +              "quarterly"
      +            ],
      +            "type": "string"
      +          },
      +          "timeline_values": {
      +            "additionalProperties": {
      +              "anyOf": [
      +                {
      +                  "anyOf": [
      +                    {
      +                      "type": "number"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ]
      +                },
      +                {
      +                  "items": {
      +                    "anyOf": [
      +                      {
      +                        "type": "number"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "type": "array"
      +                }
      +              ]
      +            },
      +            "description": "Periodic values, keyed by context. List-mode item: one series per list entry, keyed by the element UID, label, or a `list_create` temp id of the same batch (a temp id is scoped to the batch that declares it; later batches key by label or UID). Non-list item: a sparse per-period patch keyed by period id (`{\"2026-06\": -119.19}`, keys YYYY / YYYY-MM / YYYY-Qn) that rewrites the named cells of the typed `values` series and leaves the rest intact; a full series keyed by a canonical grain (`monthly` / `quarterly` / `yearly` / `constant`) is import-owned and rejected here. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +            "propertyNames": {
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "unit": {
      +            "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are not divided",
      +            "enum": [
      +              "none",
      +              "k",
      +              "m",
      +              "auto"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "values": {
      +            "items": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "type": "array"
      +          },
      +          "variance": {
      +            "description": "mini_table écart columns (axis=branches)",
      +            "properties": {
      +              "abs": {
      +                "type": "boolean"
      +              },
      +              "color": {
      +                "type": "boolean"
      +              },
      +              "pct": {
      +                "type": "boolean"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "role",
      +          "name"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "preserve_order": {
      +        "type": "boolean"
      +      },
      +      "preserve_parent": {
      +        "type": "boolean"
      +      },
      +      "preserve_presentation": {
      +        "description": "Default true: every presentation / annotation field `new_item` omits (item_style, format, comment, check, span, position, period_window, compare_to, sparkline, series_defs, …) is carried over from the replaced item when the new role can hold it; `false` rebuilds the item from `new_item` alone.",
      +        "type": "boolean"
      +      },
      +      "preserve_style": {
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "from_uid",
      +      "new_item"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "UID of item to place after (for ordering)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "move",
      +        "type": "string"
      +      },
      +      "parent": {
      +        "description": "New parent UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to move",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_create",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_update",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "list_delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of list to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "finance_md": {
      +        "anyOf": [
      +          {
      +            "maxLength": 5000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "formats": {
      +        "additionalProperties": {
      +          "properties": {
      +            "display_name": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "excel_format": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "name": {
      +              "maxLength": 50,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "excel_format"
      +          ],
      +          "type": "object"
      +        },
      +        "propertyNames": {
      +          "maxLength": 50,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "glyph": {
      +        "anyOf": [
      +          {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      +      },
      +      "name": {
      +        "maxLength": 100,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "number_locale": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "en",
      +              "fr",
      +              "de"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "op": {
      +        "const": "meta",
      +        "type": "string"
      +      },
      +      "subtitle": {
      +        "anyOf": [
      +          {
      +            "maxLength": 160,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "timelines": {
      +        "properties": {
      +          "monthly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "quarterly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "yearly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / summary / description
      Previous value: -"Required: short human-readable note (3–100 chars) summarising what this change does. Shown as the label in the model version history. Be specific (e.g. \"Renamed Revenue to Net Revenue\", \"Imported 2024 OPEX from Excel\")."New value: +"Short note (3–100 chars) describing the change, stored as the label of the resulting version. Examples: \"Renamed Revenue to Net Revenue\", \"Imported 2024 OPEX from Excel\"."
  3. Changed1 schema field changed
    • changedInput schema / properties / ops / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (null clears it)."
      -      },
      -      "compare_to": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "KPI native comparison; null clears it."
      -      },
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      -      },
      -      "name": {
      -        "description": "New display label (also the formula identifier)",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "update",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "New parent UID (null to move to root)"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "description": "Chart series UIDs",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch; supersedes `series`.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "uid": {
      -        "description": "Existing item UID to update",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -        "properties": {
      -          "tolerance": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -      },
      -      "compare_to": {
      -        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -        "properties": {
      -          "branch_id": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "display": {
      -            "enum": [
      -              "abs",
      -              "pct",
      -              "both"
      -            ],
      -            "type": "string"
      -          },
      -          "mode": {
      -            "enum": [
      -              "branch",
      -              "prev_period",
      -              "prev_year"
      -            ],
      -            "type": "string"
      -          },
      -          "thresholds": {
      -            "properties": {
      -              "green": {
      -                "type": "number"
      -              },
      -              "red": {
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "green",
      -              "red"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "mode"
      -        ],
      -        "type": "object"
      -      },
      -      "default_branch": {
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -        "properties": {
      -          "assert": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "assert"
      -        ],
      -        "type": "object"
      -      },
      -      "name": {
      -        "description": "Display name",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "create",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart under the value.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "role",
      -      "name",
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "from_uid": {
      -        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "new_item": {
      -        "description": "Inline payload describing the replacement item",
      -        "properties": {
      -          "aggregation": {
      -            "enum": [
      -              "sum",
      -              "average",
      -              "stock"
      -            ],
      -            "type": "string"
      -          },
      -          "axis": {
      -            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -            "enum": [
      -              "time",
      -              "branches",
      -              "list"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "bridge_config": {
      -            "properties": {
      -              "axis": {
      -                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -                "enum": [
      -                  "time",
      -                  "branches"
      -                ],
      -                "type": "string"
      -              },
      -              "branches": {
      -                "description": "Branch ids compared when axis=branches: [from, to].",
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "contributions": {
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "end_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              },
      -              "endpoint": {
      -                "description": "Single endpoint item (stock/balance) read at start & end periods",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "endpoint_branch": {
      -                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "residual_label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              },
      -              "start_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "endpoint"
      -            ],
      -            "type": "object"
      -          },
      -          "chart_type": {
      -            "enum": [
      -              "line",
      -              "bar",
      -              "area",
      -              "bridge"
      -            ],
      -            "type": "string"
      -          },
      -          "check": {
      -            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "comment": {
      -            "anyOf": [
      -              {
      -                "maxLength": 2000,
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -          },
      -          "compare_to": {
      -            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          "default_branch": {
      -            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "format": {
      -            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "formula": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "inputs": {
      -            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "item_style": {
      -            "enum": [
      -              "normal",
      -              "subtotal",
      -              "total",
      -              "kpi"
      -            ],
      -            "type": "string"
      -          },
      -          "list_mode": {
      -            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -            "enum": [
      -              "split",
      -              "total"
      -            ],
      -            "type": "string"
      -          },
      -          "list_total": {
      -            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -            "type": "boolean"
      -          },
      -          "liste": {
      -            "description": "mini_table list whose entries become the columns (axis=list)",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "liste_ref": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "monitor": {
      -            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          "name": {
      -            "description": "Display name",
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "opening_balance": {
      -            "type": "number"
      -          },
      -          "period_window": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  },
      -                  "fit": {
      -                    "enum": [
      -                      "data",
      -                      "full"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -          },
      -          "position": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "col": {
      -                    "maximum": 11,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "row": {
      -                    "maximum": 400,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  }
      -                },
      -                "required": [
      -                  "col",
      -                  "row"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -          },
      -          "role": {
      -            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -            "enum": [
      -              "assumption",
      -              "formula",
      -              "callup",
      -              "balance",
      -              "section",
      -              "chart",
      -              "dashboard",
      -              "kpi",
      -              "mini_table"
      -            ],
      -            "type": "string"
      -          },
      -          "row_break": {
      -            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -            "type": "boolean"
      -          },
      -          "rows": {
      -            "description": "mini_table curated row item UIDs / temp IDs / names",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series_defs": {
      -            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -            "items": {
      -              "properties": {
      -                "branch_id": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "uid": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "uid"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "description": "Callup source UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "span": {
      -            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -            "properties": {
      -              "cols": {
      -                "maximum": 12,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "rows": {
      -                "maximum": 4,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "sparkline": {
      -            "description": "KPI trend mini-chart under the value.",
      -            "type": "boolean"
      -          },
      -          "target": {
      -            "description": "KPI/mini_table target UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "target_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "timeline_ref": {
      -            "enum": [
      -              "constant",
      -              "monthly",
      -              "yearly",
      -              "quarterly"
      -            ],
      -            "type": "string"
      -          },
      -          "timeline_values": {
      -            "additionalProperties": {
      -              "anyOf": [
      -                {
      -                  "anyOf": [
      -                    {
      -                      "type": "number"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ]
      -                },
      -                {
      -                  "items": {
      -                    "anyOf": [
      -                      {
      -                        "type": "number"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ]
      -                  },
      -                  "type": "array"
      -                }
      -              ]
      -            },
      -            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -            "propertyNames": {
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "value": {
      -            "anyOf": [
      -              {
      -                "type": "number"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "values": {
      -            "items": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            "type": "array"
      -          },
      -          "variance": {
      -            "description": "mini_table écart columns (axis=branches)",
      -            "properties": {
      -              "abs": {
      -                "type": "boolean"
      -              },
      -              "color": {
      -                "type": "boolean"
      -              },
      -              "pct": {
      -                "type": "boolean"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "role",
      -          "name"
      -        ],
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "preserve_order": {
      -        "type": "boolean"
      -      },
      -      "preserve_parent": {
      -        "type": "boolean"
      -      },
      -      "preserve_style": {
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "from_uid",
      -      "new_item"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "after": {
      -        "description": "UID of item to place after (for ordering)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "move",
      -        "type": "string"
      -      },
      -      "parent": {
      -        "description": "New parent UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to move",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_create",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_update",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "list_delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of list to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "finance_md": {
      -        "anyOf": [
      -          {
      -            "maxLength": 5000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "formats": {
      -        "additionalProperties": {
      -          "properties": {
      -            "display_name": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "excel_format": {
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "name": {
      -              "maxLength": 50,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "excel_format"
      -          ],
      -          "type": "object"
      -        },
      -        "propertyNames": {
      -          "maxLength": 50,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "glyph": {
      -        "anyOf": [
      -          {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      -      },
      -      "name": {
      -        "maxLength": 100,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "number_locale": {
      -        "anyOf": [
      -          {
      -            "enum": [
      -              "en",
      -              "fr",
      -              "de"
      -            ],
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "op": {
      -        "const": "meta",
      -        "type": "string"
      -      },
      -      "subtitle": {
      -        "anyOf": [
      -          {
      -            "maxLength": 160,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "timelines": {
      -        "properties": {
      -          "monthly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "quarterly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "yearly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "by_branch": {
      +        "description": "Chart only: one styled series per branch; false reverts to the checked-out view.",
      +        "type": "boolean"
      +      },
      +      "cagr": {
      +        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +        "type": "boolean"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (null clears it)."
      +      },
      +      "compare_to": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "KPI native comparison; null clears it."
      +      },
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      +      },
      +      "name": {
      +        "description": "New display label (also the formula identifier)",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "update",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "New parent UID (null to move to root)"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "description": "Chart series UIDs",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch; supersedes `series`.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "uid": {
      +        "description": "Existing item UID to update",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "unit": {
      +        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are never divided",
      +        "enum": [
      +          "none",
      +          "k",
      +          "m",
      +          "auto"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "by_branch": {
      +        "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      +        "type": "boolean"
      +      },
      +      "cagr": {
      +        "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +        "type": "boolean"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +        "properties": {
      +          "tolerance": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +      },
      +      "compare_to": {
      +        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +        "properties": {
      +          "branch_id": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "display": {
      +            "enum": [
      +              "abs",
      +              "pct",
      +              "both"
      +            ],
      +            "type": "string"
      +          },
      +          "mode": {
      +            "enum": [
      +              "branch",
      +              "prev_period",
      +              "prev_year"
      +            ],
      +            "type": "string"
      +          },
      +          "thresholds": {
      +            "properties": {
      +              "green": {
      +                "type": "number"
      +              },
      +              "red": {
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "green",
      +              "red"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "mode"
      +        ],
      +        "type": "object"
      +      },
      +      "default_branch": {
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +        "properties": {
      +          "assert": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "assert"
      +        ],
      +        "type": "object"
      +      },
      +      "name": {
      +        "description": "Display name",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "create",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart under the value.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "unit": {
      +        "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are never divided",
      +        "enum": [
      +          "none",
      +          "k",
      +          "m",
      +          "auto"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "role",
      +      "name",
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "from_uid": {
      +        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "new_item": {
      +        "description": "Inline payload describing the replacement item",
      +        "properties": {
      +          "aggregation": {
      +            "enum": [
      +              "sum",
      +              "average",
      +              "stock"
      +            ],
      +            "type": "string"
      +          },
      +          "axis": {
      +            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +            "enum": [
      +              "time",
      +              "branches",
      +              "list"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "bridge_config": {
      +            "properties": {
      +              "axis": {
      +                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +                "enum": [
      +                  "time",
      +                  "branches"
      +                ],
      +                "type": "string"
      +              },
      +              "branches": {
      +                "description": "Branch ids compared when axis=branches: [from, to].",
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "contributions": {
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "end_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              },
      +              "endpoint": {
      +                "description": "Single endpoint item (stock/balance) read at start & end periods",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "endpoint_branch": {
      +                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "residual_label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              },
      +              "start_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "endpoint"
      +            ],
      +            "type": "object"
      +          },
      +          "by_branch": {
      +            "description": "Chart only: plot one styled series per branch instead of the checked-out view.",
      +            "type": "boolean"
      +          },
      +          "cagr": {
      +            "description": "mini_table (axis=time): show the trailing CAGR column. Default true",
      +            "type": "boolean"
      +          },
      +          "chart_type": {
      +            "enum": [
      +              "line",
      +              "bar",
      +              "area",
      +              "bridge"
      +            ],
      +            "type": "string"
      +          },
      +          "check": {
      +            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "comment": {
      +            "anyOf": [
      +              {
      +                "maxLength": 2000,
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +          },
      +          "compare_to": {
      +            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          "default_branch": {
      +            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "format": {
      +            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "formula": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "inputs": {
      +            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "item_style": {
      +            "enum": [
      +              "normal",
      +              "subtotal",
      +              "total",
      +              "kpi"
      +            ],
      +            "type": "string"
      +          },
      +          "list_mode": {
      +            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +            "enum": [
      +              "split",
      +              "total"
      +            ],
      +            "type": "string"
      +          },
      +          "list_total": {
      +            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +            "type": "boolean"
      +          },
      +          "liste": {
      +            "description": "mini_table list whose entries become the columns (axis=list)",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "liste_ref": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "monitor": {
      +            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          "name": {
      +            "description": "Display name",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "opening_balance": {
      +            "type": "number"
      +          },
      +          "period_window": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  },
      +                  "fit": {
      +                    "enum": [
      +                      "data",
      +                      "full"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +          },
      +          "position": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "col": {
      +                    "maximum": 11,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "row": {
      +                    "maximum": 400,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "col",
      +                  "row"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +          },
      +          "role": {
      +            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +            "enum": [
      +              "assumption",
      +              "formula",
      +              "callup",
      +              "balance",
      +              "section",
      +              "chart",
      +              "dashboard",
      +              "kpi",
      +              "mini_table"
      +            ],
      +            "type": "string"
      +          },
      +          "row_break": {
      +            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +            "type": "boolean"
      +          },
      +          "rows": {
      +            "description": "mini_table curated row item UIDs / temp IDs / names",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series_defs": {
      +            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +            "items": {
      +              "properties": {
      +                "branch_id": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "uid": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "uid"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "description": "Callup source UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "span": {
      +            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +            "properties": {
      +              "cols": {
      +                "maximum": 12,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "rows": {
      +                "maximum": 4,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "sparkline": {
      +            "description": "KPI trend mini-chart under the value.",
      +            "type": "boolean"
      +          },
      +          "target": {
      +            "description": "KPI/mini_table target UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "target_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "timeline_ref": {
      +            "enum": [
      +              "constant",
      +              "monthly",
      +              "yearly",
      +              "quarterly"
      +            ],
      +            "type": "string"
      +          },
      +          "timeline_values": {
      +            "additionalProperties": {
      +              "anyOf": [
      +                {
      +                  "anyOf": [
      +                    {
      +                      "type": "number"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ]
      +                },
      +                {
      +                  "items": {
      +                    "anyOf": [
      +                      {
      +                        "type": "number"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "type": "array"
      +                }
      +              ]
      +            },
      +            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +            "propertyNames": {
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "unit": {
      +            "description": "mini_table amount scaling: 'none' (default), 'k' (thousands), 'm' (millions), 'auto' (per-table scale); %, multiples and dates are never divided",
      +            "enum": [
      +              "none",
      +              "k",
      +              "m",
      +              "auto"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "values": {
      +            "items": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "type": "array"
      +          },
      +          "variance": {
      +            "description": "mini_table écart columns (axis=branches)",
      +            "properties": {
      +              "abs": {
      +                "type": "boolean"
      +              },
      +              "color": {
      +                "type": "boolean"
      +              },
      +              "pct": {
      +                "type": "boolean"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "role",
      +          "name"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "preserve_order": {
      +        "type": "boolean"
      +      },
      +      "preserve_parent": {
      +        "type": "boolean"
      +      },
      +      "preserve_presentation": {
      +        "description": "Default true: every presentation / annotation field `new_item` omits (item_style, format, comment, check, span, position, period_window, compare_to, sparkline, series_defs, …) is carried over from the replaced item when the new role can hold it. Pass false to rebuild the item from `new_item` alone.",
      +        "type": "boolean"
      +      },
      +      "preserve_style": {
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "from_uid",
      +      "new_item"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "UID of item to place after (for ordering)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "move",
      +        "type": "string"
      +      },
      +      "parent": {
      +        "description": "New parent UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to move",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_create",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_update",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "list_delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of list to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "finance_md": {
      +        "anyOf": [
      +          {
      +            "maxLength": 5000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "formats": {
      +        "additionalProperties": {
      +          "properties": {
      +            "display_name": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "excel_format": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "name": {
      +              "maxLength": 50,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "excel_format"
      +          ],
      +          "type": "object"
      +        },
      +        "propertyNames": {
      +          "maxLength": 50,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "glyph": {
      +        "anyOf": [
      +          {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      +      },
      +      "name": {
      +        "maxLength": 100,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "number_locale": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "en",
      +              "fr",
      +              "de"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "op": {
      +        "const": "meta",
      +        "type": "string"
      +      },
      +      "subtitle": {
      +        "anyOf": [
      +          {
      +            "maxLength": 160,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "timelines": {
      +        "properties": {
      +          "monthly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "quarterly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "yearly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
  4. Changed1 schema field changed
    • changedInput schema / properties / ops / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (null clears it)."
      -      },
      -      "compare_to": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "KPI native comparison; null clears it."
      -      },
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      -      },
      -      "name": {
      -        "description": "New display label (also the formula identifier)",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "update",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "New parent UID (null to move to root)"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "description": "Chart series UIDs",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch; supersedes `series`.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "uid": {
      -        "description": "Existing item UID to update",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -        "properties": {
      -          "tolerance": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -      },
      -      "compare_to": {
      -        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -        "properties": {
      -          "branch_id": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "display": {
      -            "enum": [
      -              "abs",
      -              "pct",
      -              "both"
      -            ],
      -            "type": "string"
      -          },
      -          "mode": {
      -            "enum": [
      -              "branch",
      -              "prev_period",
      -              "prev_year"
      -            ],
      -            "type": "string"
      -          },
      -          "thresholds": {
      -            "properties": {
      -              "green": {
      -                "type": "number"
      -              },
      -              "red": {
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "green",
      -              "red"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "mode"
      -        ],
      -        "type": "object"
      -      },
      -      "default_branch": {
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -        "properties": {
      -          "assert": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "assert"
      -        ],
      -        "type": "object"
      -      },
      -      "name": {
      -        "description": "Display name",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "create",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "position": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "col": {
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "row": {
      -                "maximum": 400,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "col",
      -              "row"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -      },
      -      "role": {
      -        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart under the value.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "role",
      -      "name",
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "from_uid": {
      -        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "new_item": {
      -        "description": "Inline payload describing the replacement item",
      -        "properties": {
      -          "aggregation": {
      -            "enum": [
      -              "sum",
      -              "average",
      -              "stock"
      -            ],
      -            "type": "string"
      -          },
      -          "axis": {
      -            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -            "enum": [
      -              "time",
      -              "branches",
      -              "list"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "bridge_config": {
      -            "properties": {
      -              "axis": {
      -                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -                "enum": [
      -                  "time",
      -                  "branches"
      -                ],
      -                "type": "string"
      -              },
      -              "branches": {
      -                "description": "Branch ids compared when axis=branches: [from, to].",
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "contributions": {
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "end_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              },
      -              "endpoint": {
      -                "description": "Single endpoint item (stock/balance) read at start & end periods",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "endpoint_branch": {
      -                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "residual_label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              },
      -              "start_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "endpoint"
      -            ],
      -            "type": "object"
      -          },
      -          "chart_type": {
      -            "enum": [
      -              "line",
      -              "bar",
      -              "area",
      -              "bridge"
      -            ],
      -            "type": "string"
      -          },
      -          "check": {
      -            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "comment": {
      -            "anyOf": [
      -              {
      -                "maxLength": 2000,
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -          },
      -          "compare_to": {
      -            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          "default_branch": {
      -            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "format": {
      -            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "formula": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "inputs": {
      -            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "item_style": {
      -            "enum": [
      -              "normal",
      -              "subtotal",
      -              "total",
      -              "kpi"
      -            ],
      -            "type": "string"
      -          },
      -          "list_mode": {
      -            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -            "enum": [
      -              "split",
      -              "total"
      -            ],
      -            "type": "string"
      -          },
      -          "list_total": {
      -            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -            "type": "boolean"
      -          },
      -          "liste": {
      -            "description": "mini_table list whose entries become the columns (axis=list)",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "liste_ref": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "monitor": {
      -            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          "name": {
      -            "description": "Display name",
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "opening_balance": {
      -            "type": "number"
      -          },
      -          "period_window": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  },
      -                  "fit": {
      -                    "enum": [
      -                      "data",
      -                      "full"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -          },
      -          "position": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "col": {
      -                    "maximum": 11,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "row": {
      -                    "maximum": 400,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  }
      -                },
      -                "required": [
      -                  "col",
      -                  "row"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      -          },
      -          "role": {
      -            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -            "enum": [
      -              "assumption",
      -              "formula",
      -              "callup",
      -              "balance",
      -              "section",
      -              "chart",
      -              "dashboard",
      -              "kpi",
      -              "mini_table"
      -            ],
      -            "type": "string"
      -          },
      -          "row_break": {
      -            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      -            "type": "boolean"
      -          },
      -          "rows": {
      -            "description": "mini_table curated row item UIDs / temp IDs / names",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series_defs": {
      -            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -            "items": {
      -              "properties": {
      -                "branch_id": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "uid": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "uid"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "description": "Callup source UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "span": {
      -            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -            "properties": {
      -              "cols": {
      -                "maximum": 12,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "rows": {
      -                "maximum": 4,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "sparkline": {
      -            "description": "KPI trend mini-chart under the value.",
      -            "type": "boolean"
      -          },
      -          "target": {
      -            "description": "KPI/mini_table target UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "target_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "timeline_ref": {
      -            "enum": [
      -              "constant",
      -              "monthly",
      -              "yearly",
      -              "quarterly"
      -            ],
      -            "type": "string"
      -          },
      -          "timeline_values": {
      -            "additionalProperties": {
      -              "anyOf": [
      -                {
      -                  "anyOf": [
      -                    {
      -                      "type": "number"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ]
      -                },
      -                {
      -                  "items": {
      -                    "anyOf": [
      -                      {
      -                        "type": "number"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ]
      -                  },
      -                  "type": "array"
      -                }
      -              ]
      -            },
      -            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -            "propertyNames": {
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "value": {
      -            "anyOf": [
      -              {
      -                "type": "number"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "values": {
      -            "items": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            "type": "array"
      -          },
      -          "variance": {
      -            "description": "mini_table écart columns (axis=branches)",
      -            "properties": {
      -              "abs": {
      -                "type": "boolean"
      -              },
      -              "color": {
      -                "type": "boolean"
      -              },
      -              "pct": {
      -                "type": "boolean"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "role",
      -          "name"
      -        ],
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "preserve_order": {
      -        "type": "boolean"
      -      },
      -      "preserve_parent": {
      -        "type": "boolean"
      -      },
      -      "preserve_style": {
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "from_uid",
      -      "new_item"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "after": {
      -        "description": "UID of item to place after (for ordering)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "move",
      -        "type": "string"
      -      },
      -      "parent": {
      -        "description": "New parent UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to move",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_create",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_update",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "list_delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of list to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "finance_md": {
      -        "anyOf": [
      -          {
      -            "maxLength": 5000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "formats": {
      -        "additionalProperties": {
      -          "properties": {
      -            "display_name": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "excel_format": {
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "name": {
      -              "maxLength": 50,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "excel_format"
      -          ],
      -          "type": "object"
      -        },
      -        "propertyNames": {
      -          "maxLength": 50,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "glyph": {
      -        "anyOf": [
      -          {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      -      },
      -      "name": {
      -        "maxLength": 100,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "number_locale": {
      -        "anyOf": [
      -          {
      -            "enum": [
      -              "en",
      -              "fr",
      -              "de"
      -            ],
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "op": {
      -        "const": "meta",
      -        "type": "string"
      -      },
      -      "subtitle": {
      -        "anyOf": [
      -          {
      -            "maxLength": 160,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "timelines": {
      -        "properties": {
      -          "monthly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "quarterly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "yearly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (null clears it)."
      +      },
      +      "compare_to": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "KPI native comparison; null clears it."
      +      },
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      +      },
      +      "name": {
      +        "description": "New display label (also the formula identifier)",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "update",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "New parent UID (null to move to root)"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "description": "Chart series UIDs",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch; supersedes `series`.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "uid": {
      +        "description": "Existing item UID to update",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +        "properties": {
      +          "tolerance": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +      },
      +      "compare_to": {
      +        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +        "properties": {
      +          "branch_id": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "display": {
      +            "enum": [
      +              "abs",
      +              "pct",
      +              "both"
      +            ],
      +            "type": "string"
      +          },
      +          "mode": {
      +            "enum": [
      +              "branch",
      +              "prev_period",
      +              "prev_year"
      +            ],
      +            "type": "string"
      +          },
      +          "thresholds": {
      +            "properties": {
      +              "green": {
      +                "type": "number"
      +              },
      +              "red": {
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "green",
      +              "red"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "mode"
      +        ],
      +        "type": "object"
      +      },
      +      "default_branch": {
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +        "properties": {
      +          "assert": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "assert"
      +        ],
      +        "type": "object"
      +      },
      +      "name": {
      +        "description": "Display name",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "create",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart under the value.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "role",
      +      "name",
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "from_uid": {
      +        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "new_item": {
      +        "description": "Inline payload describing the replacement item",
      +        "properties": {
      +          "aggregation": {
      +            "enum": [
      +              "sum",
      +              "average",
      +              "stock"
      +            ],
      +            "type": "string"
      +          },
      +          "axis": {
      +            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +            "enum": [
      +              "time",
      +              "branches",
      +              "list"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "bridge_config": {
      +            "properties": {
      +              "axis": {
      +                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +                "enum": [
      +                  "time",
      +                  "branches"
      +                ],
      +                "type": "string"
      +              },
      +              "branches": {
      +                "description": "Branch ids compared when axis=branches: [from, to].",
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "contributions": {
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "end_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              },
      +              "endpoint": {
      +                "description": "Single endpoint item (stock/balance) read at start & end periods",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "endpoint_branch": {
      +                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "residual_label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              },
      +              "start_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "endpoint"
      +            ],
      +            "type": "object"
      +          },
      +          "chart_type": {
      +            "enum": [
      +              "line",
      +              "bar",
      +              "area",
      +              "bridge"
      +            ],
      +            "type": "string"
      +          },
      +          "check": {
      +            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "comment": {
      +            "anyOf": [
      +              {
      +                "maxLength": 2000,
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +          },
      +          "compare_to": {
      +            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          "default_branch": {
      +            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "format": {
      +            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK); the excel_format follows Excel / Google Sheets, bracket colours and conditions included (`[Green]0;[Red](0);-` paints negatives red on the web and in Excel). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "formula": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "inputs": {
      +            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "item_style": {
      +            "enum": [
      +              "normal",
      +              "subtotal",
      +              "total",
      +              "kpi"
      +            ],
      +            "type": "string"
      +          },
      +          "list_mode": {
      +            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +            "enum": [
      +              "split",
      +              "total"
      +            ],
      +            "type": "string"
      +          },
      +          "list_total": {
      +            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +            "type": "boolean"
      +          },
      +          "liste": {
      +            "description": "mini_table list whose entries become the columns (axis=list)",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "liste_ref": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "monitor": {
      +            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          "name": {
      +            "description": "Display name",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "opening_balance": {
      +            "type": "number"
      +          },
      +          "period_window": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  },
      +                  "fit": {
      +                    "enum": [
      +                      "data",
      +                      "full"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +          },
      +          "position": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "col": {
      +                    "maximum": 11,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "row": {
      +                    "maximum": 400,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "col",
      +                  "row"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +          },
      +          "role": {
      +            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +            "enum": [
      +              "assumption",
      +              "formula",
      +              "callup",
      +              "balance",
      +              "section",
      +              "chart",
      +              "dashboard",
      +              "kpi",
      +              "mini_table"
      +            ],
      +            "type": "string"
      +          },
      +          "row_break": {
      +            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +            "type": "boolean"
      +          },
      +          "rows": {
      +            "description": "mini_table curated row item UIDs / temp IDs / names",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series_defs": {
      +            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +            "items": {
      +              "properties": {
      +                "branch_id": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "uid": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "uid"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "description": "Callup source UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "span": {
      +            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +            "properties": {
      +              "cols": {
      +                "maximum": 12,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "rows": {
      +                "maximum": 4,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "sparkline": {
      +            "description": "KPI trend mini-chart under the value.",
      +            "type": "boolean"
      +          },
      +          "target": {
      +            "description": "KPI/mini_table target UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "target_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "timeline_ref": {
      +            "enum": [
      +              "constant",
      +              "monthly",
      +              "yearly",
      +              "quarterly"
      +            ],
      +            "type": "string"
      +          },
      +          "timeline_values": {
      +            "additionalProperties": {
      +              "anyOf": [
      +                {
      +                  "anyOf": [
      +                    {
      +                      "type": "number"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ]
      +                },
      +                {
      +                  "items": {
      +                    "anyOf": [
      +                      {
      +                        "type": "number"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "type": "array"
      +                }
      +              ]
      +            },
      +            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +            "propertyNames": {
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "value": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "values": {
      +            "items": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "type": "array"
      +          },
      +          "variance": {
      +            "description": "mini_table écart columns (axis=branches)",
      +            "properties": {
      +              "abs": {
      +                "type": "boolean"
      +              },
      +              "color": {
      +                "type": "boolean"
      +              },
      +              "pct": {
      +                "type": "boolean"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "role",
      +          "name"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "preserve_order": {
      +        "type": "boolean"
      +      },
      +      "preserve_parent": {
      +        "type": "boolean"
      +      },
      +      "preserve_style": {
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "from_uid",
      +      "new_item"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "UID of item to place after (for ordering)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "move",
      +        "type": "string"
      +      },
      +      "parent": {
      +        "description": "New parent UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to move",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_create",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_update",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "list_delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of list to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "finance_md": {
      +        "anyOf": [
      +          {
      +            "maxLength": 5000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "formats": {
      +        "additionalProperties": {
      +          "properties": {
      +            "display_name": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "excel_format": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "name": {
      +              "maxLength": 50,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "excel_format"
      +          ],
      +          "type": "object"
      +        },
      +        "propertyNames": {
      +          "maxLength": 50,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "glyph": {
      +        "anyOf": [
      +          {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      +      },
      +      "name": {
      +        "maxLength": 100,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "number_locale": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "en",
      +              "fr",
      +              "de"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "op": {
      +        "const": "meta",
      +        "type": "string"
      +      },
      +      "subtitle": {
      +        "anyOf": [
      +          {
      +            "maxLength": 160,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "timelines": {
      +        "properties": {
      +          "monthly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "quarterly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "yearly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
  5. Changed1 schema field changed
    • changedInput schema / properties / ops / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (null clears it)."
      -      },
      -      "compare_to": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "KPI native comparison; null clears it."
      -      },
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      -      },
      -      "name": {
      -        "description": "New display label (also the formula identifier)",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "update",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "New parent UID (null to move to root)"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "role": {
      -        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break: start this widget on a fresh grid row",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "description": "Chart series UIDs",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch; supersedes `series`.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "uid": {
      -        "description": "Existing item UID to update",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "check": {
      -        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -        "properties": {
      -          "tolerance": {
      -            "exclusiveMinimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -      },
      -      "compare_to": {
      -        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -        "properties": {
      -          "branch_id": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "display": {
      -            "enum": [
      -              "abs",
      -              "pct",
      -              "both"
      -            ],
      -            "type": "string"
      -          },
      -          "mode": {
      -            "enum": [
      -              "branch",
      -              "prev_period",
      -              "prev_year"
      -            ],
      -            "type": "string"
      -          },
      -          "thresholds": {
      -            "properties": {
      -              "green": {
      -                "type": "number"
      -              },
      -              "red": {
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "green",
      -              "red"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "mode"
      -        ],
      -        "type": "object"
      -      },
      -      "default_branch": {
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -        "properties": {
      -          "assert": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "assert"
      -        ],
      -        "type": "object"
      -      },
      -      "name": {
      -        "description": "Display name",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "create",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "role": {
      -        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break: start this widget on a fresh grid row",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart under the value.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "role",
      -      "name",
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "from_uid": {
      -        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "new_item": {
      -        "description": "Inline payload describing the replacement item",
      -        "properties": {
      -          "aggregation": {
      -            "enum": [
      -              "sum",
      -              "average",
      -              "stock"
      -            ],
      -            "type": "string"
      -          },
      -          "axis": {
      -            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -            "enum": [
      -              "time",
      -              "branches",
      -              "list"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "bridge_config": {
      -            "properties": {
      -              "axis": {
      -                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -                "enum": [
      -                  "time",
      -                  "branches"
      -                ],
      -                "type": "string"
      -              },
      -              "branches": {
      -                "description": "Branch ids compared when axis=branches: [from, to].",
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "contributions": {
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "end_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              },
      -              "endpoint": {
      -                "description": "Single endpoint item (stock/balance) read at start & end periods",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "endpoint_branch": {
      -                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "residual_label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              },
      -              "start_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "endpoint"
      -            ],
      -            "type": "object"
      -          },
      -          "chart_type": {
      -            "enum": [
      -              "line",
      -              "bar",
      -              "area",
      -              "bridge"
      -            ],
      -            "type": "string"
      -          },
      -          "check": {
      -            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -            "properties": {
      -              "tolerance": {
      -                "exclusiveMinimum": 0,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "comment": {
      -            "anyOf": [
      -              {
      -                "maxLength": 2000,
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -          },
      -          "compare_to": {
      -            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          "default_branch": {
      -            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "format": {
      -            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "formula": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "inputs": {
      -            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "item_style": {
      -            "enum": [
      -              "normal",
      -              "subtotal",
      -              "total",
      -              "kpi"
      -            ],
      -            "type": "string"
      -          },
      -          "list_mode": {
      -            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -            "enum": [
      -              "split",
      -              "total"
      -            ],
      -            "type": "string"
      -          },
      -          "list_total": {
      -            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -            "type": "boolean"
      -          },
      -          "liste": {
      -            "description": "mini_table list whose entries become the columns (axis=list)",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "liste_ref": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "monitor": {
      -            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          "name": {
      -            "description": "Display name",
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "opening_balance": {
      -            "type": "number"
      -          },
      -          "period_window": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  },
      -                  "fit": {
      -                    "enum": [
      -                      "data",
      -                      "full"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -          },
      -          "role": {
      -            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -            "enum": [
      -              "assumption",
      -              "formula",
      -              "callup",
      -              "balance",
      -              "section",
      -              "chart",
      -              "dashboard",
      -              "kpi",
      -              "mini_table"
      -            ],
      -            "type": "string"
      -          },
      -          "row_break": {
      -            "description": "dashboard-child line break: start this widget on a fresh grid row",
      -            "type": "boolean"
      -          },
      -          "rows": {
      -            "description": "mini_table curated row item UIDs / temp IDs / names",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series_defs": {
      -            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -            "items": {
      -              "properties": {
      -                "branch_id": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "uid": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "uid"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "description": "Callup source UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "span": {
      -            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -            "properties": {
      -              "cols": {
      -                "maximum": 12,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "rows": {
      -                "maximum": 4,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "sparkline": {
      -            "description": "KPI trend mini-chart under the value.",
      -            "type": "boolean"
      -          },
      -          "target": {
      -            "description": "KPI/mini_table target UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "target_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "timeline_ref": {
      -            "enum": [
      -              "constant",
      -              "monthly",
      -              "yearly",
      -              "quarterly"
      -            ],
      -            "type": "string"
      -          },
      -          "timeline_values": {
      -            "additionalProperties": {
      -              "anyOf": [
      -                {
      -                  "anyOf": [
      -                    {
      -                      "type": "number"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ]
      -                },
      -                {
      -                  "items": {
      -                    "anyOf": [
      -                      {
      -                        "type": "number"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ]
      -                  },
      -                  "type": "array"
      -                }
      -              ]
      -            },
      -            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -            "propertyNames": {
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "value": {
      -            "anyOf": [
      -              {
      -                "type": "number"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "values": {
      -            "items": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            "type": "array"
      -          },
      -          "variance": {
      -            "description": "mini_table écart columns (axis=branches)",
      -            "properties": {
      -              "abs": {
      -                "type": "boolean"
      -              },
      -              "color": {
      -                "type": "boolean"
      -              },
      -              "pct": {
      -                "type": "boolean"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "role",
      -          "name"
      -        ],
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "preserve_order": {
      -        "type": "boolean"
      -      },
      -      "preserve_parent": {
      -        "type": "boolean"
      -      },
      -      "preserve_style": {
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "from_uid",
      -      "new_item"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "after": {
      -        "description": "UID of item to place after (for ordering)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "move",
      -        "type": "string"
      -      },
      -      "parent": {
      -        "description": "New parent UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to move",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_create",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_update",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "list_delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of list to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "finance_md": {
      -        "anyOf": [
      -          {
      -            "maxLength": 5000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "formats": {
      -        "additionalProperties": {
      -          "properties": {
      -            "display_name": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "excel_format": {
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "name": {
      -              "maxLength": 50,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "excel_format"
      -          ],
      -          "type": "object"
      -        },
      -        "propertyNames": {
      -          "maxLength": 50,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "glyph": {
      -        "anyOf": [
      -          {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      -      },
      -      "name": {
      -        "maxLength": 100,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "number_locale": {
      -        "anyOf": [
      -          {
      -            "enum": [
      -              "en",
      -              "fr",
      -              "de"
      -            ],
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "op": {
      -        "const": "meta",
      -        "type": "string"
      -      },
      -      "subtitle": {
      -        "anyOf": [
      -          {
      -            "maxLength": 160,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "timelines": {
      -        "properties": {
      -          "monthly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "quarterly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "yearly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (null clears it)."
      +      },
      +      "compare_to": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "KPI native comparison; null clears it."
      +      },
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      +      },
      +      "name": {
      +        "description": "New display label (also the formula identifier)",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "update",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "New parent UID (null to move to root)"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "description": "Chart series UIDs",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch; supersedes `series`.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "uid": {
      +        "description": "Existing item UID to update",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +        "properties": {
      +          "tolerance": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +      },
      +      "compare_to": {
      +        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +        "properties": {
      +          "branch_id": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "display": {
      +            "enum": [
      +              "abs",
      +              "pct",
      +              "both"
      +            ],
      +            "type": "string"
      +          },
      +          "mode": {
      +            "enum": [
      +              "branch",
      +              "prev_period",
      +              "prev_year"
      +            ],
      +            "type": "string"
      +          },
      +          "thresholds": {
      +            "properties": {
      +              "green": {
      +                "type": "number"
      +              },
      +              "red": {
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "green",
      +              "red"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "mode"
      +        ],
      +        "type": "object"
      +      },
      +      "default_branch": {
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +        "properties": {
      +          "assert": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "assert"
      +        ],
      +        "type": "object"
      +      },
      +      "name": {
      +        "description": "Display name",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "create",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "position": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "col": {
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "row": {
      +                "maximum": 400,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "col",
      +              "row"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +      },
      +      "role": {
      +        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart under the value.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "role",
      +      "name",
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "from_uid": {
      +        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "new_item": {
      +        "description": "Inline payload describing the replacement item",
      +        "properties": {
      +          "aggregation": {
      +            "enum": [
      +              "sum",
      +              "average",
      +              "stock"
      +            ],
      +            "type": "string"
      +          },
      +          "axis": {
      +            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +            "enum": [
      +              "time",
      +              "branches",
      +              "list"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "bridge_config": {
      +            "properties": {
      +              "axis": {
      +                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +                "enum": [
      +                  "time",
      +                  "branches"
      +                ],
      +                "type": "string"
      +              },
      +              "branches": {
      +                "description": "Branch ids compared when axis=branches: [from, to].",
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "contributions": {
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "end_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              },
      +              "endpoint": {
      +                "description": "Single endpoint item (stock/balance) read at start & end periods",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "endpoint_branch": {
      +                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "residual_label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              },
      +              "start_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "endpoint"
      +            ],
      +            "type": "object"
      +          },
      +          "chart_type": {
      +            "enum": [
      +              "line",
      +              "bar",
      +              "area",
      +              "bridge"
      +            ],
      +            "type": "string"
      +          },
      +          "check": {
      +            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "comment": {
      +            "anyOf": [
      +              {
      +                "maxLength": 2000,
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +          },
      +          "compare_to": {
      +            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          "default_branch": {
      +            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "format": {
      +            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "formula": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "inputs": {
      +            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "item_style": {
      +            "enum": [
      +              "normal",
      +              "subtotal",
      +              "total",
      +              "kpi"
      +            ],
      +            "type": "string"
      +          },
      +          "list_mode": {
      +            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +            "enum": [
      +              "split",
      +              "total"
      +            ],
      +            "type": "string"
      +          },
      +          "list_total": {
      +            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +            "type": "boolean"
      +          },
      +          "liste": {
      +            "description": "mini_table list whose entries become the columns (axis=list)",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "liste_ref": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "monitor": {
      +            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          "name": {
      +            "description": "Display name",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "opening_balance": {
      +            "type": "number"
      +          },
      +          "period_window": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  },
      +                  "fit": {
      +                    "enum": [
      +                      "data",
      +                      "full"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +          },
      +          "position": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "col": {
      +                    "maximum": 11,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "row": {
      +                    "maximum": 400,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  }
      +                },
      +                "required": [
      +                  "col",
      +                  "row"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "dashboard-child pinned grid origin {col 0–11, row ≥ 0}: the widget sits at these cells (pushed down when it collides with an earlier pinned widget). Absent = flow placement (first-fit dense in sort order — a new widget fills the topmost free hole); null clears the pin. The web canvas pins every widget on the first drag"
      +          },
      +          "role": {
      +            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +            "enum": [
      +              "assumption",
      +              "formula",
      +              "callup",
      +              "balance",
      +              "section",
      +              "chart",
      +              "dashboard",
      +              "kpi",
      +              "mini_table"
      +            ],
      +            "type": "string"
      +          },
      +          "row_break": {
      +            "description": "dashboard-child line break (flow widgets only): start this widget on a fresh grid row. Inert once the widget has a position",
      +            "type": "boolean"
      +          },
      +          "rows": {
      +            "description": "mini_table curated row item UIDs / temp IDs / names",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series_defs": {
      +            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +            "items": {
      +              "properties": {
      +                "branch_id": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "uid": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "uid"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "description": "Callup source UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "span": {
      +            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +            "properties": {
      +              "cols": {
      +                "maximum": 12,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "rows": {
      +                "maximum": 4,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "sparkline": {
      +            "description": "KPI trend mini-chart under the value.",
      +            "type": "boolean"
      +          },
      +          "target": {
      +            "description": "KPI/mini_table target UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "target_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "timeline_ref": {
      +            "enum": [
      +              "constant",
      +              "monthly",
      +              "yearly",
      +              "quarterly"
      +            ],
      +            "type": "string"
      +          },
      +          "timeline_values": {
      +            "additionalProperties": {
      +              "anyOf": [
      +                {
      +                  "anyOf": [
      +                    {
      +                      "type": "number"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ]
      +                },
      +                {
      +                  "items": {
      +                    "anyOf": [
      +                      {
      +                        "type": "number"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "type": "array"
      +                }
      +              ]
      +            },
      +            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +            "propertyNames": {
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "value": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "values": {
      +            "items": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "type": "array"
      +          },
      +          "variance": {
      +            "description": "mini_table écart columns (axis=branches)",
      +            "properties": {
      +              "abs": {
      +                "type": "boolean"
      +              },
      +              "color": {
      +                "type": "boolean"
      +              },
      +              "pct": {
      +                "type": "boolean"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "role",
      +          "name"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "preserve_order": {
      +        "type": "boolean"
      +      },
      +      "preserve_parent": {
      +        "type": "boolean"
      +      },
      +      "preserve_style": {
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "from_uid",
      +      "new_item"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "UID of item to place after (for ordering)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "move",
      +        "type": "string"
      +      },
      +      "parent": {
      +        "description": "New parent UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to move",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_create",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_update",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "list_delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of list to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "finance_md": {
      +        "anyOf": [
      +          {
      +            "maxLength": 5000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "formats": {
      +        "additionalProperties": {
      +          "properties": {
      +            "display_name": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "excel_format": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "name": {
      +              "maxLength": 50,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "excel_format"
      +          ],
      +          "type": "object"
      +        },
      +        "propertyNames": {
      +          "maxLength": 50,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "glyph": {
      +        "anyOf": [
      +          {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      +      },
      +      "name": {
      +        "maxLength": 100,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "number_locale": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "en",
      +              "fr",
      +              "de"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "op": {
      +        "const": "meta",
      +        "type": "string"
      +      },
      +      "subtitle": {
      +        "anyOf": [
      +          {
      +            "maxLength": 160,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "timelines": {
      +        "properties": {
      +          "monthly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "quarterly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "yearly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
  6. Changed1 schema field changed
    • changedInput schema / properties / ops / items / oneOf
      Previous value: -[
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (null clears it)."
      -      },
      -      "compare_to": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "KPI native comparison; null clears it."
      -      },
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Business watchpoint. `assert` is a boolean expression where the reserved token `value` is this item's computed value (a leading comparator like \"== 0\" implies it). Values are evaluated rounded to 2 decimals, so \"== 0\" already absorbs sub-0.005 residuals (a balance netting to 1e-11 reads as 0 and passes); use a wider tolerance (\"ABS(value) < 1\") only to ignore a materially larger gap. Pass `null` to clear. Failing periods surface in `layerz_read` under `health` — non-blocking."
      -      },
      -      "name": {
      -        "description": "New display label (also the formula identifier)",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "update",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "New parent UID (null to move to root)"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "role": {
      -        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break: start this widget on a fresh grid row",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "description": "Chart series UIDs",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch; supersedes `series`.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "uid": {
      -        "description": "Existing item UID to update",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "aggregation": {
      -        "enum": [
      -          "sum",
      -          "average",
      -          "stock"
      -        ],
      -        "type": "string"
      -      },
      -      "axis": {
      -        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -        "enum": [
      -          "time",
      -          "branches",
      -          "list"
      -        ],
      -        "type": "string"
      -      },
      -      "branches": {
      -        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "bridge_config": {
      -        "properties": {
      -          "axis": {
      -            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -            "enum": [
      -              "time",
      -              "branches"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "Branch ids compared when axis=branches: [from, to].",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "contributions": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "end_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "endpoint": {
      -            "description": "Single endpoint item (stock/balance) read at start & end periods",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "endpoint_branch": {
      -            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "residual_label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          },
      -          "start_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "endpoint"
      -        ],
      -        "type": "object"
      -      },
      -      "chart_type": {
      -        "enum": [
      -          "line",
      -          "bar",
      -          "area",
      -          "bridge"
      -        ],
      -        "type": "string"
      -      },
      -      "comment": {
      -        "anyOf": [
      -          {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -      },
      -      "compare_to": {
      -        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -        "properties": {
      -          "branch_id": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "display": {
      -            "enum": [
      -              "abs",
      -              "pct",
      -              "both"
      -            ],
      -            "type": "string"
      -          },
      -          "mode": {
      -            "enum": [
      -              "branch",
      -              "prev_period",
      -              "prev_year"
      -            ],
      -            "type": "string"
      -          },
      -          "thresholds": {
      -            "properties": {
      -              "green": {
      -                "type": "number"
      -              },
      -              "red": {
      -                "type": "number"
      -              }
      -            },
      -            "required": [
      -              "green",
      -              "red"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "mode"
      -        ],
      -        "type": "object"
      -      },
      -      "default_branch": {
      -        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "format": {
      -        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "formula": {
      -        "maxLength": 2000,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "inputs": {
      -        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "item_style": {
      -        "enum": [
      -          "normal",
      -          "subtotal",
      -          "total",
      -          "kpi"
      -        ],
      -        "type": "string"
      -      },
      -      "list_mode": {
      -        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -        "enum": [
      -          "split",
      -          "total"
      -        ],
      -        "type": "string"
      -      },
      -      "list_total": {
      -        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -        "type": "boolean"
      -      },
      -      "liste": {
      -        "description": "mini_table list whose entries become the columns (axis=list)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "liste_ref": {
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "monitor": {
      -        "description": "Business watchpoint. `assert` is a boolean expression in the formula language; the reserved token `value` is this item's computed value (a leading comparator like \"== 0\" implies it). Values are evaluated rounded to 2 decimals, so \"== 0\" already absorbs sub-0.005 residuals (a balance netting to 1e-11 reads as 0 and passes); use a wider tolerance (\"ABS(value) < 1\") only to ignore a materially larger gap — a sub-cent tolerance adds nothing over \"== 0\". Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -        "properties": {
      -          "assert": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "label": {
      -            "maxLength": 200,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "assert"
      -        ],
      -        "type": "object"
      -      },
      -      "name": {
      -        "description": "Display name",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "create",
      -        "type": "string"
      -      },
      -      "opening_balance": {
      -        "type": "number"
      -      },
      -      "parent": {
      -        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "period_window": {
      -        "anyOf": [
      -          {
      -            "properties": {
      -              "end": {
      -                "maxLength": 20,
      -                "type": "string"
      -              },
      -              "fit": {
      -                "enum": [
      -                  "data",
      -                  "full"
      -                ],
      -                "type": "string"
      -              },
      -              "start": {
      -                "maxLength": 20,
      -                "type": "string"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -      },
      -      "role": {
      -        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -        "enum": [
      -          "assumption",
      -          "formula",
      -          "callup",
      -          "balance",
      -          "section",
      -          "chart",
      -          "dashboard",
      -          "kpi",
      -          "mini_table"
      -        ],
      -        "type": "string"
      -      },
      -      "row_break": {
      -        "description": "dashboard-child line break: start this widget on a fresh grid row",
      -        "type": "boolean"
      -      },
      -      "rows": {
      -        "description": "mini_table curated row item UIDs / temp IDs / names",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series": {
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "series_defs": {
      -        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -        "items": {
      -          "properties": {
      -            "branch_id": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "uid"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "source": {
      -        "description": "Callup source UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "span": {
      -        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -        "properties": {
      -          "cols": {
      -            "maximum": 12,
      -            "minimum": 1,
      -            "type": "integer"
      -          },
      -          "rows": {
      -            "maximum": 4,
      -            "minimum": 1,
      -            "type": "integer"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "sparkline": {
      -        "description": "KPI trend mini-chart under the value.",
      -        "type": "boolean"
      -      },
      -      "target": {
      -        "description": "KPI/mini_table target UID or temp ID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "target_period": {
      -        "maxLength": 50,
      -        "type": "string"
      -      },
      -      "timeline_ref": {
      -        "enum": [
      -          "constant",
      -          "monthly",
      -          "yearly",
      -          "quarterly"
      -        ],
      -        "type": "string"
      -      },
      -      "timeline_values": {
      -        "additionalProperties": {
      -          "anyOf": [
      -            {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            {
      -              "items": {
      -                "anyOf": [
      -                  {
      -                    "type": "number"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              },
      -              "type": "array"
      -            }
      -          ]
      -        },
      -        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "value": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "values": {
      -        "items": {
      -          "anyOf": [
      -            {
      -              "type": "number"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ]
      -        },
      -        "type": "array"
      -      },
      -      "variance": {
      -        "description": "mini_table écart columns (axis=branches)",
      -        "properties": {
      -          "abs": {
      -            "type": "boolean"
      -          },
      -          "color": {
      -            "type": "boolean"
      -          },
      -          "pct": {
      -            "type": "boolean"
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "role",
      -      "name",
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "from_uid": {
      -        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "new_item": {
      -        "description": "Inline payload describing the replacement item",
      -        "properties": {
      -          "aggregation": {
      -            "enum": [
      -              "sum",
      -              "average",
      -              "stock"
      -            ],
      -            "type": "string"
      -          },
      -          "axis": {
      -            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      -            "enum": [
      -              "time",
      -              "branches",
      -              "list"
      -            ],
      -            "type": "string"
      -          },
      -          "branches": {
      -            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "bridge_config": {
      -            "properties": {
      -              "axis": {
      -                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      -                "enum": [
      -                  "time",
      -                  "branches"
      -                ],
      -                "type": "string"
      -              },
      -              "branches": {
      -                "description": "Branch ids compared when axis=branches: [from, to].",
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "contributions": {
      -                "items": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "end_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              },
      -              "endpoint": {
      -                "description": "Single endpoint item (stock/balance) read at start & end periods",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "endpoint_branch": {
      -                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "residual_label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              },
      -              "start_period": {
      -                "maxLength": 50,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "endpoint"
      -            ],
      -            "type": "object"
      -          },
      -          "chart_type": {
      -            "enum": [
      -              "line",
      -              "bar",
      -              "area",
      -              "bridge"
      -            ],
      -            "type": "string"
      -          },
      -          "comment": {
      -            "anyOf": [
      -              {
      -                "maxLength": 2000,
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      -          },
      -          "compare_to": {
      -            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      -            "properties": {
      -              "branch_id": {
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "display": {
      -                "enum": [
      -                  "abs",
      -                  "pct",
      -                  "both"
      -                ],
      -                "type": "string"
      -              },
      -              "mode": {
      -                "enum": [
      -                  "branch",
      -                  "prev_period",
      -                  "prev_year"
      -                ],
      -                "type": "string"
      -              },
      -              "thresholds": {
      -                "properties": {
      -                  "green": {
      -                    "type": "number"
      -                  },
      -                  "red": {
      -                    "type": "number"
      -                  }
      -                },
      -                "required": [
      -                  "green",
      -                  "red"
      -                ],
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          "default_branch": {
      -            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "format": {
      -            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "formula": {
      -            "maxLength": 2000,
      -            "type": "string"
      -          },
      -          "inputs": {
      -            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "item_style": {
      -            "enum": [
      -              "normal",
      -              "subtotal",
      -              "total",
      -              "kpi"
      -            ],
      -            "type": "string"
      -          },
      -          "list_mode": {
      -            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      -            "enum": [
      -              "split",
      -              "total"
      -            ],
      -            "type": "string"
      -          },
      -          "list_total": {
      -            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      -            "type": "boolean"
      -          },
      -          "liste": {
      -            "description": "mini_table list whose entries become the columns (axis=list)",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "liste_ref": {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "monitor": {
      -            "description": "Business watchpoint. `assert` is a boolean expression in the formula language; the reserved token `value` is this item's computed value (a leading comparator like \"== 0\" implies it). Values are evaluated rounded to 2 decimals, so \"== 0\" already absorbs sub-0.005 residuals (a balance netting to 1e-11 reads as 0 and passes); use a wider tolerance (\"ABS(value) < 1\") only to ignore a materially larger gap — a sub-cent tolerance adds nothing over \"== 0\". Failing periods surface in `layerz_read` under `health` — non-blocking.",
      -            "properties": {
      -              "assert": {
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "maxLength": 200,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "assert"
      -            ],
      -            "type": "object"
      -          },
      -          "name": {
      -            "description": "Display name",
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "opening_balance": {
      -            "type": "number"
      -          },
      -          "period_window": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  },
      -                  "fit": {
      -                    "enum": [
      -                      "data",
      -                      "full"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "maxLength": 20,
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      -          },
      -          "role": {
      -            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      -            "enum": [
      -              "assumption",
      -              "formula",
      -              "callup",
      -              "balance",
      -              "section",
      -              "chart",
      -              "dashboard",
      -              "kpi",
      -              "mini_table"
      -            ],
      -            "type": "string"
      -          },
      -          "row_break": {
      -            "description": "dashboard-child line break: start this widget on a fresh grid row",
      -            "type": "boolean"
      -          },
      -          "rows": {
      -            "description": "mini_table curated row item UIDs / temp IDs / names",
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series": {
      -            "items": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "series_defs": {
      -            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      -            "items": {
      -              "properties": {
      -                "branch_id": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "uid": {
      -                  "minLength": 1,
      -                  "type": "string"
      -                }
      -              },
      -              "required": [
      -                "uid"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "source": {
      -            "description": "Callup source UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "span": {
      -            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      -            "properties": {
      -              "cols": {
      -                "maximum": 12,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "rows": {
      -                "maximum": 4,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "sparkline": {
      -            "description": "KPI trend mini-chart under the value.",
      -            "type": "boolean"
      -          },
      -          "target": {
      -            "description": "KPI/mini_table target UID or temp ID",
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "target_period": {
      -            "maxLength": 50,
      -            "type": "string"
      -          },
      -          "timeline_ref": {
      -            "enum": [
      -              "constant",
      -              "monthly",
      -              "yearly",
      -              "quarterly"
      -            ],
      -            "type": "string"
      -          },
      -          "timeline_values": {
      -            "additionalProperties": {
      -              "anyOf": [
      -                {
      -                  "anyOf": [
      -                    {
      -                      "type": "number"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ]
      -                },
      -                {
      -                  "items": {
      -                    "anyOf": [
      -                      {
      -                        "type": "number"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ]
      -                  },
      -                  "type": "array"
      -                }
      -              ]
      -            },
      -            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      -            "propertyNames": {
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "value": {
      -            "anyOf": [
      -              {
      -                "type": "number"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "values": {
      -            "items": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "null"
      -                }
      -              ]
      -            },
      -            "type": "array"
      -          },
      -          "variance": {
      -            "description": "mini_table écart columns (axis=branches)",
      -            "properties": {
      -              "abs": {
      -                "type": "boolean"
      -              },
      -              "color": {
      -                "type": "boolean"
      -              },
      -              "pct": {
      -                "type": "boolean"
      -              }
      -            },
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "role",
      -          "name"
      -        ],
      -        "type": "object"
      -      },
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "preserve_order": {
      -        "type": "boolean"
      -      },
      -      "preserve_parent": {
      -        "type": "boolean"
      -      },
      -      "preserve_style": {
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "from_uid",
      -      "new_item"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "after": {
      -        "description": "UID of item to place after (for ordering)",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "move",
      -        "type": "string"
      -      },
      -      "parent": {
      -        "description": "New parent UID",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of item to move",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "id": {
      -        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      -        "maxLength": 32,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_create",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "name"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "items": {
      -        "items": {
      -          "properties": {
      -            "id": {
      -              "maxLength": 32,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "mapped_to": {
      -              "additionalProperties": {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "uid": {
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 500,
      -        "type": "array"
      -      },
      -      "name": {
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "op": {
      -        "const": "list_update",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "op": {
      -        "const": "list_delete",
      -        "type": "string"
      -      },
      -      "uid": {
      -        "description": "UID of list to delete",
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "uid"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "properties": {
      -      "default_branch": {
      -        "anyOf": [
      -          {
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "finance_md": {
      -        "anyOf": [
      -          {
      -            "maxLength": 5000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "formats": {
      -        "additionalProperties": {
      -          "properties": {
      -            "display_name": {
      -              "maxLength": 80,
      -              "type": "string"
      -            },
      -            "excel_format": {
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "name": {
      -              "maxLength": 50,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "excel_format"
      -          ],
      -          "type": "object"
      -        },
      -        "propertyNames": {
      -          "maxLength": 50,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "glyph": {
      -        "anyOf": [
      -          {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      -      },
      -      "name": {
      -        "maxLength": 100,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "number_locale": {
      -        "anyOf": [
      -          {
      -            "enum": [
      -              "en",
      -              "fr",
      -              "de"
      -            ],
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "op": {
      -        "const": "meta",
      -        "type": "string"
      -      },
      -      "subtitle": {
      -        "anyOf": [
      -          {
      -            "maxLength": 160,
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "timelines": {
      -        "properties": {
      -          "monthly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "quarterly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          },
      -          "yearly": {
      -            "anyOf": [
      -              {
      -                "properties": {
      -                  "end": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "start": {
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "required": [
      -                  "start",
      -                  "end"
      -                ],
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Flag the line as a control, judged on its OWN value: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals); a formula that is itself a comparison / AND / OR / NOT passes when true. Pass `null` to remove the check. Failing periods surface in `layerz_read` under `health` — non-blocking."
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (null clears it)."
      +      },
      +      "compare_to": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "KPI native comparison; null clears it."
      +      },
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; null clears it."
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: 'split' (default) = one series per list element, 'total' = the list-backed item's aggregate as one series.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; forced ON while the aggregate is referenced.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert is converted, any other rule is rejected; `null` removes the check."
      +      },
      +      "name": {
      +        "description": "New display label (also the formula identifier)",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "update",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "New parent UID (null to move to root)"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "role": {
      +        "description": "Change the item role. Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break: start this widget on a fresh grid row",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "description": "Chart series UIDs",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch; supersedes `series`.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "uid": {
      +        "description": "Existing item UID to update",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "branches": {
      +        "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "bridge_config": {
      +        "properties": {
      +          "axis": {
      +            "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +            "enum": [
      +              "time",
      +              "branches"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "Branch ids compared when axis=branches: [from, to].",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "contributions": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "end_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "endpoint": {
      +            "description": "Single endpoint item (stock/balance) read at start & end periods",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "endpoint_branch": {
      +            "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "residual_label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "start_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "endpoint"
      +        ],
      +        "type": "object"
      +      },
      +      "chart_type": {
      +        "enum": [
      +          "line",
      +          "bar",
      +          "area",
      +          "bridge"
      +        ],
      +        "type": "string"
      +      },
      +      "check": {
      +        "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +        "properties": {
      +          "tolerance": {
      +            "exclusiveMinimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "comment": {
      +        "anyOf": [
      +          {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +      },
      +      "compare_to": {
      +        "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +        "properties": {
      +          "branch_id": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "display": {
      +            "enum": [
      +              "abs",
      +              "pct",
      +              "both"
      +            ],
      +            "type": "string"
      +          },
      +          "mode": {
      +            "enum": [
      +              "branch",
      +              "prev_period",
      +              "prev_year"
      +            ],
      +            "type": "string"
      +          },
      +          "thresholds": {
      +            "properties": {
      +              "green": {
      +                "type": "number"
      +              },
      +              "red": {
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "green",
      +              "red"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "mode"
      +        ],
      +        "type": "object"
      +      },
      +      "default_branch": {
      +        "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "format": {
      +        "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "formula": {
      +        "maxLength": 2000,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can use this value as their `parent`, `source`, `target`, or `series` to wire references before the real UID is generated. Numeric (`_1`, `_2`) keeps it short; descriptive (`_starting_customers`) is fine up to 32 chars.",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "inputs": {
      +        "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "item_style": {
      +        "enum": [
      +          "normal",
      +          "subtotal",
      +          "total",
      +          "kpi"
      +        ],
      +        "type": "string"
      +      },
      +      "list_mode": {
      +        "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +        "enum": [
      +          "split",
      +          "total"
      +        ],
      +        "type": "string"
      +      },
      +      "list_total": {
      +        "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +        "type": "boolean"
      +      },
      +      "liste": {
      +        "description": "mini_table list whose entries become the columns (axis=list)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "liste_ref": {
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "monitor": {
      +        "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +        "properties": {
      +          "assert": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "label": {
      +            "maxLength": 200,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "assert"
      +        ],
      +        "type": "object"
      +      },
      +      "name": {
      +        "description": "Display name",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "create",
      +        "type": "string"
      +      },
      +      "opening_balance": {
      +        "type": "number"
      +      },
      +      "parent": {
      +        "description": "Parent container: either an 8-char UID of an existing section/balance/dashboard, or a temp `id` from an earlier create op in the same batch (e.g. set `id: \"_pl\"` on a section create, then `parent: \"_pl\"` on each child item).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "period_window": {
      +        "anyOf": [
      +          {
      +            "properties": {
      +              "end": {
      +                "maxLength": 20,
      +                "type": "string"
      +              },
      +              "fit": {
      +                "enum": [
      +                  "data",
      +                  "full"
      +                ],
      +                "type": "string"
      +              },
      +              "start": {
      +                "maxLength": 20,
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +      },
      +      "role": {
      +        "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +        "enum": [
      +          "assumption",
      +          "formula",
      +          "callup",
      +          "balance",
      +          "section",
      +          "chart",
      +          "dashboard",
      +          "kpi",
      +          "mini_table"
      +        ],
      +        "type": "string"
      +      },
      +      "row_break": {
      +        "description": "dashboard-child line break: start this widget on a fresh grid row",
      +        "type": "boolean"
      +      },
      +      "rows": {
      +        "description": "mini_table curated row item UIDs / temp IDs / names",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series": {
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "series_defs": {
      +        "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +        "items": {
      +          "properties": {
      +            "branch_id": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "uid"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "source": {
      +        "description": "Callup source UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "span": {
      +        "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +        "properties": {
      +          "cols": {
      +            "maximum": 12,
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "rows": {
      +            "maximum": 4,
      +            "minimum": 1,
      +            "type": "integer"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "sparkline": {
      +        "description": "KPI trend mini-chart under the value.",
      +        "type": "boolean"
      +      },
      +      "target": {
      +        "description": "KPI/mini_table target UID or temp ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "target_period": {
      +        "maxLength": 50,
      +        "type": "string"
      +      },
      +      "timeline_ref": {
      +        "enum": [
      +          "constant",
      +          "monthly",
      +          "yearly",
      +          "quarterly"
      +        ],
      +        "type": "string"
      +      },
      +      "timeline_values": {
      +        "additionalProperties": {
      +          "anyOf": [
      +            {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            {
      +              "items": {
      +                "anyOf": [
      +                  {
      +                    "type": "number"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              },
      +              "type": "array"
      +            }
      +          ]
      +        },
      +        "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "values": {
      +        "items": {
      +          "anyOf": [
      +            {
      +              "type": "number"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "type": "array"
      +      },
      +      "variance": {
      +        "description": "mini_table écart columns (axis=branches)",
      +        "properties": {
      +          "abs": {
      +            "type": "boolean"
      +          },
      +          "color": {
      +            "type": "boolean"
      +          },
      +          "pct": {
      +            "type": "boolean"
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "role",
      +      "name",
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "from_uid": {
      +        "description": "Existing item UID to replace atomically (section/dashboard unsupported)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "new_item": {
      +        "description": "Inline payload describing the replacement item",
      +        "properties": {
      +          "aggregation": {
      +            "enum": [
      +              "sum",
      +              "average",
      +              "stock"
      +            ],
      +            "type": "string"
      +          },
      +          "axis": {
      +            "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +            "enum": [
      +              "time",
      +              "branches",
      +              "list"
      +            ],
      +            "type": "string"
      +          },
      +          "branches": {
      +            "description": "mini_table compared branch ids (axis=branches); first = écart base",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "bridge_config": {
      +            "properties": {
      +              "axis": {
      +                "description": "Bridge dimension: 'time' (default, delta start→end period) or 'branches' (gap between two branches at one period — budget vs actual waterfall).",
      +                "enum": [
      +                  "time",
      +                  "branches"
      +                ],
      +                "type": "string"
      +              },
      +              "branches": {
      +                "description": "Branch ids compared when axis=branches: [from, to].",
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "contributions": {
      +                "items": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "end_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              },
      +              "endpoint": {
      +                "description": "Single endpoint item (stock/balance) read at start & end periods",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "endpoint_branch": {
      +                "description": "Read endpoint + contributions under this branch basis (axis=time only).",
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "residual_label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              },
      +              "start_period": {
      +                "maxLength": 50,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "endpoint"
      +            ],
      +            "type": "object"
      +          },
      +          "chart_type": {
      +            "enum": [
      +              "line",
      +              "bar",
      +              "area",
      +              "bridge"
      +            ],
      +            "type": "string"
      +          },
      +          "check": {
      +            "description": "Flag the line as a control, judged on its OWN value at every period: a plain amount must stay within `tolerance` of 0 (ABS(value) < tolerance, default 1, on values rounded to 2 decimals — a balance netting to 1e-11 passes); a formula that is itself a comparison / AND / OR / NOT (e.g. \"Revenue >= 0\") passes when true. Assumption and formula only. Failing periods surface in `layerz_read` under `health` — non-blocking.",
      +            "properties": {
      +              "tolerance": {
      +                "exclusiveMinimum": 0,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "comment": {
      +            "anyOf": [
      +              {
      +                "maxLength": 2000,
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Free-form annotation on the item (hypothesis source, rationale, review note)."
      +          },
      +          "compare_to": {
      +            "description": "KPI native comparison: a delta vs another branch (`mode:\"branch\"` + `branch_id`) or a shifted period (`prev_period`/`prev_year`). Rendered as the value plus a signed delta %.",
      +            "properties": {
      +              "branch_id": {
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "display": {
      +                "enum": [
      +                  "abs",
      +                  "pct",
      +                  "both"
      +                ],
      +                "type": "string"
      +              },
      +              "mode": {
      +                "enum": [
      +                  "branch",
      +                  "prev_period",
      +                  "prev_year"
      +                ],
      +                "type": "string"
      +              },
      +              "thresholds": {
      +                "properties": {
      +                  "green": {
      +                    "type": "number"
      +                  },
      +                  "red": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [
      +                  "green",
      +                  "red"
      +                ],
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          "default_branch": {
      +            "description": "Dashboard-only: branch checked out when this dashboard opens; overrides the model default.",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "format": {
      +            "description": "Number format name. Pre-installed: default, decimal_2, decimal_neg, integer, multiple, percent, percent_neg, percent_2, date_dmy, date_dmmmyy, date_mmmyy, date_dmmm (+ the magic `date`, and `currency`/`currency_2` — resolved live from the FINANCE.md `currency` code: `$1,234` for USD, `1 234 €` for EUR). Custom names refer to entries in model.formats — add one with the `meta` op `formats` field (same batch OK). An unknown name is REJECTED with code UNKNOWN_FORMAT listing what is available; prefer `percent` over legacy `\"%\"`. Full catalog with each excel_format and rendered positive/negative/zero examples (e.g. `default` = dash-for-zero accounting style vs `integer` = plain 0): MCP resource `format-spec://reference`. See docs/mdk-format.md § 4.4.",
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "formula": {
      +            "maxLength": 2000,
      +            "type": "string"
      +          },
      +          "inputs": {
      +            "description": "Direct contributors override (item UIDs or same-batch temp ids). Useful for `balance` items, which carry no formula but can declare the flows that roll into the stock; for `formula` items inputs are derived from the expression, so set this only to override that derivation.",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "item_style": {
      +            "enum": [
      +              "normal",
      +              "subtotal",
      +              "total",
      +              "kpi"
      +            ],
      +            "type": "string"
      +          },
      +          "list_mode": {
      +            "description": "Chart only: how a list-backed series renders — 'split' (default) plots one series per list element, 'total' plots the item's aggregate as ONE series. Use 'total' to chart a list total without a mirror formula.",
      +            "enum": [
      +              "split",
      +              "total"
      +            ],
      +            "type": "string"
      +          },
      +          "list_total": {
      +            "description": "List-mode only: show the list's total (aggregate row values). Default off; the total is forced ON while any formula/callup/parent/widget reads the aggregate.",
      +            "type": "boolean"
      +          },
      +          "liste": {
      +            "description": "mini_table list whose entries become the columns (axis=list)",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "liste_ref": {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "monitor": {
      +            "description": "Deprecated (MDK 0.13.0) — use `check`. A canonical assert (\"ABS(value) < t\", \"== 0\") is converted; any other rule is rejected: put it in the line's formula and set `check: {}`.",
      +            "properties": {
      +              "assert": {
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "maxLength": 200,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "assert"
      +            ],
      +            "type": "object"
      +          },
      +          "name": {
      +            "description": "Display name",
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "opening_balance": {
      +            "type": "number"
      +          },
      +          "period_window": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  },
      +                  "fit": {
      +                    "enum": [
      +                      "data",
      +                      "full"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "maxLength": 20,
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Display period window of a chart / kpi sparkline / time mini_table. `start`/`end` are period labels at the widget's grain (bounds independent — either alone is valid); `fit` governs the unset bounds: 'data' (the default, absent field included) auto-fits to the periods actually carrying data and follows imports, 'full' spans the whole timeline. Pass null to clear (back to fit-to-data)."
      +          },
      +          "role": {
      +            "description": "Role of the item — pick by intent. assumption: an input/driver you own (set value/values/timeline_values; the only role a Dataset can override). formula: a computed transformation (set formula). formula with NO expression + children: a Σ aggregator that sums its children (a subtotal VALUE — use a nested section instead when you only need structural grouping). callup: a typed mirror of ONE source whose value flows into its parent (set source) — for balance flows and surfacing a value in a section/subtotal, NOT for arithmetic (reference the source directly inside a real formula). balance: a rolling stock (set opening_balance; sums its callup-child flows). section: structural container, no value. dashboard/chart/kpi/mini_table: presentational. A formula is an aggregator XOR a transformation (never both expression AND children). A single bare reference written as a formula is auto-posed as a callup mirror.",
      +            "enum": [
      +              "assumption",
      +              "formula",
      +              "callup",
      +              "balance",
      +              "section",
      +              "chart",
      +              "dashboard",
      +              "kpi",
      +              "mini_table"
      +            ],
      +            "type": "string"
      +          },
      +          "row_break": {
      +            "description": "dashboard-child line break: start this widget on a fresh grid row",
      +            "type": "boolean"
      +          },
      +          "rows": {
      +            "description": "mini_table curated row item UIDs / temp IDs / names",
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series": {
      +            "items": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "series_defs": {
      +            "description": "Per-series branch: supersedes `series`. Each entry plots one item under a specific branch (e.g. Revenue@budget vs Revenue@actuals). `uid` accepts a temp id.",
      +            "items": {
      +              "properties": {
      +                "branch_id": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "uid": {
      +                  "minLength": 1,
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "uid"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "source": {
      +            "description": "Callup source UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "span": {
      +            "description": "dashboard-child grid footprint (chart/kpi/mini_table): cols on the 12-column grid × 140-px row units. Defaults: kpi 3×1, chart/mini_table 6×2",
      +            "properties": {
      +              "cols": {
      +                "maximum": 12,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "rows": {
      +                "maximum": 4,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "sparkline": {
      +            "description": "KPI trend mini-chart under the value.",
      +            "type": "boolean"
      +          },
      +          "target": {
      +            "description": "KPI/mini_table target UID or temp ID",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "target_period": {
      +            "maxLength": 50,
      +            "type": "string"
      +          },
      +          "timeline_ref": {
      +            "enum": [
      +              "constant",
      +              "monthly",
      +              "yearly",
      +              "quarterly"
      +            ],
      +            "type": "string"
      +          },
      +          "timeline_values": {
      +            "additionalProperties": {
      +              "anyOf": [
      +                {
      +                  "anyOf": [
      +                    {
      +                      "type": "number"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ]
      +                },
      +                {
      +                  "items": {
      +                    "anyOf": [
      +                      {
      +                        "type": "number"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "type": "array"
      +                }
      +              ]
      +            },
      +            "description": "Periodic values, keyed by context. List-mode item: one series per list entry — key is the element UID, label, OR a `list_create` temp id from the SAME batch (temp ids do not survive to a later batch; use the label/UID then). Non-list item: either a full series keyed by a canonical grain (`monthly`/`quarterly`/`yearly`/`constant`, the import path) OR a sparse per-period patch keyed by period id (e.g. `{\"2026-06\": -119.19}`) that overwrites only the named cells and leaves the rest — the future projection — intact. A single number is coerced to a 1-element array. List cells left unset read as 0 (no forward-fill).",
      +            "propertyNames": {
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "value": {
      +            "anyOf": [
      +              {
      +                "type": "number"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "values": {
      +            "items": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "type": "array"
      +          },
      +          "variance": {
      +            "description": "mini_table écart columns (axis=branches)",
      +            "properties": {
      +              "abs": {
      +                "type": "boolean"
      +              },
      +              "color": {
      +                "type": "boolean"
      +              },
      +              "pct": {
      +                "type": "boolean"
      +              }
      +            },
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "role",
      +          "name"
      +        ],
      +        "type": "object"
      +      },
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "preserve_order": {
      +        "type": "boolean"
      +      },
      +      "preserve_parent": {
      +        "type": "boolean"
      +      },
      +      "preserve_style": {
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "from_uid",
      +      "new_item"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "UID of item to place after (for ordering)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "move",
      +        "type": "string"
      +      },
      +      "parent": {
      +        "description": "New parent UID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of item to move",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "id": {
      +        "description": "Temp ID for intra-batch references — other create ops in the same batch can pass this value as their `liste_ref` so a list and its consumers can ship in one patch (e.g. set `id: \"_emp\"` on `list_create`, then `liste_ref: \"_emp\"` on an assumption created in the same batch).",
      +        "maxLength": 32,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_create",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "items": {
      +        "items": {
      +          "properties": {
      +            "id": {
      +              "maxLength": 32,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "mapped_to": {
      +              "additionalProperties": {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "uid": {
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 500,
      +        "type": "array"
      +      },
      +      "name": {
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "list_update",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "op": {
      +        "const": "list_delete",
      +        "type": "string"
      +      },
      +      "uid": {
      +        "description": "UID of list to delete",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "default_branch": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "finance_md": {
      +        "anyOf": [
      +          {
      +            "maxLength": 5000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "formats": {
      +        "additionalProperties": {
      +          "properties": {
      +            "display_name": {
      +              "maxLength": 80,
      +              "type": "string"
      +            },
      +            "excel_format": {
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "name": {
      +              "maxLength": 50,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "excel_format"
      +          ],
      +          "type": "object"
      +        },
      +        "propertyNames": {
      +          "maxLength": 50,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "glyph": {
      +        "anyOf": [
      +          {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Model emblem icon: a kebab-case Lucide icon name (https://lucide.dev/icons), e.g. \"trending-up\", \"coffee\", \"landmark\", \"rocket\", \"house\", \"users\". Shown in-app and on the social/OG card. Emojis and free text are rejected with suggestions. Aliases normalized: cash/money→banknote, bank→landmark, cart→shopping-cart, chart/graph→chart-line. `null` clears it (falls back to a monogram of the model name)."
      +      },
      +      "name": {
      +        "maxLength": 100,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "number_locale": {
      +        "anyOf": [
      +          {
      +            "enum": [
      +              "en",
      +              "fr",
      +              "de"
      +            ],
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "op": {
      +        "const": "meta",
      +        "type": "string"
      +      },
      +      "subtitle": {
      +        "anyOf": [
      +          {
      +            "maxLength": 160,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "timelines": {
      +        "properties": {
      +          "monthly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "quarterly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "yearly": {
      +            "anyOf": [
      +              {
      +                "properties": {
      +                  "end": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "start": {
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "required": [
      +                  "start",
      +                  "end"
      +                ],
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  }
      +]
  7. First observed

TDQS

Score is being calculated.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources