feat(conformance): add open_mandate_hash derivation vectors v0#279
feat(conformance): add open_mandate_hash derivation vectors v0#279chopmob-cloud wants to merge 14 commits into
Conversation
Lands the v0 conformance vector set for open_mandate_hash derivation proposed in google-agentic-commerce#265, cross-validated across 6 independent implementations. Derivation rule: open_mandate_hash = SHA-256(JCS_RFC8785(unsigned_open_checkout_mandate_body)) Hash input is the mandate claims object, NOT the JWS compact form. 7 vectors covering the canonicalisation rules that catch implementation divergence in practice: - baseline-001: reference - object-key-order-002: JCS sorts object keys (MUST be same hash as baseline) - array-order-003: arrays are order-significant (MUST differ from baseline) - optional-fields-004: presence != absence (MUST differ from baseline) - currency-minor-unit-005: integer minor units only (no float/decimal) - unicode-nfc-006a: no Unicode normalisation (MUST differ from 006b) - unicode-nfd-006b: no Unicode normalisation (MUST differ from 006a) Cross-validated: Python rfc8785@0.1.4, JS canonicalize@3.0.0 (RFC 8785 author), Go gowebpki/jcs v1.0.1, Java cyberphone/json-canonicalization (RFC 8785 reference), Rust serde_jcs 0.2.0, Python rfc8785 (Crest). All 6 implementations: 7/7 vectors + 4/4 pair invariants. PEAC Protocol has already adopted this derivation as normative in AP2-COMPOSITION.md (peacprotocol/peac). Closes google-agentic-commerce#265.
There was a problem hiding this comment.
Code Review
This pull request introduces conformance vectors for the AP2 open_mandate_hash derivation rule, adding a detailed README and a JSON file containing seven test vectors. The feedback suggests correcting the description of the base64 encoding in the README to specify standard base64 instead of base64url, updating the vector IDs in the README table to use their full names for consistency, and adding a trailing newline to the JSON file.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| { | ||
| "vector_id": "ap2-omh-v0-<name>", | ||
| "mandate_body": { ... }, | ||
| "expected_jcs_bytes_b64": "<base64url of RFC 8785 canonical bytes>", |
There was a problem hiding this comment.
The description states that expected_jcs_bytes_b64 is the base64url of the JCS bytes. However, the actual values in vectors-v0.json are encoded using standard base64 (including padding = and / characters). The description should be updated to specify standard base64 to avoid confusion for implementers.
| "expected_jcs_bytes_b64": "<base64url of RFC 8785 canonical bytes>", | |
| "expected_jcs_bytes_b64": "<standard base64 of RFC 8785 canonical bytes>", |
| | `unicode-nfc-006a` | `different_hash_from:unicode-nfd-006b` | No Unicode normalisation | | ||
| | `unicode-nfd-006b` | `different_hash_from:unicode-nfc-006a` | No Unicode normalisation | |
There was a problem hiding this comment.
The expectations in the table use short names (e.g., unicode-nfd-006b) instead of the full vector IDs (e.g., ap2-omh-v0-unicode-nfd-006b) defined in vectors-v0.json. Updating these to match the exact IDs ensures consistency for automated test runners.
Suggested changes:
| `unicode-nfc-006a` | `different_hash_from:ap2-omh-v0-unicode-nfd-006b` | No Unicode normalisation |
| `unicode-nfd-006b` | `different_hash_from:ap2-omh-v0-unicode-nfc-006a` | No Unicode normalisation |…nstant, whitespace in constructor
Apply google-java-format 1.35.0 (the version super-linter runs) to satisfy GOOGLE_JAVA_FORMAT. Whitespace and line-wrapping only, no logic changes.
The repo runs google-java-format and Sun-style Checkstyle together,
whose rules contradict (gjf: {} and 100-col; checkstyle: { } and
80-col), so no Java formatting passes both validators. Drop JcsRunner
and package-info; the Python, Node, and Go runners and the vectors
remain. The Java runner can return once the repo adds a Checkstyle
config.
Addresses review note: the field is standard base64 (with padding and +// characters), not base64url.
What
Lands the v0 conformance vector set for
open_mandate_hashderivation proposed in #265.Derivation rule
Hash input is the mandate claims object, not the JWS compact form. This is the load-bearing interop rule: JWS re-encoding by intermediaries changes the envelope even when the underlying payload is identical.
Location
code/sdk/schemas/ap2/conformance/open_mandate_hash/vectors-v0.json— 7 conformance vectorsREADME.md— derivation rule, verification recipe, known implementation hazardsVectors
baseline-001object-key-order-002array-order-003optional-fields-004currency-minor-unit-005unicode-nfc-006aunicode-nfd-006bCross-implementation validation
6 independent implementations, all 7/7 vectors + 4/4 pair invariants:
rfc8785@0.1.4canonicalize@3.0.0gowebpki/jcs v1.0.1cyberphone/json-canonicalizationserde_jcs 0.2.0rfc8785(fixed)Full validation history in #265.
Prior adoption
PEAC Protocol has already adopted this derivation as normative in
AP2-COMPOSITION.md:Test gate
Closes #265.