All checks were successful
wai-quantum WebGPU member / does this change touch it (pull_request) Successful in 6s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 14s
jouleclaw public surface must stay documented / Public-surface audit (jouleclaw-rs) (pull_request) Successful in 49s
standards workspaces build + test / mesh-rs (mesh/mesh-rs, -p mesh-engine-gguf -p mesh-openai --features mesh-engine-gguf/gguf,mesh-openai/server, mesh-rs, linux-arm64) (pull_request) Successful in 54s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 1m13s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 1m49s
standards workspaces build + test / jouleclaw-rs (-nodebug, jouleclaw/jouleclaw-rs, -p jouleclaw-energy --features rapl,nvml, jouleclaw-rs, linux-arm64, -C target-feature=+fp16) (pull_request) Successful in 2m56s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m30s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness (pull_request) Successful in 3m24s
energy meters on real hardware / sink decode table · per-task energy and the GPU rail on macOS (pull_request) Successful in 2m16s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 2m46s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 1m42s
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Successful in 7m42s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 3m52s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 6m56s
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Successful in 11m48s
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 35s
energy meters on real hardware / sink decode table · RAPL on jetson-hub (NVML surveyed) (pull_request) Successful in 2m23s
wai-quantum WebGPU member / member · GPU, Vulkan (thor) (pull_request) Successful in 24m54s
wai-quantum WebGPU member / member · GPU, Vulkan (jetson-hub) (pull_request) Successful in 17m32s
A counter declares the smallest window over which its readings are not noise (min_window_ns: about 10 ms for RAPL and IOReport, 100 ms for NVML; 2 s for a Mac's SMC power integral). Across a shorter span its delta is whatever its updates and quantization gave, often zero or a whole update period, yet mesh graded it at the counter's grade: a few-millisecond request could be sealed HwShunt at 0 µJ, or ModelBased at a power reading's extrapolation. - SPEC 3.3: a span shorter than the minimum window of the counter that would grade it MUST NOT be graded HwShunt or ModelBased from that counter; it is an estimate of the request, and SHOULD be billed by an estimator that resolves the span's own length, so a short request is never billed zero. - HwMeter opens its own window (Meter::open_span), which Session uses: it times the span, and one shorter than the backend's floor (HwMeter::min_window) is billed this crate's EstimatorMeter over the span's own length, graded Estimator with no measured_uj, as a span across a failed read is. Past the floor the counter's figure stands, graded as before. min_window is zero where the bridge already bills by its estimator. - ProcessMeter: where ProcessSpanMeter falls back to the host meter, a span shorter than the host meter's floor is billed the same way. Spans its own CPU and GPU counters metered are not the host meter's and are unaffected. - jouleclaw-energy: ProcessSpanMeter::fallback_min_window, the active fallback meter's min_window_ns, so a caller can apply the rule. Additive. Each span is timed from after its opening read to before its closing one, a little shorter than the counter's own window, so a span at the floor is judged short rather than long. Tests: under a 50 ms floor a 20 ms span is Estimator at the estimator's figure for 20 ms, and a 60 ms span keeps the counter's figure and grade (HwShunt and ModelBased); the bridge's minimum window is its counter's until a failed read, then zero; a host-meter fallback span under the host floor is an estimate, past it the host figure stands, and a span this process's own counters metered keeps its grade. Linux x86_64: mesh-meter (default, hw-meter-rapl), mesh-core (hw-meter-rapl) and mesh-conformance pass; clippy clean. macOS (M3 Ultra): mesh-meter and mesh-core with hw-meter-apple pass, including a real in-process serve sealed HwShunt; clippy clean for mesh-meter and jouleclaw-energy. Co-Authored-By: Claude Opus 5.5 <[email protected]>
817 lines
44 KiB
Markdown
817 lines
44 KiB
Markdown
# Mesh — Energy-Accounted Inference Serving & Routing
|
||
|
||
**Version:** 0.1.0-draft.1 · **Status:** Draft · **Profile:** `mesh/1`
|
||
**Specification text:** CC-BY-4.0 · **Reference code (`mesh-rs/`):** Apache-2.0
|
||
|
||
Mesh is the open standard for **serving and routing inference as a metered
|
||
transaction**. A request declares a joule ceiling and a fidelity floor; the mesh
|
||
routes it to the cheapest-sufficient model on the cheapest-sufficient backend,
|
||
serves it under an energy meter, and seals a receipt whose headline figure is
|
||
**microjoules per accepted output token** — measured at the meter, not estimated
|
||
from a price list.
|
||
|
||
Mesh is one of the [Transaction Science open standards](../README.md).
|
||
Transaction Science is the steward, not the proprietor: the wire format and the
|
||
right to fork are public.
|
||
|
||
---
|
||
|
||
## §1 Why Mesh exists
|
||
|
||
The serving shelf reports two numbers: dollars per token and tokens per second.
|
||
Neither tells an operator, an auditor, or a regulator what an inference **cost**
|
||
— in the one unit that is physical, comparable across hardware, and impossible to
|
||
inflate: the joule. Mesh makes that number first-class. Every served inference
|
||
produces a signed receipt carrying the route that was taken and *why*, the recipe
|
||
that served it, the honest provenance of the energy figure, and the joules per
|
||
accepted token.
|
||
|
||
Mesh does not replace the runtime that executes one inference, nor the substrate
|
||
that supplies the compute. It is the **front door** in front of many models and
|
||
many backends: the layer that decides where a request goes, meters what it spent,
|
||
and proves it (§9).
|
||
|
||
---
|
||
|
||
## §2 Roles and the serve lifecycle
|
||
|
||
A Mesh deployment has four roles:
|
||
|
||
- **Caller** — issues a `ServeRequest` and, optionally, presents a JCP grant it
|
||
issued to the steward, signed for that request (§2.1).
|
||
- **Router** — selects a backend (§4).
|
||
- **Engine** — a backend that serves the request (§5).
|
||
- **Steward** — the endpoint that meters the span (§5/§6) and seals the receipt
|
||
(§6). The steward identity is the COSE `kid` and signs the receipt log.
|
||
|
||
One serve proceeds in four phases, in order:
|
||
|
||
1. **Route.** The router selects the cheapest admissible backend (§4). If none is
|
||
admissible, the serve fails with the router's recorded reason. When the
|
||
request rides on a grant whose chain carries a `ModelIn` caveat (JCP §4.9),
|
||
a backend whose model the grant does not permit is inadmissible, and so is a
|
||
backend that names no model.
|
||
2. **Authorise.** If the request rides on a grant, the steward first verifies
|
||
the presentation (§2.1), then decides the grant as a JCP enforcement point,
|
||
and as the grant's holder, in JCP's two-phase metered path over its chain
|
||
(JCP §4.2, §7, §4.9). The frame it decides over names the action `infer` on
|
||
the request's content id, the request's `prompt_hash` as payload, and, as
|
||
`model`, the content address of the weights the chosen backend runs, when the
|
||
backend names one. Every check of that decision applies, on every link of
|
||
the chain: signature, attenuation, expiry, revocation, and every
|
||
cost-independent caveat. The steward MUST also refuse the serve when what the
|
||
grant has left (the least any link has left, its budget less what earlier
|
||
serves on it were debited) is below the request's joule ceiling. The
|
||
decision is recorded in the steward's journal (§2.2) before the engine runs.
|
||
A failure at any step aborts the serve before any work is done.
|
||
3. **Meter.** The steward opens an energy window, calls the engine, and closes
|
||
the window. Energy MUST be metered **around** the engine; an engine MUST NOT
|
||
self-report energy. With a grant, the steward then debits the metered joules
|
||
against it (JCP's second phase), where a cost-dependent caveat such as
|
||
`MaxCostUj` binds. The work has run, so the joules are debited even when the
|
||
debit breaches a caveat, and the breach is recorded on the receipt
|
||
(`grant_breach`, §6.1). An engine that names its weights before serving MUST
|
||
report the same weights after; the steward MUST NOT seal a serve whose
|
||
engine reports others, since they are not the weights the grant was decided
|
||
over.
|
||
4. **Seal.** The steward builds the receipt (§6), stamps it into its hash-chained
|
||
log, and seals it as a JCR-1 envelope.
|
||
|
||
### §2.1 Presenting a grant
|
||
|
||
A grant is a signed public object, so holding one MUST NOT be enough to spend
|
||
it. A caller presents a grant as:
|
||
|
||
```
|
||
Presentation {
|
||
chain: [signed-grant…] ; root first, leaf last (JCP §4.2); a chain of one for a direct grant
|
||
caller: did:key
|
||
nonce: bytes(16)
|
||
signature: bytes(64) ; Ed25519 by `caller` over canonical_cbor({request_id, grant_id, caller, nonce})
|
||
}
|
||
```
|
||
|
||
where `request_id` is the request's content id and `grant_id` the leaf's. The
|
||
steward MUST refuse a presentation whose `caller` is not the leaf's issuer, or
|
||
whose signature does not verify for the request being served. The leaf's issuer
|
||
is the party that authorised the steward to spend on its behalf, so it is the
|
||
only party that may.
|
||
|
||
The leaf's **subject is the steward**: the steward decides the chain as its
|
||
holder, under the identity of the key it seals receipts with, and MUST refuse a
|
||
grant held by another steward. One grant therefore spends at one steward. A
|
||
budget meant for several is sharded by its holder into sibling children, one
|
||
held by each steward, whose budgets sum to no more than the parent's (JCP §4.5);
|
||
each steward enforces only its own, and the total stays bounded without the
|
||
stewards coordinating.
|
||
|
||
A presentation spends once at a steward. The steward MUST refuse one it has
|
||
already spent, identified by the leaf and the nonce, so a captured presentation
|
||
cannot be replayed there. A caller that wants the same request served again
|
||
signs a new presentation with a new nonce, and that serve is debited too.
|
||
|
||
### §2.2 The decision journal
|
||
|
||
A grant's spend at a steward is state, and a steward that restarts with its
|
||
spend in memory would give every grant its budget back (JCP §4.11). A steward
|
||
that can restart MUST therefore keep a durable journal of its grant decisions:
|
||
|
||
- An `Authorised` entry, holding the presentation, the request, the model, the
|
||
backend and the decision time, MUST be written **before** the engine runs. A
|
||
serve whose authorisation cannot be recorded is refused.
|
||
- A `Debited` entry, holding the metered energy, is written after the debit.
|
||
- A `Sealed` entry, holding a receipt's sequence and its envelope's content id,
|
||
MUST be written for **every** receipt, granted or not, **before** the receipt
|
||
is handed out. A receipt that cannot be recorded is not handed out, and the
|
||
receipt chain does not advance past it.
|
||
|
||
Each entry is a record of one chain: `{seq, prev, entry}`, where `seq` counts
|
||
records from 0 and `prev` is the BLAKE3 hash of the previous record's encoding.
|
||
|
||
On restart the steward MUST re-establish the spend before serving by replaying
|
||
the journal through the gate: each authorisation is verified and decided again,
|
||
at its recorded time, and each debit applied to the serve it belongs to. Records
|
||
that do not form one chain, a replay the gate refuses, a debit with no
|
||
authorisation, a presentation spent twice, or a receipt out of sequence means the
|
||
journal is not one the steward produced, and the steward MUST NOT serve from it.
|
||
Replayed presentations count as spent, and the receipt chain continues from the
|
||
last `Sealed` entry (§6.3).
|
||
|
||
**One steward per journal.** A steward MUST take exclusive access to the
|
||
journal when it opens it, and MUST fail to start rather than serve where
|
||
another holds it — or where the platform cannot provide exclusivity at all.
|
||
|
||
The chain above **detects** a second writer; it does not prevent one. Two
|
||
stewards sharing a journal each replay it, each re-establish the same spend and
|
||
each serve against it, so the grant is overspent *while both are running*.
|
||
Their records then collide on `seq`, the chain no longer forms, and the rule
|
||
above requires the steward not to serve from the journal at all — so the
|
||
detection arrives after the overspend and costs the steward its ability to
|
||
restart. An exclusive claim the operating system releases when the holding
|
||
process dies is preferable to one the steward must clean up, because a crash
|
||
then leaves nothing to recover.
|
||
|
||
An authorisation with no debit is a serve that was in flight when the steward
|
||
stopped, and whether the engine finished is not knowable from the journal. The
|
||
steward MUST NOT retry it or report it as completed or failed. It stays debited,
|
||
at its request's joule ceiling, which is what its authorisation admitted, and is
|
||
surfaced as unresolved, naming the caller and the backend that held it, for an
|
||
operator to settle.
|
||
|
||
**A cut journal.** Because the records form one chain, a record removed from the
|
||
middle, edited or moved fails the replay. Records cut from the **end** leave a
|
||
chain that is whole, and nothing on the steward's own storage can show they
|
||
existed; but every receipt the steward handed out was recorded first, so the
|
||
receipts in callers' hands can. Any party may show the steward a receipt it
|
||
sealed, with its envelope. If the steward's journal does not hold that receipt,
|
||
records were cut after it left, the spend the steward replayed is less than it
|
||
signed for, and the steward MUST refuse every grant from then on, until an
|
||
operator restores the journal. A caller SHOULD show its latest receipt from a
|
||
steward after the steward restarts. A cut that removes only a serve that
|
||
produced no receipt, one that was in flight, leaves no evidence outside the
|
||
steward.
|
||
|
||
The reference journal is an append-only file of one JSON record per line, each
|
||
synced before the append returns. A final line with no newline is an append cut
|
||
short and is dropped: an authorisation never recorded never started its serve, a
|
||
debit never recorded leaves its serve unresolved, and a seal never recorded was
|
||
never handed out.
|
||
|
||
|
||
### §2.3 Grants over the OpenAI-compatible binding (informative)
|
||
|
||
The reference binding (`mesh-openai`) serves `/v1/chat/completions` and
|
||
`/v1/responses`. A request rides on a grant by carrying its presentation (§2.1)
|
||
in the body field `jcp_presentation`. The presentation is signed for a request
|
||
id, so a caller must be able to compute the request a body is served as: a
|
||
granted request is served as exactly what the binding derives from the body
|
||
alone, with the prompt-token figure left as the body's estimate rather than
|
||
replaced by the server's tokenizer count, and it MUST name its own
|
||
`metadata.joule_ceiling_uj`, since a server default would otherwise enter the id
|
||
unseen. The binding exports that derivation as `granted_serve_request`.
|
||
|
||
`GET /v1/mesh/steward` returns the steward's `did:key`, the subject a grant must
|
||
name. `POST /v1/mesh/witness`, with a body of the `receipt` and `envelope_hex`
|
||
a response's `usage.energy` carried, answers 200 when the journal holds that
|
||
receipt and 409 when it does not, after which grants are refused (§2.2). A
|
||
refused grant answers 401 when the caller is not its issuer, 403 when the
|
||
steward refuses the grant, and 503 once the steward has stopped honouring grants.
|
||
|
||
---
|
||
|
||
## §3 The request and the energy record
|
||
|
||
### §3.1 `ServeRequest`
|
||
|
||
A request is content-addressed. Its identity `request_id = ContentId.of(request)`
|
||
is the resource a JCP capability authorises and the `request_id` on the receipt.
|
||
|
||
| Field | Type | Meaning |
|
||
|---|---|---|
|
||
| `prompt_hash` | ContentId (BLAKE3) | content address of the prompt bytes — never the prompt text |
|
||
| `prompt_tokens` | u32 | declared input token count (for the estimate) |
|
||
| `max_tokens` | u32 | output token ceiling |
|
||
| `fidelity_floor` | Fidelity | minimum acceptable fidelity (§3.2) |
|
||
| `joule_ceiling_uj` | u64 | hard energy budget, microjoules |
|
||
|
||
A conforming request MUST carry both a `fidelity_floor` and a `joule_ceiling_uj`.
|
||
The pair is the contract: *give me an answer at least this good, for at most this
|
||
much energy.*
|
||
|
||
A request MAY additionally carry a `decision` (§3.6), which says it is asking for
|
||
a bounded typed decision rather than generated text. Its absence is a generation,
|
||
and is omitted from the canonical form — so the `request_id` of every request
|
||
written before this field existed is unchanged.
|
||
|
||
### §3.2 Fidelity
|
||
|
||
Fidelity is an ordered scale `F0 … F4` — `F0` the coarsest sufficient answer
|
||
(cache / lawful / tiny model), `F4` a frontier-grade response. Ordering is
|
||
normative: a backend is admissible only when its level ≥ the request's floor
|
||
(§4).
|
||
|
||
#### §3.2.1 Advertised and delivered
|
||
|
||
A Mesh request carries two bounds, and until this revision only one of them was
|
||
held to a standard of honesty. Energy has a provenance model whose coupling MUST
|
||
be enforced before sealing (§3.3) — the rule that keeps "measured" from meaning
|
||
"estimated". Fidelity had none: a backend's level is an **advertisement**, read
|
||
out of the route table *before* the engine runs, and `fidelity_met` was derived
|
||
from it and never reconciled with what came back. A backend admitted at `F3`
|
||
that degraded at serve time still sealed `fidelity_met: 1` against an `F3`
|
||
floor.
|
||
|
||
Fidelity therefore has two figures, and they are different claims:
|
||
|
||
| figure | who says it | when |
|
||
|---|---|---|
|
||
| **advertised** — `ServingEngine::fidelity` | the route table | before the work; the basis the router admits on (§4) |
|
||
| **delivered** — `ServeOutcome.delivered_fidelity` | the backend that served | after the work |
|
||
|
||
The coupling is normative:
|
||
|
||
- Where the backend reports a delivered level, `fidelity_met` **MUST** be
|
||
derived from it, not from the advertisement.
|
||
- A backend **MUST NOT** report a delivered level **above** its advertised
|
||
rating. The router admitted it on the rating; it cannot raise that basis after
|
||
the fact. An implementation **MUST** refuse such a serve rather than clamp the
|
||
figure — clamping hides a misconfigured or dishonest engine behind a receipt
|
||
that looks ordinary.
|
||
- Where the backend reports nothing, `fidelity_met` rests on the advertisement.
|
||
This is the older and weaker basis and is retained, because an engine that
|
||
cannot report what it served is still conformant. A consumer that requires the
|
||
stronger basis **MUST** check for `fidelity_delivered` rather than reading
|
||
`fidelity_met` alone.
|
||
- The receipt **MUST** carry `fidelity_advertised` and `fidelity_delivered`
|
||
together or carry neither. Their purpose is the comparison; the advertisement
|
||
alone adds nothing a verifier does not already have from `backend`. Carrying
|
||
neither is what a receipt sealed before these fields existed means, so such a
|
||
receipt is unchanged and `mesh/1` stays byte-stable.
|
||
|
||
**What this does not claim.** A delivered figure is the account of the party that
|
||
did the work. It is better grounded than a table entry written before the work,
|
||
and it is not an independent assessment of the output — Mesh does not score
|
||
responses. What the pair buys is that a divergence between promise and delivery
|
||
is *visible in the receipt* and attributable to a named backend, where before it
|
||
was invisible.
|
||
|
||
### §3.3 Energy and provenance
|
||
|
||
Energy is a two-part integer-microjoule record with an honest provenance tag:
|
||
|
||
```
|
||
Energy { measured_uj: Option<u64>, estimated_uj: u64, provenance: Provenance }
|
||
Provenance ∈ { HwShunt, ModelBased, Estimator }
|
||
```
|
||
|
||
The coupling is normative and MUST be enforced before a receipt is sealed:
|
||
|
||
- `HwShunt` ⇒ `measured_uj` is present (a hardware reading exists).
|
||
- `Estimator` ⇒ `measured_uj` is absent (no measurement is implied).
|
||
- `ModelBased` ⇒ `measured_uj` MAY be absent.
|
||
|
||
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`
|
||
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
|
||
IOReport), but a counter counts only while it is live:
|
||
|
||
> A reading from a vendor energy counter (RAPL, NVML, Apple IOReport, …) MAY be
|
||
> graded as a hardware reading only while the counter is demonstrably live for
|
||
> the domain the figure claims: the implementation MUST have observed the
|
||
> counter covering that domain advance under load (for Apple IOReport: the CPU
|
||
> energy rail itself advancing in at least 5 sample intervals, in at least 4 of
|
||
> every 5, over at least 300 ms while the probing thread burns CPU). A counter
|
||
> that is present but not live — frozen, or republished in lumps — MUST NOT
|
||
> produce a hardware-graded figure; the implementation falls back to its
|
||
> estimator or reports the work unmetered, and SHOULD record why. A figure MUST
|
||
> NOT claim coverage of a domain its counter does not read; where the format
|
||
> has a coverage field, such a figure is Partial.
|
||
|
||
`mesh/1` has no coverage field. So a figure from a counter that does not cover
|
||
the whole request, such as a GPU counter on a host whose CPU has none, MUST NOT
|
||
be graded `HwShunt`.
|
||
|
||
**A span shorter than its counter's minimum window.** A counter declares the
|
||
smallest window over which its readings are not noise (JouleClaw's
|
||
`min_window_ns`: about 10 ms for RAPL and IOReport, 100 ms for NVML). Across a
|
||
shorter span its delta is whatever the counter's update and quantization gave
|
||
— often zero, or a whole update period — not the span's energy. A span shorter
|
||
than the minimum window of the counter that would grade it MUST NOT be graded
|
||
`HwShunt` or `ModelBased` from that counter: it is an estimate of the request,
|
||
`Estimator`, and SHOULD be billed by an estimator that resolves the span's own
|
||
length, so that a short request is never billed zero.
|
||
|
||
### §3.6 Typed decisions — the other unit of work
|
||
|
||
A **decision model** takes state plus typed questions and returns a calibrated
|
||
probability per allowed answer, generating no text. The category converged
|
||
through 2026 on three primitives — a proposition (`noul`), a choice over 1–255
|
||
named options, and a score over an ordered rubric — and backends score the
|
||
schema **non-autoregressively** rather than emitting tokens.
|
||
|
||
Everything else in this spec measures work in tokens, and a decision's output
|
||
token count is zero. Measured on a 421M decision model: `output_tokens: 0`, with
|
||
132 input tokens of which **121 were the question schema and 11 the state under
|
||
judgement**. Three consequences follow, and a conforming implementation MUST
|
||
handle each.
|
||
|
||
A request asking for a decision carries:
|
||
|
||
| Field | Type | Meaning |
|
||
|---|---|---|
|
||
| `questions` | u32 | typed questions in the request |
|
||
| `options_scored` | u32 | options scored across all of them |
|
||
| `schema_tokens` | u32 | how many of `prompt_tokens` are schema, not state |
|
||
|
||
1. **It MUST NOT be priced for tokens it cannot emit.** The estimate for a
|
||
decision MUST exclude `max_tokens`. Including it refuses work at a ceiling
|
||
that would in fact have covered it.
|
||
2. **Cost MUST be allowed to follow the schema.** A profile MAY declare a cost
|
||
per scored option; one question over 20 options is more work than one over 2
|
||
at identical token counts, and no token count expresses the difference.
|
||
Declaring nothing reproduces the token-only model exactly, so an unmeasured
|
||
profile claims nothing.
|
||
3. **The efficiency figure MUST be defined.** `uj_per_accepted_token` (§6) is
|
||
undefined when no tokens were accepted, which is every request in this
|
||
category. A decision receipt MUST instead carry `uj_per_decision`, and
|
||
SHOULD carry `uj_per_option_scored`. The unit of work is the answered
|
||
question.
|
||
|
||
`schema_tokens` is reported because a fixed schema is a **cacheable input
|
||
prefix** — distinct from `cache_hit_tokens`, which counts output tokens served
|
||
from cache, of which a decision has none. In the measured request 92% of the
|
||
input was schema, so a reader that cannot see the split cannot tell a cold
|
||
decision from a warm one.
|
||
|
||
> **Why a decision receipt is worth more than a generation receipt.** A decision
|
||
> is a single forward pass with no sampling. Given the weight digest, revision
|
||
> and numeric precision, it is reproducible — so a receipt over one is verifiable
|
||
> **by re-execution**, which a receipt over sampled text can never be. A receipt
|
||
> for a decision SHOULD therefore bind the weight digest and the precision; the
|
||
> probabilities of a published decision model differ between `fp16` and `fp32`
|
||
> even where the selected answer agrees, so a receipt that omits precision does
|
||
> not reproduce.
|
||
>
|
||
> The fields are `weights_digest` and `precision` (§6.1), both OPTIONAL. A
|
||
> backend that can address its weights **SHOULD** report both; one that cannot
|
||
> omits them, and the receipt then binds the model by `recipe` alone — a name,
|
||
> which an operator can re-point at other weights while every receipt sealed
|
||
> under it goes on verifying. That is the weaker basis, and the absence of the
|
||
> fields is how a verifier can tell it apart from the stronger one, rather than
|
||
> having to assume.
|
||
|
||
A backend that loads its weights from files addresses them as BLAKE3 over the
|
||
canonical encoding of the list of files its forward pass reads, in path order,
|
||
each as its path relative to the model directory and the BLAKE3 of its bytes.
|
||
Every byte is hashed, once, when the backend loads: a digest over a sample, a
|
||
header or a size would look like a binding while leaving the weights free to
|
||
change beneath it, and is worse than none. The file names are part of the
|
||
address because they are part of what loads, and files that do not reach the
|
||
forward pass, such as a tokenizer, are not. The reference engines address
|
||
`config.json` with `model.safetensors`, or with `model.safetensors.index.json`
|
||
and every shard it names; Gemma reports `fp32`, the arithmetic its loader
|
||
widens to, and Falcon-H1 `bf16`. A backend that names its weights before
|
||
serving MUST report the same digest after (§2).
|
||
|
||
|
||
### §3.7 Where a decision model came from
|
||
|
||
§3.6 makes a decision receipt verifiable **by re-execution**: given the weight
|
||
digest and the precision, a verifier runs the forward pass again and gets the
|
||
same probabilities. That settles one question — did this answer come from these
|
||
weights — and is silent on a different one. A decision model is ordinarily
|
||
fitted to a corpus of earlier decisions, and that corpus is its **disposition**:
|
||
it decides which answer the probabilities favour before any request arrives. A
|
||
receipt binding the weights and not the corpus can prove the answer reproduces
|
||
while leaving unanswerable what taught it to answer that way.
|
||
|
||
Two OPTIONAL fields, paired as `weights_digest` and `precision` are, because
|
||
neither carries the claim alone:
|
||
|
||
| Field | Type | Meaning |
|
||
|---|---|---|
|
||
| `training_digest` | bstr | content address of the corpus the weights were fitted to |
|
||
| `training_authority` | tstr | what a verifier can do with that corpus — `signed`, `logged` or `opaque` |
|
||
|
||
`training_digest` is BLAKE3 over the canonical encoding of the corpus records in
|
||
the order the fit consumed them, each record as its content id. The order is part
|
||
of the address because it is part of what the fit consumed; a digest over an
|
||
unordered set would look like a binding while leaving the curriculum free to
|
||
change beneath it.
|
||
|
||
`training_authority` states the strength of that binding, and only three values
|
||
say anything a verifier can act on:
|
||
|
||
- `signed` — every record carries a signature over its own content by the
|
||
principal that produced it, so a third party can check the corpus **without
|
||
trusting whoever trained on it**. A corpus drawn from the accepted transitions
|
||
of a signed op-log is this case.
|
||
- `logged` — the records sit in an append-only log whose head is attested, so
|
||
removal and reordering are detectable, but individual records are not
|
||
attributable to a principal.
|
||
- `opaque` — bytes with a digest and nothing more. The digest still detects
|
||
substitution of the whole corpus; it establishes nothing about the records in
|
||
it.
|
||
|
||
A backend that cannot address its corpus omits both fields, and the receipt then
|
||
binds the disposition to nothing. As with `weights_digest`, **the absence is the
|
||
signal**: a verifier distinguishes an unattributable model from an attributable
|
||
one instead of assuming, which is the only reason these are optional rather than
|
||
required.
|
||
|
||
> **What this does not license.** A decision model is usually introduced because
|
||
> it is cheaper than the generation it displaces, and a receipt **MUST NOT**
|
||
> state that saving. The joules that generation would have cost were never
|
||
> metered, because it was never run. `uj_per_decision` (§6.2) is a measured
|
||
> figure; a difference against an unrun alternative is not, and a receipt that
|
||
> carried one would be asserting an estimate in a field a reader is entitled to
|
||
> read as measurement. An operator who wants the comparison runs both and keeps
|
||
> both receipts, and the difference then lives where it belongs — between two
|
||
> sealed figures, rather than inside one of them as a claim about the other.
|
||
|
||
---
|
||
|
||
## §4 Routing — cheapest-sufficient
|
||
|
||
For each registered backend the router computes an estimate
|
||
`est_total_uj = uj_per_token × (prompt_tokens + max_tokens)`, or for a typed
|
||
decision (§3.6) `uj_per_token × prompt_tokens + uj_per_option_scored ×
|
||
options_scored`, and marks it **admissible** iff:
|
||
|
||
```
|
||
backend.fidelity ≥ request.fidelity_floor AND est_total_uj ≤ request.joule_ceiling_uj
|
||
```
|
||
|
||
The router MUST choose the admissible backend with the **lowest** `est_total_uj`.
|
||
Ties are broken deterministically (registration order). When no backend is
|
||
admissible the serve fails, and the decision records why.
|
||
|
||
The router MUST record, for every backend it weighed, a `RouteCandidate` with its
|
||
fidelity, estimate, admissibility, and — when inadmissible — a human-readable
|
||
reason (below floor / over ceiling). The chosen route MUST carry a one-line
|
||
justification. This is what makes a route **auditable from the receipt alone**:
|
||
the cheapest sufficient answer is preferred and a frontier model is the expensive
|
||
last resort, and the comparison is denominated in joules.
|
||
|
||
A model is addressed as a **recipe** — a base plus optional merges/adapters — not
|
||
a fixed blob, so the receipt can record *which* composed model answered.
|
||
|
||
---
|
||
|
||
## §5 The serving engine
|
||
|
||
A backend implements one interface: advertise a fidelity level and a modeled
|
||
per-token energy cost, and serve a request producing tokens and a `ServeOutcome`:
|
||
|
||
```
|
||
ServeOutcome {
|
||
tokens_in, tokens_out, tokens_accepted,
|
||
cache_hit_tokens, spec_proposed, spec_accepted,
|
||
delivered_fidelity: Option<Fidelity> // §3.2.1
|
||
}
|
||
```
|
||
|
||
The advertised level is a promise made before the work; `delivered_fidelity` is
|
||
what the backend says it actually served. An engine that cannot degrade may
|
||
report its rating; an engine that can — a fallback, a truncation, a timeout that
|
||
drops to a cheaper path — reports what it served. Omitting it is conformant and
|
||
means `fidelity_met` rests on the advertisement (§3.2.1).
|
||
|
||
The input token payload travels **with** the serve call, alongside the request —
|
||
it is never part of the request's sealed identity and never enters the receipt
|
||
in the clear. The receipt records the content-addressed `prompt_hash` (§3.1),
|
||
and the payload's digest only inside the output commitment, under its opening
|
||
(§6.4). A receipt is therefore safe to publish without disclosing the prompt.
|
||
|
||
`tokens_accepted` is the denominator of the wedge metric. For greedy decode it
|
||
equals `tokens_out`; under speculative decoding it is the number of proposed
|
||
tokens the target model accepted. `cache_hit_tokens` records output served from a
|
||
prefix/result cache (energy saved). An engine MUST do real work proportional to
|
||
the tokens it serves so the surrounding meter reads a real span; it MUST NOT
|
||
self-report energy.
|
||
|
||
An engine declares whether it is **deterministic**: whether serving the same
|
||
request and prompt payload again yields the same tokens. Only a deterministic
|
||
engine's serve can be re-executed against its receipt (§6.4). An engine that
|
||
samples MUST NOT declare it, and the default is not to.
|
||
|
||
The reference engine (`mesh-engine::ReferenceEngine`) is deterministic and
|
||
weights-free, for conformance. Production backends — a quantized device-resident
|
||
decoder, a high-throughput batching server — implement the same interface and
|
||
drop in unchanged; `mesh-engine-gguf::GgufEngine` (behind the `gguf` feature) is
|
||
one such backend over a pure-Rust GGUF/Metal decoder, so the mesh routes and
|
||
meters real model tokens.
|
||
|
||
---
|
||
|
||
## §6 The receipt — `mesh/1`
|
||
|
||
A `MeshReceipt` is sealed with **JCR-1**: canonical det-CBOR (RFC 8949 §4.2.1)
|
||
inside a COSE_Sign1 envelope (RFC 9052, EdDSA/Ed25519, `alg = -8`), byte-compatible
|
||
with the rest of the family's receipts. The signed core forbids floats, booleans,
|
||
and nulls; booleans are encoded as `0|1` uints and absent options dropped.
|
||
|
||
### §6.1 Wire fields (`mesh/1`)
|
||
|
||
| Key | Meaning |
|
||
|---|---|
|
||
| `mesh_receipt` | `"mesh/1"` |
|
||
| `request_id` | hex content id of the request |
|
||
| `grant_id` | hex JCP grant id this inference debited (omitted if ungranted) |
|
||
| `backend`, `recipe` | the backend and composed model that served it — `recipe` is a name, read it with the two fields below |
|
||
| `weights_digest` | hex content address of the weights that answered (OPTIONAL — §3.6; absent means the receipt binds the model by name alone) |
|
||
| `precision` | the numeric precision the forward pass ran at, as the backend names it — `fp32`, `fp16`, `bf16`, `int8` (OPTIONAL — §3.6; paired with `weights_digest`, since neither reproduces alone) |
|
||
| `training_digest` | hex content address of the corpus the weights were fitted to (OPTIONAL — §3.7; absent means the receipt binds the model's disposition to nothing) |
|
||
| `training_authority` | what a verifier can do with that corpus — `signed`, `logged`, `opaque` (OPTIONAL — §3.7; paired with `training_digest`, since a digest alone says which corpus, not whether anyone can check it) |
|
||
| `route` | the router's one-line justification |
|
||
| `tokens_in/out/accepted`, `cache_hit_tokens`, `spec_proposed/accepted` | the outcome counters |
|
||
| `fidelity_floor` | the floor the request demanded (uint) |
|
||
| `fidelity_advertised` | the level the backend is rated for (uint, OPTIONAL — paired with the next) |
|
||
| `fidelity_delivered` | the level the backend says it served (uint, OPTIONAL — §3.2.1) |
|
||
| `fidelity_met` | `0|1` — was the floor met, on the delivered figure where there is one |
|
||
| `estimated_uj` | always present |
|
||
| `measured_uj` | present **iff** provenance is `HwShunt` |
|
||
| `uj_per_accepted_token` | **the wedge metric** for a generation — `energy.uj() / tokens_accepted`; omitted when no tokens were accepted |
|
||
| `questions_answered`, `options_scored`, `schema_tokens` | present **iff** the request was a typed decision (§3.6) |
|
||
| `uj_per_decision` | **the wedge metric** for a decision — `energy.uj() / questions_answered` |
|
||
| `uj_per_option_scored` | the finer decision figure — `energy.uj() / options_scored` |
|
||
| `energy_provenance` | `HwShunt | ModelBased | Estimator` |
|
||
| `grant_breach` | the JCP denial label when debiting the metered joules breached the grant, e.g. `caveat-unsatisfied` for a per-call cost caveat (OPTIONAL — §2; absent means the debit was within the grant, or the serve rode on none) |
|
||
| `output_commitment` | hex commitment to the output tokens of a generation and the prompt payload they were served on (§6.4; absent for a typed decision, whose answer the engine interface does not carry, and in receipts sealed before the field existed) |
|
||
| `sequence`, `prev` | hash-chain position and prior envelope's content id |
|
||
| `nonce`, `steward` | per-receipt nonce and the sealing identity (COSE `kid`) |
|
||
|
||
### §6.2 The wedge metric
|
||
|
||
`uj_per_accepted_token = energy.uj() / tokens_accepted`, where `energy.uj()` is
|
||
the measured figure if present, else the estimate. It is `null`/absent when no
|
||
tokens were accepted. This is the number Mesh exists to make legible, and it is
|
||
sealed into every receipt.
|
||
|
||
### §6.3 Hash chain
|
||
|
||
A steward keeps a receipt log. Appending a receipt stamps its `sequence` (from 0)
|
||
and `prev` (the content id of the previous sealed envelope; absent at genesis),
|
||
seals it, and advances the head. The log is tamper-evident end to end: altering
|
||
any envelope breaks verification of that receipt and the chain link from the next.
|
||
A steward that restarts continues its chain from its journal (§2.2): the next
|
||
receipt takes the next sequence and chains to the last envelope sealed, rather
|
||
than starting a new chain at 0, so a restart is not mistaken for a log that lost
|
||
its history.
|
||
|
||
### §6.4 The output commitment, and replay
|
||
|
||
A receipt that binds what was asked (`request_id`, which content-addresses the
|
||
prompt) and what it cost, but nothing about what came back, cannot show which
|
||
answer it was for. A generation's receipt therefore carries
|
||
`output_commitment`:
|
||
|
||
```text
|
||
payload = BLAKE3("mesh/1 prompt payload\0" ‖ prompt)
|
||
output_commitment = BLAKE3("mesh/1 output commitment\0" ‖ opening ‖ request_id ‖ payload ‖ tokens)
|
||
```
|
||
|
||
Here `prompt` is the input token payload the engine was handed (§5) and
|
||
`tokens` are the output token ids, each as little-endian `u32`s in order;
|
||
`request_id` and `payload` are their 32 bytes; and `opening` is a 32-byte
|
||
value the steward derives per request from a key it holds. In the reference
|
||
steward, the key is derived from its signing key, so a steward that restarts
|
||
can disclose any receipt's opening without having stored it.
|
||
|
||
- **It is a commitment, not a hash.** A plain hash of a short output, such as a
|
||
one-token answer, can be reversed by trying every output, and a receipt is
|
||
shown to parties who were not owed the answer. Without its opening, the
|
||
commitment reveals nothing about the tokens.
|
||
- **Disclosure.** A steward that discloses an output for one receipt discloses
|
||
that receipt's opening and `payload` with it. Anyone can then check that this
|
||
is the output the receipt sealed. The opening binds `request_id`, so it opens
|
||
no other receipt.
|
||
- **The payload is bound.** `prompt_hash` addresses the prompt's bytes, and an
|
||
engine is handed token ids. Nothing ties the two together without the
|
||
tokenizer, so `request_id` alone cannot confirm the payload a replay runs on.
|
||
The commitment binds it instead.
|
||
- **Replay.** Where the engine is deterministic (§5: its tokens are a function
|
||
of the request and the prompt payload alone), a party holding the prompt
|
||
payload and the opening can re-execute the serve and compare.
|
||
- Re-execution yields one of three verdicts: *verified* (the re-run opens the
|
||
commitment), *diverged*, or *not replayable*.
|
||
- It is *diverged* only when a disclosed output opens the commitment on the
|
||
payload the replay ran. That confirms the opening, the payload and the
|
||
output together, so the mismatch is the serve's. The verdict names the
|
||
first token at which the two outputs part.
|
||
- A replay MUST NOT report a divergence it cannot attribute to the serve. It
|
||
is *not replayable* when:
|
||
- the engine samples;
|
||
- it is not the backend and recipe the receipt names, or not the weights,
|
||
where the receipt sealed `weights_digest`;
|
||
- the request is not the receipt's;
|
||
- the receipt commits to no output;
|
||
- the re-run does not open the commitment, and no disclosed output opens it
|
||
on the replay's payload and opening. The mismatch might then be the
|
||
replayer's own input.
|
||
- A sampled generation is not expected to repeat, and re-running it settles
|
||
nothing.
|
||
|
||
These hold a serve to its record. Whether such a record carries any weight in a
|
||
given dispute is not this specification's to say. It is evidence anyone can
|
||
produce and check without the steward's help, opening apart.
|
||
|
||
### §6.5 The weights change record
|
||
|
||
A receipt's `weights_digest` (§3.6) names the weights that answered. Without a
|
||
further record, nothing shows when a backend's weights changed, from what, or
|
||
whether the change was one its steward had planned for. A backend's **change
|
||
record** is that record. It is a hash-chained sequence of entries, each sealed
|
||
as a JCR-1 envelope under the steward key that seals its receipts, with the
|
||
profile tag `mesh_change: "mesh/1"`.
|
||
|
||
Every entry carries `backend`, `recipe`, `seq` (its position, from 0), `prev`
|
||
(the content id of the envelope before it, absent for the first), `made_at`
|
||
(Unix seconds) and `kind`. Optional fields are omitted when absent. There are
|
||
two kinds:
|
||
|
||
| `kind` | Fields | Records |
|
||
|---|---|---|
|
||
| `plan` | `precisions`, `fidelity_floor`, `validation`, `foresees`, `risk_assessment`? | the changes the steward foresees for the backend, before them |
|
||
| `weights` | `from`?, `to`, `precision`?, `fidelity`, `plan`?, `validation_result`?, `effective_from`, `reason` | one change of the backend's weights |
|
||
|
||
The digests are hex content addresses. For a `weights` entry:
|
||
- `from` and `to` are the weights before and after the change; `from` is absent
|
||
for the backend's first entry of this kind.
|
||
- `plan` is the content id of the `plan` entry the change falls under, and is
|
||
absent for a change no plan foresaw.
|
||
- `effective_from` is the first sequence of the steward's receipt log (§6.3)
|
||
served on the new weights.
|
||
|
||
An entry MUST be refused when:
|
||
|
||
- it is for another backend, or does not chain: its `seq` is not the next, or
|
||
its `prev` is not the content id of the envelope before it;
|
||
- its `made_at` is earlier than the entry before it;
|
||
- it is a `weights` entry and:
|
||
- its `from` is not the `to` of the last `weights` entry before it;
|
||
- its `to` equals its `from`;
|
||
- its `effective_from` is earlier than the last change's;
|
||
- it names a `plan`, and that is not a `plan` entry earlier in the same record,
|
||
or the change is outside it. A change is outside its plan when it has:
|
||
- another `recipe`;
|
||
- a `precision` the plan's non-empty `precisions` does not list, or no
|
||
precision at all;
|
||
- a `fidelity` below the plan's `fidelity_floor`;
|
||
- no `validation_result`.
|
||
|
||
A plan therefore covers only the changes recorded after it. A change recorded
|
||
as planned was foreseen before it was made, by the record's own order. A plan
|
||
recorded later does not reach back over it. A change no plan covers is
|
||
recorded too, without a `plan`. The record shows what changed, and makes no
|
||
judgement of it.
|
||
|
||
**The gate.** Once a backend has a change record, the steward MUST serve on it
|
||
only the weights its last `weights` entry has in effect. It MUST refuse a serve
|
||
before any grant is decided or work runs where the engine names other weights,
|
||
or none. It MUST refuse to seal a serve whose engine reports other weights, or
|
||
none. A weights change takes effect only by being recorded, so every receipt
|
||
from `effective_from` on was served on the weights the change put in effect.
|
||
A steward that restarts holds a backend to the record it persisted, once every
|
||
entry verifies under its key, the record holds, and its weights in effect are
|
||
the ones the engine runs.
|
||
|
||
**Coverage.** A party holding a receipt and the record for its backend reads the
|
||
`weights` entry in effect at the receipt's `sequence`: the last one whose
|
||
`effective_from` is at or before it. The receipt is covered when that entry is
|
||
for its backend and recipe, its `to` is the receipt's `weights_digest`, and,
|
||
where both name one, its precision is the receipt's. Otherwise it is not
|
||
covered. The entry then says which change put the weights in effect, when the
|
||
steward made it, under which plan, and with which validation result. A position
|
||
in the receipt log orders a change against receipts without trusting a clock;
|
||
`made_at` is the steward's statement of the time.
|
||
|
||
---
|
||
|
||
## §7 Conformance
|
||
|
||
A conforming implementation MUST:
|
||
|
||
1. Decide a serve's grant as a JCP enforcement point and as its holder before any
|
||
work (§2): reject a presentation not signed for the request by the grant's
|
||
issuer, or already spent here (§2.1); reject a chain that fails verification,
|
||
is held by another steward, has expired or been revoked, does not permit
|
||
`infer` on the request, carries a cost-independent caveat that does not hold,
|
||
or has less left than the request's joule ceiling; debit the metered joules
|
||
against every link after the work, recording a breach on the receipt.
|
||
2. Where the steward can restart, journal each decision before its serve runs
|
||
and each receipt before it is handed out, re-establish spend and the receipt
|
||
chain from the journal before serving again, and refuse grants once shown a
|
||
receipt the journal does not hold (§2.2).
|
||
3. Choose the cheapest admissible backend and record every candidate weighed
|
||
(§4).
|
||
4. Meter energy around the engine and tag provenance honestly, enforcing the
|
||
`Energy` coupling before sealing (§3.3).
|
||
5. Seal the receipt as a JCR-1 `mesh/1` envelope and compute
|
||
`uj_per_accepted_token` (§6).
|
||
6. Maintain a tamper-evident hash chain (§6.3).
|
||
7. Where a backend has a change record, refuse its entries and its serves as
|
||
§6.5 sets out, so that its weights change only by being recorded.
|
||
|
||
The published vectors in [`../conformance/v1/`](../conformance/v1/) pin a
|
||
deterministic reference serve. `reference/signed_core.hex` MUST canonical-CBOR
|
||
encode identically across implementations, and `reference/envelope.hex` MUST be
|
||
reproducible from it with the steward key in `meta.json`. Regenerate with:
|
||
|
||
```text
|
||
cargo run -p mesh-conformance --bin gen-vectors -- ../conformance/v1
|
||
```
|
||
|
||
---
|
||
|
||
## §8 Security considerations
|
||
|
||
Mesh composes proven primitives: Ed25519 signatures, BLAKE3 content addressing,
|
||
RFC 9052 COSE_Sign1, and the JCP capability model. It introduces no new
|
||
cryptography. These properties are correctness, not style:
|
||
|
||
- **Authorisation happens outside the model.** The grant check (§2) is enforced
|
||
by the steward before any inference runs; a prompt cannot grant itself budget
|
||
or capability.
|
||
- **A grant spends only for its issuer, once per presentation, at one steward.**
|
||
A presentation is signed by the grant's issuer for one request (§2.1), so a
|
||
party that obtains a grant, or a captured presentation, cannot spend it; and
|
||
the steward is the grant's holder, so a grant cannot be spent at a steward it
|
||
was not issued to. Spreading a budget over stewards is sharding.
|
||
- **Spend survives the process.** The journal is written before the work and
|
||
replayed through the gate on restart (§2.2), so a restart gives no budget back
|
||
and a crash mid-serve leaves the serve debited and unresolved rather than
|
||
free. A journal is only as durable as the storage under it, and a steward
|
||
with an in-memory journal has no such guarantee. Records cut from its end are
|
||
invisible to the steward, but not to whoever holds a receipt it sealed after
|
||
the cut point: shown one, the steward stops honouring grants.
|
||
- **Honesty is enforced at seal time.** A receipt cannot claim a measurement it
|
||
does not have (§3.3). An operator without a hardware meter produces honest
|
||
`Estimator` receipts.
|
||
|
||
Energy figures are only as honest as the worst meter in the span. A receipt's
|
||
provenance tag states which meter produced its figure; consumers SHOULD treat
|
||
`Estimator` figures as bounds, not measurements.
|
||
|
||
---
|
||
|
||
## §9 Relationship to the family
|
||
|
||
Mesh is the serving + routing fabric. It is expressed in primitives the family
|
||
already publishes, and it composes with the neighbouring standards rather than
|
||
duplicating them:
|
||
|
||
- It **rides on [JCP](../jcp/)**: a serve request is authorised by a JCP `Grant`
|
||
(capability ⊗ joule-budget), and the receipt seals in JCR-1 — the same envelope
|
||
every family receipt uses.
|
||
- It **dispatches to runtimes** such as [JouleClaw](../jouleclaw/): a backend that
|
||
executes one inference cheaply is one engine behind the mesh.
|
||
- It **routes across compute** described by [EOC](../eoc/) and isolated by
|
||
[Sandbox](../sandbox/): a backend may be a metered, attested execution target.
|
||
|
||
The boundary is deliberate: a runtime executes *one* inference; Mesh routes
|
||
across *many* models and *many* backends and proves what each one cost.
|