PSR-001: PrimeSwarm Receipt Format Specification
Status: Draft v0.1 Published: 2026-09-12 Authors: Grigori Korotkikh, Only Institute License: MIT (the spec is open; implementations may be commercial)Abstract
This specification defines a receipt format for AI agent governance decisions. A receipt is a cryptographically verifiable record that proves a governance gate evaluated a specific input against a specific policy and produced a specific decision. An auditor can replay the receipt using an open-source verifier and confirm the decision without trusting the system that produced it.
This format is designed to be framework-agnostic. Any AI governance system — PrimeSwarm, Microsoft AGT, NVIDIA NeMoClaw, or a custom implementation — can produce PSR-001 receipts. The format does not require ONLY Lang, PrimeSwarm, or any specific vendor.
Conformance Notation
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in BCP 14 [RFC 2119] [RFC 8174] when, and only when, they appear in all capitals.
1. Motivation
Most AI systems produce logs. A log says "this happened." A receipt says "this happened, here is the proof, and here is how you can verify it."
Logs are append-only narratives. They are useful for debugging. They are not useful for compliance. An auditor cannot replay a log entry and verify that the system made the correct decision. They can only trust that the log is accurate.
Receipts are cryptographic proofs. They include the policy that was evaluated, the input hash, the decision, and a hash that binds them together. An auditor can replay the evaluation and verify the result independently. They do not need to trust the receipt — they can verify it.
This specification defines the receipt format so that auditors, SIEM systems, and compliance tools can parse receipts from any conforming implementation using a single interface.
2. Receipt Structure
A PSR-001 receipt is a JSON document with the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
spec_version | string | REQUIRED | The spec version. MUST be PSR-001. |
receipt_id | string | REQUIRED | A unique identifier for this receipt. SHOULD be a UUID v4 or a timestamp-prefixed identifier. |
timestamp | string | REQUIRED | ISO 8601 UTC timestamp when the decision was made. MUST be UTC. |
gate_state | string | REQUIRED | The decision. MUST be one of ALLOW, DENY, ESCALATE. |
reason | string | OPTIONAL | Human-readable explanation of the decision. Defaults to empty string. |
policy | object | REQUIRED | The policy that was evaluated. See §2.1. |
input | object | REQUIRED | The input that was evaluated. See §2.2. |
evidence | object | REQUIRED | The evidence produced by the evaluation. See §2.3. |
identity | object | OPTIONAL | The identity of the agent and human involved. See §2.4. |
governance_root | object | OPTIONAL | The authority state at authorization time (T₀). See §2.5. |
gate_decision | object | OPTIONAL | The authority state at execution time (T₁). See §2.6. |
receipt_hash | string | REQUIRED | SHA-256 hash binding all REQUIRED fields. See §3. |
signature | object | OPTIONAL | Cryptographic signature over the receipt_hash. See §4. |
The policy object describes what was evaluated.
| Field | Type | Required | Description |
|---|---|---|---|
language | string | REQUIRED | The policy language used. MUST be one of: only-lang, yaml, rego, cedar, python, custom. |
version | string | REQUIRED | The version of the policy script. SHOULD be a semantic version or a content hash. |
script_hash | string | REQUIRED | SHA-256 hash of the policy script source. The exact bytes that were evaluated. |
script_source | string | OPTIONAL | URL or path where the policy script can be retrieved for verification. If absent, the auditor must obtain the script through other means. |
script_hash is the SHA-256 of the script text. For YAML policies (e.g., AGT), script_hash is the SHA-256 of the YAML file. For Rego policies, script_hash is the SHA-256 of the .rego file.
2.2 Input Object
The input object describes what was evaluated. PII MUST be stripped before hashing.
| Field | Type | Required | Description |
|---|---|---|---|
input_hash | string | REQUIRED | SHA-256 hash of the input that was evaluated. PII MUST be stripped or replaced with cryptographic hashes before hashing. The raw input MUST NOT be included in the receipt. |
input_type | string | REQUIRED | The type of input. MUST be one of: tool_call, message, decision, transaction, custom. |
field_values | array of number | OPTIONAL | The numeric field values passed to the gate, if applicable. These are the values the gate evaluated after PII sanitization. |
metadata | object | OPTIONAL | Additional non-PII metadata about the input (e.g., tool name, action type, parameters with PII stripped). |
The evidence object contains the proof that the evaluation produced the stated decision.
| Field | Type | Required | Description |
|---|---|---|---|
residual | number | OPTIONAL | The equilibrium residual — how far from perfect balance. For ONLY Lang gates, this is the mathematical residual. For non-ONLY-Lang gates, this MAY be omitted. |
residual_history | array of number | OPTIONAL | Step-by-step convergence values, if the gate iterates. |
indices_healed | array of integer | OPTIONAL | Which field indices the gate repaired during evaluation. |
reason_codes | array of string | OPTIONAL | Machine-readable reason codes for the decision (e.g., boundary_violation, budget_exceeded, bias_detected). |
explanation | string | OPTIONAL | Human-readable explanation trace from the gate. |
replay_inputs | object | OPTIONAL | The exact inputs needed to replay the evaluation. MUST include everything the verifier needs to reproduce the decision. |
The identity object binds the decision to the agent that proposed it and the human that approved it, if applicable.
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | OPTIONAL | The identifier of the agent that proposed the action. |
agent_did | string | OPTIONAL | A decentralized identifier for the agent, if available. |
human_approver_id | string | OPTIONAL | The identifier of the human who approved an escalated action. REQUIRED if gate_state is ESCALATE and the action was approved. |
human_approver_hash | string | OPTIONAL | SHA-256 hash of the human approver's identity, if PII-sensitive. |
approval_timestamp | string | OPTIONAL | ISO 8601 UTC timestamp when the human approved. |
The governance_root object records the authority state at authorization time (T₀). It answers: who authorized this agent, under what role, on what basis, and in what context.
This object is OPTIONAL for PSR-001 v0.1 conformance but REQUIRED for Runtime Authority Continuity (see §12).
| Field | Type | Required | Description |
|---|---|---|---|
actors | array of object | REQUIRED | Who authorized this agent. Each entry has actor_id, actor_hash (optional), role, and authority_scope. |
lineage | array of object | OPTIONAL | The delegation chain. Each entry links to a prior receipt by receipt_hash, forming a temporal chain from T₀ to this receipt. |
policy_version | string | REQUIRED | The version of the governance policy active when authority was granted at T₀. |
justification | string | REQUIRED | Why authority was granted. The conditions that justified the authorization. |
context_t0 | object | REQUIRED | The execution context at authorization time. Contains timestamp, data_hash, policy_hash, and metadata. |
actors array records the human or system that authorized the agent. If a compliance officer authorized an agent to make lending decisions, the actors array records their identity, role, and the scope of authority granted.
The lineage array forms a hash-linked chain. Each entry contains the receipt_hash of a prior receipt in the delegation chain. This creates a temporal chain of authority from the original authorization through every intermediate step to the current execution. An auditor can trace the full chain without trusting any single receipt.
The context_t0 object records the state of the world when authority was granted. At execution time (T₁), the gate compares context_t0 to context_t1 (in gate_decision) to detect condition drift.
2.6 Gate Decision Object
The gate_decision object records the authority state at execution time (T₁). It answers: was the authority from T₀ still valid when the action was actually executed?
This object is OPTIONAL for PSR-001 v0.1 conformance but REQUIRED for Runtime Authority Continuity (see §12).
| Field | Type | Required | Description |
|---|---|---|---|
context_t1 | object | REQUIRED | The execution context at the moment of action. Contains timestamp, data_hash, policy_hash, and metadata. |
authority_still_valid | boolean | REQUIRED | Whether the authorizing actors still held valid authority at T₁. False if any actor was revoked, expired, or changed role. |
condition_drift | boolean | REQUIRED | Whether the conditions that justified the original authorization (context_t0) changed materially by T₁. |
condition_drift_fields | array of string | OPTIONAL | Which context fields drifted between T₀ and T₁, if condition_drift is true. |
revocation_detected | boolean | OPTIONAL | Whether any actor in the lineage chain had their authority revoked between T₀ and T₁. |
lineage_intact | boolean | OPTIONAL | Whether the full delegation chain from T₀ to T₁ is intact and unbroken. |
authority_still_valid is false, the gate MUST DENY regardless of the action's compliance with policy. A technically compliant action executed under revoked authority is a governance failure.
3. Receipt Hash
The receipt_hash binds all REQUIRED fields of the receipt. It is computed as:
1. Construct a canonical JSON string containing only the REQUIRED fields: spec_version, receipt_id, timestamp, gate_state, policy, input, evidence, and receipt_hash itself set to the empty string.
2. Sort object keys lexicographically (RFC 8785 JSON Canonicalization Scheme).
3. Compute SHA-256 of the canonical JSON string.
4. The resulting hex digest is the receipt_hash.
The receipt_hash field in the receipt MUST match the hash computed by this procedure. If it does not, the receipt is invalid.
4. Signature
The signature object is OPTIONAL but RECOMMENDED for production deployments.
| Field | Type | Required | Description |
|---|---|---|---|
algorithm | string | REQUIRED | The signature algorithm. MUST be ed25519. |
public_key | string | REQUIRED | The base64-encoded public key. |
signature | string | REQUIRED | The base64-encoded signature over the receipt_hash. |
receipt_hash using the public key.
3. If verification succeeds, the receipt is authentic. If it fails, the receipt is forged or tampered.
5. Replay Verification
An auditor verifies a receipt by replaying the evaluation:
1. Retrieve the policy script. Use policy.script_source or obtain the script through other means. Verify that SHA-256(script) == policy.script_hash.
2. Reconstruct the input. Use evidence.replay_inputs to reconstruct the exact input that was evaluated. Verify that SHA-256(sanitized_input) == input.input_hash.
3. Run the verifier. Execute the policy script against the reconstructed input using an open-source verifier (e.g., the ONLY Lang WASM verifier, or a conforming verifier for the stated policy.language).
4. Compare the result. The verifier's output MUST match:
- gate_state
- evidence.residual (if present)
- evidence.indices_healed (if present)
- evidence.reason_codes (if present)
5. Verify the hash. Recompute the receipt_hash per §3. It MUST match.
6. Verify the signature. If present, verify per §4.
If all checks pass, the decision is verified. The auditor did not need to trust the system — they verified it.
6. Example Receipt
{
"spec_version": "PSR-001",
"receipt_id": "rcpt_2026-09-12T14:30:00Z_a1b2c3d4",
"timestamp": "2026-09-12T14:30:00.123Z",
"gate_state": "ALLOW",
"reason": "Budget within limits, bounds satisfied, no bias detected",
"policy": {
"language": "only-lang",
"version": "1.2.0",
"script_hash": "a3f5e8c1d2b4...",
"script_source": "https://only.institute/policies/lending-v1.2.0.only"
},
"input": {
"input_hash": "f7e2d1c9b8a6...",
"input_type": "transaction",
"field_values": [0.45, 0.30, 0.25],
"metadata": {
"tool": "loan_approval",
"action": "approve",
"amount_sanitized": true
}
},
"evidence": {
"residual": 0.0000000123,
"residual_history": [0.15, 0.08, 0.03, 0.0000000123],
"indices_healed": [2],
"reason_codes": ["within_budget", "within_bounds", "no_bias"],
"explanation": "Field 2 was healed from 0.0 to 0.25. Residual converged to 1.23e-8.",
"replay_inputs": {
"signs": [1, -1, 1, -1],
"field": [0.45, 0.30, 0.25, 0.0],
"script": "harmony([0.5, 0.3, 0.2])\nassert_bounds(0, 50, 0)\nbudget_limit(500)"
}
},
"identity": {
"agent_id": "loan-agent-001",
"human_approver_id": null
},
"governance_root": {
"actors": [
{
"actor_id": "compliance-officer-42",
"actor_hash": "a1b2c3d4e5f6...",
"role": "compliance_officer",
"authority_scope": "lending_decisions"
}
],
"lineage": [
{
"receipt_hash": "f8e3d2c1b0a9...",
"receipt_id": "rcpt_2026-09-12T10:00:00Z_x9y8z7",
"timestamp": "2026-09-12T10:00:00.000Z"
}
],
"policy_version": "1.2.0",
"justification": "Agent authorized for loan approvals up to $50k with credit score >= 700",
"context_t0": {
"timestamp": "2026-09-12T10:00:00.000Z",
"data_hash": "b4c5d6e7f8a9...",
"policy_hash": "a3f5e8c1d2b4...",
"metadata": {
"credit_score": 720,
"max_loan_amount": 50000
}
}
},
"gate_decision": {
"context_t1": {
"timestamp": "2026-09-12T14:30:00.123Z",
"data_hash": "c5d6e7f8a9b0...",
"policy_hash": "a3f5e8c1d2b4...",
"metadata": {
"credit_score": 720,
"max_loan_amount": 50000
}
},
"authority_still_valid": true,
"condition_drift": false,
"condition_drift_fields": [],
"revocation_detected": false,
"lineage_intact": true
},
"receipt_hash": "e9c4f7a2b1d8...",
"signature": {
"algorithm": "ed25519",
"public_key": "MCowBQYDK2VwAyEA...",
"signature": "MEUCIQDk..."
}
}
7. SIEM Integration
Receipts are designed to be forwarded to SIEM systems (Splunk, Datadog, Elastic, Sumo Logic, QRadar). The recommended forwarding format is:
- Transport: HTTPS POST or HEC (Splunk) or equivalent
- Encoding: JSON (this spec)
- Event type:
primeswarm.receipt - Indexing: By
receipt_id,timestamp,gate_state,agent_id
index=ai_governance event_type="primeswarm.receipt" gate_state="DENY"
| stats count by reason_codes
8. Framework Compatibility
This format is designed to be produced by any governance system, not just PrimeSwarm:
| System | policy.language | Compatibility |
|---|---|---|
| PrimeSwarm | only-lang | Native — full receipt including residual, healing, replay |
| Microsoft AGT | yaml | Compatible — AGT produces allow/deny/escalate/warn/transform verdicts. Map warn to ALLOW with a reason code. Map transform to ALLOW with a reason code. evidence.residual is omitted. |
| NVIDIA NeMoClaw | custom | Compatible — NeMoClaw produces network policy decisions. Map allow/deny to ALLOW/DENY. input_type is network_request. evidence contains the network policy that was evaluated. |
| Custom | python, rego, cedar, custom | Compatible — any system that produces a deterministic decision can produce a PSR-001 receipt. The policy.language field identifies the system. |
receipt_hash per §3.
3. Strip PII before computing input_hash.
4. Include evidence.replay_inputs sufficient for independent verification.
9. What This Spec Does Not Require
- It does not require ONLY Lang. Any policy language works.
- It does not require PrimeSwarm. Any governance system can produce conforming receipts.
- It does not require a specific verifier. Any open-source verifier that can replay the evaluation is sufficient.
- It does not require Ed25519 signatures. Signatures are RECOMMENDED but OPTIONAL.
- It does not require a specific SIEM. The JSON format is SIEM-agnostic.
10. Open Source Verifier
The Only Institute provides an open-source verifier for ONLY Lang receipts at:
- WASM verifier: github.com/only-institute/only-lang-wasm — runs in any browser, 162KB
- CLI verifier: github.com/only-institute/dgv-verifier — runs on any platform with Rust
- Test card catalogue: 89 website definitions, including proposed authority-continuity coverage. Catalogue size is not an executed-test or receipt count — dgv-verification-deck
policy.language. The receipt format is the interface; the verifier is the implementation.
11. Versioning
This is version 0.1 (Draft). The spec version string is PSR-001.
Future versions:
PSR-002— adds batch receipts (multiple decisions in one document)PSR-003— adds Merkle chain (hash-linked receipt sequences)PSR-004— adds cross-system attestation (multiple systems co-signing a decision)
12. Runtime Authority Continuity
The problem
An agent can receive valid authority at T₀. By T₁, when it reaches the execution boundary, the conditions surrounding that authority may have changed. The data may be different. The policy may have changed. The delegation may have expanded. The risk may have changed. The intended objective may no longer match the action. Yet the technical permission can still remain active.
This creates a distinction: permission to act ≠ continuing authority to act.
Access control can establish that an agent is permitted to perform an action. Governance continuity asks something harder: was the authority still valid when the consequential action was actually executed?
The temporal governance chain
AUTHORIZATION → DELEGATION → CHANGING CONDITIONS → RUNTIME REASSESSMENT → EXECUTION → EVIDENCE
If governance verifies only the beginning of that chain, it may prove that the agent was authorized once without proving that the authority remained valid at execution.
How PSR-001 addresses this
The governance_root object (§2.5) records the authority state at T₀:
- Who authorized the agent (
actors) - The delegation chain (
lineage) - The policy version (
policy_version) - Why authority was granted (
justification) - The context when authority was granted (
context_t0)
gate_decision object (§2.6) records the authority state at T₁:
- The context at execution time (
context_t1) - Whether authority was still valid (
authority_still_valid) - Whether conditions drifted (
condition_drift) - Whether revocation was detected (
revocation_detected) - Whether the lineage chain is intact (
lineage_intact)
Proposed ONLY Lang commands (not implemented by the local experiment)
The following table specifies intended semantics. Website syntax highlighting and test-card descriptions do not implement these commands or demonstrate interpreter support. TC-070 through TC-089 remain proposed coverage until backed by executable fixtures and measured results:
| Command | When it runs | What it does |
|---|---|---|
bind_authority(actor_id, role, scope) | At T₀ (authorization) | Records who authorized the agent and under what role |
bind_context(data_hash, policy_hash) | At T₀ (authorization) | Records the context state when authority was granted |
bind_objective(objective_id, permitted_actions) | At T₀ (authorization) | Records the authorized objective and the set of permitted action types |
link_lineage(prior_receipt_hash) | At T₀ (authorization) | Links this receipt to the prior receipt in the delegation chain |
revoke_authority(actor_id, reason) | Between T₀ and T₁ | Records authority revocation in the revocation registry with a reason |
require_continuous_lineage() | At T₁ (execution) | Enforces that the lineage chain is unbroken — DENY if any step is missing |
check_authority(actor_id) | At T₁ (execution) | Verifies the authorizing actor still holds valid authority |
check_context_drift() | At T₁ (execution) | Compares context_t0 to context_t1 and flags material drift |
check_revocation() | At T₁ (execution) | Checks the revocation registry for any actor in the lineage |
check_objective_drift(action_type) | At T₁ (execution) | Checks whether the proposed action type is in the authorized objective scope |
check_authority fails, the gate MUST DENY. If check_context_drift returns true, the gate MUST ESCALATE. If check_revocation returns true, the gate MUST DENY. If require_continuous_lineage finds a gap, the gate MUST DENY. If check_objective_drift finds the action outside the authorized scope, the gate MUST DENY.
Implemented experiment: Objective Contracts for quote preparation
The Python evaluator in only-dgv-verifier/objective_contract.py checks a structured contract against a proposed prepare_quote action and a separate host-supplied context. It checks the customer, service, currency, aggregate budget, actor, policy version, contract expiry, snapshot freshness, contract review and exact-proposal approval. Explicit unresolved requirements escalate rather than being interpreted as permission. It does not interpret natural-language intent.
Run dgv_runner.py --objective-experiment in the verifier repository to reproduce 28 synthetic cases. Results and replay inputs are in evidence/objective_contract_experiment.json; unit tests additionally check tampering, rehashed false decisions, evidence substitution, strict JSON parsing, boundary values and CLI behavior. These measured cases are separate from the numbered website cards and are not a certification.
Experimental receipts use DGV-OBJECTIVE-EXPERIMENT-1, not the PSR-001 legacy hash contract. All receipt fields except receipt_hash are covered by SHA-256. Canonicalization is sorted-key compact ASCII JSON with safe integer values, ordered arrays, booleans and null; duplicate keys and floats are rejected. No general RFC 8785 conformance or digital signature is claimed.
The replay verifier re-evaluates all recorded predicates and compares the complete receipt. Without an independent original request/context it returns UNVERIFIABLE. With a matching host-supplied reference it returns VERIFIED_AGAINST_SUPPLIED_CONTEXT, not an authorization to execute again. External identity, approval and revocation assertions are not authenticated by this experiment.
Implemented experiment: revocation propagation with two local gates
The Python module only-dgv-verifier/revocation_store.py implements a versioned authority store backed by SQLite. Authority checks, token consumption and the synthetic destination write all happen inside one BEGIN IMMEDIATE transaction. A gate cannot authorize a write using a stale cached authority, because the check and the write commit together or fail together.
Run dgv_runner.py --revocation-experiment in the verifier repository to reproduce 36 cases: 12 sequential scenarios plus 24 simultaneous revoke/write races using two local gate processes against one temporary SQLite database. Results, the full committed history snapshot, measurements and a report hash are in evidence/revocation_experiment.json; unit tests additionally check tampering, audit reordering, clock rollback, store identity, token binding, expiry and CLI behavior.
The experiment demonstrated:
- A gate with a stale cached authority cannot execute after revocation commits — the execution check runs inside the same transaction as the write.
- Store unavailability (locked database) fails closed — no cached-permission fallback.
- One-use tokens are bound to the exact action, payload and destination.
- 24 simultaneous revoke/write races all resolved correctly, ordered by transaction commit.
- A write committed before revocation is not retroactively undone.
- The committed history is independently auditable: reordering, omission or payload alteration is detected.
- Network partition resilience: the "unavailable store" case is a SQLite lock timeout, not a real network outage.
- Replicated consensus: one SQLite database, one writer at a time. Multi-region deployment needs consensus to maintain the same guarantee.
- Authenticated identities: trusted local processes have direct database access.
- External exactly-once: commit errors are unconfirmed — reconcile by action ID before retrying.
- Production SLA: latency samples describe this run only.
Still outside the demonstrated scope
- Live integration: no CRM writes or ONLY Lang interpreter integration. No quote was sent or accepted.
- Semantic completeness: a human must review whether the contract captures the objective. The evaluator cannot detect an omitted requirement in free text.
- Network-scale authority: no network partition, replicated consensus or multi-region propagation is tested. The revocation experiment uses two local processes against one SQLite database.
- Atomic enforcement: aggregate checks require a complete authoritative ledger and atomic check-and-reserve at the live write boundary. The revocation experiment tests synthetic writes, not CRM actions.
- Independent assurance: the native verifier source is now published in
native/. An audit package (AUDIT_PACKAGE.md) and differential test (differential_test.py) are provided. However, no named third party has completed an audit. A passing card description is not a build comparison. The native binary simulates most governance checks via hard-coded responses rather than computing them.
Conformance
Including governance_root and gate_decision MUST NOT be treated as proof of Runtime Authority Continuity. Legacy PSR-001 compatibility and authority-evidence verification are separate questions. The experimental Objective Contract profile is explicitly separate; migrating it into PSR-001 requires a versioned schema, canonicalization and trust-model review. A receipt establishes only the relationships actually verified against trustworthy evidence, not legal certification.
References
- RFC 2119 — Key words for use in RFCs
- RFC 8785 — JSON Canonicalization Scheme
- Ed25519 — Edwards-curve Digital Signature Algorithm
- OWASP Agentic Top 10 — Agentic security risks
- NIST AI RMF 1.0 — AI Risk Management Framework
Appendix A: JSON Schema
A machine-readable JSON Schema for PSR-001 receipts is available at /specs/psr-001/schema.json. Implementations SHOULD validate receipts against this schema before accepting them.
Appendix B: Mapping to Existing Implementations
PrimeSwarm VerificationReceipt (dgv-verifier)
The existing VerificationReceipt struct maps to PSR-001 as follows:
| PSR-001 field | VerificationReceipt field |
|---|---|
gate_state | gate_status (OPEN→ALLOW, CLOSED→DENY, ESCALATE→ESCALATE) |
evidence.residual | residual_final |
evidence.indices_healed | indices_healed |
policy.script_hash | (computed from script path) |
input.input_hash | (computed from field values) |
receipt_hash | (not currently computed — REQUIRED for PSR-001 conformance) |
The existing EvidencePack struct maps to PSR-001 as follows:
| PSR-001 field | EvidencePack field |
|---|---|
receipt_id | run_id |
timestamp | created_unix_ms |
policy.version | policy_version |
evidence.replay_inputs | replay_inputs |
receipt_hash | decision_hash |
identity.agent_id | agent_id |
AGT's audit entry maps to PSR-001 as follows:
| PSR-001 field | AGT Audit Entry field |
|---|---|
timestamp | timestamp |
gate_state | decision (allow→ALLOW, deny→DENY, escalate→ESCALATE, warn→ALLOW+reason_code) |
reason | reason |
identity.agent_id | agent_id |
evidence.reason_codes | (derived from policy rule name) |
policy.script_hash, input.input_hash, and evidence.replay_inputs to enable independent replay.