jcp: energy traceability across operation, activity and outcome #138

Merged
dcharlot merged 3 commits from efficiency/energy-trace into main 2026-10-10 09:49:57 -04:00

2026-10-02

David Charlot
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]>
2026-10-02 00:14:19 -04:00
David Charlot
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-02 00:06:10 -04:00

2026-10-01

David Charlot
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]>
2026-10-01 18:58:26 -04:00