Skip to content

test(signing): add cross-SDK signature vectors - #1286

Open
ogasurfproject-jpg wants to merge 1 commit into
a2aproject:mainfrom
ogasurfproject-jpg:test/cross-sdk-signature-vectors
Open

ogasurfproject-jpg wants to merge 1 commit into
a2aproject:mainfrom
ogasurfproject-jpg:test/cross-sdk-signature-vectors

Conversation

@ogasurfproject-jpg

Copy link
Copy Markdown

Adds tests that pin what a change to _canonicalize_agent_card (#1278) has to keep: a card signed by another SDK still verifies here. Test only; no library code changes.

One caveat on that last test: the frozen card carries securityRequirements: [{}], a nested empty value whose canonical form is part of #2122. So it pins today's bytes, the ones this SDK and @a2a-js/sdk agree on, as agreed in #1278, and it needs updating if #2122 settles the other way. The docstring says so.

The reading-dependent group (s1-default-valued: description: "", skills: [], tags: [], extensions: []) is deliberately not lifted. Its expectations depend on #2122, and adding them now would lock in one answer before the spec does.

All 11 tests pass on main (fad0482). ruff check, ruff format --check and ty check are clean.

The production card is ours (HORIZON SHIELD publishes it). If you would rather not carry it in the repo, test_frozen_js_signed_production_card and its two files drop out cleanly.

cc @aeoess @kuangmi-bit

Pins what a change to _canonicalize_agent_card (a2aproject#1278) has to keep: a
card signed by another SDK still verifies here.

signing_interop_vectors.json carries the five s0-control vectors of the
language-neutral a2a-card-sign-v01 corpus, each lifted verbatim: one
card with every REQUIRED field and no field at its default value, signed
by this SDK, @a2a-js/sdk 1.3.0, a2a-go (main 534a60fc) and a reference
signer, plus the card edited after signing. These hold however
a2aproject/A2A#2122 is settled.

The frozen JS-signed production card from a2aproject/a2a-go#445 is
checked against the anchors used in a2aproject#1278. It carries a nested empty
value, so that test pins today's bytes and needs updating if #2122
settles the other way.

Test only; no library code changes.

Signed-off-by: Horizon <horizon@example.com>
@ogasurfproject-jpg
ogasurfproject-jpg requested a review from a team as a code owner September 30, 2026 23:30
@github-actions

Copy link
Copy Markdown

🧪 Code Coverage (vs main)

⬇️ Download Full Report

No coverage changes.

Generated by coverage-comment.yml

@aeoess

aeoess commented Oct 1, 2026

Copy link
Copy Markdown

I ran the 11 tests from this PR (at 82e4dde) against both commits in #1287. They pass on the descriptor-only commit 3f90712 and on the Rule 1 commit cdee28e.

The frozen JS-signed card also canonicalizes to 6410 bytes / c5d5384a… on both, matching your anchors. No changes were needed to your tests.

@ogasurfproject-jpg

Copy link
Copy Markdown
Author

Thanks for running them against both commits. That is the result this PR is built for: the five s0 vectors and the frozen card carry every REQUIRED field, so they hold under every reading of §8.4.1 and should stay green whichever way A2A#2122 is settled.

The reading-dependent cases stay out of this PR on purpose. The s2 group added to a2a-tck#246 (a REQUIRED field absent from the served JSON) is where the Rule 1 commit cdee28e departs from the shipping SDKs, and it is scored per reading there rather than pinned here. The numbers are in #1287 (comment).

This branch has not been deployed

No deployments
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.

2 participants