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
`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]>
50 lines
2.2 KiB
Markdown
50 lines
2.2 KiB
Markdown
# Banding scales
|
||
|
||
Published threshold sets for [`BandingScale`](../jouleclaw-rs/crates/jouleclaw-compliance/src/banding.rs).
|
||
|
||
## 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:
|
||
|
||
```rust
|
||
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.
|