jcp: energy traceability across operation, activity and outcome #138
Merged
dcharlot
merged 3 commits from 2026-10-10 09:49:57 -04:00
efficiency/energy-trace into main 2026-10-02
jcp: traceability becomes a precondition, not a report
All checks were successful
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 3m1s
standards workspaces build + test / aac-rs (pull_request) Successful in 2m10s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 54s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 40s
standards workspaces build + test / map-rs (pull_request) Successful in 37s
standards workspaces build + test / mesh-rs (pull_request) Successful in 37s
standards workspaces build + test / openpay (pull_request) Successful in 1m49s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m50s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m20s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m13s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m10s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m39s
standards workspaces build + test / arl-rs (pull_request) Successful in 2m52s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 3m10s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 3m8s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 3m4s
standards workspaces build + test / sense-rs (pull_request) Successful in 2m59s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 5m0s
§5 says JCP "makes it a precondition, not a report". Traceability was a report. `Efficiency::seal` serialises and signs whatever it is handed, so an untraceable outcome, a double-counted activity, a figure no part could have drawn, and a frozen counter claiming hardware could all be sealed, signed, and afterwards indistinguishable from a sound receipt. A signature over an unchecked claim is the most durable way to publish it. `OutcomeTrace::admit` is the gate. Three checks, in the order a verifier applies them: 1. **It reconciles.** Unbound, duplicated or over-accounted is refused — the arithmetic closes before anything else matters. 2. **No window is physically impossible.** Against the part's envelope: above the burst ceiling, or below the floor a powered executing part must draw. The second is the shape a frozen counter takes, which is why §5 has a liveness rule at all — and it is now enforced at seal time rather than stated in prose. 3. **The grade is earned, not asserted.** A receipt may carry no stronger provenance than the floor across its parts. Two deliberate asymmetries. Claiming *more* than the evidence supports is **refused**, not silently downgraded: a caller asking to seal `HwShunt` over `Estimator` evidence has a bug, and quietly writing the weaker grade would hide it. Claiming *less* is permitted — under-claiming is always allowed, and the receipt still records the floor. `AdmittedTrace` cannot be constructed except by passing the gate, so a function taking one knows the checks ran instead of hoping the caller remembered — the same reason `sandbox-attest` hands back a sealed run rather than a boolean. It carries the **derived** grade, so the sealer writes what the evidence supports in place of what it was handed. Aggregation is not a step at which a grade improves. Additive throughout: `seal()` is untouched and `jouledesk`, which path-depends on this crate from another workspace, is unaffected — checked, since `--workspace` here never builds it. Verified: 56 tests in `jcp-efficiency` (50 unit, 6 pack), including that a frozen counter cannot be sealed as anything, and that supplying no envelope admits on arithmetic alone rather than passing a physical check that never ran. Co-Authored-By: Claude Opus 5 <[email protected]>
jcp: publish the energy_trace/1 conformance pack, and replay it
Some checks failed
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 2m45s
standards workspaces build + test / aac-rs (pull_request) Successful in 1m32s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Has been cancelled
no-vanity-metrics / WAI public text names no comparison (pull_request) Has been cancelled
no-vanity-metrics / WAI public text names no company or product (pull_request) Has been cancelled
standards workspaces build + test / arl-rs (pull_request) Has been cancelled
standards workspaces build + test / eoc-rs (pull_request) Has been cancelled
standards workspaces build + test / jcp-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-ui-rs (pull_request) Has been cancelled
standards workspaces build + test / joulecontract-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / joulehook-rs (pull_request) Has been cancelled
standards workspaces build + test / map-rs (pull_request) Has been cancelled
standards workspaces build + test / mesh-rs (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
standards workspaces build + test / proof-rs (pull_request) Has been cancelled
standards workspaces build + test / sandbox-rs (pull_request) Has been cancelled
standards workspaces build + test / sense-rs (pull_request) Has been cancelled
standards workspaces build + test / smart-byte-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Has been cancelled
standards workspaces build + test / joule-code-rs (pull_request) Has been cancelled
§5.3–5.6 stated rules and nothing emitted them. The types did not even derive `Serialize`, so the profile could not cross a wire, let alone be checked by anyone else — a shape nothing emits is a proposal, which is the same gap the C2PA emitter closed for `wai` and the negative-vector replay closed for `joulecontract`. So: serde on the trace and dynamics types, a `gen_trace_vectors` binary writing `jcp/conformance/v1/energy_trace.json`, and a test that reads those bytes back from disk — the same bytes a third party would — and checks the reference implementation reproduces every recorded verdict. The pack carries the refusals, not just the acceptances, because the refusals are the load-bearing half. An implementation that admits an unbound outcome, a double-counted activity, an over-accounted total or a frozen counter has failed in the direction that flatters, which is the direction nobody notices: - conservation: the named residual, the provenance/coverage floor, and all three refusals (`Unbound`, `DuplicateActivity`, `OverAccounted`) - budget: 0.5 % over a one-joule grant is 5000 ppm against a 1 ppm floor; the same floor over `Estimator` windows is exact and physically meaningless; a ratio against a zero grant is not a figure - physical: refuted above the burst envelope, refuted **below** the idle floor (the frozen-counter shape), `NotRefuted` which is not verification, and a zero-duration window as unboundable rather than clean - shape: a total balanced by padding does not read as sustained; character is scale-invariant at 37× the magnitude; under three windows it is unresolvable - dynamism: an undeclared baseline makes no comparison, a coarser baseline does not apply to finer windows, and a cause explains only with evidence attached Falsified rather than assumed: flipping one recorded residual by a single microjoule — 250000 to 250001 — fails the replay naming the case and the field. The pack was then regenerated and the value confirmed back at 250000. Two anti-vacuity guards, because this file has been written three times this session and twice the first version could not fail: the pack path is asserted rather than skipped, and a test requires every declared section plus at least 20 replayed cases, so a wrong path or a renamed key fails instead of passing having checked nothing. Verified: 49 tests in `jcp-efficiency` — 43 unit, 6 pack. Co-Authored-By: Claude Opus 5 <[email protected]>
2026-10-01
jcp: energy traceability across operation, activity and outcome
Some checks failed
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m54s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m22s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m16s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m13s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m43s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 16m8s
standards workspaces build + test / aac-rs (pull_request) Successful in 6m26s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 5m45s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m18s
standards workspaces build + test / map-rs (pull_request) Successful in 1m41s
standards workspaces build + test / mesh-rs (pull_request) Successful in 49s
standards workspaces build + test / openpay (pull_request) Successful in 4m46s
standards workspaces build + test / arl-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-ui-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / joulehook-rs (pull_request) Has been cancelled
standards workspaces build + test / sense-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Has been cancelled
§5 graded a figure and said how much of the work it covered. It did not say which *level* the figure belonged to, and a deployed system is answerable at three that are not interchangeable: the operation (what one unit of work cost), the activity (what one authorised thing did — grant checked, environment attested, work performed, effect committed, bytes egressed), and the outcome (whether any of it bought anything). Those three were joined by nothing. `efficiency/1` identifies its unit of work by a `String`, so the level where the number is most load-bearing was the level with no binding at all; an outcome could assert any total and nothing tied it to the activities that produced it. And AR-1 carries exactly one energy figure, belonging to *binding 3: work* — so authorising, attesting, verifying and pushing bytes off the device cost joules that no receipt anywhere claimed. `Egress` counts bytes and no joules. `trace.rs` closes both. An outcome names its activities by content-id, so a verifier re-adds the figures itself, and the difference is reported as a named signed residual in exact integer µJ — the cost of being accountable, rather than a remainder that vanishes. Mirrors `eoc-carbon`'s allocation discipline, where `Σ shares + residual == total` holds exactly. Negative is a finding, not rounding. An activity bound twice is refused before the sum, because counting it twice shrinks the residual in the one direction that flatters. Provenance and coverage take the **floor**: one estimate makes the trace estimated, since aggregation must not be where a grade improves. ## The static layer is the floor, not the answer A scalar cannot tell a throttled part from a contended host from a cold cache, and on silicon nobody has profiled it cannot say what normal was. `dynamics.rs` carries energy as a series, graded per window because counters do not have uniform resolution. Three disciplines, each closing a laundering channel: - **A baseline declares where it was measured** and is inapplicable outside it — the same rule as `mesh-router`'s `Calibration`. Undeclared is inapplicable, so forgetting under-claims instead of manufacturing findings. - **A cause explains only with evidence.** Every `OperationalCause` carries a content-id for the reading behind it. Otherwise anything inconvenient gets labelled `ThermalThrottle` and disappears. - **Unresolvable is not within-band.** A phenomenon shorter than one window is invisible to it, and reporting nothing found at a resolution that could not have found it is the quietest way to be wrong. **There is no `Malicious` variant, and that absence is load-bearing.** Energy does not carry intent. A type offering that arm would have it used — something would map `Unexplained` onto it, a dashboard would colour it red, and a figure with no evidential basis would start informing decisions about people. That is the stand-in bug moved into security. `Partition` counts and produces no score, because unexplained, inapplicable and unresolvable mean "look at this", "we have no yardstick" and "we could not have seen it". ## Why fractions of a percent are detectable Integer µJ and exact sums make the detection floor arithmetic rather than statistical: against a grant of N µJ the smallest representable discrepancy is 1_000_000/N ppm — on a one-joule grant, 1 ppm. A fractional-percent drift sits three orders above it. This does not survive the usual construction, which is the point. Where energy is *derived from a performance proxy* — utilisation × TDP, tokens × a coefficient, instructions × pJ/op — the model error is tens of percent and a fractional-percent drift is invisible by construction, inside the error bar of the estimator that produced it. Deriving energy from performance does not merely lose accuracy; it destroys the ability to notice the books do not balance. So `Budget::floor_is_physical` reports whether the quoted floor rests on a measured figure or a model's opinion. ## What cannot be faked The joules were spent; the measurement is as forgeable as any report — a counter lied about, a figure fabricated, `HwShunt` stamped on a number from nowhere. What energy has that a synthetic unit does not is an external referent: a token count can be any number, a joule count is bounded by the part's envelope and the window's duration. `PowerEnvelope` refutes a figure above what the part could draw, or below what a powered executing part must — the second being the shape a frozen counter takes, which is why §5's liveness rule exists. Bounds are deliberately permissive so a refutation is unassailable. There is no `Verified` arm: a fabricated figure inside the envelope passes, and must. The one thing that cannot be faked is **how** the energy was consumed. A part cannot draw the profile of one computation while performing another. That closes the hole conservation leaves open — a total can be balanced by padding, but a fictional operation contributes no draw, so the character stops matching the declared mix. Character is also what survives unfamiliar hardware: magnitudes move with the node and the memory hierarchy, which is why a band baseline fails there, while flat stays flat and a ramp stays a ramp on any part. `DrawShape` must be declared in advance; classifying first and deciding afterwards is post-hoc pattern matching. An inconsistency refutes the declaration and names no cause and no intent. SPEC.md gains §5.3–5.6 for all of it. Verified: 43 tests in `jcp-efficiency` (24 new), 54 test binaries green across `jcp-rs`. `jouledesk` path-depends on `jcp-efficiency` from another workspace, which `--workspace` here never builds — checked separately and unaffected. Co-Authored-By: Claude Opus 5 <[email protected]>