Trace manifests
Every attribution trace is signed. The manifest is a compact ES256 JWS (header typ: provenance-trace+jwt) signed with the same keys as intent tokens and receipts, so anyone can verify it offline against /.well-known/jwks.json.
Claims
| Claim | Meaning |
| --- | --- |
| trace_id, model_version, backend, method | What was traced, on which model version, by which backend |
| prompt_hash | sha256 of canonical {model, messages} |
| completion_hash | sha256 of the completion text |
| canary_hash | sha256 of canonical {model_version_id, prompt_hash, readings} |
| graph_hash | sha256 of the canonical full graph |
| public_graph_hash | sha256 of the canonical masked public render at signing time |
| decision_tokens, iss, iat | Count of traced tokens; issuer; issued-at |
The manifest binds hashes, not neuron identities — publishing it never reveals a masked canary member.
Verify it
In the browser, paste it into the /verify page's Trace manifest tab (optionally with the graph from a share link). In code:
import { fetchJwks, verifyTraceManifest } from "@provenance/sdk";
const share = await (await fetch(`${API}/v1/trace/share/${token}`)).json();
const r = await verifyTraceManifest(share.manifest, await fetchJwks(API), share.graph);
// r.valid === true, r.graphMatches === "public"
from provenance_verify import verify_trace_manifest
r = verify_trace_manifest(manifest, jwks, graph) # r.valid, r.graph_matches ∈ {"full","public",False,None}
res := provenanceverify.VerifyTraceManifest(manifest, jwks, graph) // res.Valid, res.GraphMatches
All three check the same committed vectors (packages/core/test-vectors/trace-manifest/). A token with any other typ, such as an intent token or a receipt, is rejected.
What it proves
- ✓ Provenance recorded this trace, for this model version and these exact hashes, and the graph you hold is the one signed (full) or its signed public render.
- ✗ It does not prove the output is correct or safe, and attribution is approximate — the ablation deltas inside the graph are the measurement.
- If a model's canary sets change later, today's public render can differ from
public_graph_hash; verifiers then report the graph as not matching rather than guessing.