recursive-agent 0.8.2

A Rust coding-agent platform: kernel, tools, multi-agent orchestration, HTTP API, MCP, and TUI
Documentation
version: "1"

project:
  name: recursive-agent
  description: "Recursive Agent E2E Integration Tests"
  version: "0.6.0"

isolation:
  namespace: "{{env.WORKTREE_ID}}"

plugins:
  - ./plugins/dist/index.js

service:
  build:
    dockerfile: Dockerfile
    context: ..
    # Namespaced image tag so concurrent worktrees don't overwrite each other's
    # built image. WORKTREE_ID is set by e2e-gate.sh (wt-<commit-short>).
    # argusai config-loader substitutes {{env.XXX}} in ALL fields including image.
    image: recursive:e2e-{{env.WORKTREE_ID}}
  container:
    name: recursive-e2e
    ports:
      # Host port 0 = Docker assigns a free random host port (argusai 0.14.3+
      # reads it back via getHostPort). This lets multiple worktrees run e2e
      # concurrently without host-port collision. The smoke suite doesn't need
      # host access at all (tests run via `docker exec` inside the container +
      # talk to aimock via Docker network DNS), so the random port is never
      # consumed — it's purely to avoid the collision.
      - "0:8080"
    environment:
      RECURSIVE_API_BASE: http://aimock:4010/v1
      RECURSIVE_API_KEY: mock-key
      RECURSIVE_MODEL: mock-chat
      RECURSIVE_PROVIDER_TYPE: openai
      RUST_LOG: info
      RECURSIVE_RATE_LIMIT_BURST: "200"
      RECURSIVE_RATE_LIMIT_RPM: "6000"
      # Bypass any host-injected HTTP proxy for internal container names.
      # Docker Desktop / Colima inject http_proxy automatically, so without
      # this, all internal traffic (aimock, self) goes through the proxy
      # and fails with 502.
      no_proxy: "aimock,recursive-e2e,localhost,127.0.0.1"
      NO_PROXY: "aimock,recursive-e2e,localhost,127.0.0.1"
      # Store all sessions under /workspace so test assertions can find them
      # via container paths without knowing the per-user data dir hash.
      RECURSIVE_HOME: /workspace
      # Goal-H J1: pin the session dir to a stable location so the
      # recursive-session assertion can find sessions without
      # discovering the workspace hash. Production runs leave this
      # unset and get the default `<RECURSIVE_HOME>/workspaces/<hash>/sessions/`.
      RECURSIVE_SESSIONS_DIR: /workspace/sessions
      # Passed through for live integration tests (06, 23)
      DEEPSEEK_API_KEY: "{{env.DEEPSEEK_API_KEY}}"

# NOTE: no `mocks:` section here by design. The aimock container (fixture
# replay / record proxy) is owned by e2e/plugins/src/index.ts, which starts
# it in replay or record mode (E2E_RECORD=1) on the argusai network. Declaring
# aimock as an image mock here would make argus-setup clobber it with
# replay-only args and cannot inject OPENAI_API_KEY, so recording would break.

tests:
  suites:
    - name: "Self-Improve Smoke Gate"
      id: smoke
      file: tests/00-smoke.yaml

    - name: "ACP Initialize Handshake (Sprint 1)"
      id: acp-init
      file: tests/01-acp-initialize.yaml

    - name: "Basic Agent Tool Usage"
      id: basic
      file: tests/01-basic-tools.yaml

    - name: "Session JSONL Persistence"
      id: session
      file: tests/02-session-persistence.yaml

    - name: "Memory Scratchpad"
      id: memory
      file: tests/03-memory-scratchpad.yaml

    - name: "Cost Tracking"
      id: cost
      file: tests/04-cost-tracking.yaml

    - name: "Sessions Export CLI"
      id: export
      file: tests/05-sessions-export.yaml

    - name: "Live LLM Integration"
      id: live
      file: tests/06-live-integration.yaml

    - name: "LLM-as-Judge (Mock Agent + Real Judge)"
      id: judge
      file: tests/07-llm-judge.yaml

    - name: "HTTP API Server (AgentRuntime, port 9090)"
      id: http-api
      file: tests/08-http-api.yaml

    - name: "HTTP API Server — Rate Limit (port 9091)"
      id: http-rate-limit
      file: tests/08b-http-rate-limit.yaml

    - name: "REPL Mode (multi-turn interactive)"
      id: repl
      file: tests/09-repl-mode.yaml

    - name: "Loop Mode (agent self-scheduling)"
      id: loop
      file: tests/10-loop-mode.yaml

    - name: "Session Resume (continue interrupted runs)"
      id: resume
      file: tests/11-session-resume.yaml

    - name: "Hooks Lifecycle (PreToolCall / PostToolCall)"
      id: hooks
      file: tests/12-hooks.yaml

    - name: "In-place file modification (read then write)"
      id: apply-patch
      file: tests/13-apply-patch.yaml

    - name: "MCP Stdio Server (recursive serve)"
      id: mcp-serve
      file: tests/14-mcp-serve.yaml

    - name: "search_files tool (pattern search across workspace)"
      id: search-files
      file: tests/15-search-files.yaml

    - name: "Skill lazy loading via load_skill tool"
      id: skill-lazy-load
      file: tests/16-skill-lazy-load.yaml

    - name: "Loop mode — schedule_wakeup triggers a second turn"
      id: loop-schedule
      file: tests/17-loop-mode.yaml

    - name: "Goal loop API — set / get / clear goal on a session"
      id: goal-loop
      file: tests/18-goal-loop.yaml

    - name: "HTTP API Interrupt endpoint"
      id: http-interrupt
      file: tests/19-http-interrupt.yaml

    - name: "Python SDK smoke test"
      id: python-sdk
      file: tests/20-python-sdk.yaml

    - name: "TypeScript SDK smoke test"
      id: typescript-sdk
      file: tests/21-typescript-sdk.yaml

    - name: "Context compaction e2e test"
      id: compaction
      file: tests/22-compaction.yaml

    - name: "Deferred Tool Loading — Real LLM Validation"
      id: deferred-tool-loading
      file: tests/23-deferred-tool-loading.yaml

    # ── P0: Critical gaps ──────────────────────────────────────────────────────
    - name: "Bash Tool (run_shell)"
      id: bash-tool
      file: tests/24-bash-tool.yaml

    - name: "Glob Tool (file pattern matching)"
      id: glob-tool
      file: tests/25-glob-tool.yaml

    # ── P1: High-priority gaps ──────────────────────────────────────────────────
    - name: "Semantic Facts Memory (remember / recall)"
      id: facts-memory
      file: tests/26-facts-memory.yaml

    - name: "TodoWrite Tool (agent task list management)"
      id: todo-tool
      file: tests/27-todo-tool.yaml

    - name: "Episodic Recall Tool (cross-session transcript search)"
      id: episodic-recall
      file: tests/28-episodic-recall.yaml

    - name: "Background Tasks (run_background / check_background)"
      id: background-tasks
      file: tests/29-background-tasks.yaml

    - name: "Checkpoint Tools (checkpoint_list / checkpoint_diff)"
      id: checkpoint-tool
      file: tests/31-checkpoint-tool.yaml

    - name: "Utility Tools (estimate_tokens / count_lines)"
      id: utility-tools
      file: tests/33-utility-tools.yaml

    - name: "Sandbox Path Escape Rejection (Invariant #3)"
      id: sandbox-security
      file: tests/34-sandbox-security.yaml

    - name: "Permission System — deny/allow Rules"
      id: permissions
      file: tests/35-permissions.yaml

    - name: "Session Rewind CLI"
      id: session-rewind
      file: tests/36-session-rewind.yaml

    - name: "HTTP API Authentication (RECURSIVE_HTTP_AUTH_KEYS)"
      id: http-auth
      file: tests/39-http-auth.yaml

    - name: "Claude-compatible JSON stream + control channel"
      id: claude-json-stream
      file: tests/40-claude-json-stream.yaml

    - name: "Multi Sub-Agent Delegation (agent tool)"
      id: multi-agent
      file: tests/41-multi-agent.yaml

    - name: "Sub-Agent Cross-Turn Continuation (background + send_message)"
      id: multi-agent-continue
      file: tests/42-multi-agent-continue.yaml