a2aproject / a2aproject/a2a-js

[Bug]: canonicalizeAgentCard drops REQUIRED fields with default values, contradicting the §8.4.1 worked example

Aperta
#627 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
TypeScript
Stelle
613
Fork
169
Merge medio
1g 6h
PR unite (30g)
21

Descrizione

**What happened?**

`canonicalizeAgentCard` in `src/signature.ts` runs `cleanEmpty` before `jcsStringify`, and `cleanEmpty` deletes empty strings, empty arrays and empty objects unconditionally. Spec §8.4.1 rule 1 says the opposite for one class of field: "Required fields: Fields marked with `REQUIRED` MUST always be present, even if the field value matches the default." The section then prints a worked example that turns on exactly this, deriving `description: ""` include and `skills: []` include, and shows the canonical result.

Running the section's own fragment through this SDK gives `{"capabilities":{"pushNotifications":false,"streaming":false},"name":"Example Agent"}` where the specification says `{"capabilities":{"pushNotifications":false,"streaming":false},"description":"","name":"Example Agent","skills":[]}`. `a2a-python` produces byte-identical output to this SDK here, so the two agree with each other and both differ from the text. That agreement is why the divergence is invisible: no cross-implementation test can see it, and it will surface the first time somebody writes a third canonicalizer from the specification rather than from one of these two. `a2aproject/a2a-go#141` is open to do precisely that.

I want to be clear that I do not think this is straightforwardly this SDK's fault, and I have filed the substance against the specification at a2aproject/A2A#2122. `description` is a proto3 singular string with no presence carrying only a `google.api.field_behavior = REQUIRED` annotation, and ADR-001 makes ProtoJSON normative. ProtoJSON does not read `field_behavior`, so `AgentCard.toJSON` cannot distinguish "REQUIRED and defaulted" from "unset" and no stock encoder can produce the bytes §8.4.1 prints. Whichever way the specification resolves that, this SDK will need a change: either `cleanEmpty` grows a list of REQUIRED field paths that it never strips, or the specification's rule 1 and worked example change to match what a ProtoJSON encoder emits and this code is already correct. I would rather not send a patch until that is decided, but I wanted the divergence recorded here so it is not rediscovered by whoever writes the third implementation.

Separately and unrelated to the above, I checked this SDK's canonicalization against two independent RFC 8785 implementations, `rfc8785.py` and `gowebpki/jcs` v1.0.1, across non-ASCII string content, non-BMP object keys and ECMAScript number serialization. This SDK is conformant on all three, and the divergence I found in the cross-SDK direction is on the Python side, which I have reported there. `jcsStringify` is doing the right thing.

One question rather than a bug: `verifyAgentCardSignature` rejects any signature whose protected header lacks `typ`, `kid` or `alg`. §8.4.2 lists `typ` under "The protected header MUST include:" but the bullet itself says `typ` "SHOULD be set to \"JOSE\" for JWS", so it is not obvious from the text whether absence of `typ` is a verification failure. In practice cards signed by `a2a-python` always carry a `typ` because PyJWT stamps one, but the value is `"JWT"` rather than `"JOSE"` unless the caller sets it explicitly, so this SDK currently accepts a header the specification arguably discourages while rejecting one it arguably permits. I have asked on a2aproject/A2A#2122 and will follow whatever the answer is.

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.