# Map sub-spec — The receipt Normative refinement of [SPEC §6](../SPEC.md). Reference: `map-receipt`. Every resolve/decode of a tile emits a signed energy receipt. Receipts seal as **JCR-1** envelopes — the family's shared signed-receipt format (canonical det-CBOR + COSE_Sign1/EdDSA, `alg = -8`) — so a Map receipt verifies with the same tooling as a Joule Code, Sandbox, or JouleClaw receipt. The JCR-1 wire profile is `"map/1"`. ## 1. Shape ``` Receipt = { cell: CellKey, // rendered as its content id on the wire content_id: ContentId, // the tile that closed the request tier: Tier, // F0..F4 — the closing tier energy: { measured_uj: Option, estimated_uj: u64, provenance }, sequence: u64, nonce: [u8; 8], } ``` ## 2. The provenance coupling (REQUIRED) | Provenance | `measured_uj` | Meaning | |--------------|---------------|---------| | `HwShunt` | **required** | Read from a hardware energy interface (shunt, or a RAPL/NVML/SMC/IOReport counter while it is live — below). | | `ModelBased` | optional | Computed from a calibrated per-operation model. | | `Estimator` | **forbidden** | A coarse constant; honestly flagged as not measured. | `Receipt::seal` validates this coupling *before* signing, so a dishonest receipt (`HwShunt` with no measured figure; `Estimator` carrying one) cannot be sealed (conformance **C-neg**). The spec never claims an accuracy the platform cannot deliver. A reading from a vendor energy counter (RAPL, NVML, Apple IOReport, ...) **MAY** be graded as a hardware reading (`HwShunt`, with `measured_uj`) only while the counter is demonstrably live for the domain the figure claims: the implementation **MUST** have observed the counter covering that domain advance under load (for Apple IOReport: the CPU energy rail itself advancing in at least 5 sample intervals, in at least 4 of every 5, over at least 300 ms while the probing thread burns CPU; an interval runs from when one sample is in hand to when the next is, and only one no longer than three of the probe's ticks, 75 ms at its 25 ms tick, counts: a longer one counts as nothing, neither among the intervals, nor as an advance, nor towards the 300 ms, which is the summed length of the intervals that count). A counter that is present but not live — frozen, or republished in lumps — **MUST NOT** produce a hardware-graded figure; the implementation falls back to its estimator or reports the work unmetered, and **SHOULD** record why. A figure **MUST NOT** claim coverage of a domain its counter does not read; where the format has a coverage field, such a figure is Partial. `Receipt::seal` cannot check liveness; that duty is the meter's, upstream of the receipt. ## 3. Reference estimator (non-normative) Microjoules per resolved tile, ordered by tier — `map_receipt::UJ_BY_TIER`: | Tier | µJ (order of magnitude) | |------|--------------------------| | F0 Cache | 1 (picojoules) | | F1 Base | 1 000 (microjoules) | | F2 Field | 200 000 (sub-millijoules) | | F3 Feature | 5 000 000 (millijoules) | | F4 Photoreal | 2 000 000 000 (joules) | A session's total cost is the sum of its tile receipts. The standard is that the figure is **reported and honestly tagged** — not the constant. Conformance suite **C5** pins receipt sealing, verification, and the signed core in [`../conformance/v1/receipt_vectors.json`](../conformance/v1/receipt_vectors.json).