{
  "esm_integrator": "0.1.0",
  "description": "Refusal codes of the planner (spec/plan.md, spec/run-config.md §8, D79). A refusal reports its code, a JSON pointer into the run config (or a model location) and a message; conformance tests compare the code and the pointer only. 'rule' is the rule number of spec/run-config.md §8, or null for a refusal that section does not list.",
  "codes": [
    {"code": "run_config_invalid", "rule": null, "where": "spec/plan.md §4 step 1", "meaning": "The run config does not validate against its JSON Schema (pointer \"\", the document root), or a duration read from a parameter is not a positive finite number (pointer: the duration's key), or a partition.shards entry names a coupled node or an operator a coupled node names (pointer: /partition/shards/<key>, spec/plan.md §7.4)."},
    {"code": "version_unsupported", "rule": null, "where": "spec/run-config.md §1", "meaning": "The run config's esm_integrator version is not one this planner implements. Pointer: /esm_integrator."},
    {"code": "toy_model_not_plannable", "rule": 1, "where": "spec/plan.md §4 step 2", "meaning": "The model is toy:<problem>, which only the conformance harness accepts. Pointer: /model."},
    {"code": "model_load_failed", "rule": 1, "where": "spec/plan.md §4 step 3", "meaning": "The model does not load or validate with EarthSciAST; the message carries EarthSciAST's own code. A rejected solver.time_span whose cause is a rule-14 one takes that code instead (spec/plan.md §4 step 3). Pointer: /model."},
    {"code": "solver_external_mismatch", "rule": 1, "where": "spec/plan.md §4 step 4", "meaning": "The model's solver.external does not resolve to this run config. Pointer: /model."},
    {"code": "model_flatten_failed", "rule": 1, "where": "spec/plan.md §4 step 5", "meaning": "EarthSciAST refused to flatten the model or expand its references. Pointer: /model."},
    {"code": "unsupported_algebraic_equation", "rule": 16, "where": "spec/plan.md §0.1", "meaning": "The flattened model has algebraic unknowns; algebraic operators need U6 (M4b). Pointer: /model."},
    {"code": "unsupported_event", "rule": 16, "where": "spec/plan.md §0.1", "meaning": "The flattened model has continuous or discrete events; condition and map operators need U6 (M4b). Pointer: /model."},
    {"code": "unsupported_parameter_update", "rule": 16, "where": "spec/plan.md §0.1, D75", "meaning": "A parameter carries an update rule; none is planned at M2, schedule and data included. Pointer: /model."},
    {"code": "unsupported_forcing", "rule": 16, "where": "spec/plan.md §0.1", "meaning": "The flattened model reads data-loader fields; forcing epochs arrive at M3. Pointer: /model."},
    {"code": "unsupported_index_set", "rule": 16, "where": "spec/plan.md §4 step 6", "meaning": "An index set is not an interval with an integer size. Pointer: /model."},
    {"code": "unsupported_map_operator", "rule": 16, "where": "spec/plan.md §0.1", "meaning": "A map operator or map node; map operators need U6 (M4b)."},
    {"code": "unsupported_step_limit", "rule": 16, "where": "spec/plan.md §7.1", "meaning": "An observed step limit in step.limits or subcycle.limits; limit operators need U6 (M4b). Refused in spec/plan.md §7.1's unsupported-construct pass, step.limits after the schedule. Pointer: the entry, /step/limits/<i> or the subcycle's limits/<i>."},
    {"code": "unsupported_solve_node", "rule": 16, "where": "spec/plan.md §0.1", "meaning": "A solve node; algebraic operators need U6 (M4b)."},
    {"code": "unsupported_coupled_dae", "rule": 16, "where": "spec/run-config.md §4.3", "meaning": "A coupled node with algebraic operators (D3b, after M6)."},
    {"code": "unsupported_split_explicit", "rule": 16, "where": "spec/run-config.md §4.11", "meaning": "A split_explicit node (M7)."},
    {"code": "unsupported_crossing_update", "rule": 16, "where": "D22", "meaning": "A crossing parameter-update rule (not in v1). Reported in place of unsupported_parameter_update whenever any parameter has one, whatever the parameter order; it does not jump ahead of unsupported_algebraic_equation or unsupported_event (spec/plan.md §4 step 6). Pointer: /model."},
    {"code": "axes_unresolved", "rule": null, "where": "spec/plan.md §5.2.1, D67", "meaning": "axes names an index set that does not exist or names one twice, or more than two horizontal axes result. Pointer: /axes."},
    {"code": "name_unresolved", "rule": 2, "where": "spec/run-config.md §8", "meaning": "A qualified name does not resolve in the flattened model, or a precision key names no operator, node or default (spec/plan.md §7.1)."},
    {"code": "name_wrong_kind", "rule": 2, "where": "spec/run-config.md §8", "meaning": "A qualified name resolves to the wrong kind of variable."},
    {"code": "operator_undefined", "rule": 3, "where": "spec/run-config.md §8", "meaning": "The schedule names an operator that is neither defined nor an existing default operator, in a leaf or coupled list, a frozen entry or an imex entry. Pointer: the entry, such as <node>/leaf/<i> or <node>/imex/<part>/<i> (spec/plan.md §7.1)."},
    {"code": "term_selected_twice", "rule": 4, "where": "spec/plan.md §5.1.3", "meaning": "A term is matched by two operators' selectors."},
    {"code": "selector_matches_nothing", "rule": 4, "where": "spec/plan.md §5.1.3", "meaning": "An operator's selector matches no term. With several, the first in code-point order is reported."},
    {"code": "ambiguous_term_owner", "rule": null, "where": "spec/plan.md §5.1.3, D65", "meaning": "A term that reads variables of two or more other components is matched by no selector while some selector uses components. Pointer: /operators."},
    {"code": "term_origin_unknown", "rule": null, "where": "spec/plan.md §5.1.1", "meaning": "A contribution has an empty origins list. Pointer: /model."},
    {"code": "operator_not_advanced", "rule": 5, "where": "spec/run-config.md §8", "meaning": "An operator, named or default, is advanced by no node of the schedule (a frozen entry counts as advancing). Pointer: /operators/<op>, or /schedule for a default operator."},
    {"code": "operator_advanced_twice", "rule": 5, "where": "spec/run-config.md §8", "meaning": "An operator is named by two leaf or coupled nodes (a strang running a child twice is one place; frozen entries do not count). Pointer: the second such node's operator entry in tree order, <node>/leaf/<i> or <node>/coupled/<i> (<node>/leaf when the leaf is a single string; spec/plan.md §7.1)."},
    {"code": "imex_partition_invalid", "rule": 6, "where": "spec/run-config.md §4.5", "meaning": "An imex partition leaves an operator of the leaf in neither part or puts one in both, or an IMEXEuler leaf has no imex. Pointer: the leaf's <node>/imex for a bad partition; the leaf's pointer (spec/plan.md §7.1) when imex is missing."},
    {"code": "duplicate_node_id", "rule": 7, "where": "spec/plan.md §7.1", "meaning": "Two nodes have the same id, or a given id equals a path the planner assigns."},
    {"code": "node_id_reserved", "rule": 7, "where": "spec/plan.md §7.1", "meaning": "A path-form node id on a node whose path it is not."},
    {"code": "hold_tendency_child_not_leaf", "rule": 8, "where": "spec/run-config.md §4.9", "meaning": "An every node with hold: tendency whose child is not a single leaf. Pointer: the every node's <node>/every."},
    {"code": "tstop_off_fixed_step", "rule": 9, "where": "spec/run-config.md §5", "meaning": "A tstop that is not t0 plus a multiple of a fixed step.dt, under a root that cannot land on it. Pointer: /step/hit_multiples, or /adjoint/functional/over for an adjoint observation time (spec/plan.md §7.3)."},
    {"code": "precision_contradicts_declaration", "rule": 10, "where": "spec/plan.md §7.5", "meaning": "A state or rhs precision role contradicts a declared element_type, or a leaf's written states declare different element_types. Pointer: the precision entry that set the role, /precision/<key>; for mixed declarations with no entry setting state, the leaf's pointer in the schedule (spec/plan.md §7.1)."},
    {"code": "precision_rhs_below_state", "rule": 10, "where": "spec/plan.md §7.5", "meaning": "The rhs role is below the state role. Pointer: the precision entry that set the role, /precision/<key>."},
    {"code": "precision_conflict", "rule": null, "where": "spec/plan.md §7.5", "meaning": "precision entries for two operators of one leaf disagree on a role. Pointer: the first entry in the leaf's operator order that disagrees on that role with the leaf's first entry setting it, /precision/<op>."},
    {"code": "precision_low_with_classical_rosenbrock", "rule": null, "where": "spec/plan.md §7.5, architecture §8", "meaning": "A jacobian or factors role below rhs on a Rosenbrock method other than Rosenbrock23; for an alg of \"auto\", checked once spec/plan.md §5.5.3 resolves the method. Pointer: the precision entry that set the role, /precision/<key>."},
    {"code": "wrt_matches_nothing", "rule": 11, "where": "spec/run-config.md §7.2", "meaning": "An adjoint.wrt entry matches nothing; at M2 every forcing: entry does (spec/plan.md §7.6)."},
    {"code": "wrt_bound_parameter", "rule": 11, "where": "spec/run-config.md §7.2", "meaning": "An adjoint.wrt entry names a parameter bound by bind_dt."},
    {"code": "step_control_missing", "rule": 12, "where": "spec/plan.md §7.3", "meaning": "step has neither dt nor limits and the schedule root is not a single adaptive leaf or coupled node."},
    {"code": "adaptive_without_error_estimate", "rule": 13, "where": "spec/run-config.md §4.2, D52", "meaning": "A leaf with dt omitted whose method has no embedded error estimate."},
    {"code": "time_interval_missing", "rule": 14, "where": "spec/plan.md §7.2", "meaning": "No source gives a run interval. Pointer: /time."},
    {"code": "time_interval_empty", "rule": 14, "where": "spec/plan.md §7.2", "meaning": "The interval's end is not after its start. Pointer: /time, \"\" for the caller's interval, /model for the model's solver.time_span."},
    {"code": "time_invalid_date", "rule": 14, "where": "spec/plan.md §7.2", "meaning": "A timestamp names a day its month does not have. Pointer: the timestamp's key, \"\" for the caller's, /model for the model's solver.time_span."},
    {"code": "time_origin_invalid", "rule": 14, "where": "spec/plan.md §7.2, D74", "meaning": "A timestamp is given and the model's time-origin field cannot be read. Pointer: the timestamp's key (\"\" for the caller's, /model for solver.time_span)."},
    {"code": "bind_dt_leaf_without_dt0", "rule": 15, "where": "spec/run-config.md §4.2", "meaning": "An adaptive leaf binds a parameter to the leaf step but gives no control.dt0. Pointer: the binding, the leaf's bind_dt or /operators/<op>/bind_dt."},
    {"code": "output_time_outside_interval", "rule": null, "where": "spec/run-config.md §7.3", "meaning": "An output or saveat time lies outside the run interval. Cannot occur at M2: saveat is a duration whose multiples are taken inside (t0, tf] (D83)."},
    {"code": "auto_strategy_unavailable", "rule": null, "where": "spec/plan.md §5.5.3, D71", "meaning": "An auto choice has no M2 resolution: a stiff global leaf, a stiff pointwise leaf whose Jacobian storage is not block_diagonal, a stencil leaf with a stiff column operator and no dt, or an implicit method on a stencil or global leaf with linsolve omitted."},
    {"code": "band_model_failed", "rule": null, "where": "spec/plan.md §5.2.2, §5.4", "meaning": "EarthSciASTDiff refused to differentiate a term or an operator. Pointer: /model."},
    {"code": "lift_shape_unresolved", "rule": null, "where": "spec/plan.md §4 step 8, §6.1.3, D68", "meaning": "No declared shape of a non-lifted variable has a lifted state's extents. Pointer: /model."},
    {"code": "reserved_component_name", "rule": null, "where": "spec/plan.md §4 step 7, §6.1.4", "meaning": "The model has a top-level component named _jacobian. Pointer: /model."},
    {"code": "partition_axis_missing", "rule": null, "where": "spec/plan.md §7.4", "meaning": "ranks or tiles divide a horizontal axis the model does not have. Pointer: /partition."},
    {"code": "partition_too_fine", "rule": null, "where": "spec/plan.md §7.4", "meaning": "ranks times tiles exceeds an axis's size. Pointer: /partition."},
    {"code": "partition_conflict", "rule": null, "where": "spec/plan.md §7.4", "meaning": "partition.shards entries for two operators of one leaf disagree. Pointer: the first entry in the leaf's operator order that disagrees with the leaf's first entry, /partition/shards/<op>."},
    {"code": "validation_rhs_sum_failed", "rule": null, "where": "spec/plan.md §8.1", "meaning": "The operators' right-hand sides do not sum to the model's. Pointer: /model."},
    {"code": "validation_band_model_failed", "rule": null, "where": "spec/plan.md §8.1", "meaning": "An operator's band Jacobian disagrees with the independent Jacobian. Pointer: /model."},
    {"code": "validation_empty_operator", "rule": null, "where": "spec/plan.md §8.1", "meaning": "An operator has no term, or no band although a term reads a state. Pointer: /model."}
  ]
}
