open-standards/mesh/mesh-rs/crates/mesh-router
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science afde4f18ec
Some checks failed
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Failing after 1m55s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 13s
standards workspaces build + test / macOS energy backends (pull_request) Has been skipped
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Has been cancelled
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) Has been cancelled
mesh: a grant is decided by JCP's runtime, so expiry, caveats, the model and spend bind
Mesh honoured a JCP grant by checking three things: the issuer signature,
that the capability permits `infer` on the request, and that the budget
covered the request's ceiling. Nothing else was checked:
- An expired grant was served.
- No caveat was evaluated, so `NotAfter`, `NotBefore`, `PayloadIs`,
  `MaxCostUj` and `ModelIn` were ignored.
- Nothing was ever debited, so one grant paid for any number of serves.
mesh-core had no unit test of the grant path.

The steward now holds a jcp-runtime `Runtime` and decides every grant in
JCP's two-phase metered path:
- **Route.** With a grant, a backend whose model the grant's `ModelIn`
  does not permit is inadmissible, and so is one that names no model. The
  route is the cheapest permitted backend, and the candidates record why
  the others were refused (`Router::route_where`).
- **Authorise,** before any work. The frame names `infer` on the request,
  the prompt hash as payload, and the chosen backend's weights as `model`.
  Signature, expiry, revocation and every cost-independent caveat apply,
  and what the grant has left must cover the request's ceiling.
- **Debit,** after metering. The metered joules are charged whatever
  happens next. A per-call cost caveat binds here, and a breach is sealed on
  the receipt as `grant_breach`.
- **Model check.** An engine that runs other weights than the ones it named
  before serving is refused a receipt.

Engines name their weights before serving through a new
`ServingEngine::weights_digest()`, which defaults to `None`.

The refusals that existed keep their errors (`GrantInvalid`,
`Unauthorized`, `BudgetTooLow`). `BudgetTooLow` now reports what the grant
has left. SPEC §2, §6.1, §7 and §8 and the README describe the new order.
§8 states that Mesh does not authenticate the caller, honouring a grant
as a bearer token of its subject, and that spend is per steward.

Checked on the build host:
- mesh-rs: 65 tests pass, six of them new, and every regenerated `mesh/1`
  vector is byte-identical.
- The gguf and openai server features build.
- clippy is clean on the changed crates.
- Mutations: no debit, a router that ignores the filter, ignoring other
  denials, and skipping the model check each fail tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 09:34:11 -04:00
..
src mesh: a grant is decided by JCP's runtime, so expiry, caveats, the model and spend bind 2026-10-17 09:34:11 -04:00
Cargo.toml wai.generate.spectral: extend the lexicon to 370 words (data-only, pin unchanged) 2026-06-27 05:33:47 -04:00