# api.qa report — api.lawyer

> **Grade A+** · AX score **10/10** · remote mode · attested

- verified: 2026-08-23T14:29:17.528Z
- verifier: api.qa v0.3.0 · seed 4165428812 (replayable)
- evidence digest: `c82d6148d600940dfc674eaed74bf0fefa39a4b0f405363bb76951518edd73c1`
- report digest: `be1d6942998ef64c1ba1554305aa522b73c585a970604d24a4f725420fb186f8` (Ed25519-signed)

## AX score (the 10-point checklist)

| # | check | verdict |
| --- | --- | --- |
| 1 | llms.txt is served and agent-actionable | PASS |
| 2 | /.well-known/agents.json capability card parses | PASS |
| 3 | /icp.json self-classification surface | PASS |
| 4 | root content-negotiates (curl → markdown, browser → HTML, agent JSON → JSON/non-HTML) | PASS |
| 5 | machine-readable API contract (OpenAPI) is published | PASS |
| 6 | MCP interface declared with transport + tools | PASS |
| 7 | at least one declared endpoint answers 2xx with no key | PASS |
| 8 | payment boundaries answer as structured 402 offers | PASS |
| 9 | surfaces cross-reference each other (linkset) | PASS |
| 10 | attestation/identity ladder is declared | PASS |

## Check details

### PASS — llms.txt is served and agent-actionable (`llms-txt`)

markdown with an H1 and substantive content

### PASS — /.well-known/agents.json capability card parses (`agents-json`)

valid JSON; name="api.lawyer", 9 http endpoint(s) declared

### PASS — /icp.json self-classification surface (`icp-json`)

valid JSON with agent_classes — an agent can self-classify

### PASS — root content-negotiates (curl → markdown, browser → HTML, agent JSON → JSON/non-HTML) (`content-negotiation`)

Accept: */* got non-HTML text; Accept: text/html got HTML; Accept: application/json got a parseable JSON body

### PASS — machine-readable API contract (OpenAPI) is published (`openapi`)

OpenAPI parses; 40 path(s), 9 keyless GET candidate(s)

### PASS — MCP interface declared with transport + tools (`mcp-declared`)

mcp: stdio with tools [file_provisional, get_matter, advance_matter] (presence-grade; stdio not spawned)

### skip — MCP endpoint publishes RFC 9728 protected-resource metadata (`mcp-oauth-protected-resource`)

MCP declared stdio transport (no url) — not an OAuth resource server; skipped

### skip — authorization server publishes RFC 8414 metadata (openid-configuration fallback) (`mcp-oauth-as-metadata`)

MCP declared stdio transport (no url) — not an OAuth resource server; skipped

### skip — authorization server advertises PKCE S256 (RFC 7636) (`mcp-pkce`)

MCP declared stdio transport (no url) — not an OAuth resource server; skipped

### skip — authorization server supports Dynamic Client Registration (RFC 7591) (`mcp-oauth-dcr`)

MCP declared stdio transport (no url) — not an OAuth resource server; skipped

### skip — protected-resource declares an RFC 8707 audience bound to the MCP origin (`mcp-oauth-resource-indicators`)

MCP declared stdio transport (no url) — not an OAuth resource server; skipped

### skip — unauthenticated MCP request returns 401 with WWW-Authenticate → protected-resource metadata (`mcp-www-authenticate`)

MCP declared stdio transport (no url) — not an OAuth resource server; skipped

### skip — AAP discovery advertises Ed25519 + approval methods + register/status/revoke + jwks_uri (`aap-discovery`)

no /.well-known/agent-configuration document (2xx) — target does not claim the Agent Auth Protocol

### skip — auth.md agent-identity advertised (agent_auth identity/claim/events + ID-JAG + SET revocation) (`authmd-agent-identity`)

no authorization-server metadata resolved (no MCP/OAuth AS declared) — nothing advertises an agent_auth block

### PASS — at least one declared endpoint answers 2xx with no key (`keyless-flow`)

3/3 sampled endpoint(s) answered 2xx keyless (seed 4165428812)

### PASS — payment boundaries answer as structured 402 offers (`offers-402`)

observed Pricing Document declares "model": "free" and the card declares no purchasable surface (no monetization.offers, no monetization.probe) — no 402 boundary exists to prove, so the offer obligation is satisfied vacuously (AXP Clause 5/A.5: the metering obligations bind iff the observed model is "metered")

### PASS — surfaces cross-reference each other (linkset) (`linkset`)

Link header present on root

### PASS — attestation/identity ladder is declared (`attestation`)

attestation ladder declared (agents.json attestationLadder / icp.json ladder)

### PASS — sampled responses conform to their published schemas (`schema-conformance`)

2 sampled response(s) conform to their OpenAPI schemas

### PASS — claimed endpoints actually exist (no ghost surface) (`claims-honesty`)

every probed claimed endpoint exists (no 404/5xx)

### PASS — live responses match the published OpenAPI contract (full diff) (`contract-diff`)

live surface conforms to every declared contract; 3 additive deviation(s) (undeclared field/endpoint — live has more than declared, non-breaking)

### skip — MCP registry manifest (server.json) is valid and registry-publishable (`mcp-server-json`)

no server.json manifest served at the well-known/declared path — target is not claiming MCP-registry publishability

### skip — declared MCP remote resolves live (initialize → tools/list advertises tools) (`mcp-remote-live`)

no server.json manifest — no registry remote to resolve

### skip — domain/account can prove ownership to publish under its reverse-DNS namespace (`mcp-registry-ownership`)

no server.json manifest — no namespace ownership to prove

### skip — server is present in the official MCP registry (informational) (`mcp-registry-presence`)

no server.json manifest — registry presence not applicable

### skip — MCP-UI tool result links a ui:// resource served with an MCP-Apps MIME (`mcp-ui-resource-linkage`)

no MCP-UI declared (no tool advertises a ui:// template) — informational not-ready, not a failure

### skip — ui:// srcDoc is self-contained (no remote code) and CSP-safe (`mcp-ui-self-contained`)

no MCP-UI declared (no tool advertises a ui:// template) — informational not-ready, not a failure

### skip — no secret leaks into a model-visible channel (content/structuredContent) (`mcp-ui-envelope-hygiene`)

no MCP-UI declared (no tool advertises a ui:// template) — informational not-ready, not a failure

### skip — widget structuredContent is consistent with the agent/API register (no divergence) (`mcp-ui-register-parity`)

no MCP-UI declared (no tool advertises a ui:// template) — informational not-ready, not a failure

### skip — first-render-without-input tolerance + tool annotations / widgetDescription present (`mcp-ui-host-render`)

no MCP-UI declared (no tool advertises a ui:// template) — informational not-ready, not a failure

### skip — UI-message-stream is served with the v1 stream header and an SSE content-type (`ui-stream-transport`)

no UI-message-stream face declared (no interfaces.uiMessageStream) — informational not-ready, not a failure

### skip — SSE framing is valid — data:{json} chunks, a bare [DONE] terminal, each payload a typed JSON part (`ui-stream-framing`)

no UI-message-stream face declared (no interfaces.uiMessageStream) — informational not-ready, not a failure

### skip — every UI-message-stream part is spec-correct (known type, required fields present) (`ui-stream-part-shapes`)

no UI-message-stream face declared (no interfaces.uiMessageStream) — informational not-ready, not a failure

### skip — no secret leaks into any UI-message-stream part (token/key in a part → FAIL) (`ui-stream-envelope-hygiene`)

no UI-message-stream face declared (no interfaces.uiMessageStream) — informational not-ready, not a failure

### skip — tool-output-available `output` is byte/JSON-consistent with the JSON twin (no divergence) (`ui-stream-parity`)

no UI-message-stream face declared (no interfaces.uiMessageStream) — informational not-ready, not a failure

### skip — a DECLARED Digital Link interface serves a schema-valid GS1 resolver description file at its well-known (`digital-link-resolver`)

no Digital Link interface declared (agents.json `interfaces.digitalLink` absent) — the interface is OPTIONAL and this card does not claim it, so nothing was fetched and nothing is judged; under a pinned must:pass this fails closed

### skip — a DECLARED test-suite interface publishes a digest-pinned suite the surface actually passes (`published-test-suite`)

no published test suite interface declared (agents.json `interfaces.testSuite` absent) — the interface is OPTIONAL and this card does not claim it, so nothing was fetched and nothing is judged; under a pinned must:pass this fails closed

### skip — every capability the card declares is exercised by a passing test of its published suite (`capability-coverage`)

no published test suite interface declared (agents.json `interfaces.testSuite` absent) — capability coverage is judged only over a declared suite's run (A.8.7): nothing is claimed, so nothing is judged; under a pinned must:pass this fails closed

### PASS — home + typed bodies are machine-legible for every machine-class client (AXP Clause 3) (`machine-legible-home`)

home machine-legible under all three machine-class profiles; 3 sampled typed bodies non-HTML

### PASS — explicit Accept selects its face: text/html → HTML, application/json → JSON, text/markdown → markdown (AXP A.7 step 2) (`conneg-accept`)

text/html → HTML, application/json → JSON, text/markdown → markdown; JSON face is JSON-LD ($context/@context present)

### PASS — client-class defaults on Accept: */*: browser (Sec-Fetch) → HTML, known agent UA → markdown, everything else → JSON (AXP A.7 step 3) (`conneg-client-class`)

*/* defaults: bare client → JSON, Sec-Fetch navigation → HTML, agent User-Agent → markdown

### PASS — every face response advertises its sibling faces via Link rel="alternate" (AXP A.7.5) (`conneg-alternates`)

every face response advertises both sibling faces via Link rel="alternate" + type

### PASS — Link-advertised face addresses pin their face against a contradictory Accept (AXP A.7 rule 1) (`conneg-forced-face`)

all three Link-advertised face addresses serve their face under a contradictory Accept — the address wins

### PASS — card names its interfaces and card ↔ openapi ↔ llms.txt mutually cross-link (AXP Clause 6) (`card-interfaces-linked`)

card names 9 http endpoint(s) + mcp; card ↔ openapi ↔ llms.txt mutually cross-linked

### PASS — card-declared probe manifest is valid (`probe-manifest`)

probe manifest declares every required channel (observed pricing model: free); all entries same-origin GET on contract-declared paths

### PASS — capability card names its interfaces and cross-links its sibling surfaces (`card-interfaces-linked`)

card names interfaces (http/mcp) and cross-links llms.txt <-> agents.json <-> openapi

## Replay this verdict

The full evidence bundle is embedded in the JSON report. Judging is a pure
function of the bundle — re-run the checks over it and you MUST get this
same grade, or the report is forged / the verifier version changed:

```sh
curl -H 'accept: application/json' https://api.qa/api.lawyer | npx autonomous-qa rejudge
```
