a2aproject / a2aproject/a2a-rs

a2acli: card get --validate against the A2A JSON schema

Open
#185 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
75
Forks
19
Avg merge
11h 27m
Merged PRs (30d)
21

Description

Part of #181 (Tier 2).

## Summary

`A2ACLI_CARD_GET_002` (Tier 2) requires `card get --validate` — validate the Agent Card against the A2A schema (§10.1).

`a2acli` deserializes the card into `a2a::AgentCard` and reports a deserialization failure as `A2ACLI_ERR_CARD_INVALID` (#173). That is a type check, not a schema check: it accepts a card that parses into the Rust type while violating the published schema, and it says nothing about *which* constraint failed.

The canonical schema is [`A2A/specification/json/a2a.json`](https://github.com/a2aproject/A2A/blob/main/specification/json/a2a.json) — the same source the Python SDK generates its types from.

## Why

`card get` is the command you reach for when an agent is not behaving, and "is this card actually valid?" is the first question. Serde's answer is binary and its error messages describe Rust types, not schema constraints, so a card that is structurally wrong in a way serde tolerates (a field with a permissive type, an unrecognized enum handled leniently) passes today.

## A note on conforming to the canonical implementation

The Go CLI validates the card **unconditionally** rather than behind a flag — `internal/cli/card_get.go` calls `cfg.agentCard.Validate()` on every `card get`, and has no `--validate`. `COMPLIANCE.md` names the flag, so the specification and the reference implementation disagree here.

Proposal: implement `--validate` as the spec names it, and keep the current unconditional type check as-is. That satisfies the requirement without changing default behavior, and leaves room to align with Go if the spec is later amended toward unconditional validation. Worth raising upstream in `a2a-cli` either way.

## Scope

- [ ] Add `--validate` to `card get`: validate the fetched card against the A2A JSON schema and report the outcome.
- [ ] Decide how the schema is obtained — vendored into the repo at a pinned A2A version, or generated into `a2a` at build time. Vendoring is simpler; either way the A2A version it came from must be recorded and reported, because "valid" is meaningless without saying valid against what.
- [ ] Report **every** violation, not just the first, with a JSON-pointer path to each — a card with three problems should take one run to diagnose.
- [ ] `text` renders violations as a block under its own `Label:` line (§11.2); `-o json` carries them as structured data.
- [ ] A card that fails validation exits non-zero with `A2ACLI_ERR_CARD_INVALID` (Appendix D), consistent with the existing deserialization failure.
- [ ] `--validate` against an unreachable agent still reports `A2ACLI_ERR_UNREACHABLE`; validation is not reached.
- [ ] Tests: a valid card passes; a card with a missing required field, a wrong type, and a bad enum value reports all three with their paths.

## Requirements closed

| ID | Requirement |
| --- | --- |
| `A2ACLI_CARD_GET_002` | `card get --validate` — validate the Agent Card against the A2A schema (§10.1) |

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.