agentleFS
dylanroscoverdylanroscover/Embody/.claude/skills/agent-tests/SKILL.md

agent-tests

Skill213 starsChanged 2 months agoMITView on GitHub

MUST READ before calling RunAgentTests or touching agent-tier test infrastructure -- these tests spawn real AI clients (Claude Code, Codex) and SPEND SUBSCRIPTION USAGE; never run casually. Tier model, async runner rationale, auth/isolation rules.

  • Reads credentials

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 0 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Tier 1 (test_agent_contract): no LLM. An out-of-process stdlib MCP client (agent_clients/mcp_contract_client.py) spawns the EXACT bridge …

    line 23
  2. Very specific:

    Never run RunAgentTests() casually: it spends the user's subscription usage and takes minutes.

    line 98
  3. Very specific:

    Prefer Tier 1 alone (RunAgentTests(suite_name='test_agent_contract')) for transport/contract diagnosis -- it is free and deterministic.

    line 101

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Agent-Tier Tests (AI-client connectivity)

The AGENT tier verifies that real AI clients -- Claude Code, Codex, and a deterministic MCP contract client -- can reach and correctly use Envoy's MCP tools end to end. Like destructive-tests.md, this is a dev-only convention for the Embody test harness -- it has NO shipped template counterpart.

The tier model

  • Suites inherit AgentTestCase (which carries AGENT = True). They are EXCLUDED from RunTests / RunTestsSync / RunTestsDeferred* AND from RunDestructiveTests by _discoverTestSuites' tier filter. Do not remove that guard: a normal full run must never spawn AI clients or burn subscription usage silently.
  • They run ONLY via op.unit_tests.RunAgentTests(suite_name=None, test_name=None, delay_frames=30) -- fire-and-forget; poll GetResults().
  • Two layers:
    • Tier 1 (test_agent_contract): no LLM. An out-of-process stdlib MCP client (agent_clients/mcp_contract_client.py) spawns the EXACT bridge command from .mcp.json and checks handshake, tool inventory vs the EXPECTED_ENVOY_TOOLS manifest, and a curated call sequence. This is the cheap, deterministic half -- run it first when diagnosing.
    • Tier 2 (test_agent_smoke_claude / test_agent_smoke_codex): a real agent on scripted micro-tasks, verified against LIVE TD state (probe op exists with the exact run token), never the agent's prose alone.

Why the runner is async (do not "simplify" it)

Envoy drains MCP requests on TD's MAIN thread (max 5 per frame). A test that blocks the main thread while an agent subprocess makes MCP calls deadlocks the very tools under test until every call times out. So RunAgentTests launches subprocesses non-blocking (stdout/stderr to temp FILES -- an unread PIPE deadlocks the child at ~64KB; stdin always DEVNULL -- codex exec hangs probing a silent stdin pipe on Windows, openai/codex#20919) and polls them via a run(delayFrames=N) chain using the STRING-EXPRESSION form, so a mid-run extension reinit cannot strand the state machine on a stale instance. Timeouts kill the whole process TREE (the CLIs spawn the bridge as a child).

Auth and billing (subscription only)

  • AgentTestCase.launchEnv() strips ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, OPENAI_API_KEY, CODEX_API_KEY from the child env: a set API key silently OVERRIDES subscription auth and bills per token. With them absent, claude -p uses the stored Pro/Max OAuth login and codex exec the ChatGPT login.
  • Missing CLI -> loud SKIP (requireCli). Codex suites gate on codex login status (exit 0 = logged in) before any billed task.
  • Claude exit codes worth knowing: 100 = not logged in, 101 = MCP server unreachable (with --strict-mcp-config), 102 = tool permission denied in -p mode (no TTY -> no prompt -> immediate deny). Codex exec exit codes are NOT documented as task success -- judge by --output-last-message + TD state.

Isolation choices (keep them)

  • Smoke agents run from a NEUTRAL temp cwd: no CLAUDE.md / AGENTS.md / project settings, so the agent does the micro-task, not session rituals.
  • Claude: --mcp-config <envoy-only json> + --strict-mcp-config + per-task --allowedTools allowlists + a standing --disallowedTools denylist (execute_python, run_tests, delete_op, import_network, restart_td, launch_td, switch_instance).
  • Codex: inline -c mcp_servers.envoy.* overrides (Codex does not read .mcp.json; the user's ~/.codex/config.toml is never touched), with -c approval_policy="never" (the exec subcommand rejects -a on installed builds) + default_tools_approval_mode="auto" so MCP calls are not auto-cancelled, --sandbox read-only (MCP servers spawn OUTSIDE the sandbox), and a real .exe when the npm .cmd shim is what PATH probing finds.
  • delete_op is NOT part of any Tier-2 smoke task: a peer session's recent writes can gate it mid-test (multi-session destructive gate). Tier 1 covers delete_op and treats a MULTI-SESSION GATE refusal as operational-with-gate.
  • Each spawned client registers as its own Envoy session via EMBODY_SESSION_LABEL (agent-test-tier1, claude-smoke, codex-smoke), so get_sessions / _peers traffic is attributable.

Maintenance

  • Envoy tool surface changed -> update EXPECTED_ENVOY_TOOLS in test_agent_contract.py in the SAME commit. The inventory check fails on drift in either direction. Remember tools register on the MCPServer instance at Envoy START -- restart Envoy before believing a mismatch.
  • Model pins live at the top of the smoke suites (CLAUDE_SMOKE_MODEL, CODEX_SMOKE_MODEL). The Codex model list rotates with releases; update deliberately, never blindly.
  • The runner machinery itself is unit-tested in test_agent_runner.py (normal tier): tier gating, job lifecycle, timeout kill, verdict classification, Filecleanup storage roundtrip. Update it when touching the agent runner.

For the AI agent

  • Never run RunAgentTests() casually: it spends the user's subscription usage and takes minutes. Run it when asked, before releases, or when MCP-facing code changed.
  • Prefer Tier 1 alone (RunAgentTests(suite_name='test_agent_contract')) for transport/contract diagnosis -- it is free and deterministic.
  • The spawned agents appear as peer sessions; expect _peers advisories during a run and do not treat the smoke agents' touches as a human peer.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.