open-standards/mesh
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 660ab68a04 jouleclaw-energy: a live counter of this process's own CPU energy, kept out of detect_meter
On macOS 27.0.1 an unprivileged process gets no live CPU energy from IOReport:
its CPU rails are frozen on an M5 Max and an M3 Ultra, so `detect_meter` falls
to the load-average estimator there. The kernel does keep one live CPU energy
figure an unprivileged process can read: `proc_pid_rusage(getpid(),
RUSAGE_INFO_V6)` returns `ri_energy_nj`, the cumulative energy it attributes to
this process's threads. Public libproc API, no privilege. Measured here (M5 Max,
macOS 27.0.1, 2026-09-30, host heavily loaded): it changes about every 0.6 ms
(86 changes in 50 ms of polling); 200 ms of one thread's CPU time read 0.448 J;
a 200 ms sleep read 137 µJ.

The trap is coverage. It reads this process's threads and nothing else: not
other processes, not this process's children, not the GPU, ANE or DRAM, this
process's own GPU work included. A figure from it is a hardware reading of work
that ran on this process's threads, and would bill zero for a model served by a
subprocess. JouleClaw SPEC §1.3: a figure must not claim coverage of a domain
its counter does not read.

- `process::ProcessCpuCounter` (macOS, no feature) reads it over a new domain,
  `EnergyDomain::ProcessCpu`, documented to exactly that scope, graded HwShunt
  like RAPL and NVML, and only while live: the shared sustained-advance rule,
  with the probing thread burning 25 ms of its own CPU between samples, probed
  once per process and cached (`process_cpu_liveness`). Whether AMX work a
  thread drives is in the kernel's figure is not verified, and the docs say so.
- A window over which it did not advance by a whole µJ is not a reading:
  `ProcessCpuCounter::measure` returns the new `EnergyError::NotAdvanced`,
  never a zero; a failed read or a counter going backwards is an error too.
- `detect_meter` does not include it, and says why. `detect_in_process_meter`
  returns it when live, else exactly `detect_meter`; its docs limit it to work
  on this process's own threads. `CompositeMeter::names` lists what a
  composite holds, so a test can say what is not in it.
- mesh-meter decides the new domain, as its exhaustive match requires: a
  per-process figure does not cover a mesh/1 request, so through `HwMeter` it
  would be an estimate. `HwMeter::detect` uses `detect_meter`, so it never
  meets this counter unless bridged by hand.

Tests. The hardware checks run in `tests/process_cpu.rs`, one test in its own
process, because the counter reads every thread of the process and concurrent
tests would be in the figure: live, probed once across four threads; 200 ms of
one thread's CPU reads 0.2 to 20 J, HwShunt over ProcessCpu; a 200 ms sleep
reads under 0.1 J or is NotAdvanced; `detect_meter` holds apple-ioreport,
apple-silicon and estimation and not process-cpu, while the in-process meter
selects it; a busy `/bin/sh` child that burned 0.744 J (its own counter, read
independently at the SDK's offset) put 264 µJ in this process's window, which
spans its kill and reap. In the lib: the struct matches the SDK layout (464
bytes, energy at 336, checked with the C compiler); a counter given Frozen or
Unavailable reads and measures nothing; the production probe over a held
reader is Frozen after the budget and over a failing one Unavailable; the
window rule; and a live one-sided burn check.

Ran: `cargo test -p jouleclaw-energy` with default features and with
`ioreport,rapl,nvml`; mesh-meter with `hw-meter`, `hw-meter-apple`,
`hw-meter-nvml`; clippy clean on the new code.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:21:00 -04:00
..
conformance/v1 wai.generate.spectral: extend the lexicon to 370 words (data-only, pin unchanged) 2026-06-27 05:33:47 -04:00
mesh-rs jouleclaw-energy: a live counter of this process's own CPU energy, kept out of detect_meter 2026-09-30 22:21:00 -04:00
CONTRIBUTING.md wai.generate.spectral: extend the lexicon to 370 words (data-only, pin unchanged) 2026-06-27 05:33:47 -04:00
LICENSE wai.generate.spectral: extend the lexicon to 370 words (data-only, pin unchanged) 2026-06-27 05:33:47 -04:00
LICENSE-SPEC wai.generate.spectral: extend the lexicon to 370 words (data-only, pin unchanged) 2026-06-27 05:33:47 -04:00
README.md jouleclaw-energy: a live IOReport reading is a hardware reading, and only a live one 2026-09-30 20:17:13 -04:00
SPEC.md wai.generate.spectral: extend the lexicon to 370 words (data-only, pin unchanged) 2026-06-27 05:33:47 -04:00

Mesh

Energy-accounted inference serving & routing. One of the Transaction Science open standards.

Mesh treats every 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.

The serving shelf reports dollars per token and tokens per second. Mesh reports the number that is physical, comparable across hardware, and impossible to inflate: the joule.

The shape

ServeRequest ──▶ authorise (JCP grant) ──▶ route (cheapest-sufficient)
                                              │
                                              ▼
                          meter ◀── serve (engine) ──▶ tokens
                                              │
                                              ▼
                         sealed JCR-1 receipt: µJ / accepted token

Four roles — caller, router, engine, steward — and four phases per serve: authorise, route, meter, seal. See SPEC.md §2.

The reference workspace

mesh-rs/ is a pure-Rust reference implementation:

Crate What it is
mesh-schema wire types — ServeRequest, Fidelity, two-part Energy, RouteDecision, ServeOutcome
mesh-router energy-weighted cheapest-sufficient routing with a full candidate audit
mesh-engine the ServingEngine interface + a deterministic, weights-free ReferenceEngine
mesh-engine-gguf a real backend (behind gguf): wraps the family's pure-Rust GGUF/Metal inference substrate so the mesh routes and meters actual model tokens
mesh-meter the meter window; an always-available estimator + an optional bridge to the family hardware meter (RAPL / NVML / Apple) behind hw-meter
mesh-receipt the mesh/1 receipt, JCR-1 sealing (det-CBOR + COSE_Sign1), and a hash-chained log
mesh-core the orchestration that ties authorise → route → meter → seal together
mesh-conformance the deterministic reference scenario, its checks, and the gen-vectors bin

Mesh rides on JCP (a serve request is authorised by a JCP grant; receipts seal in JCR-1), dispatches to runtimes such as JouleClaw, and routes across compute described by EOC and isolated by Sandbox. It introduces no new cryptography (see SPEC.md §9).

Run it

cd mesh-rs

# all crates green
cargo test --workspace
cargo clippy --workspace --all-targets

# end-to-end: mint a JCP grant, serve, print the sealed receipt
cargo run -p mesh-core --example demo

# on Linux/RAPL or a CUDA/NVML box, meter real silicon (HwShunt provenance, where
# the counter is live; a counter that is not live falls back to the estimator)
cargo run -p mesh-core --example demo --features hw-meter-rapl

# regenerate the published conformance vectors
cargo run -p mesh-conformance --bin gen-vectors -- ../conformance/v1

# serve a REAL model end-to-end through Mesh (Falcon-H1 0.5B), seal the receipt
cargo run --release -p mesh-engine-gguf --features gguf --bin serve_falcon -- \
    /path/to/falcon-h1-0.5b-instruct 12 "The capital of France is"

The serve_falcon run demonstrates the whole standard on real model tokens: a JCP grant authorises each request (an underfunded grant is refused before any decode runs), the cheapest-sufficient backend is chosen, the decode is metered, and a mesh/1 receipt is sealed and hash-chained across the session — e.g. prompt "The capital of France is" → " Paris. It is known for its historical landmarks", prompt "Photosynthesis is the process by which" → " plants convert sunlight into chemical energy in the form of", with both seals verifying and the chain's prev-links intact.

The demo prints the route (every backend weighed, with the reason each was kept or rejected), the honest energy provenance, and the wedge metric — then verifies the sealed envelope under the steward key.

Status

v0.1.0-draft.1. Reference workspace builds and tests green (mesh-schema, mesh-router, mesh-engine, mesh-meter, mesh-receipt, mesh-core, mesh-conformance); cargo clippy --all-targets warning-free; published vectors in conformance/v1/. The reference engine is deterministic and weights-free; production backends implement the same ServingEngine interface — mesh-engine-gguf (behind gguf) is a real one over the family's pure-Rust GGUF/Metal substrate, kept out of the default build so it needs no weights.