Skip to content

spec/adoption: the profile MUSTs an Agent Card declaration that nothing implements #92

Description

@imran-siddique

The gap

docs/spec/profile.md states a normative requirement:

An agent supporting this profile MUST declare the extension URI in its Agent Card, and a client opting in MUST signal it per the A2A extension mechanism (the A2A-Extensions header for HTTP and JSON-RPC bindings, or the equivalent binding metadata).

There is no Agent Card anywhere in the implementation. The only .well-known path we serve is our own:

$ grep -rn "agent-card\|AgentCard\|well-known" src/
src/cmcp_runtime/... (none)
src/ca2a_runtime/transport/server.py:  CHANNEL_PATH = "/.well-known/ca2a/channel"

A2A serves the card at /.well-known/agent-card.json. We neither publish one nor read one. So:

  • An adopter cannot comply with a MUST in our own spec using our own runtime.
  • The reference server is, by our spec's own wording, not a conforming cA2A agent.
  • Discovery does not work in the direction that matters: a client has no way to find out that a peer speaks the profile before it tries. Today the only way to discover cA2A support is to send a cA2A request and see whether it is understood.

docs/spec/transport.md also says the Signed Agent Card "remains the A2A identity anchor" and that cA2A "treats it as the anchor the delegation credential's subject and the peer's attestation measurement are checked against", with the check "not yet wired". That is a second, larger unimplemented claim resting on the same missing piece.

Scope

Minimum, to make the MUST satisfiable:

  • Publish an Agent Card from the reference server that declares the cA2A extension URI, at the path A2A specifies.
  • Read a peer's card on the client side and confirm it declares the extension before sending a cA2A request, rather than discovering support by failure.
  • Send the A2A-Extensions opt-in header on outbound requests, and decide what the server does when it is absent but cA2A metadata is present (today it just parses it).

Deliberately not in the minimum:

  • Verifying the card's signature and binding a delegation subject or an attestation measurement to it. That is the identity-anchor claim, it is a real design question, and conflating it with "publish a card" would stall the small fix behind the big one. It should get its own issue once the card exists.

What needs deciding

  • Whether the card is generated from PeerNode state or supplied as config. Generated means it cannot drift from what the node actually enforces; supplied means an operator controls what is published, which is what most deployments will want.
  • Whether a missing or non-declaring peer card is a refusal or a warning on the client side. Per the pattern used everywhere else in this stack it should be recorded and configurable, defaulting to permissive, because most peers today have no card at all.
  • Whether to weaken the spec's MUST to a SHOULD until the card is implemented, or leave the MUST and treat the implementation as the thing that is behind. Leaving a MUST that our own reference violates is the sort of thing a reviewer at graduation will find.

Acceptance

  • The reference server publishes a card declaring the extension URI, fetched and asserted in a test.
  • A client can decide whether a peer speaks cA2A from its card alone, without sending a task.
  • profile.md and transport.md say exactly which parts of the Agent Card story are implemented and which are not.

Related: #91 (SDK interop — the SDK has its own card handling, so the two should not invent different ones), #18 (profile stability with AAIF/Google), #47.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions