open-standards/jcp/jcp-rs
Repository files (latest commit first)
Filename Latest commit message Latest commit date
David Charlot 4ba3e61841 jcp: an energy figure must say how much of the work it covers
`Energy { measured_uj, estimated_uj, provenance }`. `provenance` answers *how*
the number was acquired and nothing answers *how much of the task it accounts
for* — two different questions, routinely conflated to the figure's advantage.

The concrete case: on a host where the accelerator exposes an energy counter but
the CPU does not, a caller reads the accelerator and `Energy::measured()` stamps
`HwShunt` on a figure presented as the task's energy. The CPU's share is not
zero; it is unmeasured and silently missing. The reading is honest about its
sensor and dishonest about its scope, and nothing in the type or the receipt
could tell the difference.

`Coverage { Whole, Partial }` sits beside provenance rather than inside it,
because the axes really are independent: a partial reading is still a genuine
sensor reading, and `check_provenance` is untouched. `Energy::measured_partial`
exists so the honest case is as easy to express as the flattering one — without
it, a caller holding a partial reading reaches for `measured()` and the figure
claims the whole task by default.

The distinction is carried into the sealed receipt, not just the type. Had it
stopped at the type, a partial reading would reach a verifier looking exactly
like a whole one, which is the failure the field was added to prevent.

`Whole` is the default and is omitted from the wire, so every receipt sealed
before this field canonicalizes to the same bytes, and a legacy payload with no
`coverage` key parses as `Whole` — both pinned by tests, and the published
vectors are unchanged on disk.

On blast radius: I first declined this change on a measurement of "85 literal
sites across 8 workspaces", which was wrong — a grep for `Energy {` had swept up
`mesh::Energy`, `proof::Energy`, `DeviceEnergy` and `AttestedEnergy`, which are
different types. The compiler put the real figure at **one** site, a test inside
`jcp-schema` itself. Every one of the eight path-depending workspaces compiles
untouched, checked before and again after the receipt change, since that is the
whole risk of editing this crate.

Verified: 240 jcp-rs tests pass, conformance passes all classes, published
vectors unchanged, and joule-code / joule-ui / jouleclaw / joulehook / jouledesk
/ sandbox / mesh all check clean with zero errors.
2026-08-29 03:10:53 -04:00
..
conformance/v1 jcp: JCR-1 receipts bind their payload — jcp/2 + version dispatch (SPEC §8, C23) 2026-07-18 03:04:19 -04:00
crates jcp: an energy figure must say how much of the work it covers 2026-08-29 03:10:53 -04:00
Cargo.lock chore(deps): cargo update across the workspace; eoc toolchain → 1.98.0 2026-08-26 07:39:26 -04:00
Cargo.toml Land the FL-2 taint-propagation stack (increments 1-5) 2026-07-25 10:06:50 -04:00