open-standards/jouleclaw/scales/README.md
David Charlot 4d9236fe1c
Some checks failed
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 1m3s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 4s
standards workspaces build + test / aac-rs (pull_request) Successful in 1m37s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m47s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 2m1s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m14s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m10s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m1s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 2m32s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 33s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 18s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 7m19s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m18s
standards workspaces build + test / map-rs (pull_request) Successful in 1m11s
standards workspaces build + test / mesh-rs (pull_request) Successful in 53s
standards workspaces build + test / openpay (pull_request) Successful in 3m43s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 1m7s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 33s
standards workspaces build + test / arl-rs (pull_request) Successful in 26m42s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 14m25s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 11m21s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 9m52s
standards workspaces build + test / sense-rs (pull_request) Successful in 8m13s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 1m21s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 21s
WAI conformance / cargo-class corpora · windows (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · windows (pull_request) Has been cancelled
compliance: publish the EU draft PUE bands as a sourced data pack, not as code
`BandingScale` deliberately ships no canonical scale: which thresholds are
correct for a metric is a policy question a library has no standing to settle,
and baking one in would repeat the mistake the type was written to retire —
`is_compliant`'s `pue < 1.5 && renewable_pct >= 50.0`, two magic floats with no
provenance, no version, and no way to say which instrument they encoded.

So the EU draft's PUE bands are published as **data**, in `jouleclaw/scales/v1/`,
with their sources beside them. `BandingScale` already derives `Deserialize`, so
a pack loads with `serde_json::from_str` and this adds no crate code at all —
which is the point.

Each pack is exactly a `BandingScale`, accompanied by a provenance file
recording where the numbers came from, the status of that source, what the pack
omits, and the reuse terms. A pack with no provenance file is not publishable
here; a threshold whose origin is unstated is the thing the directory exists to
replace.

Three things the provenance says plainly:

- **The instrument is a DRAFT** — registered 2026-03-26, revised 2026-07-02, not
  adopted and not in the Official Journal, with first labels expected
  2027-08-15. A grade produced from it is not a regulatory determination.
- **WUE is deliberately absent.** The instrument sets the grade from PUE *and*
  WUE, and only the PUE bands were read from it. Inventing WUE boundaries to
  complete the set would be exactly the failure this design prevents: a
  threshold with no provenance, presented as though it had one. A test asserts
  that a composite built from this pack reports `covers(&["pue","wue"]) ==
  false`, so a half-graded facility cannot read as graded.
- **The instrument permits calculation and estimates**, not only measurement, so
  a PUE fed to this scale may be self-declared. The scale bands whatever number
  it is given and says nothing about how that number was acquired.

The scale id is a version and is never edited in place. Ratings cite their
`scale_id` and `comparable_with` refuses to rank across scales, which only works
if an id means one fixed set of boundaries forever — so a changed instrument is
a new id, never an edit that would silently re-band grades already issued.

The pack is tested, not merely committed: it is `include_str!`-ed, deserialized,
validated and banded, and the test pins that its last boundary is **1900** —
this file's own example fixture uses 2000, and only one of the two is sourced.

Verified: 52 jouleclaw-compliance tests pass (2 new).

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-06 06:24:25 -04:00

2.2 KiB
Raw Permalink Blame History

Banding scales

Published threshold sets for BandingScale.

Why scales live here and not in the crate

BandingScale::rate turns a measurement into an A–G band. The crate ships the shape of a scale and no scale at all, deliberately: which thresholds are correct for a given metric is a policy question a library has no standing to settle. Baking one in would repeat the mistake the type was written to retire — EedReport::is_compliant's pue < 1.5 && renewable_pct >= 50.0, two magic floats with no provenance, no version, and no way to say which instrument they encoded — only with more ceremony.

So a scale is data, published here with its sources beside it. BandingScale derives Deserialize, so a pack loads with serde_json::from_str and needs no crate code:

let scale: BandingScale = serde_json::from_str(include_str!("…/eu.eed.dr2026.pue.json"))?;
let rating = scale.rate(report.pue_milli())?;

What a pack must carry

Each <scale_id>.json is exactly a BandingScale. Each is accompanied by <scale_id>.provenance.json recording where the numbers came from, the status of that source, what the pack deliberately omits, and the reuse terms.

A pack with no provenance file is not publishable here. A threshold whose origin is unstated is the thing this directory exists to replace.

The scale id is a version, and never edited in place

Ratings cite their scale_id, and Rating::comparable_with refuses to rank two ratings from different scales. That only works if an id means one fixed set of boundaries forever. When a source instrument changes, the result is a new id — never an edit to an existing file, which would silently re-band every grade already issued under it.

Current packs

scale metric source status
eu.eed.dr2026.pue/1 PUE, milli-units Draft delegated regulation (revised 2026-07-02, not adopted)

A grade produced from a draft instrument is not a regulatory determination, and the provenance file says so in those words. These packs exist so that a figure can be banded against a stated source; they do not make the source binding, and they do not make a self-declared input measured.