efficiency/1: a partial energy figure is sealed as partial and never headlines as a task total #369

Merged
dcharlot merged 1 commit from fix/efficiency-keeps-coverage into main 2026-10-20 16:05:30 -04:00
7 changed files with 644 additions and 11 deletions

View file

@ -926,6 +926,16 @@ interceptor chain (`jcp-intercept`) carries it as `coverage`, beside its
`"Partial"`; a verifier MUST refuse any other value, `"Whole"` included, rather
than read it either way.
The `efficiency/1` outcome receipt (§5.3) carries it as `energy_coverage`,
under the same one-value rule. Its headline figures are ratios of a task total:
energy per accepted token on the receipt, and energy per completed unit over a
ledger. So a `Partial` receipt MUST NOT carry `uj_per_accepted_token`, and a
verifier MUST refuse one that does. A total summed from receipts of which any
is `Partial` is `Partial` and gives no per-unit energy figure. A partial figure
divided by tokens is not what the work cost per token, nor a bound on it,
because a partial figure may fall short of the work or exceed it. The vectors
are in [`conformance/v1/efficiency.json`](conformance/v1/efficiency.json).
### 5.3 Traceability across operation, activity and outcome (REQUIRED where an outcome claims energy)
§5.1 grades a figure and §5.2 says how much of the work it covers. Neither says

View file

@ -0,0 +1,228 @@
{
"aggregate": {
"cases": [
{
"expected": {
"completed_uj": 1600000,
"coverage": "Partial",
"provenance_floor": "Estimator",
"tokens_per_completed_unit": 3000,
"uj_per_completed_unit": null,
"wasted_uj": 400000
},
"input": [
{
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_uj": 1000000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "HwShunt",
"seq": 0,
"steward": "did:example:steward",
"task": "whole",
"tokens_in": 2000,
"tokens_out": 500,
"uj_per_accepted_token": 2000,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
{
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_coverage": "Partial",
"energy_uj": 600000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "HwShunt",
"seq": 0,
"steward": "did:example:steward",
"task": "gpu-only",
"tokens_in": 2000,
"tokens_out": 500,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
{
"completed": 0,
"efficiency_receipt": "efficiency/1",
"energy_uj": 400000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "Estimator",
"seq": 0,
"steward": "did:example:steward",
"task": "estimated",
"tokens_in": 800,
"tokens_out": 200,
"uj_per_accepted_token": 2000,
"verdict": "gate-failed",
"wall_ns": 1000000000
}
],
"note": "a total over a partial figure is partial and gives no per-unit energy; its provenance is the floor"
},
{
"expected": {
"completed_uj": 1000000,
"coverage": "Whole",
"provenance_floor": "Estimator",
"tokens_per_completed_unit": 3500,
"uj_per_completed_unit": 1400000,
"wasted_uj": 400000
},
"input": [
{
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_uj": 1000000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "HwShunt",
"seq": 0,
"steward": "did:example:steward",
"task": "whole",
"tokens_in": 2000,
"tokens_out": 500,
"uj_per_accepted_token": 2000,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
{
"completed": 0,
"efficiency_receipt": "efficiency/1",
"energy_uj": 400000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "Estimator",
"seq": 0,
"steward": "did:example:steward",
"task": "estimated",
"tokens_in": 800,
"tokens_out": 200,
"uj_per_accepted_token": 2000,
"verdict": "gate-failed",
"wall_ns": 1000000000
}
],
"note": "a total over whole figures gives its per-unit energy, at the weakest provenance"
}
]
},
"payload": {
"negative": [
{
"expected": {
"refused": "presented as a task total"
},
"input": {
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_coverage": "Partial",
"energy_uj": 600000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "HwShunt",
"seq": 0,
"steward": "did:example:steward",
"task": "gpu-only",
"tokens_in": 2000,
"tokens_out": 500,
"uj_per_accepted_token": 1200,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
"note": "a GPU-only figure presented as a task total, with a per-token headline"
},
{
"expected": {
"refused": "energy_coverage"
},
"input": {
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_coverage": "Whole",
"energy_uj": 1000000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "HwShunt",
"seq": 0,
"steward": "did:example:steward",
"task": "whole",
"tokens_in": 2000,
"tokens_out": 500,
"uj_per_accepted_token": 2000,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
"note": "an absent coverage is Whole; \"Whole\" on the wire is refused"
},
{
"expected": {
"refused": "not a provenance label"
},
"input": {
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_uj": 1000000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "Measured",
"seq": 0,
"steward": "did:example:steward",
"task": "whole",
"tokens_in": 2000,
"tokens_out": 500,
"uj_per_accepted_token": 2000,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
"note": "a provenance that is not one of the three labels"
}
],
"positive": [
{
"expected": {
"energy_coverage": "Whole",
"energy_uj": 1000000,
"provenance": "HwShunt",
"uj_per_accepted_token": 2000
},
"input": {
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_uj": 1000000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "HwShunt",
"seq": 0,
"steward": "did:example:steward",
"task": "whole",
"tokens_in": 2000,
"tokens_out": 500,
"uj_per_accepted_token": 2000,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
"note": "a whole figure seals its per-token headline and no coverage field"
},
{
"expected": {
"energy_coverage": "Partial",
"energy_uj": 600000,
"provenance": "HwShunt",
"uj_per_accepted_token": null
},
"input": {
"completed": 1,
"efficiency_receipt": "efficiency/1",
"energy_coverage": "Partial",
"energy_uj": 600000,
"prev": "0000000000000000000000000000000000000000000000000000000000000000",
"provenance": "HwShunt",
"seq": 0,
"steward": "did:example:steward",
"task": "gpu-only",
"tokens_in": 2000,
"tokens_out": 500,
"verdict": "tests-pass",
"wall_ns": 1000000000
},
"note": "a GPU-only figure seals its coverage and no per-token headline: it is no task total"
}
]
},
"profile": "efficiency/1",
"spec": "jcp/SPEC.md §5.2-5.3"
}

View file

@ -52,7 +52,7 @@ receipts.
| SCI-for-AI concept | `efficiency/1` field / method | What TX adds |
|---|---|---|
| `E` — energy of the functional unit | `energy_uj` + `provenance` | **Honest provenance** (`HwShunt`/`ModelBased`/`Estimator`) — SCI leaves `E`'s trust unstated |
| `E` — energy of the functional unit | `energy_uj` + `provenance` + `energy_coverage` | **Honest provenance** (`HwShunt`/`ModelBased`/`Estimator`) — SCI leaves `E`'s trust unstated — and **coverage**: a `Partial` figure (a GPU counter alone) is sealed as such and gives no per-token rate, since it is not `E` |
| `R` — functional unit (per token / inference) | `tokens_out` (accepted) → `uj_per_accepted_token()` | The unit is **sealed**, not asserted |
| `SCI` rate | `uj_per_accepted_token`, `tokens_per_sec()`, `uusd_per_accepted_token()` | Rates **recompute from sealed integers** — reproducible, tamper-evident |
| — (no outcome concept in SCI) | `completed` + `verdict`, `aggregate()` | The **outcome anchor** + waste accounting SCI has no notion of |

View file

@ -0,0 +1,134 @@
//! Emit the `efficiency/1` payload conformance pack to `jcp/conformance/v1/`.
//!
//! jcp SPEC §5.2 says a `Partial` figure MUST NOT be presented as a task total,
//! and §5.3 that aggregation is not a step at which a grade improves. These are
//! the vectors a third party replays to check an independent `efficiency/1`
//! reader against those rules: payloads (the signed core, once its signature
//! holds) with the reading a conformant reader must reach, the refusals
//! included, and receipt sets with the totals they must sum to. The payloads
//! carry no signature, because the rules are about what a verified receipt
//! says, not about the signature, which `jcr1` vectors already cover.
//!
//! Run: `cargo run -p jcp-efficiency --bin gen_efficiency_vectors -- ../conformance/v1`
use std::path::PathBuf;
use jcp_efficiency::{aggregate, read_payload, Efficiency};
use jcp_schema::{ContentId, Energy};
use serde_json::{json, Value};
fn unit(task: &str, completed: bool, tokens_out: u64, energy: Energy) -> Efficiency {
Efficiency {
task: task.into(),
completed,
verdict: if completed { "tests-pass".into() } else { "gate-failed".into() },
tokens_in: tokens_out * 4,
tokens_out,
energy,
wall_ns: 1_000_000_000,
value_uusd: None,
energy_attestation: None,
}
}
fn payload(e: &Efficiency) -> Value {
e.payload(0, &ContentId([0u8; 32]), "did:example:steward")
}
/// A case carries the input and the verdict a conformant reader must reach.
fn case(note: &str, input: Value, expected: Value) -> Value {
json!({ "note": note, "input": input, "expected": expected })
}
fn read(note: &str, p: Value) -> Value {
let r = read_payload(&p).unwrap_or_else(|e| panic!("{note}: a positive must read: {e}"));
case(
note,
p,
json!({
"energy_uj": r.energy_uj,
"provenance": r.provenance,
"energy_coverage": r.energy_coverage.label(),
"uj_per_accepted_token": r.uj_per_accepted_token,
}),
)
}
fn refuse(note: &str, p: Value, because: &str) -> Value {
let err = read_payload(&p).expect_err(note).to_string();
assert!(err.contains(because), "{note}: refused for '{err}', not '{because}'");
case(note, p, json!({ "refused": because }))
}
/// A set of payloads and the totals a conformant reader must sum them to.
fn totals(note: &str, ps: Vec<Value>) -> Value {
let rs: Vec<_> = ps.iter().map(|p| read_payload(p).expect("reads")).collect();
let t = aggregate(&rs);
case(
note,
json!(ps),
json!({
"completed_uj": t.completed_uj,
"wasted_uj": t.wasted_uj,
"coverage": t.coverage.label(),
"provenance_floor": t.provenance_floor.map(|p| p.jcr1_label()),
"uj_per_completed_unit": t.uj_per_completed_unit(),
"tokens_per_completed_unit": t.tokens_per_completed_unit(),
}),
)
}
fn main() {
let out = std::env::args()
.nth(1)
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../../conformance/v1"));
std::fs::create_dir_all(&out).expect("create output dir");
let whole = unit("whole", true, 500, Energy::measured(1_000_000));
let gpu_only = unit("gpu-only", true, 500, Energy::measured_partial(600_000));
let estimated = unit("estimated", false, 200, Energy::estimator(400_000));
let mut presented = payload(&gpu_only);
presented["uj_per_accepted_token"] = json!(1_200);
let mut said_whole = payload(&whole);
said_whole["energy_coverage"] = json!("Whole");
let mut unnamed = payload(&whole);
unnamed["provenance"] = json!("Measured");
let pack = json!({
"profile": "efficiency/1",
"spec": "jcp/SPEC.md §5.2-5.3",
"payload": {
"positive": [
read("a whole figure seals its per-token headline and no coverage field", payload(&whole)),
read(
"a GPU-only figure seals its coverage and no per-token headline: it is no task total",
payload(&gpu_only)
),
],
"negative": [
refuse(
"a GPU-only figure presented as a task total, with a per-token headline",
presented,
"presented as a task total"
),
refuse("an absent coverage is Whole; \"Whole\" on the wire is refused", said_whole, "energy_coverage"),
refuse("a provenance that is not one of the three labels", unnamed, "not a provenance label"),
],
},
"aggregate": { "cases": [
totals(
"a total over a partial figure is partial and gives no per-unit energy; its provenance is the floor",
vec![payload(&whole), payload(&gpu_only), payload(&estimated)],
),
totals(
"a total over whole figures gives its per-unit energy, at the weakest provenance",
vec![payload(&whole), payload(&estimated)],
),
] },
});
let path = out.join("efficiency.json");
std::fs::write(&path, serde_json::to_string_pretty(&pack).expect("serialise") + "\n").expect("write pack");
println!("wrote {}", path.display());
}

View file

@ -35,7 +35,7 @@
use ed25519_dalek::SigningKey;
use jcp_receipt::jcr1;
use jcp_schema::{ContentId, Energy};
use jcp_schema::{ContentId, Coverage, Energy, Provenance};
pub mod avoided;
/// Energy traceability across operation, activity and outcome.
@ -95,7 +95,18 @@ impl Efficiency {
/// sealed and read straight back out rather than recomputed. `mesh/SPEC.md`
/// §6 states the family convention this matches: "omitted when no tokens were
/// accepted".
///
/// Also `None` for a `Partial` figure. The headline is the unit's energy
/// per token, a ratio of a task total, and a `Partial` figure MUST NOT be
/// presented as one (jcp SPEC §5.2). A GPU-only reading divided by the
/// tokens is not what the unit cost per token, and not a bound on it
/// either: a partial figure can be short of the work or over it. The
/// receipt seals `energy_uj` with `energy_coverage` instead, so a reader
/// still sees what was measured and how much of the work it covers.
pub fn uj_per_accepted_token(&self) -> Option<u64> {
if !self.energy.is_whole() {
return None;
}
self.energy.uj().checked_div(self.tokens_out)
}
@ -142,6 +153,13 @@ impl Efficiency {
jcr1::cose_sign1_envelope(&core, steward_sk, steward)
}
/// The payload [`Self::seal`] signs, as JSON: what a verifier reads back
/// with [`read_payload`] once the signature holds. Published conformance
/// vectors are built from it.
pub fn payload(&self, seq: u64, prev: &ContentId, steward: &str) -> Value {
self.wire(seq, prev, steward)
}
fn wire(&self, seq: u64, prev: &ContentId, steward: &str) -> Value {
// JCR-1: integers + strings only. `completed` is 0/1, energy is integer µJ,
// and the rate figures (tokens/sec, joules-in-J) are recomputed on read.
@ -166,6 +184,13 @@ impl Efficiency {
if let Some(uj) = self.uj_per_accepted_token() {
o["uj_per_accepted_token"] = json!(uj);
}
// Carried only when `Partial` (jcp SPEC §5.2), so a receipt sealed
// before the field existed, and every whole one, keeps its bytes. It
// dropped out of the receipt entirely: a GPU-only figure sealed as
// `HwShunt` reached a verifier as a whole-task total.
if !self.energy.is_whole() {
o["energy_coverage"] = json!(self.energy.coverage.label());
}
if let Some(v) = self.value_uusd {
o["value_uusd"] = json!(v);
if let Some(per) = self.uusd_per_accepted_token() {
@ -260,8 +285,12 @@ pub struct EfficiencyReceipt {
pub tokens_out: u64,
/// Total energy, microjoules.
pub energy_uj: u64,
/// Energy provenance label.
/// Energy provenance label: `HwShunt`, `ModelBased` or `Estimator`.
pub provenance: String,
/// How much of the unit the energy figure covers. `Partial` when the
/// receipt carries `energy_coverage`; such a receipt seals no
/// `uj_per_accepted_token`, and is not a task total.
pub energy_coverage: Coverage,
/// Wall-clock nanoseconds.
pub wall_ns: u64,
/// Microjoules per accepted token (headline). `None` when the receipt sealed
@ -294,11 +323,34 @@ impl EfficiencyReceipt {
}
/// Verify a sealed `efficiency/1` receipt against the steward key and recover its
/// fields. A flipped byte anywhere fails the signature.
/// fields ([`read_payload`]). A flipped byte anywhere fails the signature.
pub fn verify(envelope: &[u8], steward: &str, pubkey: &[u8; 32]) -> Result<EfficiencyReceipt, EfficiencyError> {
let payload = jcr1::verify_cose_sign1(envelope, steward, pubkey)?;
let v: Value =
jcp_schema::from_canonical_cbor(&payload).map_err(|e| EfficiencyError::Schema(e.to_string()))?;
read_payload(&v)
}
/// The provenance a sealed label names, and `None` for a label that is not one.
fn provenance_of(label: &str) -> Option<Provenance> {
[Provenance::HwShunt, Provenance::ModelBased, Provenance::Estimator]
.into_iter()
.find(|p| p.jcr1_label() == label)
}
/// Read an `efficiency/1` payload, the signed core [`verify`] recovers once the
/// signature holds, and refuse one that is not a well-formed receipt. It is
/// apart from [`verify`] so that the payload's rules can be replayed from
/// published vectors with no signature in them
/// (`jcp/conformance/v1/efficiency.json`). Beyond the required fields:
///
/// - `provenance` MUST be one of the three labels;
/// - `energy_coverage`, when present, MUST be `"Partial"`. An absent field is
/// `Whole`, so `"Whole"` and every other value are refused rather than read
/// either way;
/// - a `Partial` receipt MUST NOT carry `uj_per_accepted_token`, since that
/// would present a partial figure as a task total (jcp SPEC §5.2).
pub fn read_payload(v: &Value) -> Result<EfficiencyReceipt, EfficiencyError> {
if v.get("efficiency_receipt").and_then(Value::as_str) != Some("efficiency/1") {
return Err(EfficiencyError::Malformed("not an efficiency/1 receipt".into()));
}
@ -313,6 +365,25 @@ pub fn verify(envelope: &[u8], steward: &str, pubkey: &[u8; 32]) -> Result<Effic
.and_then(Value::as_u64)
.ok_or_else(|| EfficiencyError::Malformed(format!("missing uint '{k}'")))
};
let provenance = s("provenance")?;
if provenance_of(&provenance).is_none() {
return Err(EfficiencyError::Malformed(format!("'{provenance}' is not a provenance label")));
}
let energy_coverage = match v.get("energy_coverage") {
None => Coverage::Whole,
Some(c) if c.as_str() == Some(Coverage::Partial.label()) => Coverage::Partial,
Some(c) => {
return Err(EfficiencyError::Malformed(format!(
"energy_coverage {c} is not \"Partial\", the one value it carries; an absent field is Whole"
)))
}
};
let uj_per_accepted_token = v.get("uj_per_accepted_token").and_then(Value::as_u64);
if energy_coverage == Coverage::Partial && uj_per_accepted_token.is_some() {
return Err(EfficiencyError::Malformed(
"a Partial figure presented as a task total: it carries uj_per_accepted_token".into(),
));
}
Ok(EfficiencyReceipt {
task: s("task")?,
completed: u("completed")? != 0,
@ -320,9 +391,10 @@ pub fn verify(envelope: &[u8], steward: &str, pubkey: &[u8; 32]) -> Result<Effic
tokens_in: u("tokens_in")?,
tokens_out: u("tokens_out")?,
energy_uj: u("energy_uj")?,
provenance: s("provenance")?,
provenance,
energy_coverage,
wall_ns: u("wall_ns")?,
uj_per_accepted_token: v.get("uj_per_accepted_token").and_then(Value::as_u64),
uj_per_accepted_token,
value_uusd: v.get("value_uusd").and_then(Value::as_u64),
energy_attestation: v.get("energy_attestation").and_then(Value::as_str).map(str::to_string),
seq: u("seq")?,
@ -375,6 +447,13 @@ pub struct Totals {
pub wasted_uj: u64,
/// Value delivered by completed units, micro-USD.
pub value_uusd: u64,
/// The weakest provenance among the receipts summed, `None` for none: a
/// total is never more measured than its least measured part (jcp SPEC
/// §5.3).
pub provenance_floor: Option<Provenance>,
/// `Partial` if any receipt summed was. The energy totals then do not
/// cover the work, and no per-unit energy figure is given.
pub coverage: Coverage,
}
impl Totals {
@ -393,8 +472,13 @@ impl Totals {
}
/// Total microjoules per completed unit, including waste. `None` when nothing
/// completed — see [`Self::tokens_per_completed_unit`].
/// completed — see [`Self::tokens_per_completed_unit`] — and when any
/// receipt summed was `Partial`: the energy totals then do not cover the
/// work, so their ratio is not what a result cost (jcp SPEC §5.2).
pub fn uj_per_completed_unit(&self) -> Option<u64> {
if !self.coverage.is_whole() {
return None;
}
self.completed_uj
.saturating_add(self.wasted_uj)
.checked_div(self.completed_units)
@ -407,9 +491,13 @@ impl Totals {
/// so the fallback is this figure's *worst* value, not its optimum. The same
/// holds for [`Efficiency::tokens_per_sec`]. A zero that understates is not the
/// defect those `Option`s fix.
///
/// `0.0` too when any receipt summed was `Partial`, for the same reason:
/// value over an energy total that does not cover the work is not value
/// per joule of it, and this figure's fallback is its worst value.
pub fn value_per_joule(&self) -> f64 {
let total_uj = self.completed_uj.saturating_add(self.wasted_uj);
if total_uj == 0 {
if total_uj == 0 || !self.coverage.is_whole() {
0.0
} else {
// value (µUSD) per joule = value_uusd / (total_uj / 1e6)
@ -430,10 +518,19 @@ impl Totals {
}
}
/// Aggregate verified receipts into the honest efficiency ledger.
/// Aggregate verified receipts into the honest efficiency ledger. The energy
/// totals carry the floor of what they sum: the weakest provenance and, if any
/// receipt was `Partial`, `Partial` coverage. Aggregation is not a step at
/// which a grade improves (jcp SPEC §5.3), and a sum of partial figures is no
/// more a task total than one of them is.
pub fn aggregate<'a>(receipts: impl IntoIterator<Item = &'a EfficiencyReceipt>) -> Totals {
let mut t = Totals::default();
for r in receipts {
// A label [`read_payload`] would refuse counts as the weakest: a
// receipt built by hand is not given a grade it does not name.
let p = provenance_of(&r.provenance).unwrap_or(Provenance::Estimator);
t.provenance_floor = Some(t.provenance_floor.map_or(p, |f| trace::weakest_provenance(f, p)));
t.coverage = trace::weakest_coverage(t.coverage, r.energy_coverage);
if r.completed {
t.completed_units += 1;
t.completed_tokens = t.completed_tokens.saturating_add(r.tokens_in).saturating_add(r.tokens_out);
@ -470,6 +567,85 @@ mod tests {
}
}
/// **A GPU-only figure is not a task total.** It used to seal as
/// `energy_uj` + `provenance: HwShunt` with no coverage, and a per-token
/// headline over it, so it reached a verifier as the whole task's energy
/// per token. Now it seals its coverage, and no headline.
#[test]
fn a_partial_figure_seals_its_coverage_and_no_task_total() {
let sk = key();
let mut e = measurement("gpu-only", true, 500, 0, None);
e.energy = Energy::measured_partial(600_000);
assert_eq!(e.uj_per_accepted_token(), None, "a partial figure gives no per-token cost of the task");
let p = e.payload(0, &ContentId([0u8; 32]), "did:example:steward");
assert_eq!(p["energy_coverage"], "Partial");
assert!(p.get("uj_per_accepted_token").is_none(), "{p}");
let env = e.seal(0, &ContentId([0u8; 32]), &sk, "did:example:steward");
let r = verify(&env, "did:example:steward", &sk.verifying_key().to_bytes()).unwrap();
assert_eq!(r.energy_coverage, Coverage::Partial);
assert_eq!((r.energy_uj, r.provenance.as_str()), (600_000, "HwShunt"), "what was measured still reads");
assert_eq!(r.uj_per_accepted_token, None);
// A whole figure carries no coverage field, so its bytes are what they
// were before the field existed, and it reads back `Whole`.
let whole = measurement("whole", true, 500, 1_000_000, None);
let p = whole.payload(0, &ContentId([0u8; 32]), "did:example:steward");
assert!(p.get("energy_coverage").is_none(), "{p}");
assert_eq!(read_payload(&p).unwrap().energy_coverage, Coverage::Whole);
}
/// A reader refuses a partial figure presented as a task total, a coverage
/// other than `"Partial"` (absent is `Whole`), and a provenance label that
/// is not one of the three.
#[test]
fn a_reader_refuses_what_a_conformant_receipt_never_carries() {
let mut e = measurement("gpu-only", true, 500, 0, None);
e.energy = Energy::measured_partial(600_000);
let base = e.payload(0, &ContentId([0u8; 32]), "did:example:steward");
let refused = |edit: &dyn Fn(&mut Value), because: &str| {
let mut p = base.clone();
edit(&mut p);
let err = read_payload(&p).expect_err(because).to_string();
assert!(err.contains(because), "{err}");
};
refused(&|p| p["uj_per_accepted_token"] = json!(1_200), "presented as a task total");
refused(&|p| p["energy_coverage"] = json!("Whole"), "energy_coverage");
refused(&|p| p["energy_coverage"] = json!("partial"), "energy_coverage");
refused(&|p| p["provenance"] = json!("Measured"), "not a provenance label");
}
/// A total is never more measured, nor more complete, than what it sums
/// (jcp SPEC §5.3): one estimated receipt makes it estimated, and one
/// partial receipt makes it partial, with no per-unit energy figure.
#[test]
fn aggregation_takes_the_floor_of_provenance_and_coverage() {
let sk = key();
let pk = sk.verifying_key().to_bytes();
let mut log = EfficiencyLog::new(sk, "did:example:steward");
let mut hw = measurement("a", true, 100, 0, Some(1_000_000));
hw.energy = Energy::measured(500_000);
let mut gpu = measurement("b", true, 100, 0, Some(1_000_000));
gpu.energy = Energy::measured_partial(300_000);
let mut est = measurement("c", false, 100, 0, None);
est.energy = Energy::estimator(200_000);
log.append(&hw);
let whole_only = aggregate(&verify_chain(log.receipts(), "did:example:steward", &pk).unwrap());
assert_eq!((whole_only.coverage, whole_only.provenance_floor), (Coverage::Whole, Some(Provenance::HwShunt)));
assert_eq!(whole_only.uj_per_completed_unit(), Some(500_000));
log.append(&est);
log.append(&gpu);
let t = aggregate(&verify_chain(log.receipts(), "did:example:steward", &pk).unwrap());
assert_eq!(t.provenance_floor, Some(Provenance::Estimator), "one estimate makes the total estimated");
assert_eq!(t.coverage, Coverage::Partial, "one partial figure makes the total partial");
assert_eq!(t.uj_per_completed_unit(), None, "a partial total is no cost per result");
assert_eq!(t.value_per_joule(), 0.0, "nor value per joule of the work");
assert_eq!(t.completed_uj, 800_000, "what was measured is still summed");
assert_eq!(t.tokens_per_completed_unit(), Some(750), "token figures do not depend on the energy");
assert_eq!(aggregate(&[]).provenance_floor, None, "an empty ledger names no grade");
}
#[test]
fn the_four_metrics_compute_from_the_inputs() {
let e = measurement("t", true, 500, 1_000_000, Some(2_000_000));

View file

@ -258,7 +258,7 @@ impl OutcomeTrace {
///
/// A composite is never more measured than its least-measured part. Averaging
/// would let one hardware reading launder a pile of estimates.
fn weakest_provenance(a: Provenance, b: Provenance) -> Provenance {
pub(crate) fn weakest_provenance(a: Provenance, b: Provenance) -> Provenance {
fn rank(p: Provenance) -> u8 {
match p {
Provenance::HwShunt => 2,
@ -275,7 +275,7 @@ fn weakest_provenance(a: Provenance, b: Provenance) -> Provenance {
/// `Partial` if either is partial. An unaccounted share does not become
/// accounted for by being summed with accounted ones.
fn weakest_coverage(a: Coverage, b: Coverage) -> Coverage {
pub(crate) fn weakest_coverage(a: Coverage, b: Coverage) -> Coverage {
match (a, b) {
(Coverage::Whole, Coverage::Whole) => Coverage::Whole,
_ => Coverage::Partial,

View file

@ -0,0 +1,85 @@
//! Replay the published `efficiency/1` payload pack from disk.
//!
//! jcp SPEC §5.2-5.3 states the rules and `gen_efficiency_vectors` emits the
//! vectors. This reads those bytes back, the same bytes a third party would,
//! and checks the reference reader reproduces every recorded verdict. The
//! refusals are the half that matters: a reader that accepts a partial figure
//! presented as a task total has failed in the direction that flatters.
use jcp_efficiency::{aggregate, read_payload};
use serde_json::{json, Value};
fn pack() -> Value {
let p = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../../../conformance/v1/efficiency.json");
// Assert, not skip: a `return` here would pass green in the one case this
// exists to catch, the pack going missing.
assert!(p.exists(), "conformance pack missing at {} — it is what this test replays", p.display());
let bytes = std::fs::read(&p).unwrap_or_else(|e| panic!("read {}: {e}", p.display()));
serde_json::from_slice(&bytes).expect("pack parses")
}
#[test]
fn the_pack_declares_its_profile_and_spec() {
let v = pack();
assert_eq!(v["profile"], "efficiency/1");
assert!(v["spec"].as_str().unwrap().contains("5.2"));
}
#[test]
fn every_positive_payload_reads_as_recorded() {
let v = pack();
let cases = v["payload"]["positive"].as_array().expect("positives");
assert!(cases.len() >= 2, "expected the published positive cases");
for c in cases {
let note = c["note"].as_str().unwrap_or("?");
let r = read_payload(&c["input"]).unwrap_or_else(|e| panic!("{note}: must read: {e}"));
let got = json!({
"energy_uj": r.energy_uj,
"provenance": r.provenance,
"energy_coverage": r.energy_coverage.label(),
"uj_per_accepted_token": r.uj_per_accepted_token,
});
assert_eq!(got, c["expected"], "{note}");
}
}
#[test]
fn every_negative_payload_is_refused_for_its_recorded_reason() {
let v = pack();
let cases = v["payload"]["negative"].as_array().expect("negatives");
assert!(cases.len() >= 3, "expected the published refusals");
for c in cases {
let note = c["note"].as_str().unwrap_or("?");
let because = c["expected"]["refused"].as_str().expect("a refusal reason");
match read_payload(&c["input"]) {
Ok(r) => panic!("{note}: accepted, as {r:?}"),
Err(e) => assert!(e.to_string().contains(because), "{note}: refused for '{e}', not '{because}'"),
}
}
}
#[test]
fn every_aggregate_sums_to_its_recorded_totals() {
let v = pack();
let cases = v["aggregate"]["cases"].as_array().expect("aggregate cases");
assert!(cases.len() >= 2);
for c in cases {
let note = c["note"].as_str().unwrap_or("?");
let rs: Vec<_> = c["input"]
.as_array()
.expect("payloads")
.iter()
.map(|p| read_payload(p).unwrap_or_else(|e| panic!("{note}: {e}")))
.collect();
let t = aggregate(&rs);
let got = json!({
"completed_uj": t.completed_uj,
"wasted_uj": t.wasted_uj,
"coverage": t.coverage.label(),
"provenance_floor": t.provenance_floor.map(|p| p.jcr1_label()),
"uj_per_completed_unit": t.uj_per_completed_unit(),
"tokens_per_completed_unit": t.tokens_per_completed_unit(),
});
assert_eq!(got, c["expected"], "{note}");
}
}