# Measurement ledger v1

Keep this as task-local data. It is not a WebMCP tool payload and does not authorize mutations.

```json
{
  "version": 1,
  "source": {"name": "floor-1.png", "page": 1},
  "target": {"projectHash": "<returned hash>", "floorId": "<read ID>", "sceneRevision": "<read revision>"},
  "measurements": [
    {
      "label": "Living width",
      "sourceRef": "page 1 upper horizontal dimension",
      "sourceKind": "labeled_dimension",
      "expectedCm": 470,
      "referenceBasis": "clear_span",
      "objectId": "<read wall ID>",
      "axis": "x",
      "observedCm": 469.8,
      "observedBasis": "clear_span",
      "observedMethod": "native wall length property",
      "toleranceCm": 5
    }
  ]
}
```

Convert length units explicitly: meters × 100, inches × 2.54, feet × 30.48. Keep area separately in m². Use `null` for missing values; do not insert placeholder dimensions or a default scale.

The example's tolerance reflects a source label rounded to 0.1 m; it is not a default for exact supplied dimensions. Retain source precision and any tighter user constraint. Keep each span's actual endpoints/semantic wall in working notes so a different edge cannot silently replace it.

For each row compute `observedCm - expectedCm` and compare its absolute value to the explicit tolerance. If dimension bases differ, source provenance is unreliable, or a value is missing, mark insufficient evidence rather than pass/fail. The helper [compare_measurements.py](../scripts/compare_measurements.py) performs that arithmetic without network access or scene mutation:

```sh
python3 <skill-directory>/scripts/compare_measurements.py <ledger.json>
```

Output is a ledger assessment, not a whole-plan verdict. It does not check wall topology, actual openings, room access, or persistence. A ratio observed across independent X/Y path measurements may suggest investigating uniform scale; the script deliberately does not choose or apply a scale factor.
