Agent Phases

Phase 3: Code Agent

The Code Agent turns the approved test design into working automation code in the target repository. It reads the TestDesignPack, follows the repository's .agents configuration and implementation skills, edits the test code, runs verification, heals failures, and optionally commits, pushes, and raises a pull request.

The defining capability

The environment-aware implementation loop: if the repository has Docker Compose support and the stack configuration tells Testonaut how to start it, Testonaut brings the app up, explores it, implements the tests, verifies against the live app, heals failures, and tears the environment down.
Phase 3 high-level flow: load design, read config, start Docker, explore, implement, verify, heal, commit and raise a PR
The implementation loop — each stage is bounded, recorded, and can fall back gracefully.

Inputs and outputs

ItemDescription
Input: TestDesignPackThe design artifact from Phase 2, either loaded from disk with --design or reconstructed from Xray with --issue.
Input: target repositoryThe repo where the automation code will be written. Required.
Input: .agents/testonaut.config.jsonDefines stacks, verify commands, optional Docker setup/teardown, app URLs, MCP servers, policy, and PR gates.
Input: implementation runnerClaude Agent SDK, Codex SDK, or configured shell runner.
Output: ImplementationPackChanged files, scenario outcomes, verification result, heal attempts, branch/PR metadata, warnings, and provenance.
Output filesout/<KEY>/implementation.json, implementation.md, implementation.prompt.md, and optionally exploration.md.

Design source: file or Xray

The implementation phase can start from either a local design file or directly from the story's linked Xray tests. The --issue path is important for pipelines — it makes implementation stateless: the design step can upload tests to Xray, and a later implementation rule can reconstruct the work from Xray without needing a local artifact hand-off.

Design source decision: local test-design file via --design, or reconstruction from linked Xray tests via --issue
Two entry points: a local TestDesignPack via --design, or stateless reconstruction from the story's linked Xray tests via --issue.

Why configuration exists

The Code Agent cannot safely guess how a repository should be tested. Different repositories have different frameworks, folder layouts, verify commands, Docker commands, application URLs, and MCP tools. testonaut init --repo <path> scaffolds the .agents folder; stack detection can pre-fill basic entries, and teams then tune the config with the real commands and URLs for their app. A typical stack config:

{
  "id": "ui-playwright",
  "root": ".",
  "verifyCommand": "npm run test:e2e",
  "featureGlob": "features/**/*.feature",
  "kind": "ui",
  "setupCommand": "docker compose up -d --build",
  "teardownCommand": "docker compose down -v",
  "appUrl": "http://localhost:4200",
  "healthCheck": "http://localhost:4200/health",
  "readinessTimeoutMs": 480000
}

Key point

Docker Compose files alone are not enough. Testonaut uses them through the configured setupCommand and teardownCommand — the config is where you tell Testonaut exactly how to start the app and how to know it is ready.

Environment-aware Docker flow

When a stack has setupCommand and the user did not pass --no-env, Testonaut attempts an environment-aware run.

Docker environment flow: run setupCommand, wait for readiness, implement and verify, then teardown
The environment manager: setupCommand starts the app, readiness is polled against healthCheck or appUrl, and teardown runs best-effort after the attempt.

Start environment

The environment manager runs setupCommand from the target repository root — usually docker compose up -d --build — then waits until the application is reachable. Readiness is checked against healthCheck when configured, otherwise appUrl. Any non-5xx response means the server is up and listening.

Readiness timeout

The default readiness timeout is 120 seconds. Some frontend stacks — especially monorepos or Nx apps that compile on startup — may need several minutes. That is why readinessTimeoutMs exists: if the app is slow, increase the timeout instead of letting the Code Agent implement tests against an app that never actually came up.

Teardown

After the implementation attempt, Testonaut runs teardownCommand if configured (best-effort, typically docker compose down -v). Teardown matters because these runs happen in CI and should not leave containers, networks, or volumes behind.

Why the Docker path matters

Without live environmentWith environment-aware run
Agent may invent selectors or endpoints.Agent receives real observed locators/endpoints.
Verify may fail because no app is running.Verify runs against the app started by Testonaut.
Failures are discovered later in human review.Failures are fed back into the healer immediately.
PR can still be useful but is more speculative.PR is backed by a real verification attempt.

Explore before implementing

After the environment is ready, Testonaut tries to produce an exploration brief. This brief is injected into the implementation prompt so the Code Agent grounds its work in the real app.

  • UI stacks: Playwright MCP opens the running app and reports concrete navigation paths, stable locators, labels, visible copy, and UI states.
  • API stacks: openApiUrl fetches the OpenAPI/Swagger document and summarizes endpoints, HTTP methods, operation names, request/response schemas, and payload shapes.
Exploration brief flow: Playwright MCP explores UI stacks, OpenAPI is fetched for API stacks, both feed the implementation prompt
Exploration: Playwright MCP for UI stacks, the OpenAPI document for API stacks — the resulting brief is injected into the implementation prompt.

Implementation prompt composition

The Code Agent receives a structured prompt, not a vague instruction to write tests:

Prompt sectionPurpose
Goal and repositoryWhich repo the agent is editing and which ticket it implements.
Stack configStack id, root, verify command, feature glob.
Operating rulesTest-only edits, do not modify product code, do not weaken assertions, preserve traceability.
Binding skillStack-specific implementation contract, e.g. Playwright BDD TypeScript or Reqnroll.
Repository conventionsAGENTS.md, .agents/test-architecture.md, .agents/test-conventions.json, .agents/product-context.md.
Available MCP toolsPlaywright, Figma, or other configured tools.
Live exploration briefReal locators/endpoints/states from the running app or API.
Scenarios to implementFull scenario list from the TestDesignPack.

This structure keeps the Code Agent focused on implementing tests in the repository's style instead of inventing a parallel automation framework.

Verification and healing loop

Verification runs the stack's verifyCommand, unless the user passes --no-verify or overrides it with --verify. The verifier captures command, exit code, duration, stdout, and stderr.

Verification and healing loop: run verify command, on failure send narrow repair prompt to the Healer, re-verify within the budget
The verify-and-heal loop: failing output feeds a narrow repair prompt; healing is bounded by --max-heal-attempts (default 1).

If verification fails, the Healer receives a narrow prompt containing the failing output and the changed files from the previous attempt. It is explicitly told to repair only the failing tests or test-support code — not to restart the implementation, change product code, weaken assertions, skip scenarios, or disable retries just to get green. The default healing budget is one attempt, controlled by --max-heal-attempts.

Graceful fallback behavior

The Docker path is best-effort — Testonaut still produces a useful PR when the environment cannot run:

SituationBehavior
setupCommand is missingSkip the environment-aware path and implement normally.
--no-env is passedSkip Docker setup even if configured.
Docker command failsContinue without live exploration/verify environment and record a warning.
App never becomes readyContinue without live exploration and record a warning.
Playwright MCP is not configured for a UI stackSkip UI exploration and record a warning.
openApiUrl is missing for an API stackSkip API exploration and record a warning.
Verify fails after the healing budgetStatus becomes partial; a PR can still be raised for human review.

Reading a green run

A green run means verification passed. It does not automatically prove the app was live unless exploration.md or the implementation artifact shows that the environment started and exploration/verify happened against it.

Branch, commit, push, and PR

After implementation, Testonaut can create a branch, commit changes, push, and raise a pull request. For unattended pipeline runs, the VCS token authenticates both REST operations and git push — injected as a redacted http.extraHeader, never written into the remote URL. The PR platform is resolved from the repository remote and can use Azure DevOps or GitHub adapters.

Branch, commit, push, and PR flow with redacted token auth and platform adapters
From changed files to a reviewable PR: branch, commit, authenticated push via a redacted http.extraHeader, and the platform adapter raises the pull request.

Crash rescue

The implementation agent can occasionally exit non-zero after making valid changes — for example, if an agent transport drops near the end. If the agent reports failure but verification passed and files changed, the final status becomes partial instead of failed, so the branch and PR can proceed for human review rather than discarding working verified code.

ImplementationPack

FieldMeaning
ticketJira key and title.
stackStack id used for implementation.
repoRootTarget repository path.
statuscompleted, partial, failed, or dry-run.
implementationCode-agent command result.
verificationVerify command result, when run.
healingAttemptsEach healer run and its verification result.
changedFilesRepo-relative files changed by the agent.
scenariosPer-scenario implementation status.
pullRequestPR branch, target, status, URL/id/message, when requested.
promptPathPath to the implementation prompt used for traceability.
warningsEnvironment, commit, crash-rescue, or other non-fatal warnings.

CI requirements for Docker-backed verification

RequirementWhy it matters
Docker available on the runnersetupCommand usually calls Docker Compose.
Hermetic compose filesHosted agents do not have sibling repos or local-only bind mounts.
Published host portsappUrl / healthCheck must be reachable from the Testonaut process.
Required secrets mapped into the pipeline stepThe app may need auth, API, or database credentials at startup.
Realistic readiness timeoutSlow frontend builds may need several minutes.
Teardown commandPrevents leftover containers, networks, and volumes.

Why this phase matters

Phase 3 is the difference between "the agent wrote tests" and "the agent produced a reviewable, verified automation PR." The Docker-aware flow gives the Code Agent feedback from the real application — actual locators and API contracts, the repository's own verify command, and a bounded repair loop. That is the path from generated test design to tested code.