TEA Configuration Reference
TEA Configuration Reference
Section titled “TEA Configuration Reference”TEA configuration keys, defaults, and the skills they affect.
Where Configuration Lives
Section titled “Where Configuration Lives”bmad setup tea asks TEA’s setup questions and writes the answers to the [modules.tea] table of _bmad/config.toml.
The bmad skill from BMad Method core runs setup; TEA’s questions come from skills/bmod-tea/bmod.toml.
If a TEA skill finds no [modules.tea] table, it tells you to run bmad setup tea and stops.
Skills read the config through _bmad/scripts/resolve_config.py, which merges three layers, later files winning:
| File | Holds |
|---|---|
_bmad/config.toml | The setup answers |
_bmad/custom/config.toml | Team overrides, committed with the project |
_bmad/custom/config.user.toml | Personal overrides, kept out of version control |
Setup answers are strings.
A boolean key holds "true" or "false", and skills read those as booleans.
To change an answer, run bmad setup tea again: it shows each answer with its value and the file it lives in, and changes the ones you name.
You can also edit the TOML directly.
Skills read the config once at activation, so start a fresh chat after a change.
Every module setup key is read by a skill. The two Per-Skill Settings live in customization files and are configured separately.
Upgrading Customizations to 3.0
Section titled “Upgrading Customizations to 3.0”TEA 3.0 names every direct workflow bmad-tea-*. Use these command replacements:
| Before 3.0 | From 3.0 |
|---|---|
bmad-testarch-automate | bmad-tea-automate |
bmad-testarch-evaluate | bmad-tea-evaluate |
bmad-testarch-framework | bmad-tea-framework |
bmad-testarch-nfr | bmad-tea-nfr |
bmad-testarch-test-design | bmad-tea-test-design |
bmad-testarch-test-review | bmad-tea-test-review |
bmad-testarch-trace | bmad-tea-trace |
bmad-teach-me-testing | bmad-tea-teach-me-testing |
The 3.0 package does not publish the old slash commands. The agent name bmad-tea, module name bmod-tea, menu codes, and existing tea-* CLI names remain.
After installing 3.0, run this in each existing project before invoking a workflow directly:
npx --package=bmad-method-test-architecture-enterprise@3 tea-migrate-customizations --project-root . --checknpx --package=bmad-method-test-architecture-enterprise@3 tea-migrate-customizations --project-root .The migration renames old customization files, including ATDD, CI, and teaching files. It updates old [[agent.menu]] skill IDs in _bmad/custom/bmad-tea.toml and .user.toml; ATDD routes to Automate and CI to Framework. It preserves other settings, comments, and file permissions. When old and new files coexist in one layer, merge their values and comments manually. The command checks every file before writing. Headless TEA CLIs can read old filenames until migration completes.
An upgrade can leave the former skill folders in a host’s project or global skills directory. After migrating customization files, check for old slash commands and move their folders to a backup. Review edits in those folders before removing them from the host’s skill discovery path.
Recommended Configuration
Section titled “Recommended Configuration”The setup defaults are the recommended values:
[modules.tea]test_artifacts = "{project-root}/_bmad-output/test-artifacts"tea_use_playwright_utils = "true" # production-ready fixtures and utilitiestea_use_pactjs_utils = "true" # pactjs-utils is the implementation whenever contract tests are writtentea_pact_mcp = "mcp" # use a broker when one is reachable; skipped automatically when it is nottea_browser_automation = "auto" # smart CLI/MCP selection with fallbacktea_execution_mode = "auto" # capability-aware orchestrationtea_capability_probe = "true" # fall back safely when a mode is unsupportedtest_stack_type = "auto"test_framework = "auto"auto_validate = "true"auto_heal_failures = "true"max_healing_iterations = "3"use_mcp_healing = "true"npm install -D @seontechnologies/playwright-utilsnpm install -g @playwright/cli@latest # needed for 'cli' and 'auto' browser modesPact scaffolding requires an applicable consumer-provider boundary.
For applicable Pact suites, tea_use_pactjs_utils: true selects Pact.js Utils; false selects raw Pact.
tea_pact_mcp: mcp uses available broker tools, with provider source or an OpenAPI spec as the fallback.
The report identifies the source used.
Setup Questions
Section titled “Setup Questions”Each key below is asked by bmad setup tea and stored under [modules.tea].
test_artifacts
Section titled “test_artifacts”Base output folder for TEA-generated artifacts (test designs, reports, traceability).
Type: string · Default: {project-root}/_bmad-output/test-artifacts
Setup question: Where should test artifacts be stored? (test plans, coverage reports, quality audits)
Skills replace {project-root} in the value with the project root, so it can live outside the core output folder.
Each skill writes into its own folder under it, as described in Output Layout.
test_artifacts = "{project-root}/docs/testing-artifacts"tea_use_playwright_utils
Section titled “tea_use_playwright_utils”Enable Playwright Utils integration for production-ready fixtures and utilities.
Type: boolean · Default: true
Setup question: Use Playwright Utils (@seontechnologies/playwright-utils) as the default implementation for Playwright tests?
When the flag is true and the package is a project dependency, playwright-utils-mandate defines the default implementation:
| Capability | Implementation |
|---|---|
| Network interception | interceptNetworkCall |
| API requests | apiRequest |
| Polling | recurse |
| Test logging | log |
| Fixture entry point | test from the project’s merged fixtures |
A capability outside the utilities’ scope can use plain Playwright with a // playwright-utils deviation: <reason> comment and an entry in the output summary.
auth-session, network-recorder, webhook helpers, and burn-in are recommended integrations that need project wiring.
Skills describe that wiring when proposing them.
With the flag enabled and the package absent, TEA generates plain Playwright, skips the utility review criteria, and recommends running framework.
tea_use_pactjs_utils has the same package gate.
The Playwright mandate applies to JavaScript/TypeScript suites on the Playwright runner.
Affects skills (each reads the key and branches on it):
automatered mode loads the mandate, selects a playwright-utils fragment profile, and passesuse_playwright_utilsto generation workers. Red-phase scaffolds are generated in playwright-utils style, since the scaffold is the file the developer un-skips and keepsautomateexpand mode uses the same fragment profile and worker flag, plus amerged-fixtures.tsentry point and an auth fixture built onauth-sessionduring aggregationtest-designloads the mandate so every code example in the design document matches whatautomatewill generatetest-reviewscores registry rowsM9(a configured utility bypassed with no stated deviation, MEDIUM) andL9(a spec importingtestfrom@playwright/testagainst a merged-fixtures convention, LOW).M9also requires the package to be a project dependency: the flag alone never produces a deductionframeworkframework phase installs the package, scaffoldsmerged-fixtures.tsand the auth fixture, and generates samples in the mandated styleframeworkCI phase usesrunBurnInfor Playwright burn-in selection
The trace and nfr-assess skills do not read this key.
tea_use_playwright_utils = "true" # "false" selects plain PlaywrightPrerequisites:
npm install -D @seontechnologies/playwright-utilsRelated:
tea_use_pactjs_utils
Section titled “tea_use_pactjs_utils”Enable Pact.js Utils integration for consumer-driven contract testing utilities.
Type: boolean · Default: true
Setup question: Use Pact.js Utils (@seontechnologies/pactjs-utils) when contract tests are written?
When the flag is true and the package is installed, pactjs-utils-mandate defines the default implementation for applicable Pact artifacts:
| Capability | Implementation |
|---|---|
| Provider-state parameters | createProviderState |
| Verifier configuration | buildVerifierOptions |
| Auth request filter | createRequestFilter |
| PactV4 request/response bodies | setJsonContent / setJsonBody |
Raw Pact is allowed where the helpers cannot cover a capability, with a // pactjs-utils deviation: <reason> comment and an entry in the output summary.
Before creating contract scaffolds, TEA checks whether contract testing applies to the project.
Existing Pact artifacts, a dependency on @pact-foundation/pact, broker variables, two or more independently deployable services in the repo that call each other, or an explicit request for contract testing each establish relevance.
See pactjs-utils-mandate for the full rules.
zodToPactMatchers and the pact-consumer-di injection are recommended integrations.
The first needs a Zod schema; the second needs a production-code change.
TEA describes the missing setup when proposing them.
The determinism rules never relax under the mandate: one addInteraction() per it(), fileParallelism: false plus pool: 'forks' plus singleFork: true on the consumer config, the pool pair on the provider config, and provider scrutiny before any response matcher.
Affects skills:
frameworkframework phase installs the packages and scaffolds Pact samples when contract testing is relevantautomatered mode loads the mandate and generates contract scaffolds in that styleautomateexpand mode loads the mandate and passes pact config to subagentstest-designloads the mandate so Pact code examples in design documents match whatautomategeneratestest-reviewscores registry rowM10(a configured contract utility bypassed with no stated deviation, MEDIUM), gated on the flag plus the package being installedframeworkCI phase adds a contract-test stage and quality gates
Set this to false for raw @pact-foundation/pact output.
tea_use_pactjs_utils = "true" # "false" selects raw PactPrerequisites:
npm install -D @seontechnologies/pactjs-utils @pact-foundation/pact# peer dependency: @pact-foundation/pact >= 16.2.0For the remote flow with a Pact Broker, set PACT_BROKER_BASE_URL and PACT_BROKER_TOKEN, plus GITHUB_SHA (GitHub Actions sets this) and GITHUB_BRANCH (you must set it explicitly: ${{ github.head_ref || github.ref_name }}).
The flow follows PACT_BROKER_BASE_URL: when it is set the remote flow runs, otherwise the local monorepo flow runs and needs pactUrls, the list of local pact files, instead of a broker.
The consumer generates the pacts and the provider verifies them locally.
Related:
tea_pact_mcp
Section titled “tea_pact_mcp”Pact MCP strategy for broker interaction during contract testing skills.
Type: string · Default: "mcp" · Options: "mcp" | "none"
Setup question: Use the SmartBear MCP for PactFlow or a Pact Broker?
Controls whether TEA can use SmartBear MCP tools for provider-state discovery, Pact test review assistance, and can-i-deploy/matrix guidance.
Each broker-dependent step checks once whether SmartBear MCP tools are available in the session.
When they are unavailable, it follows pact-mcp’s fallback: provider source, then an OpenAPI spec, then the confidence gate if the needed facts remain unknown.
The report records tool availability and the source used for provider states.
Affects skills: test-design, automate (red and expand), framework (framework and CI), and test-review.
Set it to none to disable broker calls, for example in an air-gapped environment.
tea_pact_mcp = "mcp" # "none" disables all broker/MCP integrationPrerequisites:
npm install -g @smartbear/mcp # Node.js 20+ required# or run on demand: npx -y @smartbear/mcp@latestRequired broker env vars:
PACT_BROKER_BASE_URL(for examplehttps://{tenant}.pactflow.io)PACT_BROKER_TOKEN(or username/password for basic auth)
Related:
tea_browser_automation
Section titled “tea_browser_automation”Browser automation strategy. Controls how TEA interacts with live browsers during test generation.
Type: string · Default: "auto" · Options: "auto" | "cli" | "mcp" | "none"
Setup question: How should TEA drive live browsers while generating tests?
| Mode | Behavior |
|---|---|
auto | Recommended. CLI for stateless tasks, MCP for stateful flows. Falls back gracefully. |
cli | CLI only (@playwright/cli). MCP ignored. |
mcp | MCP only. CLI ignored. Same as the old tea_use_mcp_enhancements: true. |
none | No browser interaction. Pure AI generation from docs and code. |
Affects skills:
test-designexploratory mode (CLI snapshots for page discovery)automatered and expand modes: recording for selector verification, plus browser evidence for test repairs when enablednfr-assessbrowser-based evidence collection when the mode iscliorautotest-reviewevidence collection (CLI for traces and screenshots)
Prerequisites:
# CLI mode (and 'auto')npm install -g @playwright/cli@latestplaywright-cli install --skills # run from project root; Node.js 18+
# MCP mode (and 'auto') needs two servers configured in your IDE:# playwright -> npx @playwright/mcp@latest# playwright-test -> npx playwright run-test-mcp-servertea_browser_automation = "auto" # "cli" | "mcp" | "none"Migration from the old flag:
| Old setting | New equivalent |
|---|---|
tea_use_mcp_enhancements: true | tea_browser_automation: "auto" |
tea_use_mcp_enhancements: false | tea_browser_automation: "none" |
Related:
tea_execution_mode
Section titled “tea_execution_mode”Execution strategy for orchestration-capable TEA skills.
Type: string · Default: "auto" · Options: "auto" | "subagent" | "agent-team" | "sequential"
Setup question: How should TEA run multi-step generation and evaluation?
Applies to automate (red and expand), test-review, nfr-assess, framework (framework and CI), test-design, and trace.
teach-me-testing does not use this setting.
| Mode | Behavior |
|---|---|
auto | Recommended. Picks the best supported mode using runtime capability checks when probing. |
agent-team | Prefer runtime team/delegation orchestration. |
subagent | Prefer isolated subagent-style orchestration. |
sequential | Force one-by-one execution. Most deterministic, typically slowest. |
Per-skill effect:
| Skill | Orchestrated unit | What the mode changes |
|---|---|---|
automate expand mode | API + E2E/backend/mobile generation workers | Dispatch style only |
automate red mode (ATDD) | failing API + failing E2E workers | Dispatch style only |
test-review | quality-dimension workers | Dispatch style only |
nfr-assess | domain assessment workers | Dispatch style only |
framework | scaffold work units | Dispatch style only |
framework CI phase | orchestration-capable pipeline generation step | Orchestration policy |
test-design | orchestration-capable output generation step | Orchestration policy |
trace | phase/work-unit separation with dependencies | Orchestration policy |
In agent-team and subagent modes, the runtime decides scheduling and concurrency.
Output contracts are the same across modes.
Resolution order:
- Normalize an explicit run-level request when one is present:
agent team/agent teams/agentteambecomeagent-team;subagent/subagents/sub agent/sub agentsbecomesubagent;sequentialandautopass through. - With no explicit override, use
tea_execution_modefrom[modules.tea]. - With
tea_capability_probe: true, detect runtime support foragent-teamandsubagent. - Resolve:
autowalksagent-teamthensubagentthensequential; an explicitagent-teamorsubagentfalls back only when probing is enabled;sequentialis always sequential.
tea_execution_mode = "auto" # "sequential" forces deterministic single-threaded runstea_capability_probe
Section titled “tea_capability_probe”Whether TEA probes runtime capabilities before resolving the execution mode.
Type: boolean · Default: true
Setup question: Check what the tool supports before choosing an execution mode, and fall back when it is missing?
When enabled, TEA checks whether agent-team or subagent execution is supported and falls back safely.
When disabled, TEA honors the configured mode strictly and fails if it is unsupported.
tea_capability_probe = "true" # "false" honors tea_execution_mode strictlytest_stack_type
Section titled “test_stack_type”Detected or configured project stack type. Controls CI pipeline generation and framework selection.
Type: string · Default: "auto" · Options: "auto" | "frontend" | "backend" | "fullstack" | "mobile"
Setup question: What type of project is this?
| Stack type | Behavior |
|---|---|
auto | Auto-detect from project manifests (playwright.config.*, jest.config.*, pyproject.toml, go.mod, pubspec.yaml, and similar) |
frontend | Browser-based tests (Playwright/Cypress), browser install in CI, burn-in enabled |
backend | API/unit tests (pytest, JUnit, Go test, Jest/Vitest), no browser install, burn-in skipped by default |
fullstack | Both frontend and backend tests, full CI pipeline |
mobile | Native app: Maestro device flows plus the app’s unit/component suite, no browser install, burn-in enabled and scoped to changed flows |
Detection checks mobile first: a React Native or Expo project carries package.json with react and would otherwise misdetect as frontend.
Affects skills:
frameworkCI phase uses stack-conditional pipeline stages (browser install, burn-in, device/emulator legs)frameworkframework phase adapts the scaffold to the stack typeautomateexpand mode selects which generation workers launch (mobileruns the API worker plus the mobile worker)test-designscopes the planned test levels to the stackautomatered mode picks stack-appropriate failing-test patternstest-reviewapplies stack-appropriate review criteria
test_stack_type = "fullstack"test_framework
Section titled “test_framework”Detected or configured test framework preference.
Type: string · Default: "auto"
Options: "auto" | "playwright" | "cypress" | "jest" | "vitest" | "pytest" | "junit" | "go-test" | "dotnet-test" | "rspec" | "maestro" | "other"
Setup question: Which test framework does the project use?
Controls which framework patterns TEA uses for code generation.
With "auto", TEA detects from project configuration files and manifests.
Affects skills: framework (scaffold generation and CI test commands) and automate (red and expand test generation patterns).
test_framework = "playwright"auto_validate
Section titled “auto_validate”Execute generated tests during Create.
Type: boolean · Default: true
Setup question: Run generated tests during Create? true (recommended) or false to report generation without execution.
Affects skills: automate in red and expand modes.
Set "false" to generate tests without executing them, matching the generation-only behavior of version 2.0.0.
Repair requires execution, so this also disables repairs for the run.
auto_validate = "true"auto_heal_failures
Section titled “auto_heal_failures”Repair confirmed defects in generated tests after execution while preserving acceptance criteria and real product defects.
Type: boolean · Default: true
Setup question: Repair confirmed defects in generated tests after running them? true (recommended) or false to report failures without repairs. Acceptance criteria and real product defects are preserved.
Affects skills: automate Create in red and expand modes.
Requires auto_validate to be enabled. Set "false" to execute tests and report failures without repairs.
auto_heal_failures = "true"max_healing_iterations
Section titled “max_healing_iterations”Maximum repair and rerun rounds after the initial execution, from 0 to 3.
Type: integer · Default: 3
Setup question: How many repair rounds may generated tests use? 0 to 3, with 3 recommended.
Affects skills: automate Create and Resume in red and expand modes.
Set "0" to execute tests once and report failures without repairs. Resume retains rounds already used.
max_healing_iterations = "3"use_mcp_healing
Section titled “use_mcp_healing”Use available browser evidence tools to diagnose generated browser test failures when the browser automation setting permits MCP.
Type: boolean · Default: true
Setup question: Use available browser evidence tools to diagnose generated browser test failures? true (recommended) or false to use source, runner reports and traces.
Affects skills: automate Create in red and expand modes.
Test execution and repairs also work without MCP. Set "false" to diagnose failures from source, runner reports, and traces.
use_mcp_healing = "true"Per-Skill Settings
Section titled “Per-Skill Settings”Each setting below is read by one skill and lives in its customization file under [workflow].
Put team values in _bmad/custom/<skill>.toml and personal values in _bmad/custom/<skill>.user.toml.
The bmad-customize skill can write either file.
evaluations_folder
Section titled “evaluations_folder”Base folder for Evaluate (bmad-tea-evaluate) evaluation folders.
Type: string · Default: evals · File: _bmad/custom/bmad-tea-evaluate.toml
Resolves to {project-root}/{value}, independent of test_artifacts.
Earlier releases named this key tea_evaluations_folder and stored it with the module config; a value there is no longer read.
[workflow]evaluations_folder = "quality/evals"ci_platform
Section titled “ci_platform”CI/CD platform for pipeline generation.
Type: string · Default: "auto" · File: _bmad/custom/bmad-tea-framework.toml
Options: "auto" | "github-actions" | "gitlab-ci" | "jenkins" | "azure-devops" | "harness" | "circle-ci" | "other"
Controls which CI template the framework skill’s CI phase uses and where it writes.
With "auto", TEA scans for .github/workflows/, .gitlab-ci.yml, Jenkinsfile, azure-pipelines.yml, .harness/, and .circleci/config.yml, then falls back to inferring from the git remote.
Any other value skips detection.
Earlier releases stored this key with the module config; a value there is no longer read.
Affects skills: framework when CI is included.
An explicit ci_platform override in _bmad/custom/bmad-tea-framework.toml or its .user.toml wins, including an explicit "auto".
Otherwise, existing _bmad/custom/bmad-tea-ci.toml and .user.toml values supply the CI setting. The default remains "auto".
Framework customizations apply when framework setup is included. CI-only runs use your CI customizations. Both includes each phase’s customizations once; Resume skips hooks that already finished.
bmad setup tea and bmad migrate keep invocation entries and configuration values. Run the 3.0 customization migration above to rename pre-3.0 workflow files.
[workflow]ci_platform = "github-actions"Automate Run and Heal
Section titled “Automate Run and Heal”bmad-tea-automate supports red and expand modes selected by your prompt. The command and TA menu code default to expand when no task mode is given; ask for acceptance tests before implementation to select red. Unattended runs state the selected mode in the summary. Resume continues interrupted red or expand progress. A new unattended run starts over by default.
Red reads _bmad/custom/bmad-tea-atdd.toml; expand reads _bmad/custom/bmad-tea-automate.toml. Both include their .user.toml layers. Only the selected mode’s activation hooks, persistent facts, and completion hook run.
Create runs execute generated tests, classify failures, fix test issues, and rerun. Red verifies the intended missing behavior in a disposable activated copy. It uses tea-atdd-red-check when available for compatible browserless loopback Playwright tests and tea-unit-check for Vitest and Jest scaffolds; browser tests or projects needing their own environment and services use the installed project runner with original configuration and environment. The summary records the execution route and any fallback reason. Expand aims for passing coverage and reports real product defects with their assertions intact. Validate reports findings and Edit checks requested changes. These operations never repair tests or require the full suite to pass.
These are setup answers under [modules.tea]. An explicit instruction for a run overrides the setup default:
| Setting | Default | Effect |
|---|---|---|
auto_validate | true | Execute generated tests during Create. |
auto_heal_failures | true | Repair test issues after execution. Requires validation. |
max_healing_iterations | 3 | Maximum repair and rerun rounds, from 0 to 3. |
use_mcp_healing | true | Use available browser MCP evidence when browser automation allows it. Test execution and repairs also work without MCP. |
[modules.tea]auto_validate = "true"auto_heal_failures = "true"max_healing_iterations = "3"use_mcp_healing = "true"The summary lists what was repaired, the execution results, and remaining test or product failures.
Core Configuration (Read by TEA)
Section titled “Core Configuration (Read by TEA)”Every TEA skill also reads the [core] table of the same config layers.
bmad setup writes project_name and output_folder there.
The other keys below are optional; set them under [core] yourself, in _bmad/custom/config.user.toml for personal values such as your name.
output_folder
Section titled “output_folder”Type: string · Default: {project-root}/_bmad-output
Base output folder for core BMad artifacts.
TEA writes its own artifacts under test_artifacts, which defaults to {project-root}/_bmad-output/test-artifacts.
The default does not follow a different output_folder; when you changed it, answer the test_artifacts setup question to match.
[core]output_folder = "{project-root}/_bmad-output"user_name
Section titled “user_name”Type: string · Default: none
Your name.
Skills greet you with it, and teach-me-testing uses it to name your progress and session-notes files.
[core]user_name = "Jane Doe"project_name
Section titled “project_name”Type: string · Default: directory name
Used in report headers, documentation titles, CI configuration comments, and the test-design handoff filename {test_artifacts}/test-design/{project_name}-handoff.md.
[core]project_name = "my-awesome-app"communication_language
Section titled “communication_language”Type: string · Default: none (the skill answers in your language)
Language for TEA chat responses. Any language works.
[core]communication_language = "english"document_output_language
Section titled “document_output_language”Type: string · Default: none
Language for TEA-generated documents (test designs, reports).
It can differ from communication_language: chat in Spanish, generate docs in English.
[core]document_output_language = "english"Removed Keys
Section titled “Removed Keys”Older projects may still hold classic-installer files under _bmad/tea/.
To upgrade, run bmad migrate in the assistant chat.
The v6 installer in bmad-method 6.12 already writes [modules.tea] into _bmad/config.toml.
A project with that table can still carry v6 keys.
If [modules.tea] is missing from every config layer, run bmad setup tea first, then run the migration.
The migration keeps the thirteen current module settings, converts their values to strings, and moves non-default ci_platform and tea_evaluations_folder values into their skill customization files.
It removes both moved keys and all unread keys from every [modules.tea] layer, and offers to delete the classic installer’s config, help file, and TEA agent or skill copies under _bmad/tea/.
If answers survive only in the classic YAML while the TOML holds defaults, the migration proposes restoring them for your approval.
A _bmad/tea/config.yaml that is left is not read by any skill.
The tea-test-review CLI is the one exception: it reads that file only when _bmad/config.toml does not exist, so older CI setups keep working.
See tea-test-review CLI.
The risk_threshold key was never read by a skill and is no longer asked at setup.
tea_evaluations_folder and ci_platform moved to Per-Skill Settings.
Earlier releases also declared three FUTURE output-folder keys: test_design_output, test_review_output, and trace_output.
No skill ever read them, and they are removed.
Every skill now writes to a fixed folder of its own, described in Output Layout.
Output Layout
Section titled “Output Layout”Outputs use fixed folders under {test_artifacts}: test-design/, atdd/, automate/, test-review/, nfr/, trace/, ci/, and framework/.
Framework and CI setup save progress in framework/setup-run-progress.md. Resume picks up any interrupted setup run where it stopped, including Edit and Validate.
The existing framework/framework-setup-progress.md and ci/ci-pipeline-progress.md files remain Create progress checkpoints. Edit and Validate leave that earlier progress intact.
Previous setup history and validation reports are kept when a new run begins.
The folder names are fixed, and no configuration key moves them.
teach-me-testing keeps its per-learner folders, and Evaluate writes under evaluations_folder.
Commit outputs to keep a history per scope. Re-running a scope replaces its outputs; other scopes retain their files.
A file produced once per scope carries that scope’s run_key in its name, so a trace run for epic 16 never opens, rewrites, or appends to epic 15’s matrix or gate decision.
A file that exists once per project keeps a plain name: test-design-architecture.md, test-design-qa.md, {project_name}-handoff.md, ci-pipeline-progress.md, and framework-setup-progress.md.
TEA Output Files
Section titled “TEA Output Files”Paths are relative to {test_artifacts} unless noted.
Deliverables are declared in the skill’s workflow.yaml; resume progress files are declared in the steps or setup resources that write them.
| Skill | Output |
|---|---|
test-design | test-design/test-design-architecture.md and test-design/test-design-qa.md (system-level writes both) |
test-design | test-design/{project_name}-handoff.md (system-level; feeds BMAD create-epics-and-stories) |
test-design | test-design/test-design-epic-{epic_num}.md (epic-level) |
test-design | test-design/test-design-progress-{run_key}.md (resume checkpoint; run_key is system or epic-{epic_num}) |
test-design | test-design/exploration/explore-{run_key}-<page>.png (browser exploration screenshots) |
framework | {project-root}/tests/README.md |
framework | framework/setup-run-progress.md (shared setup progress for Create, Edit, and Validate) |
framework | framework/framework-setup-progress.md (Create progress checkpoint) |
framework CI phase | {project-root}/.github/workflows/test.yml (GitHub Actions default; per-platform otherwise) |
framework CI phase | ci/ci-pipeline-progress.md (Create progress checkpoint) |
automate red mode | atdd/atdd-checklist-{story_key}.md |
automate | automate/automation-summary-{run_key}.md |
test-review | test-review/test-review-{run_key}.md (a non-empty output_file_override replaces this path for one run) |
test-review | test-review/review-evidence-{run_key}.png (browser evidence screenshot) |
nfr-assess | nfr/nfr-assessment-{run_key}.md |
nfr-assess | nfr/perf-{run_key}-<page>.png (browser evidence screenshots) |
trace | trace/traceability-matrix-{run_key}.md |
trace | trace/e2e-trace-summary-{run_key}.json (machine-readable summary for CI/CD and reporting) |
trace | trace/gate-decision-{run_key}.json (emitted only when the collection is gate-eligible) |
teach-me-testing | teaching-progress/{user_name}-tea-progress.yaml |
teach-me-testing | tea-academy/{user_name}/session-{N}-notes.md |
teach-me-testing | tea-academy/{user_name}/tea-completion-summary.md |
trace also reads two optional inputs it never writes, and both stay at the root of {test_artifacts} because other tools and people produce them: live-verification-results.json and gate-waivers.md.
Any producer may write live-verification-results.json (an agent, a shell script, a CI job, or a person recording an outcome by hand).
See Live Verification Results for the contract.
Run Keys
Section titled “Run Keys”Each skill that runs once per scope resolves its run_key in its first step, before it writes anything, and records it as runScope and runKey in the output’s frontmatter.
Later steps carry both forward unchanged.
system: the whole project or system, or no narrower scope could be resolved.epic-{epic_num}: one epic. An epic with no number uses the slug of its title.story-{story_key}: one story.story_keyis the BMM story file basename without.md(for example1-2-user-authentication). Without a story file, it is the story id with.replaced by-(1.2becomes1-2).release-{slug}andhotfix-{slug}:traceonly, fromgate_typeand the release version or hotfix id.target-{slug}:automateandtest-reviewonly, when no story or epic applies. The slug comes from the automated or reviewed path or feature name. Atest-reviewrun withreview_scope: suiteand no story or epic issystem.
The slug rule applies to every {slug} and to an epic title with no number: lowercase; replace every run of characters outside a-z and 0-9 with a single -; trim leading and trailing -; truncate to 64 characters.
For example, release v1.2.0 becomes release-v1-2-0, and the review target tests/e2e/checkout.spec.ts becomes target-tests-e2e-checkout-spec-ts.
A skill resolves the scope in this order:
- The scope you name when you invoke it (“run trace for epic 16”).
- The scope the loaded artifacts carry: a story file name, an epic document’s metadata, heading, or filename, or trace’s
gate_typeand its id. - When several candidates remain, an interactive run lists them, asks which one this run covers, and waits.
A headless or autonomous run never asks: it uses
system, ortarget-{slug}where a target applies, and says so in its output. The one exception is atest-designepic plan, which has no system-level fallback: a headless epic-level run whose epic stays ambiguous halts with a message naming the candidate epics.
Automate red mode (atdd in stored identifiers) runs once per story, so its checklist is named by story_key directly.
test-design uses system or epic-{epic_num}.
Re-running a Scope
Section titled “Re-running a Scope”A run reads and writes only its own run_key’s files.
Files for other scopes are never opened.
The output path determines how a run starts:
- No file: a fresh run.
- An earlier run of this scope was interrupted (the file is marked in progress): an interactive run asks whether to resume or start over, and a headless or autonomous run starts over.
- An earlier run of this scope finished: the new run replaces the file entirely.
Two runs are never merged into one file.
A file grows only while the run that created it is still adding its later sections.
To keep an earlier result for the same scope, commit or copy it before you re-run.
A trace run that evaluates no gate also removes an earlier gate-decision-{run_key}.json for the same run_key, so the folder never pairs a new summary with a stale decision.
Framework and CI setup use fixed progress filenames. Resume continues the saved setup scope and operation. A new unattended Create, Edit, or Validate request starts over when earlier progress is unfinished; an explicit Resume request continues it. An uncertain customization action still needs your confirmation.
Files From Earlier TEA Versions
Section titled “Files From Earlier TEA Versions”Earlier TEA versions wrote everything flat under {test_artifacts} with fixed names, such as traceability-matrix.md, gate-decision.json, test-review.md, nfr-assessment.md, and automation-summary.md.
Upgrading leaves those files where they are:
- New runs never treat an old flat file as their own output, so they never rewrite it or append to it.
- Skills that read another skill’s output look in the producing skill’s folder first, then at the old root location, and name both.
For example,
nfr-assesslooks for test-design documents intest-design/and then at the root of{test_artifacts}, andautomatelooks for ATDD checklists inatdd/and then at the root. - Resume migrates an old file only while it is still in progress.
A completed flat file stays where it is.
Resume first resolves the file’s scope.
Automate red mode recovers the story from the checklist’s
storyKey, atest-designcheckpoint that already carries arunKey(test-design-progress-{run_key}.mdat the root) keeps it, and for any other old file Resume asks which scope it covers. It then writes the file into the skill’s folder under its scoped name withrunScopeandrunKeyadded, deletes the old copy, and continues. It never writes over a scoped file that already exists for the same scope. Framework and CI checkpoints have no story, epic, or release scope to resolve, so they move their root checkpoint into their folder under the same rules.
Once nothing you run still reads an old file, archive or delete it.
Upgrading Scripts That Read Old Paths
Section titled “Upgrading Scripts That Read Old Paths”CI jobs, dashboards, and scripts that read TEA’s old flat paths need the new ones:
Old path under {test_artifacts} | New path under {test_artifacts} |
|---|---|
gate-decision.json | trace/gate-decision-{run_key}.json |
e2e-trace-summary.json | trace/e2e-trace-summary-{run_key}.json |
traceability-matrix.md | trace/traceability-matrix-{run_key}.md |
test-review.md | test-review/test-review-{run_key}.md |
nfr-assessment.md | nfr/nfr-assessment-{run_key}.md |
automation-summary.md | automate/automation-summary-{run_key}.md |
atdd-checklist-{story_key}.md | atdd/atdd-checklist-{story_key}.md |
test-design-architecture.md, test-design-qa.md | test-design/test-design-architecture.md, test-design/test-design-qa.md |
test-design-epic-{epic_num}.md | test-design/test-design-epic-{epic_num}.md |
test-design-progress-{run_key}.md | test-design/test-design-progress-{run_key}.md |
test-design-progress.md | test-design/test-design-progress-{run_key}.md (after Resume migrates it) |
ci-pipeline-progress.md | ci/ci-pipeline-progress.md |
framework-setup-progress.md | framework/framework-setup-progress.md |
{workflow}-validation-report-{validation_scope}-{run_timestamp}.md | the same name inside the skill’s folder |
A job that gates one scope reads that scope’s file, for example trace/gate-decision-epic-16.json or trace/gate-decision-release-v1-2-0.json.
A job that wants the latest gate of any scope globs trace/gate-decision-*.json and picks the file with the newest evaluated_at.
The run_key in each file name identifies the scope, and the target field inside gives the gate type and target id.
The tea-test-review CLI is unaffected: it passes its own --output path (default test-review.md, resolved under --project-root, which defaults to the working directory) as output_file_override, which replaces the skill’s default path.
Rebinding {test_artifacts} From a Customization
Section titled “Rebinding {test_artifacts} From a Customization”Before this layout existed, some projects got per-skill folders with an activation_steps_append rule in _bmad/custom/bmad-tea-*.toml that rebinds {test_artifacts} to a subfolder before the first step runs.
Remove that rule when you upgrade.
Each skill already appends its own folder, so a rebound {test_artifacts} nests a second level, such as test-artifacts/traceability/trace/.
{test_artifacts} also locates shared inputs and other skills’ outputs.
Rebinding it can hide trace’s live results and waivers, test-design documents, ATDD checklists, and NFR audit reports.
Validation Report History
Section titled “Validation Report History”Validate mode preserves every report as a separate artifact.
The artifact-producing skills and their named modes write {workflow}-validation-report-{validation_scope}-{run_timestamp}.md into their own folder under {test_artifacts}, next to the outputs they validate.
The stored workflow identifier is atdd, automate, ci, framework, nfr-assess, test-design, test-review, or trace; nfr-assess reports land in nfr/.
validation_scope identifies what was checked, such as story-1-2, epic-9, system, or pull-request-123.
run_timestamp is the UTC start time with milliseconds in YYYYMMDDTHHmmssSSSZ format.
Each report also records the exact project-relative paths of its validated artifacts.
Concurrent validation runs save separate reports without overwriting earlier results.
The teach-me-testing skill validates its skill definition.
Its reports use workflow-validation/teach-me-testing-validation-{run_timestamp}.md under {test_artifacts} and follow the same no-overwrite rule.
Environment Variables
Section titled “Environment Variables”Generated tests and CI jobs can use environment variables for URLs and credentials.
Playwright:
BASE_URL=https://todomvc.com/examples/react/dist/API_BASE_URL=https://api.example.comTEST_USER_EMAIL=test@example.comTEST_USER_PASSWORD=password123Cypress:
# .env (exported as shell variables; Cypress reads variables prefixed with CYPRESS_)CYPRESS_BASE_URL=https://example.comCYPRESS_API_URL=https://api.example.comOr keep Cypress values in cypress.env.json, which Cypress loads itself:
{ "API_URL": "https://api.example.com", "TEST_USER_EMAIL": "test@example.com", "TEST_USER_PASSWORD": "replace-me"}Framework setup writes .env.example; copy it to .env and fill in real values.
A .env file helps only when something loads it: your shell (set -a; source .env; set +a), your runner’s config, or CI.
Split them per environment (.env.development, .env.staging, .env.production) and keep the production file pointed at read-only tests only.
Ignore every file that holds real credentials, and commit only a sanitized example:
.env*!.env.examplecypress.env.jsonCI/CD: set the same names as secrets in your CI platform.
env: BASE_URL: ${{ secrets.STAGING_URL }} API_KEY: ${{ secrets.API_KEY }} TEST_USER_EMAIL: ${{ secrets.TEST_USER }}Verify Your Configuration
Section titled “Verify Your Configuration”Ask the bmad skill for bmad setup tea.
It reports the module’s state and shows every answer with the file it lives in.
From a shell:
# 1. Print the TEA answers bmad setup wrotesed -n '/^\[modules.tea\]/,/^\[/p' _bmad/config.toml
# 2. Print the merged config a skill sees, all three layers applieduv run _bmad/scripts/resolve_config.py --project-root . --key core --key modules.tea
# 3. Confirm playwright-utils is installed when tea_use_playwright_utils is "true"npm ls @seontechnologies/playwright-utilsA key you set that does not appear in step 2 is misspelled or in the wrong table. Compare it against the key list on this page.
For anything that stays broken, see the Troubleshooting guide.