Agent Phases

Phase 2: Test Design Agent

The Test Design Agent — the Test Architect — turns the ContextPack from Phase 1 into a validated TestDesignPack: acceptance criteria, test strategy, Gherkin or manual scenarios, coverage matrices, risk ranking, open questions, and Xray upload results.

This phase is where Testonaut stops being a generic test-case generator and starts behaving like a repository-aware QA architect. It does not only read the Jira story: when a target repository is available, it scans the existing Cucumber feature files and reuses the team's existing Gherkin step vocabulary so it does not create near-duplicate steps that later require duplicate step definitions.

Phase 2 high-level flow from ContextPack through repo scan, AC extraction, scenario authoring, gates, and Xray upload
The high-level design flow — every hand-off is validated before it moves forward.

Inputs and outputs

ItemDescription
Input: ContextPackTicket context, comments, Confluence pages, attachments, linked tests, related tickets, evidence graph, provenance, and warnings from Phase 1.
Optional input: target repoLocal checkout used for repo skill overrides, existing .feature step reuse, and existing scenario de-duplication.
Optional input: Xray credentialsEnables creation of Cucumber or Manual tests in Xray, linked back to the story.
Output: TestDesignPackValidated test design artifact with ACs, scenarios, coverage, risk, source evidence, warnings, and optional Xray application result.
Output filesout/<KEY>/test-design.json, test-design.md, and generated .feature files for Gherkin mode.

Where the repository connection belongs

Repository discovery starts from information gathered in Phase 1, but repository-aware step reuse belongs to Phase 2 because it directly changes how the Test Architect writes scenarios. There are two ways the design phase gets a repository:

SourcePriorityHow it works
--repo <path>HighestThe pipeline or user gives the local target repository path directly.
Jira development section + TESTONAUT_REPO_ROOTSFallbackPhase 1 gathers branch/PR repository names from Jira development information. Phase 2 maps one of those names to a local checkout path.

If no repository is resolved, Testonaut still designs tests, but it cannot reuse existing step phrasings. The CLI makes that visible with a message telling the user to pass --repo or configure TESTONAUT_REPO_ROOTS.

Repository resolution: explicit --repo path first, then Jira development section mapped through TESTONAUT_REPO_ROOTS
How the design phase resolves a repository: explicit --repo wins; otherwise dev-section repo names are mapped through TESTONAUT_REPO_ROOTS.

Key capability: repository-aware Gherkin step reuse

Most AI test generators can write plausible Cucumber scenarios, but they often create subtly different phrasings for behavior that the repository already supports. That causes duplicate Gherkin steps and duplicate step-definition code:

Existing stepBad generated near-duplicate
Given the customer is logged inGiven the user has signed into the portal
When I submit the payment formWhen the payment form is submitted
Then the instalment plan is displayedThen I should see the instalment plan

Humans understand those as equivalent. Cucumber does not — if the generated wording is different, the implementation phase may need new glue code even though equivalent step definitions already exist. Testonaut handles this by scanning the target repository before scenario authoring.

Step library scan: find feature files, parse scenarios, extract and normalize steps, deduplicate vocabulary, collect scenario titles, feed prompt sections
The step library scan: parse .feature files, normalize and deduplicate step vocabulary, collect scenario titles — both feed explicit prompt sections for the Gherkin authoring LLM.

What the scanner reads

The step library scanner walks the repository and reads .feature files, ignoring generated or irrelevant folders (node_modules, .git, .agents, dist, out, build, coverage, bin, obj, target). It collects:

Collected itemPurpose
Unique Given/When/Then step vocabularyTells the LLM which exact step phrasings already exist and should be reused.
Representative raw examplesKeeps examples of how the team writes the step in practice.
Occurrence countsLets the most common steps rise to the top.
Existing scenario titlesPrevents writing a scenario that already exists in the repo.
Feature file count and total step countGives a useful audit summary in the run output.

Step normalization

The scanner normalizes value-like literals so structurally identical steps collapse into one reusable template:

Raw examplesNormalized step
the amount is "300 EUR" and the amount is "50 EUR"the amount is "<param>"
I select 12 months and I select 24 monthsI select <number> months
the status is <status>the status is <param>

This is what lets the prompt say "reuse this step shape, substituting the right data," instead of treating every literal value as a separate step.

How step reuse reaches the LLM

When a step library exists, the Gherkin prompt includes a dedicated section, grouped by keyword (Given / When / Then), instructing the model to reuse those exact phrasings and only write a new step when none matches. This is not a soft hint hidden in a paragraph — it is an explicit authoring constraint, because avoiding duplicate Cucumber glue code is a first-class design requirement.

Existing test de-duplication

Two levels of de-duplication: repository scenario titles and linked Xray tests both feed the prompt
Duplicate protection at two levels: existing repo scenarios and already-linked Xray tests both reach the prompt, plus a normalized-title check at upload time.

Repository scenario de-duplication

While scanning .feature files, Testonaut also collects scenario and scenario-outline titles. Those titles are placed in the prompt with the instruction: do not author a scenario that means the same thing; if an acceptance criterion is already covered by an existing repo scenario, put that AC id in acsCoveredByExisting instead of writing a duplicate scenario.

Linked Xray test de-duplication

The Researcher includes already-linked Xray tests in ContextPack.xrayTestCases, and Phase 2 adds them to the existing-test prompt section. During Xray upload, Testonaut performs another safety check: it normalizes scenario titles and skips tests whose title already exists among linked tests or among scenarios created in the same run — catching case, punctuation, or unicode differences that would otherwise create near-duplicates.

Two-pass design flow

The Test Architect uses multiple bounded design passes rather than one big prompt.

Two bounded LLM passes: acceptance criteria extraction, then scenario authoring
Pass 1 extracts atomic acceptance criteria; pass 2 authors scenarios that cover them.

Pass 1: acceptance criteria extraction

The first LLM pass extracts atomic acceptance criteria from the ContextPack. Each AC is assigned an id such as AC-1, written in business language, and can point back to its source — the description, a comment, or a Confluence page. After AC extraction, the evidence graph is rebuilt so requirement nodes appear in the graph.

Pass 2: scenario authoring

Output modeResultXray test type
gherkinGiven/When/Then scenarios written as .feature filesCucumber
plain-englishAction / expected-result manual test casesManual

In Gherkin mode, the author receives the existing repository step vocabulary and is instructed to reuse it. In plain-English mode, step-library reuse is not relevant, but existing test de-duplication still matters.

Scenario contract

Each generated scenario carries structured fields used by gates, reporting, and implementation:

FieldPurpose
titleBusiness-readable scenario title.
featureFeature file grouping.
tagsFeature-area tags only, such as @login or @checkout.
acIdsAcceptance criteria covered by the scenario.
drIdsDerived requirements covered by the scenario.
polaritypositive, negative, or boundary.
riskhigh, medium, or low.
readinessready or needs-clarification.
objectiveWhat the scenario verifies.
preconditionsSetup assumptions.
stepsGherkin steps or manual action/expected-result steps.
sourceEvidenceTraceability back to description, comments, Confluence, attachments, or related tickets.
openQuestionsScenario-specific questions for the product/team.
rationaleWhy this scenario exists.

Tag hygiene

Tags are deliberately kept simple — the agent does not use tags for data that belongs in structured fields:

DoDo not
@login, @checkout, @instalments@AC-1, @high, @positive, @story-ABC-123

The Jira key is added at the feature level automatically. @smoke is derived from risk: high. AC ids, risk, and polarity live in structured fields, which keeps coverage checks machine-readable.

Coverage gates

The Coverage Auditor checks the generated design before it is accepted:

GateWhat it enforcesBehavior
AC coverageEvery AC must be covered by a generated scenario or by acsCoveredByExisting.Required by default. One bounded retry fills missing ACs.
Risk / edge coverageHigh-risk ACs or derived requirements should have at least one negative or boundary scenario.Defaults to warn. Can be required, warn, or off.
Existing coverageACs covered by existing repo scenarios or linked Xray tests count as covered.Prevents forced duplicates just to satisfy a gate.

If AC coverage fails and the gate is required, the run stops with a clear error. If the gate is warn, the gap is recorded as an open question and warning.

Derived requirements and adversarial critique

The literal acceptance criteria are the floor, not always the whole test strategy. Phase 2 can also mine implied requirements from the full context — missing but evidence-backed behaviors such as:

  • error and rejection paths;
  • boundary values;
  • missing or maximal data;
  • permissions and security expectations;
  • state transitions and concurrency;
  • notable usability or performance constraints.

After the initial scenario design, an adversarial critique pass asks: "what did this design miss?" It can add genuinely missing scenarios, record coverage gaps, or raise open questions. It is bounded, evidence-grounded, and not allowed to duplicate already drafted scenarios.

Xray upload

When upload is enabled, Testonaut applies the TestDesignPack to Xray:

Xray upload flow: create Cucumber or Manual tests, link to the story, skip duplicates, record per-test results
The Xray upload: Cucumber or Manual tests are created, linked to the story, de-duplicated by normalized title, and recorded per test in the application result.
  • Gherkin scenarios become Xray Cucumber tests; plain-English scenarios become Xray Manual tests.
  • Tests are linked back to the story using the configured or resolved Jira link type.
  • Required Jira fields can be inherited or supplied through xray.testFields / --test-fields.
  • Titles are normalized to avoid duplicate creation across reruns.
  • Upload can run as --dry-run or require --yes / policy approval.

Failure behavior and guardrails

SituationBehavior
No LLM is configuredPhase 1 context is still written; Test Architect is skipped.
No repository is resolvedDesign still runs, but without step reuse; the CLI explains how to enable it.
Step library scan finds no feature filesDesign still runs; no reuse vocabulary is injected.
LLM returns non-JSON or malformed JSONRun fails with a clear schema/parsing error.
Scenario references unknown AC/DR idsUnknown ids are dropped and warnings are recorded.
AC coverage misses requirementsOne bounded retry; then warn or fail depending on the gate.
Risk coverage misses negative/boundary casesWarn or fail depending on the gate.
Xray upload sees an existing titleScenario is skipped as existing rather than duplicated.
Xray upload partially failsPer-test result and warnings are recorded in the application result.

Configuration knobs

Setting / flagPurpose
--repo <path>Explicit local repository used for step reuse and repo skill overrides.
TESTONAUT_REPO_ROOTSJSON map of repository name to local checkout path for dev-section resolution.
testDesign.outputModegherkin or plain-english.
--gate / policy.gates.acCoverageAC coverage enforcement: required, warn, or off.
--derive-requirements / policy.design.deriveRequirementsEnables implied requirement mining.
--adversarial-critique / policy.design.adversarialCritiqueEnables the critique pass.
--risk-coverage / policy.gates.riskCoverageRisk/edge gate: required, warn, or off.
--test-fields / xray.testFieldsExtra Jira fields for created Xray Test issues.
--reporterSets Reporter on created Test issues, useful for Jira automation attribution.
--dry-runPreview Xray upload without mutations.
--yesConfirms upload when human review is required.

Why this phase matters

The key differentiator is repository-aware design: Testonaut reads the existing Cucumber vocabulary and scenario titles before it writes new scenarios — producing tests that fit the current suite, avoid duplicate Gherkin steps, reduce implementation effort, and preserve maintainability over many Jira tickets. Without this, an AI test agent may appear productive while quietly creating a parallel vocabulary of near-duplicate Cucumber steps. Testonaut explicitly designs against that failure mode.