a2aproject / a2aproject/a2a-rs
a2acli: card get --validate against the A2A JSON schema
- 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
Assessment
This issue has not been assessed yet.