Live Verification

action-ref-v1 Conformance

Vectors fetched from action-ref-verify. Digests computed server-side via JCS (RFC 8785) + SHA-256. Nothing hardcoded.

repo updated 2026-05-20 | revalidates hourly

Why this matters

When an AI agent pays for a service, nothing currently proves what the agent did after payment. The action_ref binds a payment to a specific action through a deterministic, re-derivable hash. For this to work across implementations, every party must produce identical hashes from identical inputs. This page verifies that property live against the published vector set.

9
Vectors (live)
8/9
Conformant

Live verification results

VectorExpectedLiveDigest (first 16)Notes
giskard-baselinePASSCONFORMANTfdd7f810499f06be...First independent verification of action-ref-v1. Source: x402-foundation/x402#2332
ms-precision-trapFAILCONFORMANT999919e8b69846be...Timestamp drops millisecond precision (.000Z -> Z). Semantically identical time, but JCS treats strings as opaque bytes. Correct hash for this input is 999919e8b69846be116934c9ca3f72eaef6d54aac5ab17f1a6b050cae7bda197, not the baseline hash. Implementations that normalize timestamps before hashing will produce the wrong action_ref.
trailing-whitespaceFAILCONFORMANT37caadb35cfdedf1...Trailing space in action_type. JCS preserves string content exactly. Implementations that trim whitespace before canonicalization will silently produce a different hash. Correct hash for this input is 37caadb35cfdedf144827b121e004c81b471c7f22120eb372707c1814699427e.
extra-field-ignoredPASSNON-CONFORMANTf7c721770d174fec...Extra field in preimage object. The verifier extracts only the 4 canonical fields (action_type, agent_id, scope, timestamp) before canonicalization. Extra fields are ignored. This is the correct behavior: action_ref is computed from the canonical 4 fields, not from the full input object. Implementations that include extra fields in the JCS input will produce a DIFFERENT hash. Open question: should the spec explicitly require field extraction, or should it hash the full object? This vector tests that our verifier handles the extraction correctly.
key-order-resiliencePASSCONFORMANTfdd7f810499f06be...Keys in reverse order. JCS sorts lexicographically regardless of insertion order. This MUST produce the same hash as the baseline. Implementations that hash insertion-order JSON instead of canonicalized JSON will fail this test.
rfc8785-negative-zeroPASSCONFORMANTd7a591f6afb04565...Tests that the JCS implementation handles standard preimage fields. RFC 8785 requires -0 to serialize as 0. This vector validates the canonicalization pipeline end-to-end with a simple, known-good input.
rfc8785-key-sorting-stressPASSCONFORMANTfdd7f810499f06be...Same preimage as giskard-baseline but with keys in reverse alphabetical order. RFC 8785 Section 3.2.3 requires lexicographic key sorting. JCS must produce identical canonical bytes regardless of input key order. This is the most critical RFC 8785 property for action_ref correctness.
x402-2357-shared-fixturePASSCONFORMANT10d8a38c01d86721...Three-way interop vector from x402-foundation/x402#2357. Shared payment_hash and action_ref bind Axis 1 (seritalien/zkpay STARK), Axis 2 (feedoracle hybrid-PQC ES256K+ML-DSA-65), and Axis 3 (this harness). Uses timestamp_ms (epoch integer) per the original #2332 preimage spec. JCS canonicalization (RFC 8785) produces identical bytes across Node.js, Python, and Rust runtimes.
field-name-load-bearingFAILCONFORMANT89a312bc953f7bac...Same semantic instant as 0008 (1747728000000 ms = 2025-05-20T00:00:00.000Z) but using timestamp (RFC 3339 string) instead of timestamp_ms (epoch integer). JCS treats field names as opaque bytes: 'timestamp' and 'timestamp_ms' produce different canonical output and different digests. This vector MUST FAIL against the 0008 action_ref, proving the field name is load-bearing. Implementations that normalize between the two forms before hashing will produce silent interop failures.

Method

Derivation: action_ref = SHA-256(JCS(preimage))

Canonicalization: RFC 8785 (JCS)

Timestamp: timestamp_ms (epoch integer)

Field names: load-bearing opaque bytes

Independent reproductions

Node.js: action-ref-verify v0.3.0

Rust: vauban-zkpay-x402 (serde_jcs 0.2.0)

Python: FeedOracle (rfc8785 0.1.4)

4-lang: AlgoVoi (Python/JS/Go/Java)

Verify API

Submit an action receipt and get a conformance verdict.

curl https://verify.crestsystems.ai/health

curl -X POST https://verify.crestsystems.ai/v1/verify \
  -H "Content-Type: application/json" \
  -d '{
    "action_ref": "<sha256-hex>",
    "preimage": {
      "action_type": "...",
      "agent_id": "...",
      "scope": "...",
      "timestamp_ms": 1747728000000
    }
  }'

Vectors are fetched live from GitHub and verified server-side. Reports describe conformance at render time, not cached assertions.

Maintained by Crest Deployment Systems