feat: initial agent-reviewer meta-agent
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`.
This commit is contained in:
75
agent_reviewer/skills/a2apack-best-practices/SKILL.md
Normal file
75
agent_reviewer/skills/a2apack-best-practices/SKILL.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
name: a2apack-best-practices
|
||||
description: 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`, `version` must be set. Missing →
|
||||
`warning`. `description` shorter than ~30 chars → `info`.
|
||||
* `config_model` and `auth_model` must reference declared Pydantic
|
||||
models (or `NoAuth`). A mismatched generic and class var → `warning`.
|
||||
|
||||
## @skill decorators
|
||||
|
||||
* Every public skill should declare `description`. Missing → `warning`.
|
||||
* `timeout_seconds` should 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=True` is required if the skill calls `ctx.emit_progress`,
|
||||
`ctx.ask`, `ctx.collect`, or `ctx.request_scope`. Missing while the body
|
||||
does emit → `critical`.
|
||||
* `idempotent=True` matters for skills that can be safely retried. Skills
|
||||
that write files, mutate state, or charge money → `info` if 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's `input_schema` is built from these. Missing → `warning`.
|
||||
* Return type should be `dict[str, Any]`, a concrete Pydantic model, or `str`.
|
||||
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). Bare `raise` for invalid input → `info`.
|
||||
* `try/except Exception` that swallows the error without logging or returning
|
||||
→ `warning`.
|
||||
|
||||
## ctx.workspace / ctx.sandbox usage
|
||||
|
||||
* If the skill calls `ctx.workspace_backend()`, the class must declare
|
||||
`workspace_access = WorkspaceAccess.dynamic(...)`. Mismatch → `critical`.
|
||||
* Subprocesses that produce user-visible files must run through
|
||||
`ctx.workspace_shell` or `ctx.workspace_python`, not raw
|
||||
`asyncio.create_subprocess_exec`. Already covered in
|
||||
`security-anti-patterns` but worth a second look here.
|
||||
|
||||
## Recursion limits
|
||||
|
||||
* If the skill invokes a DeepAgents graph via `ainvoke` or `astream_events`,
|
||||
it must pass `config={"recursion_limit": 500}` to match agent-builder.
|
||||
Missing → `warning`.
|
||||
|
||||
## Manifest (a2a.yaml)
|
||||
|
||||
* `name` must match the agent's `name` class var. Mismatch → `critical`.
|
||||
* `entrypoint` must point at a real `module:Class`. Stub or broken → `critical`.
|
||||
* `version` should 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.
|
||||
Reference in New Issue
Block a user