mesh: a grant rides over the OpenAI-compatible HTTP binding, and a receipt can be shown back as a witness #312

Merged
dcharlot merged 1 commit from feat/mesh-http-grants into main 2026-10-18 07:20:05 -04:00

2026-10-18

Transaction Science
mesh: a grant rides over the OpenAI-compatible HTTP binding, and a receipt can be shown back as a witness
All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 12s
standards workspaces build + test / macOS energy backends (pull_request) Has been skipped
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m11s
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 59s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 1m13s
The grant work (#294, #301, #306) was reachable only through the library.
The reference HTTP server passed no grant to every request, had no way to
learn which steward a grant must name, and no way to witness a receipt
against the journal. Its binaries kept the journal in memory. It also read
whatever request body length a client declared.

- **Grants over HTTP.** A request's body carries its presentation in
  `jcp_presentation` (`presentation_in`). The presentation is signed for a
  request id, so a granted request is served as exactly the `ServeRequest`
  the body alone determines (`granted_serve_request`, plus a
  `_responses` variant). Its prompt-token figure stays the body's estimate
  rather than the server's tokenizer count, which a caller cannot
  reproduce. The body must name its own `metadata.joule_ceiling_uj`,
  since a server default would otherwise enter the id unseen.
- **Endpoints.** `GET /v1/mesh/steward` returns the steward's did:key,
  the subject a grant must name. `POST /v1/mesh/witness`, with the
  `receipt` and `envelope_hex` a response carried, answers 200 when the
  journal holds the receipt and 409 when it does not.
  `Mesh::witness_wire` checks a receipt in that wire form: the envelope
  must verify under this steward and seal exactly that wire receipt.
- **Statuses** (`http_status`): 401 when the caller is not the grant's
  issuer, 403 when the steward refuses the grant, 503 once it has stopped
  honouring grants, 500 for an unwritable journal, 400 otherwise.
- **Journal in the binaries.** With `MESH_JOURNAL` set, the reference
  server example and serve_openai_falcon record to that file and replay
  it before serving, reporting any unresolved serve.
- **Body cap.** A body declared over 4 MiB is refused (413) before it is
  read.
- **Spec.** Mesh SPEC §2.3 describes the binding (informative).

Checked on the build host:
- mesh-rs: 81 tests pass. mesh-openai with the server feature passes 15,
  including an end-to-end socket test: learn the steward, grant to it,
  present over HTTP, witness the receipt, refuse a tampered one, refuse
  an oversize body.
- The gguf and openai server features build, every Cargo.lock is
  current, and clippy is clean.
- Mutations each fail tests: a server that drops the grant, a granted
  path that recounts tokens, a wire witness that skips the seal check,
  and no body cap.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 02:20:35 -04:00