Skip to main content

🚀 Beta: All Pro and Team features are free. Install on GitHub →

What each proof proves — and what it does not

CodeRifts issues several kinds of proof. Each one is load-bearing only inside a named bound. This page is the honesty table: what the product asserts, and the residual it refuses to dress as proof.

Agents still branch on execution_action only. Unknown values are not permission.

The three distinguishers

Decision semantic hash

Proves: “fresh and replay say the same thing.” “The hash therefore proves equivalence over what a replay carries, not over the full analysis tier.”

Does not prove: identity of the input bundle or scoring config (that is a different fingerprint); verbatim equality of receipt tokens; that timestamps, correlation ids, retrieval packaging, or analysis-tier sections omitted on replay are the same.

The hash is deliberately broader than the input fingerprint and narrower than the full response, so a later lookup can still be the same decision.

Approver count

Proves: “Count proves: N distinct login strings on the list (not N real people).” “Membership proves: subject was on the supplied list at evaluation time.” “Identity: approved_by is the reviewer's GitHub login. Proves GitHub asserts this account approved a commit SHA — not that the account holds any org role.”

Does not prove: “It does NOT prove the list is correct, current, or authorised by anyone.” “Distinctness is login-string only — one person with two accounts defeats this; the code does not claim otherwise.” Approval is never “safe”: the machine verdict is unchanged (“authorized to proceed despite machine verdict”).

The count is a string-set check, not a people census.

Evidence / waiver gate suppression

Proves: “The gate is suppressed only on the full happy path: the token verifies against a registry-trusted kid AND its payload.scope is user_authorization AND payload.tool matches the request tool (or is *) AND payload.op is among the request capabilities.” For source attestation: attested is true “ONLY on the full happy path” of trusted signature plus content binding to the transmitted data.

Does not prove: “Every other case — absent, malformed, unknown kid, bad signature, wrong scope, tool or op mismatch — behaves EXACTLY as if no evidence were supplied (fail-closed).” “A suppressed A1 gate does not disable the other gates: an input that also triggers a data-laundering gate still lands on BLOCK.” Replay of the same evidence re-authorizes the same action; it is request-bound, not single-use, and is not a clock-expiry proof. A fingerprint-bound policy waiver “does not apply” when the current fingerprint is absent or mismatched (fail closed on binding). Engine-verdict approval is a different claim from a policy waiver and “does not rewrite the machine verdict.”

Suppression is a narrow, conjunctive unlock. Anything short of the full path is the unsuppressed gate.

Further boundaries

Change-set completeness commitment

Proves: a later omission against a host-submitted commitment is detectable. Self-consistency of submitted artifacts against that commitment.

Does not prove: “A cryptographic commitment does NOT prove the host sent every changed file.” “Mode ATTESTED_UNVERIFIED always carries both words; not a proof.” Never a boolean completeness:true on the generic path.

On a generic API without repo access, completeness is theoretically unprovable at issuance; the product stays honest about that.

Receipt: signature vs currently authorized; scope vs reuse

Proves: cryptographic authenticity of a receipt you already hold, and — when lifecycle is evaluated — whether it is currently valid authorization for a stated operation and target. “You must distinguish ‘signature ok’ from ‘currently authorized’.”

Does not prove: a new decision on a changed base→head set (verify_receipt does not re-diff). “A differently-scoped receipt is not reusable authorization.” Receipt TTL answers only “how long is this permission valid?” — it is not freshness or content-identity; a still-unexpired receipt still fails closed if authorized content drifted.

Signature, clock window, and content bind are three axes, not one.

execution_action (and unknown values)

Proves: the closed set CONTINUE, CONTINUE_WITH_MONITORING, REQUEST_APPROVAL, STOP is the branch key. A known continue-valued action is a necessary condition, never a sufficient one.

Does not prove: “An unrecognised execution_action is not permission: fail closed (halt or re-preflight).” Do not branch on decision or safe_for_agent. Additive / unknown envelope fields are tolerated for validation; they are not permission. Analyze mode is informational risk only (may_execute: false) — not permission.

Unknown is deny, not a creative reading of nearby fields.

next_agent_step

Proves: structured remediation guidance the agent may follow after a non-CONTINUE decision.

Does not prove: permission to act. “next_agent_step is suggestion, not permission.” Agents still branch on execution_action.

How to remediate is not whether to proceed.

Preflight vs merge / runtime enforcement

Proves: this preflight evaluates the change only.

Does not prove: “CodeRifts reports a governance decision and execution_action; it does not by itself block merges. Blocking requires separate repository configuration (required status checks, enforcement) that this rule file does not set.” Runtime enforcement of tool calls is the client-side guard; merge enforcement depends on the repository’s branch protection — “it is NOT determined by this preflight response.”

Install is not branch protection.

Guard execution proof

Proves: what the guarded path checked and whether that call executed, with explicit non-claims always set so missing fields cannot be read as “ok.”

Does not prove: that the change is safe; that the host cannot bypass; that an absent field is compliance; that change_fp is what executed (it is what was checked); that calls outside the guarded table are visible; that the execution-result hash is artifact-match proof; that a host-asserted conditional write was a verified compare-and-swap.

The package cannot force the host to only call the returned table.

An opt-out arm is a different residual from that one: with requireExecutionStateMatch: false (execution_state_check_disabled), in observeOnly, or on a 'warn' mismatch (runUnenforced), the call still runs and the proof records enforced: false. A proof is not a claim that the path enforced.

The coverage aggregator is scoped the same way: FULLY_ENFORCED and may_claim_full_tetrad hold for the applicable tetrad only. Neither is a product-wide inescapability claim.

CAS attestation

Proves: linkage of a frozen execution proof with a conditional-write outcome; authorized_and_committed only on a clean committed branch.

Does not prove: only-write-on-host; that a version token proves change-fingerprint match; that committed-stale is safe; that the execution-result hash equals CAS bytes; that the host cannot bypass; a re-decision of governance ALLOW/BLOCK.

Attestation is pairing two inputs, not a new verdict.

Commit observation (T3)

Proves: the target, re-read after the host write, matched the authorized after (content on filesystem adapters, version token on API / DB / Registry adapters) at observation time.

Does not prove: atomicity; that no other writer acted between write and observation; content equality on token-only adapters; that the host’s attestation is true.

Observed at T3, not atomic: another writer may act between write and observation; token-only adapters compare version token not content; host attestation is a host claim layered on the measurement.

enforced is a pre-write fact and is unchanged by T3. The drift event commit_observed_drift is report-only, not a permission gate.

Remediation-loop attestation

Proves: typed closure linking a prior BLOCK’s remediation transaction to a later ALLOW execution chain; refuses when the input fingerprints match (unchanged input is not permission).

Does not prove: the patch addressed required changes; recheck scope was honored; no other changes rode along; the new ALLOW was caused by the remediation; that the host cannot bypass.

Correlation is not causation; fingerprint match is not a second authorize.

Receipt chain linkage (offline)

Proves: predecessor commitments inside the token bodies you present: none removed or reordered (tamper-evident).

Does not prove: Ed25519 signatures, expiry, keys, or authorization. “Neither proves the predecessor was ever a real signed receipt.” An intact chain does not prove session completeness, that edits landed, or that downstream CI may skip re-analysis. chain_status: absent is not “unlinked”; it is a different gate. Prefer tamper-evident language over tamper-proof.

Channel-chain chain_status

Proves: a supplied previous receipt verified against the current key (intact), was omitted (absent, annotation only), or failed verification (broken).

Does not prove: a broken chain on a read-only action changes the decision (it does not). Absent is annotation only. Broken plus a destructive capability escalates to REQUIRE_APPROVAL and never silently passes.

Annotation is not authorization, except the one destructive escalation.

TOCTOU / measurement time

Proves: “Resolving content proves what was true at measurement time.”

Does not prove: the tree is still that content at write time. “A host that then writes unconditionally still races.” Opt-in execution-state recheck can detect or enforce against drift; it is not a full TOCTOU closure. Conditional write remains host-side.

Monitoring sink (CONTINUE_WITH_MONITORING)

Proves: agreement between a host declaration that a monitoring sink is wired and a present onEvent callback. Without both, WARN does not proceed (MONITORING_UNWIRED).

Does not prove: that any event reaches a destination. “A no-op () => {} is indistinguishable from a real logger.” “A declaration is a claim we record, not a fact we verify.” CONTINUE_WITH_MONITORING “is not ‘proceed with caution’ without monitoring.”

Required-check app_id

Proves: “only a real app_id proves the green came from OUR app.”

Does not prove: a required check matched by name only (app_id null) was produced by CodeRifts; that path is satisfiable by any repository writer.

Name match is not app binding.

Usage observation vs declaration

Proves: declaration answers who intends to use X; observation answers who read X (when). Element-level traffic without a consumer id still proves traffic arrived.

Does not prove: unobserved means unused. “ABSENT ≠ ZERO”: nobody sending traffic means every field is unobserved — unobserved must never mean unused. Declared intent is not measured traffic.

Decision outcomes API

Proves: post-hoc observed reality bound to a past decision id, when a row is recorded.

Does not prove: calibration, success rate, or that a missing row means the decision was good. Empty list interpretation is absence_is_unknown (absent ≠ zero / success).

Audience on a receipt

Proves: when set, the envelope audience is the authenticated key identity; a non-null intended audience that does not match is the wrong audience.

Does not prove: org or installation scope. Anonymous receipts do not bind a holder identity.

Blast-radius signals

Proves: caller-declared target sensitivity can only raise severity, never lower it.

Does not prove: absence of the signal is a finding. Absence changes nothing (the same absent-is-no-signal principle as chain attestation and evidence).

Retired signing key window

Proves: an issue timestamp inside a retired key’s closed validity window, when the window is fully stated.

Does not prove: “A retired key without retired_at cannot prove a closed window” — fail-closed false.

MCP gateway core

Proves: a derived allow / deny / require_approval from the product execution_action map (unknown or missing → deny).

Does not prove: that this module sits on a wire in front of arbitrary MCP servers. “This module alone does not sit on a wire.” Scoring is not reimplemented here.

Incomplete analysis and approval

Proves: only a completed analysis with real findings may be approved. The label may be BLOCK or REQUIRE_APPROVAL (severity, not permission).

Does not prove: that an approval on incomplete analysis is risk acceptance. “It is risk ignorance wearing process.”

Last verified: 2026-08-20. Statement changes require source quotes.

Last verified: 2026-08-20. Statement changes require source quotes.