# Material calibrations Process calibration values live in the version-controlled `config/material-calibrations.yaml`. Calculations refer to opaque IDs; IDs have no special meaning to the parser. The current entry is: ```yaml calibrations: bento1-spreader-1-2: type: rotational_discharge value: 2.75 unit: kg_per_rev_m calibrated_at: 2026-09-08 method: gravimetric_tray description: Bento 1 fresh-bentonite spreaders 1 and 2 reference: measured_application_g_m2: 4068 line_speed_m_min: 2.3 signal_values: left: 1.65 right: 1.75 ``` All entry fields are required. Type, unit, method and description are non-empty strings; value must be a finite number (booleans are rejected); calibrated_at is a calendar date in YYYY-MM-DD format, quoted or unquoted. Reference is a non-empty mapping whose contents preserve source-specific measurement provenance. Unknown entry fields and duplicate YAML keys are rejected. The generic registry permits other types and units; each consuming calculation checks its own compatibility. `config/bento1-material-consumption.yaml` contains `calibration_ref: bento1-spreader-1-2`. During configuration loading, references resolve from `material-calibrations.yaml` in the calculation file's directory, independently of the working directory. The entire registry is validated when a reference is used. Rotational discharge requires type `rotational_discharge`, unit `kg_per_rev_m` and a positive value. Resolution supplies the existing `specific_discharge_kg_per_rev_m` runtime field for both application and consumption; the calculation algorithms are unchanged. There is no unit conversion. Missing/unreadable files, missing IDs, invalid metadata and incompatible type or unit raise `CalculationConfigError` before a runner starts. Existing direct numeric configurations remain supported; specifying both a reference and a direct factor is rejected. References are currently supported by rotational discharge consumers. K7 uses direct mass rate and does not load or require a calibration file. ## Updating a calibration After a physical measurement, edit only the central entry's value, date, method and reference details, and keep its ID stable. Review and version-control the change. Additional machines can add new IDs using the same structure. A new calculation type needs an explicit consumer compatibility contract. Ship the central YAML alongside the calculation YAML and restart the consuming process to load changes. No new CLI flag, environment variable, database migration or UI is required. There is no hot reload or historical date-based selection. Changes affect future calculations and explicitly rebuilt calculations. Historical persisted snapshots are **not automatically recalculated**. Existing checkpoints retain accumulated totals, so subsequent increments use the newly loaded factor; a complete historical rebuild requires a separately planned replay. Persisted snapshots do not gain calibration-version provenance through this change. ## Current Bento provenance On 2026-09-08, an independent gravimetric tray measurement found 4068 g/m² at 2.3 m/min with actual rotational signals left 1.65 and right 1.75. `(4068 / 1000) × 2.3 / (1.65 + 1.75) ≈ 2.75188 kg/(rev*m)` gives the configured rounded factor **2.75 kg/(rev*m)**. The original measurement remains recorded, without fitting or adjusting the runtime value to reproduce it exactly. Only fresh-bentonite spreaders 1 and 2 are included. Before adding spreader 3, confirm its material scope, actual signal units, independent calibration and whether its output belongs in the fresh-material KPIs. No spreader 3 support is included here.