mesh: say what the energy figure covers — the served span, not the request #385
3 changed files with 37 additions and 2 deletions
22
mesh/SPEC.md
22
mesh/SPEC.md
|
|
@ -294,6 +294,28 @@ A receipt that violates the coupling MUST NOT be sealable. This is the rule that
|
||||||
keeps "measured" honest: a deployment with no hardware meter reports `Estimator`
|
keeps "measured" honest: a deployment with no hardware meter reports `Estimator`
|
||||||
and says so, rather than dressing an estimate up as a measurement.
|
and says so, rather than dressing an estimate up as a measurement.
|
||||||
|
|
||||||
|
**What the figure covers, and what it does not.** The figure is the **served
|
||||||
|
span**: the meter session opens immediately before the engine runs and closes
|
||||||
|
when it returns. Routing (§2) and grant authorisation precede it and are
|
||||||
|
**not** included, and a receipt therefore understates the energy of handling the
|
||||||
|
request by whatever those steps cost.
|
||||||
|
|
||||||
|
An implementation **MUST NOT** present a mesh receipt's energy as the energy of
|
||||||
|
the request. Where a router or an authorisation path itself runs a model — a
|
||||||
|
classifier or an LLM deciding the route — that omission stops being negligible,
|
||||||
|
and the shortfall lands in the direction this family treats as unsafe:
|
||||||
|
**under-reporting is the unsafe direction at a ceiling**, because the grant is
|
||||||
|
debited the served span only and admits further work on the strength of it
|
||||||
|
(`jouleclaw/SPEC.md` §1.3; `jcp/SPEC.md` §5 — named by file, because mesh has
|
||||||
|
a §5 of its own and no §1.3). An implementation that meters a
|
||||||
|
model-running router **SHOULD** seal that span as its own field rather than
|
||||||
|
folding it into this one, so the two remain separable by a verifier.
|
||||||
|
|
||||||
|
This boundary is an ordering invariant in the serving path, not an observable
|
||||||
|
property of the receipt: the meter is snapshot-driven and routing takes no
|
||||||
|
meter samples, so no test pins it today. Putting the router behind a trait, as
|
||||||
|
the engine already is, is what would let one.
|
||||||
|
|
||||||
`HwShunt` covers a shunt and a vendor energy counter (RAPL, NVML, Apple
|
`HwShunt` covers a shunt and a vendor energy counter (RAPL, NVML, Apple
|
||||||
IOReport), but a counter counts only while it is live:
|
IOReport), but a counter counts only while it is live:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -498,7 +498,11 @@ impl<'m> Mesh<'m> {
|
||||||
.expect("a chosen route carries its fidelity");
|
.expect("a chosen route carries its fidelity");
|
||||||
let recipe = route.recipe.clone().unwrap_or_default();
|
let recipe = route.recipe.clone().unwrap_or_default();
|
||||||
|
|
||||||
// 3. Meter the served span. Copy the meter reference out so the engines
|
// 3. Meter the served span — and only that span. Routing (1) and
|
||||||
|
// authorisation (2) already ran, so their energy is outside every
|
||||||
|
// receipt this path seals; SPEC §3.3 states that limit, and says why
|
||||||
|
// it stops being negligible once a router runs a model of its own.
|
||||||
|
// Copy the meter reference out so the engines
|
||||||
// borrow and the log borrow stay disjoint from it.
|
// borrow and the log borrow stay disjoint from it.
|
||||||
let meter = self.meter;
|
let meter = self.meter;
|
||||||
let engine = self
|
let engine = self
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,16 @@ pub struct MeshReceipt {
|
||||||
/// `fidelity_delivered`: without that field it says the route table promised
|
/// `fidelity_delivered`: without that field it says the route table promised
|
||||||
/// the floor, not that the backend delivered it.
|
/// the floor, not that the backend delivered it.
|
||||||
pub fidelity_met: bool,
|
pub fidelity_met: bool,
|
||||||
/// The honest, provenance-tagged energy span.
|
/// The honest, provenance-tagged energy of the **served span** — the meter
|
||||||
|
/// session around `engine.serve`, and nothing before it.
|
||||||
|
///
|
||||||
|
/// Routing and grant authorisation run first and are **not** in this
|
||||||
|
/// figure, so it understates the energy of handling the request by
|
||||||
|
/// whatever they cost (SPEC §3.3). Negligible for a table-driven router;
|
||||||
|
/// not negligible where the router itself runs a model, and the shortfall
|
||||||
|
/// falls in the unsafe direction, because the grant is debited this figure
|
||||||
|
/// and admits further work on it. Do not present it as the request's
|
||||||
|
/// energy.
|
||||||
pub energy: Energy,
|
pub energy: Energy,
|
||||||
/// The JCP denial label when debiting the metered joules against the grant
|
/// The JCP denial label when debiting the metered joules against the grant
|
||||||
/// breached it (SPEC §2): a per-call cost caveat the measured cost
|
/// breached it (SPEC §2): a per-call cost caveat the measured cost
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue