1
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
A signed decision, verified without us
Proves: the decision we return is signed, and the signature holds on your machine, from a key snapshot you cloned, without contacting us.
curl -sS -X POST https://app.coderifts.com/api/v1/action-verdict \
-d '{"action_type":"tool_call","tool":{"name":"get_customer","capabilities":["read"]}}' \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["chain_receipt"])' > receipt.txt
git clone -q --depth 1 https://github.com/coderifts/receipt-verifier
node receipt-verifier/cli.js "$(cat receipt.txt)"
{"valid":true,"status":"VERIFIED_CURRENT","payload":{"v":2,"kid":"2026-07-k1","fp":"sha256:68ac3813cf53b3bd3208028fa609a11b9a17012b4f5994aafacdc7a79303952d","prev":"null","caller":"anon","ts":"2026-09-14T10:15:45.931Z","reg":"4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945"}}
VERIFIED_CURRENT means the signature verifies against the verifier’s current pinned key snapshot. It does not mean currently_authorized: true.
The open offline verifier prints VERIFIED_CURRENT and has no currently_authorized field.
The payload line above is the 2026-09-14 verifier print. Its v field is 2. That field is the payload version in that print. It is not a format_version string. This block does not print crchain.v3.
Does not prove: that this endpoint evaluated your input. It returns a fixed decision so the envelope is inspectable. Your own installation evaluates its own change sets.
Measured 2026-09-14. ts is per-call; valid, status, kid and fp were stable on this run.
2
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
A valid signature is not authorization
Proves: the verifier separates two questions we are careful never to merge. A token can be cryptographically perfect and still authorize nothing now.
curl -sS -X POST https://app.coderifts.com/api/v1/verify-receipt \
-H 'Content-Type: application/json' \
-d "{\"token\":\"$(cat receipt.txt)\"}"
valid: true
status: VERIFIED_CURRENT
currently_authorized: null
authz_note: "status reflects signature+expiry only; provide operation/environment/fingerprint (and the body_hash-bound decision_result envelope) to evaluate current authorization"
VERIFIED_CURRENT means the signature verifies against the verifier’s current pinned key snapshot. It does not mean currently_authorized: true.
The hosted verify_receipt route, given a token alone, answers currently_authorized null.
Read the third line again. Not false. Not true. null — because with a token alone, the question cannot be answered, and an unanswered question is never a yes.
Measured 2026-09-14. Needs receipt.txt from block 1.
3
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
The limits, served as data
Proves: the boundaries are a field you can fetch and diff, not a paragraph in a PDF.
curl -sS https://coderifts.com/.well-known/coderifts.json \
| python3 -c 'import sys,json;[print(s) for s in json.load(sys.stdin)["does_not_prove"]]'
Evidence is RECORDED — a pinned capture, replayed — not a live provider run.
proof_scope TRUSTED_EXECUTOR, provider_witness NOT_APPLICABLE, externally_witnessed false: CodeRifts did not witness or sign a provider state.
Not externally witnessed, and not PATH B. The GitHub provider-loop is a separate claim.
The grant does not bind the canonical tool-call bytes, so what-was-called is not proven equal to what-was-authorized (planned, not available).
There is no single cross-domain evidence bundle over grant, measurement and supply chain (planned / on request, not available).
A downstream agent is not given a strictly narrower grant than its caller held — delegation attenuation is not available.
No DSSE or in-toto envelope is emitted by any published artifact.
The published tool-surface digest establishes what the server serves now. It does not establish that an existing client connection runs that list: clients may cache the tool list for the life of a connection, and expiry behaviour differs by client and is undocumented (measured: anthropics/claude-code#97369; on claude.ai the saved approval is keyed on a hash of the description and top-level parameter descriptions — a type, enum or required change does not reset it).
On 2026-10-04 agcty measured a claude.ai connector in claude-code issue 97369 where, after a tool-description change, sessions that had already loaded the tool kept recording the old text for about 19 hours and for about 31 hours while the server served the new text, so an approved description change does not reach every client immediately.
Does not prove: that every individual decision response carries this field. It does not. These are the boundaries of the published surface as a whole.
Eight entries in the repository file as of 2026-10-01; the eighth, on the tool-surface digest, was added that day, and the first seven were measured identical on the file and both live origins (coderifts.com and app.coderifts.com) on 2026-09-22. All eight are printed above, unabbreviated. They are flat statements, not categories — and they are not the per-endpoint does_not_prove tables that six analysis paths return on their own responses.
The three does_not_prove scopes, platform 8 · decision 6 · receipt 3, are three questions with zero lines in common, and does_not_prove_scope names which list a document carries.
4
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
What we serve is what we published
Proves: the tool text the live server hands an agent is byte-for-byte the tool text on this site. Two sources, one digest, computed by you.
Compare the two command outputs to each other — not to a value printed on this page. The current tools/list digest must equal the current server-card.json tools_sha256. A match proves that the server card describes the exact tool-list bytes currently being served, under the published canonicalization rule.
curl -sS -X POST https://app.coderifts.com/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
| python3 -c 'import sys,json,hashlib
t=json.load(sys.stdin)["result"]["tools"]
b=json.dumps(t,sort_keys=True,separators=(",",":"),ensure_ascii=False).encode()
print("sha256:"+hashlib.sha256(b).hexdigest())'
curl -sS https://coderifts.com/.well-known/mcp/server-card.json \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["surface"]["tools_sha256"])'
sha256:cb989871bb8376655bff573cb074ecac1e367a2393a88aff067055c07722ecb6
sha256:cb989871bb8376655bff573cb074ecac1e367a2393a88aff067055c07722ecb6
Example only — never compare against it; pin at approval time. Measured 2026-09-18: the two lines above are what these commands printed on that date, and nothing else. The check is the comparison of the two current outputs to each other. A digest pinned from this page is pinned to a day in September; pin the value you saw at the moment you approved the surface, and compare the live pair — the digest moves on a served-schema change with no source commit behind it.
Both commands use one rule. digest: SHA-256. canonicalization, quoted from the shipped surface anchor: “sha256 over the canonical JSON of the served tools[] as returned by tools/list … object keys sorted lexicographically at every depth (arrays keep order), no whitespace, RAW UTF-8 with no \uXXXX escaping. Python consumers must pass ensure_ascii=False — the default escapes the 58 non-ASCII characters in this surface and produces a different digest over identical data.” The command above passes sort_keys=True, separators=(",",":") and ensure_ascii=False, which is that rule.
Does not prove: that a model read the tool text, or obeyed it. It proves the text is the text. The digest covers the canonical bytes currently served, including descriptions, schema defaults and enum values. Runtime-generated metadata or a served-schema change can move it without a source-code commit. It does not bind the response to a Git commit or prove tool behavior.
Measured 2026-09-18. Live tools/list, published server-card, and the local mirror all printed this digest. App website-vendored-sync 9/9. Website check-mcp-server-card.mjs byte-identical (50932 bytes).
5
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
An unknown method is refused, by name
Proves: the server does not improvise. A method it does not implement gets a named refusal, not a helpful guess.
curl -sS -X POST https://app.coderifts.com/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"server/discover"}'
{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"Method not found: server/discover"}}
Measured 2026-09-14. The copy abbreviated this as -32601 Method not found: server/discover; the command prints the JSON envelope.
These four blocks run npx and download a package.
6
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
The guarded table, on six vectors
Proves: on the six named vectors, the adapter does not hand over a mutating tool without a grant.
npx @coderifts/conformance --assurance GUARDED_TOOL_TABLE
GUARDED_TOOL_TABLE: COVERED / LIVE — 6 vector(s)
Does not prove: anything about a tool your host registered directly. The claim is scoped to the table CodeRifts hands the agent.
Measured 2026-09-14.
7
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
A consumed grant cannot become a second success
npx @coderifts/conformance --assurance ATOMIC_COMMIT
ATOMIC_COMMIT: COVERED / RECORDED — 6 vector(s)
RECORDED, not LIVE. These are pinned captures, replayed. The profile's own output says so, and so do we: this does not prove that the live kernel behaves this way today.
Measured 2026-09-14.
8
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
The decision branches, on sixteen vectors
npx @coderifts/conformance --subject reference
reference profile=normative: 16 passed, 0 failed (n=16)
Proves: an adapter that reads execution_action branches the way the contract says. Does not prove: single-use consumption — that is block 7, and it is recorded.
Measured 2026-09-14. The command also printed sixteen PASS lines and measured_by: @coderifts/conformance@0.8.11; the copy's summary line is the one on the page.
9
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
Reproduce the evidence, do not replay it
Proves: the package does not only ship its proofs, it can rebuild the negative ones. The tamper case is regenerated, not replayed from a fixture.
npx @coderifts/conformance --assurance END_TO_END
END_TO_END: COVERED / RECORDED — 2 vector(s)
Measured 2026-09-14. RECORDED, not LIVE. The profile records 2 vectors. A reading of 7/7 is not this count.
10
Re-run daily: verified 2026-10-06 — expectation in proof-claims.json, result in docs/evidence/
Analysis is not permission
Proves: the public path analyses and says so in the envelope. A break is detected, and the same response states that nothing was authorised: may_execute: false, authorization_effect: NONE, receipt_kind: NONE.
curl -sS https://coderifts.com/examples/description-drift.json \
| curl -sS -X POST https://app.coderifts.com/api/v1/preflight \
-H 'Content-Type: application/json' -d @-
analysis_outcome : BREAKS_DETECTED
patterns : ["description_only_change", "TOOL_INSTRUCTION_DRIFT"]
may_execute : false
authorization_effect : NONE
receipt_kind : NONE
verdict_fingerprint : sha256:5096f53d…209c
Measured 2026-09-17. The fingerprint is stable across calls; patterns and the three NONE fields are what the analyse path always returns.
Does not prove: that anything was stopped. This path issues no grant and no receipt, so it cannot refuse a call — it can only describe one. The gate decides; preflight_mode=authorize with context.operation is the path that binds an operation.
What this page does not offer
Five things a reader might reasonably expect here, and why they are absent rather than faked:
Your own mutator table, key-free. No public endpoint exposes it.
An ALLOW from the public endpoint. It returns one fixed decision.
does_not_prove inside a decision JSON. It is on the surface, not in the verdict.
A merge you can watch being blocked. Not live here. But no longer unmeasured:
live-boundary-readback-2026-09-23 graded
coderifts/demo PR #4 head ENFORCING --
the required context CodeRifts /
contract-gate concluded "failure", so the
check asserted something. The default-
branch tip grades ENFORCING_UNVERIFIED_RUN
(zero check runs on a merged commit;
absence is not a pass).
A live single-use consumption. Only recorded profiles today.
Each of these is either planned, on request, or outside what we ship. The claim table says which, per item.
The merge row changed on 2026-09-23. It used to say only that the demo check’s own summary read “Enforcement status: not verified”. A read-only boundary readback (coderifts status --paths --live coderifts/demo, artifact live-boundary-readback-2026-09-23 in the release evidence bundle) has since graded the two commits above. What it still does not prove: a grade is a read at one point in time; MERGEGATE_ENFORCE is a server-side setting the read cannot see, only its effect after the fact; and the two GitHub surfaces (ruleset and classic branch protection) are reported side by side, not reconciled — here they disagree on both the context list and strict. A measured grade is not a merge you watched being blocked, which is why the row still says “not live here”.
What the gate reads
A change set is graded on the sentences a change adds, not on every description in the set. A sentence already sitting in a tool you did not touch does not decide your change. A tool that arrives new has no previous text, so every sentence of it is new and all of it is read — which is why a tool whose own description carries an instruction still goes to a human.
Measured 2026-09-14, the day that narrowing landed. Before it, one standing sentence in a browser tool — go forward/back in browser history, quoted as it read on that date — refused the whole set. A set-level report is the other question, is this set safe, and still reads every tool in full. The gate does not merge the two.
The claim table
Proof boundaries
During the public beta every organization gets Team features at $0 with a self-serve key, public and private repositories alike, no separate Team key to request, and each key allows 1,000 requests a month: after that authorize returns BETA_LIMIT_REACHED, analysis keeps working, and one email to hello@coderifts.com raises the limit.