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 later ops reference (parent, source, target, series, liste_ref, after, before, $_id in a formula); 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. after / before (create, move, list ops) order siblings and tabs; unchanged: true: nothing written. 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, a non-list item value / values. branch_id routes the value writes onto that branch as an overlay of the cells differing from the base; compute returns the computed series of the given UIDs (under compute_branch, default branch_id); dry_run validates and computes without persisting; compare_values adds value_diff (as in layerz_diff). Persists one version labelled with summary. Not advertised to read-only keys. Modeling patterns and examples: resource modeling-guide://reference.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "summary": "<summary>",
      "ops": "<ops>"
    },
    "name": "layerz_patch"
  }
}

Input 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.
compare_valuesNoAdds `value_diff`: the computed-values diff between the model before and after the batch — the `compute` UIDs, else the key lines (checks and totals) — at the finest grain under `compute_branch`, with before / after / delta per changed period and a summary. With `dry_run`, a preview of what the batch changes in the numbers.
compute_branchNoBranch whose `[base, branch]` checkout the `compute` values are returned under (mirror of `layerz_read` `branch_id`). Defaults to `branch_id` when that is set, else the base plan. 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",
      -          "first"
      -        ],
      -        "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."
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      -        "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"
      -      },
      -      "row_styles": {
      -        "additionalProperties": {
      -          "enum": [
      -            "normal",
      -            "subtotal",
      -            "total",
      -            "kpi"
      -          ],
      -          "type": "string"
      -        },
      -        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -        "propertyNames": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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",
      -          "first"
      -        ],
      -        "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"
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      -        "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"
      -      },
      -      "row_styles": {
      -        "additionalProperties": {
      -          "enum": [
      -            "normal",
      -            "subtotal",
      -            "total",
      -            "kpi"
      -          ],
      -          "type": "string"
      -        },
      -        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -        "propertyNames": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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",
      -              "first"
      -            ],
      -            "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"
      -          },
      -          "collapsed": {
      -            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -            "type": "boolean"
      -          },
      -          "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -            "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      -            "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"
      -          },
      -          "row_styles": {
      -            "additionalProperties": {
      -              "enum": [
      -                "normal",
      -                "subtotal",
      -                "total",
      -                "kpi"
      -              ],
      -              "type": "string"
      -            },
      -            "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -            "propertyNames": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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",
      +          "first"
      +        ],
      +        "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."
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs, names or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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": "Item to update: UID, temp id or name",
      +        "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": {
      +      "after": {
      +        "description": "Place right after a sibling (UID, temp id or name): a child of the same parent or, at the root, a tab of the same group (dashboard tabs come first, then section tabs). Exclusive with `before`.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "aggregation": {
      +        "enum": [
      +          "sum",
      +          "average",
      +          "stock",
      +          "first"
      +        ],
      +        "type": "string"
      +      },
      +      "axis": {
      +        "description": "mini_table column axis: 'time' (periods, default), 'branches', or 'list' (list entries + Total)",
      +        "enum": [
      +          "time",
      +          "branches",
      +          "list"
      +        ],
      +        "type": "string"
      +      },
      +      "before": {
      +        "description": "Place right before a sibling (UID, temp id or name): a child of the same parent or, at the root, a tab of the same group (dashboard tabs come first, then section tabs); before the first one puts it first. Exclusive with `after`.",
      +        "minLength": 1,
      +        "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"
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs, names or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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": "Item to replace atomically: UID, temp id or name (section/dashboard unsupported)",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "new_item": {
      +        "description": "Inline payload describing the replacement item",
      +        "properties": {
      +          "aggregation": {
      +            "enum": [
      +              "sum",
      +              "average",
      +              "stock",
      +              "first"
      +            ],
      +            "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"
      +          },
      +          "collapsed": {
      +            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +            "type": "boolean"
      +          },
      +          "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": "Inputs override of a `formula` item (item UIDs, names or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +            "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +            "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"
      +          },
      +          "row_styles": {
      +            "additionalProperties": {
      +              "enum": [
      +                "normal",
      +                "subtotal",
      +                "total",
      +                "kpi"
      +              ],
      +              "type": "string"
      +            },
      +            "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +            "propertyNames": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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": "Item to delete: UID, temp id or name",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "Place right after a sibling (UID, temp id or name): a child of the same parent or, at the root, a tab of the same group (dashboard tabs come first, then section tabs). Exclusive with `before`.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "before": {
      +        "description": "Place right before a sibling (UID, temp id or name): a child of the same parent or, at the root, a tab of the same group (dashboard tabs come first, then section tabs); before the first one puts it first. Exclusive with `after`.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "op": {
      +        "const": "move",
      +        "type": "string"
      +      },
      +      "parent": {
      +        "anyOf": [
      +          {
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "New parent UID; `null` = to the root (a section or dashboard tab). Omitted = same parent."
      +      },
      +      "uid": {
      +        "description": "Item to move: UID, temp id or name",
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "uid"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "properties": {
      +      "after": {
      +        "description": "Place right after another list tab (UID, temp id or name). Exclusive with `before`.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "before": {
      +        "description": "Place right before another list tab (UID, temp id or name); before the first one puts it first. Exclusive with `after`.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "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": {
      +      "after": {
      +        "description": "Place right after another list tab (UID, temp id or name). Exclusive with `before`.",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "before": {
      +        "description": "Place right before another list tab (UID, temp id or name); before the first one puts it first. Exclusive with `after`.",
      +        "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_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. 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."
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      -        "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"
      -      },
      -      "row_styles": {
      -        "additionalProperties": {
      -          "enum": [
      -            "normal",
      -            "subtotal",
      -            "total",
      -            "kpi"
      -          ],
      -          "type": "string"
      -        },
      -        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -        "propertyNames": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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"
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      -        "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"
      -      },
      -      "row_styles": {
      -        "additionalProperties": {
      -          "enum": [
      -            "normal",
      -            "subtotal",
      -            "total",
      -            "kpi"
      -          ],
      -          "type": "string"
      -        },
      -        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -        "propertyNames": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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"
      -          },
      -          "collapsed": {
      -            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -            "type": "boolean"
      -          },
      -          "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -            "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      -            "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"
      -          },
      -          "row_styles": {
      -            "additionalProperties": {
      -              "enum": [
      -                "normal",
      -                "subtotal",
      -                "total",
      -                "kpi"
      -              ],
      -              "type": "string"
      -            },
      -            "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -            "propertyNames": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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",
      +          "first"
      +        ],
      +        "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."
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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",
      +          "first"
      +        ],
      +        "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"
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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",
      +              "first"
      +            ],
      +            "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"
      +          },
      +          "collapsed": {
      +            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +            "type": "boolean"
      +          },
      +          "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +            "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +            "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"
      +          },
      +          "row_styles": {
      +            "additionalProperties": {
      +              "enum": [
      +                "normal",
      +                "subtotal",
      +                "total",
      +                "kpi"
      +              ],
      +              "type": "string"
      +            },
      +            "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +            "propertyNames": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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"
      +  }
      +]
  3. Changed1 schema field changed
    • changedInput schema / properties / compute_branch / description
      Previous 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`."New value: +"Branch whose `[base, branch]` checkout the `compute` values are returned under (mirror of `layerz_read` `branch_id`). Defaults to `branch_id` when that is set, else the base plan. Requires `compute`."
  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"
      -      },
      -      "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."
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -        "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"
      -      },
      -      "row_styles": {
      -        "additionalProperties": {
      -          "enum": [
      -            "normal",
      -            "subtotal",
      -            "total",
      -            "kpi"
      -          ],
      -          "type": "string"
      -        },
      -        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -        "propertyNames": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "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"
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -        "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"
      -      },
      -      "row_styles": {
      -        "additionalProperties": {
      -          "enum": [
      -            "normal",
      -            "subtotal",
      -            "total",
      -            "kpi"
      -          ],
      -          "type": "string"
      -        },
      -        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -        "propertyNames": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "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"
      -          },
      -          "collapsed": {
      -            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -            "type": "boolean"
      -          },
      -          "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      -            "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"
      -          },
      -          "row_styles": {
      -            "additionalProperties": {
      -              "enum": [
      -                "normal",
      -                "subtotal",
      -                "total",
      -                "kpi"
      -              ],
      -              "type": "string"
      -            },
      -            "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      -            "propertyNames": {
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "type": "object"
      -          },
      -          "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."
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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"
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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"
      +          },
      +          "collapsed": {
      +            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +            "type": "boolean"
      +          },
      +          "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +            "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, unless it pins a `timeline_ref` or an `aggregation` different from its source (then it stays a formula).",
      +            "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"
      +          },
      +          "row_styles": {
      +            "additionalProperties": {
      +              "enum": [
      +                "normal",
      +                "subtotal",
      +                "total",
      +                "kpi"
      +              ],
      +              "type": "string"
      +            },
      +            "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +            "propertyNames": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "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). On `update` the map merges element by element: entries it does not name keep their series (send `[]` to clear one); on `create` / `replace` it is the full set. 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"
      +  }
      +]
  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"
      -      },
      -      "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."
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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"
      -      },
      -      "collapsed": {
      -        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -        "type": "boolean"
      -      },
      -      "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"
      -          },
      -          "collapsed": {
      -            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      -            "type": "boolean"
      -          },
      -          "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"
      -  }
      -]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."
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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"
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +        "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"
      +      },
      +      "row_styles": {
      +        "additionalProperties": {
      +          "enum": [
      +            "normal",
      +            "subtotal",
      +            "total",
      +            "kpi"
      +          ],
      +          "type": "string"
      +        },
      +        "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +        "propertyNames": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "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"
      +          },
      +          "collapsed": {
      +            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +            "type": "boolean"
      +          },
      +          "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": "Inputs override of a `formula` item (item UIDs or same-batch temp ids), derived from the expression when omitted. Ignored on every other role: a `balance` takes its flows from its children, an aggregator sums them.",
      +            "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"
      +          },
      +          "row_styles": {
      +            "additionalProperties": {
      +              "enum": [
      +                "normal",
      +                "subtotal",
      +                "total",
      +                "kpi"
      +              ],
      +              "type": "string"
      +            },
      +            "description": "mini_table per-row style override { <row UID / temp ID>: 'normal' | 'subtotal' | 'total' | 'kpi' }; an absent key keeps the row item's own style, a key outside `rows` is dropped, {} clears every override",
      +            "propertyNames": {
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "type": "object"
      +          },
      +          "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"
      +  }
      +]
  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"
      -      },
      -      "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"
      -  }
      -]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."
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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"
      +      },
      +      "collapsed": {
      +        "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +        "type": "boolean"
      +      },
      +      "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"
      +          },
      +          "collapsed": {
      +            "description": "fold the group by default: a section with children, a Σ aggregator or a list-mode line opens collapsed in the web grid and its rows start hidden under the Excel outline (+/−). false unfolds. View state, outside the blueprint and the diffs",
      +            "type": "boolean"
      +          },
      +          "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"
      +  }
      +]
  7. Changed1 schema field changed
    • addedInput schema / properties / compare_values
      Added value: +{
      +  "description": "Adds `value_diff`: the computed-values diff between the model before and after the batch — the `compute` UIDs, else the key lines (checks and totals) — at the finest grain under `compute_branch`, with before / after / delta per changed period and a summary. With `dry_run`, a preview of what the batch changes in the numbers.",
      +  "type": "boolean"
      +}
  8. 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"
      +  }
      +]
  9. 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\"."
  10. 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"
      +  }
      +]
  11. 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"
      +  }
      +]
  12. 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"
      +  }
      +]
  13. 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"
      +  }
      +]
  14. First observed

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only supply safety flags (destructive, non-idempotent), while the description adds genuinely non-obvious behavior: all-or-nothing batches that return every error at once with MODEL_VALIDATION_ERROR and details[], temp-id scoping and resolution via `map`, replace preserving UID and presentation fields versus update being a strict partial merge, branch overlay semantics for branch_id, and the fact that one version labelled `summary` is persisted. These are exactly the traits an agent could not read off the schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Content is dense with real information, but it is delivered as one long semicolon-chained paragraph with no grouping of concerns (ops, temp ids, ordering, branches, output modifiers). Some phrasing duplicates the schema (the role enum expansion is repeated from the schema descriptions), and the key routing facts (dry_run, branch_id, compare_values) sit at the end rather than front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-complexity 8-parameter mutation tool with no output schema, the description covers atomicity, validation error shape, temp-id wiring, ordering, branch overlays, version labeling and the dry-run/compare preview, plus a pointer to the modeling-guide resource for patterns. The remaining gap is the success payload — where the generated UIDs and the temp-id `map` appear in the response is mentioned only in passing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes further by explaining cross-parameter semantics the schema documents only per-field: how `branch_id` scopes value writes as an overlay, that `compute` returns computed series under `compute_branch` (defaulted to `branch_id`), what `dry_run` and `compare_values` add, and that `summary` labels the persisted version. It does not restate the op-object field list, which is appropriate given the schema already carries it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource and enumerates the nine operation kinds (create, replace, update, delete, move, list_create, list_update, list_delete, meta), which is far more than a restatement of the name. An agent can tell this is the single mutating batch endpoint and can distinguish it from read (layerz_read), inspect (layerz_diff) and validate siblings without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the op inventory and the atomicity rule tell an agent 'all writes go here', and the definition notes `dry_run` validates without persisting, `compare_values` mirrors `layerz_diff`, and the tool is not advertised to read-only keys. There is no explicit when-to-use versus alternatives (e.g. layerz_build_from_blueprint vs this, or when to prefer layerz_validate_model over a dry run), so the agent must infer routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources