Add two BDD scenarios to server_lifecycle.feature that bring
previously unreachable code under coverage:
- "ServerLifecycle start runs uvicorn and marks lifecycle stopped":
mocks uvicorn.Server so start() completes without binding a real
port; covers the full start() body (lines 105-133) and the
_install_signal_handlers() call path (lines 148-159). Signal
handlers are saved and restored in a finally block so the test
runner's SIGINT/SIGTERM handlers are not permanently clobbered.
- "ServerLifecycle request_shutdown is a no-op when server not
started": calls request_shutdown() on a fresh lifecycle where
_server is None; covers the False branch of the
`if self._server is not None:` guard (previously only the True
branch was exercised by the mock-server scenario).
Also marks the diagnostics-only skill fallback in agent_card.py
(lines 244-251) with # pragma: no cover — the current A2aLocalFacade
never surfaces _cleveragents/diagnostics/ operations, making this
branch structurally unreachable without a future facade extension.
ISSUES CLOSED: #867
Add BDD scenarios for two previously uncovered asgi_app.py paths:
- A2A endpoint returns -32700 for actual invalid JSON bytes (parse error)
- A2A endpoint returns -32603 when facade dispatch raises unexpectedly
The existing "malformed request" scenario sent valid JSON with bad schema,
exercising only the -32600 Invalid Request path. The parse error path
(await request.json() catching JSONDecodeError) and the catch-all
exception handler were never triggered, dropping coverage below 96.5%.
Also marks run_server() with # pragma: no cover — it is a blocking entry
point that wraps ServerLifecycle.start() and cannot be exercised in a
unit-test environment without starting a real server.
ISSUES CLOSED: #867
A2aVersion.CURRENT was incorrectly set equal to JSONRPC_VERSION ("2.0"),
conflating the CleverAgents A2A API version with the JSON-RPC protocol
version. The Agent Card `version` field represents the CleverAgents API
version ("1.0"), not the JSON-RPC wire protocol version ("2.0").
Restores A2aVersion.CURRENT = "1.0" and SUPPORTED = ("1.0",), fixing
4 failing BDD scenarios in agent_card.feature and the Robot integration
test "Build Agent Card From Facade".
ISSUES CLOSED: #867
- Fix asgi_app.py: use a2a_request.method instead of a2a_request.operation
(A2aRequest model was updated in master to use JSON-RPC 2.0 field names)
- Fix server_lifecycle_steps.py: send JSON-RPC 2.0 wire format with
"method" field; check result.status instead of top-level status
- Fix server_lifecycle.feature: update step name to match new step
definition (A2A response result status)
- Fix helper_server_lifecycle.py: use "method" field in JSON-RPC 2.0
payload; check result.status in response
- Fix malformed JSON parse error: wrap request.json() in try/except,
return -32700 Parse error instead of unhandled HTTP 500
- Fix JSON-RPC error responses: add required 'id' field to all error
responses per JSON-RPC 2.0 Section 5
- Fix HTTP status codes: return HTTP 200 for all JSON-RPC responses
(error codes expressed in JSON body per JSON-RPC 2.0 over HTTP)
- Fix error message leakage: return generic messages instead of raw
Pydantic ValidationError internals (CWE-209)
- Add catch-all exception handler returning -32603 Internal error
- Fix Agent Card url field: use base server URL without /a2a suffix;
interfaces[0].url correctly uses endpoint URL with /a2a suffix
- Fix 0.0.0.0 host: substitute 127.0.0.1 for Agent Card URL
- Fix context typing: replace context: Any with context: Context in
all step files per project convention
- Fix inline imports: move all imports to top of step files
- Fix _COMMANDS typing: use dict[str, Callable[[], None]] to avoid
type: ignore suppression in helper files
- Add BDD scenarios for entity-sync and namespace-mgmt skill enumeration
- Update server_lifecycle.feature: correct HTTP status assertions to 200
ISSUES CLOSED: #867
Implement A2A Agent Card discovery per ADR-047 and issue #867:
- AgentCard Pydantic model (agent_card.py) with nested models for
skills, capabilities, extensions, security schemes, and interfaces.
- Factory function build_agent_card() enumerates supported operations
from the facade and maps them to A2A skills (plan-lifecycle,
registry-crud, context-mgmt, entity-sync, namespace-mgmt,
health-diagnostics).
- Version negotiation: supportedVersions and version fields from
A2aVersion constants.
- A2A conformance validation (validate_agent_card_conformance) checks
required fields, version support, and structural integrity.
- Updated ASGI app to build the Agent Card from the facade model
instead of a raw dict, with conformance validation at startup.
- Behave BDD tests: 34 scenarios covering model construction, field
validation, conformance checks, serialization, endpoint responses,
and skill enumeration from facade operations.
- Robot Framework integration tests: 6 test cases for build, conformance,
endpoint, serialization, skill enumeration, and version info.
- Updated A2A package exports and CHANGELOG.
ISSUES CLOSED: #867