# calibration/ — frame corpus for validation & regression

Two artifacts, one frame pool:

- `calibration_labels.json` — per-frame color labels. Used by
  `atm validate-calibration` to check the current palette classifies known-good
  dots correctly before a live session.
- `scenarios.json` — ordered frame sequences per FSM scenario (full cycle,
  phase skip, catchup, post-fire suppression). Consumed by
  `tests/test_scenarios_regression.py` which runs each sequence through the
  full `Detector → _handle_tick` pipeline and asserts color, FSM reason/state,
  emitted alerts, and scheduler on/off.

Frames live in `calibration/frames/` and are self-contained: purging
`logs/fires/` or `samples/` does not break either artifact.

## calibration_labels.json schema

## Schema

A JSON array of entries. Each entry:

| Field      | Type    | Required | Description                                                    |
|------------|---------|----------|----------------------------------------------------------------|
| `path`     | string  | yes      | Path to a PNG frame (relative to CWD or absolute).             |
| `expected` | string  | yes      | Expected color name: one of `turquoise`, `yellow`, `dark_green`, `dark_red`, `light_green`, `light_red`, `gray`. |
| `note`     | string  | no       | Freeform annotation; shown in SUGGESTIONS output.              |

## Usage

```bash
atm validate-calibration calibration/calibration_labels.json
```

Exit codes:
- `0` — every sample PASS
- `1` — one or more FAIL
- `2` — label file missing or malformed JSON

## Adding new samples

1. Find a screenshot in `logs/fires/` whose dot color you can verify by eye.
2. **Copy it into `calibration/frames/`** — this directory is self-contained so
   `logs/fires/` and `samples/` can be emptied without breaking validation.
3. Append an entry with `path` (pointing to `calibration/frames/...`),
   `expected`, and an optional `note`.
4. Re-run validation. If it FAILs, the SUGGESTIONS section will tell you the
   RGB distance between the observed pixel and the expected color's center —
   use that as input for `atm calibrate`.
