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
Owner

§5 graded a figure and said how much of the work it covered. It never said which level the figure belonged to — and a deployed system is answerable at three that are not interchangeable:

level artifact answers
operation jcp/2 work receipt what one unit of work cost
activity AR-1 action receipt what one authorised thing did
outcome efficiency/1 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. And AR-1 carries exactly one energy figure, in binding 3: work — so authorising, attesting, verifying and pushing bytes off the device cost joules no receipt anywhere claimed. Egress counts bytes and no joules.

Conservation, with the residual named

An outcome now names its activities by content-id, so a verifier re-adds the figures itself, and the difference is a named signed residual in exact integer µJ — the cost of being accountable, not a remainder that vanishes. Mirrors eoc-carbon's allocation discipline. Negative is a finding. A double-bound activity is refused before the sum, because counting it twice shrinks the residual in the one direction that flatters. Provenance and coverage take the floor: aggregation must not be where a grade improves.

Dynamism — because a scalar distinguishes nothing

A total cannot tell a throttled part from a contended host from a cold cache, and on unprofiled silicon it cannot say what normal was. Energy is carried as a series, graded per window since counters do not have uniform resolution.

  • A baseline declares where it was measured and is inapplicable outside it. Undeclared is inapplicable, so forgetting under-claims rather than 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. 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 the most important line in the module. Energy does not carry intent. A type offering that arm would have it used — something maps Unexplained onto it, a dashboard colours it red, and a figure with no evidential basis starts informing decisions about people. Partition counts and produces no score: 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 floor arithmetic, not 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 — 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 floor_is_physical() reports whether the quoted floor rests on a measurement or a model's opinion.

What can and 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 at all; 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: 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 memory hierarchy (which is why band baselines fail 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.

Verification

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. SPEC.md gains §5.3–5.6.

🤖 Generated with Claude Code

§5 graded a figure and said how much of the work it covered. It never said which **level** the figure belonged to — and a deployed system is answerable at three that are not interchangeable: | level | artifact | answers | |---|---|---| | **operation** | `jcp/2` work receipt | what one unit of work cost | | **activity** | AR-1 action receipt | what one *authorised* thing did | | **outcome** | `efficiency/1` | 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. And AR-1 carries exactly one energy figure, in *binding 3: work* — so authorising, attesting, verifying and pushing bytes off the device cost joules no receipt anywhere claimed. `Egress` counts bytes and no joules. ## Conservation, with the residual named An outcome now names its activities by content-id, so a verifier re-adds the figures itself, and the difference is a **named signed residual** in exact integer µJ — the cost of being accountable, not a remainder that vanishes. Mirrors `eoc-carbon`'s allocation discipline. Negative is a finding. A double-bound activity is refused *before* the sum, because counting it twice shrinks the residual in the one direction that flatters. Provenance and coverage take the **floor**: aggregation must not be where a grade improves. ## Dynamism — because a scalar distinguishes nothing A total cannot tell a throttled part from a contended host from a cold cache, and on unprofiled silicon it cannot say what normal was. Energy is carried as a series, graded **per window** since counters do not have uniform resolution. - **A baseline declares where it was measured** and is inapplicable outside it. Undeclared is inapplicable, so forgetting under-claims rather than 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.** 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 the most important line in the module.** Energy does not carry intent. A type offering that arm would have it used — something maps `Unexplained` onto it, a dashboard colours it red, and a figure with no evidential basis starts informing decisions about people. `Partition` counts and produces no score: 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 floor arithmetic, not 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 — 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 `floor_is_physical()` reports whether the quoted floor rests on a measurement or a model's opinion. ## What can and 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 at all; 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: 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 memory hierarchy (which is why band baselines fail 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. ## Verification 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. SPEC.md gains §5.3–5.6. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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
6f12f88e61
§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]>
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
f9dac4e14b
§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]>
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
eb424fb7e0
§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]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!138
No description provided.