Skip to content

feat(conformance): add open_mandate_hash derivation vectors v0#279

Open
chopmob-cloud wants to merge 14 commits into
google-agentic-commerce:mainfrom
chopmob-cloud:feat/open-mandate-hash-conformance-vectors
Open

feat(conformance): add open_mandate_hash derivation vectors v0#279
chopmob-cloud wants to merge 14 commits into
google-agentic-commerce:mainfrom
chopmob-cloud:feat/open-mandate-hash-conformance-vectors

Conversation

@chopmob-cloud

Copy link
Copy Markdown

What

Lands the v0 conformance vector set for open_mandate_hash derivation proposed in #265.

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. 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 vectors
  • README.md — derivation rule, verification recipe, known implementation hazards

Vectors

Vector Pair invariant What it catches
baseline-001 reference Canonical baseline
object-key-order-002 MUST equal baseline JCS sorts object keys
array-order-003 MUST differ from baseline Array sorting bug
optional-fields-004 MUST differ from baseline Presence ≠ absence
currency-minor-unit-005 canonical form Float/decimal encoding
unicode-nfc-006a MUST differ from 006b Unicode normalisation
unicode-nfd-006b MUST differ from 006a Unicode normalisation

Cross-implementation validation

6 independent implementations, all 7/7 vectors + 4/4 pair invariants:

Implementation Language Authors
rfc8785@0.1.4 Python Trail of Bits
canonicalize@3.0.0 JavaScript Erdtman + Rundgren (RFC 8785 author)
gowebpki/jcs v1.0.1 Go @amavashev
cyberphone/json-canonicalization Java Rundgren (RFC 8785 reference impl)
serde_jcs 0.2.0 Rust @seritalien / Vauban
rfc8785 (fixed) Python Crest Systems (@andysalvo)

Full validation history in #265.

Prior adoption

PEAC Protocol has already adopted this derivation as normative in AP2-COMPOSITION.md:

"must not re-derive the open_mandate_hash from a non-JCS canonicalization or a non-SHA-256 digest function. The derivation in AP2 issue #265 is the only one PEAC recognizes for this composition pattern."

Test gate

  • No secrets in diff
  • Schema/conformance files only — no code changes

Closes #265.

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.
@chopmob-cloud chopmob-cloud requested a review from a team as a code owner June 6, 2026 04:05

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
"expected_jcs_bytes_b64": "<base64url of RFC 8785 canonical bytes>",
"expected_jcs_bytes_b64": "<standard base64 of RFC 8785 canonical bytes>",

Comment thread code/sdk/schemas/ap2/conformance/open_mandate_hash/README.md Outdated
Comment on lines +43 to +44
| `unicode-nfc-006a` | `different_hash_from:unicode-nfd-006b` | No Unicode normalisation |
| `unicode-nfd-006b` | `different_hash_from:unicode-nfc-006a` | No Unicode normalisation |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

low

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 |

Comment thread code/sdk/schemas/ap2/conformance/open_mandate_hash/vectors-v0.json Outdated
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Proposal] v0 conformance vectors for open_mandate_hash derivation (cross-impl validated)

1 participant