diff --git a/INGEST.md b/INGEST.md index 467383059..bf9cde454 100644 --- a/INGEST.md +++ b/INGEST.md @@ -107,6 +107,47 @@ Tracked in [issues labelled `eoc`](https://github.com/Transaction-Science/open-s - Semantic-similarity threshold calibration methodology. - Registered MIME / JSON-Schema for the protocol envelope. +## mesh/ + +**Scope:** energy-accounted inference serving and routing. 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 a meter, and seals a +receipt whose headline figure is microjoules per accepted output token — +measured, not taken from a price list. + +### Included in v1 spec + +- Grants decided as a JCP enforcement point before any work, with the metered + joules debited after it and a breach recorded on the receipt (§2). +- A decision journal that survives steward restart, so a restart is not mistaken + for a log that lost its history (§2.2, §6.3). +- Fidelity floors, with advertised and delivered levels reported separately so an + unmet floor is visible rather than inferred (§3.2). +- Energy provenance as a closed set — `HwShunt`, `ModelBased`, `Estimator` — with + `measured_uj` present only for the first (§3.3). +- Cheapest-sufficient routing that records every candidate weighed (§4). +- Typed decisions as a second unit of work: calibrated probabilities over a + schema, zero output tokens, priced per scored option and reported as + `uj_per_decision` rather than per accepted token (§3.6). +- Training provenance for a decision model: `training_digest` addresses the + corpus the weights were fitted to, and `training_authority` says whether a + third party can check that corpus (§3.7). Added 2026-11-04 to close a gap in + this spec: a receipt could already bind which weights answered and at what + precision, so the answer reproduces, but it could say nothing about what + taught those weights to answer that way. §3.7 also forbids the saving such a + model is usually introduced with — the generation it displaced was never run, + so it was never metered. + +### Adding + +- The fit itself: a reference pipeline that turns a corpus of signed accepted + transitions into a decision model, emitting the `training_digest` the receipt + carries. The spec now says how such a model is bound; nothing in this + repository yet produces one. +- `uj_per_option_scored` calibration methodology across backends. + +--- + --- ## How this document evolves diff --git a/mesh/SPEC.md b/mesh/SPEC.md index 0a1214170..1b0991152 100644 --- a/mesh/SPEC.md +++ b/mesh/SPEC.md @@ -407,6 +407,62 @@ 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 @@ -499,6 +555,8 @@ and nulls; booleans are encoded as `0|1` uints and absent options dropped. | `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) |