A2A agent that audits another deployed agent's source pre-deploy. Reads the target Gitea repo via a short-lived read-only token minted through ctx.mint_gitea_token(), runs an inner DeepAgents graph backed by GiteaBackend, and emits a typed ReviewReport. Skill bundles: - security-anti-patterns (credentials, eval, sandbox bypass, egress) - a2apack-best-practices (class shape, decorators, types, timeouts) - grant-scope-evaluation (declared vs actual workspace scope) Tools: - sandbox_a2a_card : round-trips the project through microsandbox - sandbox_ruff_check: objective static checks - submit_review_report: typed final report 7 smoke tests pass; agent card loads cleanly via `a2a card`.
3.3 KiB
3.3 KiB
name, description
| name | description |
|---|---|
| a2apack-best-practices | Shape of a well-formed A2A Pack agent. Use when reviewing agent.py for class structure, @skill decorators, type hints, error handling, idempotency, and timeouts. |
A2A Pack Best Practices
Use this skill when reviewing the shape of an agent — not its security
posture (that's security-anti-patterns) and not its grants (that's
grant-scope-evaluation).
Class contract
- The class must inherit from
A2AAgent[ConfigT, AuthT]with concrete generic parameters. Missing parameters →warning. - Class variables
name,description,versionmust be set. Missing →warning.descriptionshorter than ~30 chars →info. config_modelandauth_modelmust reference declared Pydantic models (orNoAuth). A mismatched generic and class var →warning.
@skill decorators
- Every public skill should declare
description. Missing →warning. timeout_secondsshould be set explicitly. Default is short; long-running skills that omit it will time out in production. Missing on a skill that does file work, LLM calls, or sandbox exec →warning.stream=Trueis required if the skill callsctx.emit_progress,ctx.ask,ctx.collect, orctx.request_scope. Missing while the body does emit →critical.idempotent=Truematters for skills that can be safely retried. Skills that write files, mutate state, or charge money →infoif not set explicitly (either direction is fine, just be intentional).
Type hints
- Every skill parameter must have a concrete type hint (no
Any, no missing annotation). The Card'sinput_schemais built from these. Missing →warning. - Return type should be
dict[str, Any], a concrete Pydantic model, orstr. Returning untyped values surprises callers →info.
Error handling
- Skills should return structured error dicts (e.g.
{"error": "..."}), not raise unhandled exceptions for expected failure modes (bad input, missing workspace, timeouts). Bareraisefor invalid input →info. try/except Exceptionthat swallows the error without logging or returning →warning.
ctx.workspace / ctx.sandbox usage
- If the skill calls
ctx.workspace_backend(), the class must declareworkspace_access = WorkspaceAccess.dynamic(...). Mismatch →critical. - Subprocesses that produce user-visible files must run through
ctx.workspace_shellorctx.workspace_python, not rawasyncio.create_subprocess_exec. Already covered insecurity-anti-patternsbut worth a second look here.
Recursion limits
- If the skill invokes a DeepAgents graph via
ainvokeorastream_events, it must passconfig={"recursion_limit": 500}to match agent-builder. Missing →warning.
Manifest (a2a.yaml)
namemust match the agent'snameclass var. Mismatch →critical.entrypointmust point at a realmodule:Class. Stub or broken →critical.versionshould be semantic (major.minor.patch). Bad shape →info.
Severity rubric (specific to this skill)
critical— breaks the runtime contract (stream/emit mismatch, manifest doesn't import, name disagreement).warning— works today but degrades the developer or caller experience (no timeout, no type hint, bare raise).info— style nudges.