/gaia-atdd

user-facing
Category:
Testing
Lifecycle phase:
4 -- Implementation (pre-development)
Arguments:
[story-key] — omit for batch mode

What it does

/gaia-atdd generates Acceptance Test-Driven Development (ATDD) artifacts from a story's acceptance criteria. Each AC is transformed into a failing test skeleton in Given/When/Then format -- the red phase of TDD. The tests describe expected behavior that must fail because the implementation does not exist yet. No implementation code is written.

The command supports two invocation modes:

  • Single-story mode -- pass a story key (e.g., /gaia-atdd E3-S7) to generate ATDD for one specific story.
  • Batch mode -- invoke without arguments (/gaia-atdd) to scan .gaia/artifacts/planning-artifacts/epics-and-stories.md for all high-risk stories, then choose which ones to process via an interactive menu.

After generation, the command optionally offers to execute the generated tests to confirm they fail (red-phase verification).

When to use it

  • A high-risk story is about to enter development and needs acceptance test coverage before implementation begins. /gaia-dev-story enforces an ATDD gate for high-risk stories -- run this command first to satisfy it.
  • Sprint planning identified multiple high-risk stories and you want to seed failing tests across the entire high-risk scope in one pass instead of running the command story by story.
  • You want to verify that acceptance criteria are testable before committing to development -- writing Given/When/Then skeletons surfaces ambiguous or untestable ACs early.

For stories with risk: medium or risk: low, ATDD is optional. If you invoke the command for a non-high-risk story, it proceeds normally but notes in the output header that ATDD was invoked explicitly.

Prerequisites

  • A story file must exist. The file lives inside its epic directory at .gaia/artifacts/implementation-artifacts/epic-{epic_key}-{slug}/stories/{story_key}-{slug}.md (epic-grouped layout). If it does not exist, the command stops with "Story file not found for {story_key}". Create it first with /gaia-create-story.
  • The story file must have acceptance criteria. The file must contain an ## Acceptance Criteria section with at least one AC entry. If the section is missing or empty, the command exits with "No acceptance criteria found for {story_key}".
  • For batch mode: epics-and-stories.md must exist. Batch discovery reads .gaia/artifacts/planning-artifacts/epics-and-stories.md. If the file is missing or unreadable, the command halts with an error. Run /gaia-create-epics to create it.
  • For red-phase execution (optional): a test runner must be configured. Step 5b reads config/test-environment.yaml and the Test Execution Bridge configuration. If no runner is configured, red-phase execution is skipped with a warning -- it does not fail the overall invocation.

Orchestration mode

When /gaia-atdd starts in subagent mode (Mode A -- the default), the framework emits a one-shot warning to your conversation. The warning text:


────────────────────────────────────────────────────────────────────────────
GAIA orchestration: running in subagent mode (Mode A)

The skill you're invoking belongs to a class (heavy-procedural or
conversational) whose output benefits from cross-step context. Mode A
dispatches each sub-agent in its own forked context, so context may
be lossy between steps — sub-agents return summaries, not full reasoning.

For the full-fidelity experience, enable Mode B (Agent Teams):
  1. Set CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 in your environment.
  2. Add orchestration.mode: team to .gaia/config/project-config.yaml.

Mode B uses persistent teammates that preserve in-conversation state
across dispatches. See the orchestration contract for details.

This warning is shown once per session.
────────────────────────────────────────────────────────────────────────────

Why Mode B is better for this command

The /gaia-atdd skill declares orchestration_class: heavy-procedural in its SKILL.md frontmatter. Heavy-procedural skills produce output that benefits from cross-step context -- under Mode A every sub-agent dispatch runs in its own forked context and can only return a summary back to the orchestrator, losing the full reasoning trace of every prior step. Mode B uses persistent teammates that retain in-conversation state across dispatches, so each agent's contribution can build on what was said before instead of receiving only a summary.

How to enable Mode B

Both steps are required. If either is missing, the framework falls back silently to Mode A and the warning fires again on the next session.

Step 1 -- set the environment variable:

export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1

Add this to your shell rc file to persist across sessions, or set it in Claude Code's settings.json.

Step 2 -- add the YAML block to .gaia/config/project-config.yaml:

orchestration:
  mode: team

One-shot semantics

The warning is emitted once per Claude Code session. A marker file at _memory/checkpoints/orchestration-warning-shown.<session-id> suppresses the warning for the rest of the session. Starting a new session re-emits the warning once.

How to invoke

Single-story mode

/gaia-atdd E3-S7

Pass a story key in E{n}-S{n} format. The command generates ATDD for that one story.

Batch mode

/gaia-atdd

Invoke without arguments. The command discovers all high-risk stories from epics-and-stories.md and presents a menu to choose which ones to process.

What it does step by step

  1. Validate input If a story key was provided, validates it matches the E{n}-S{n} format and confirms the key exists in epics-and-stories.md. If the format is wrong, exits with "Invalid story key format". If the key is not found, exits with "Story {key} not found in epics-and-stories.md" -- it does NOT fall back to batch mode.
  2. Batch discovery (argumentless only) When invoked without a story key, scans epics-and-stories.md for stories whose risk column is exactly high (medium and low are excluded). Presents a selection menu:
    • all -- generate ATDD for every discovered high-risk story.
    • select -- pick specific stories by number (e.g., 1,3). Invalid selections re-prompt the menu.
    • skip -- exit without generating anything.

    When exactly one high-risk story is found, the menu collapses to [all / skip] (no select option). When zero high-risk stories are found, the command exits gracefully with "No high-risk stories found -- nothing to generate".

  3. Load story file Searches .gaia/artifacts/implementation-artifacts/epic-{epic_key}-{slug}/stories/{story_key}-{slug}.md for the story file. Reads the story title, risk level, and every entry in the ## Acceptance Criteria section. Stories with zero ACs are skipped with a warning.
  4. Generate AC-to-test mapping For each acceptance criterion (AC1, AC2, AC-EC1, etc.):
    • Extracts the AC identifier and description.
    • Transforms the AC into a Given/When/Then test skeleton with a descriptive test name.
    • Maintains a strict 1:1 mapping -- each AC produces exactly one test.
    Builds a traceability table linking every AC to its corresponding test.
  5. Write ATDD artifact Writes the artifact to .gaia/artifacts/test-artifacts/atdd-{story_key}.md using an atomic write (temp file then rename) to prevent corruption if interrupted. The artifact contains:
    • Header with story key, title, risk level, and generation date.
    • AC-to-test mapping table (AC ID, description, test name).
    • Test skeletons in Given/When/Then format.
    • Summary confirming total ACs, total tests, and that all tests are in failing/red state.

    If the artifact already exists from a prior run, it is overwritten with a logged warning. If the output exceeds 10KB, a size warning is displayed.

  6. Validation Verifies: every AC has exactly one test, no test references a nonexistent AC, all tests use Given/When/Then format, and the output file was written successfully.
  7. Red-phase execution (optional) Prompts: "Run generated tests now to confirm red phase? [y/N]". On y, executes the tests via the configured Test Execution Bridge runner. Each test has a per-test timeout (default 30s). All tests are expected to fail -- if any unexpectedly pass, a warning is logged. On n (default), this step is skipped entirely.

Batch mode iteration

In batch mode, Steps 3 through 7 run as a self-contained sub-invocation for each selected story. A failure on one story (missing file, empty ACs) emits a warning and continues to the next -- it does not abort the batch. At the end, a summary distinguishes stories that were generated (new artifact) from those that were overwritten (prior artifact existed).

Inputs

Input Source Description Example
story-key Command argument (optional) The story to generate ATDD for, in E{n}-S{n} format. Omit to enter batch mode. /gaia-atdd E3-S7
Story file .gaia/artifacts/implementation-artifacts/epic-{epic_key}-{slug}/stories/{story_key}-{slug}.md Contains the acceptance criteria that are transformed into test skeletons. Also provides story title and risk level. --
Epics and stories .gaia/artifacts/planning-artifacts/epics-and-stories.md Used in both modes: single-story mode verifies the key exists; batch mode filters for high-risk entries. --
Test environment config config/test-environment.yaml Read during optional Step 5b (red-phase execution) to locate the configured test runner. Not required if you skip red-phase execution. --
API testing patterns Skill knowledge fragment Schema validation and contract test patterns loaded during AC-to-test transformation for API-related acceptance criteria. --

Outputs

Output Location Description
ATDD artifact .gaia/artifacts/test-artifacts/atdd-{story_key}.md Given/When/Then test skeletons for every AC in the story, plus the AC-to-test traceability table. One file per story.
Red-phase results (optional) Console output Pass/fail counts from executing the generated tests. All tests are expected to fail (red phase).
Checkpoint files _memory/checkpoints/ Written after each step to enable /gaia-resume if the session is interrupted.

Example session

Single-story mode

Suppose story E3-S7 has the following acceptance criteria in its story file:

## Acceptance Criteria

- [ ] **AC1:** Given a user submits valid registration credentials,
      when the registration endpoint is called, then a new user
      account is created and a 201 response is returned.
- [ ] **AC2:** Given a user submits an email that is already registered,
      when the registration endpoint is called, then a 409 Conflict
      response is returned with a descriptive error message.
- [ ] **AC-EC1:** Given the database is unreachable, when the
      registration endpoint is called, then a 503 Service Unavailable
      response is returned and the error is logged.

Running /gaia-atdd E3-S7 produces:

> /gaia-atdd E3-S7

Validating story key E3-S7...
  Format: valid (E{n}-S{n}).
  Lookup: found in epics-and-stories.md.

Loading story file...
  Path: .gaia/artifacts/implementation-artifacts/epic-E3-security/stories/E3-S7-user-registration.md
  Title: User registration
  Risk: high
  Acceptance criteria: 3 (AC1, AC2, AC-EC1)

Generating AC-to-test mapping...

  | AC     | Description                          | Test Name                             |
  |--------|--------------------------------------|---------------------------------------|
  | AC1    | Valid registration creates account   | test_valid_registration_creates_user  |
  | AC2    | Duplicate email returns 409          | test_duplicate_email_returns_conflict |
  | AC-EC1 | Database unreachable returns 503     | test_db_unreachable_returns_503       |

Writing test skeletons...

  ## Test: test_valid_registration_creates_user (AC1)
  **Given** a user submits valid registration credentials
    - email: "newuser@example.com"
    - password: meets minimum complexity requirements
  **When** the registration endpoint POST /api/register is called
  **Then** a new user account is created in the database
    - AND a 201 Created response is returned
    - AND the response body contains the new user ID
  **Status:** FAILING (red phase -- implementation does not exist)

  ## Test: test_duplicate_email_returns_conflict (AC2)
  **Given** a user submits an email that is already registered
    - existing user with email "existing@example.com" in database
  **When** the registration endpoint POST /api/register is called
    with email "existing@example.com"
  **Then** a 409 Conflict response is returned
    - AND the response body contains a descriptive error message
    - AND no duplicate account is created
  **Status:** FAILING (red phase -- implementation does not exist)

  ## Test: test_db_unreachable_returns_503 (AC-EC1)
  **Given** the database is unreachable
    - database connection pool returns connection timeout
  **When** the registration endpoint POST /api/register is called
  **Then** a 503 Service Unavailable response is returned
    - AND the error is logged with severity ERROR
    - AND no partial user record is created
  **Status:** FAILING (red phase -- implementation does not exist)

Artifact written to: .gaia/artifacts/test-artifacts/atdd-E3-S7.md
  3 ACs mapped to 3 tests. All tests in red (failing) state.

Validation: PASSED
  - Every AC has exactly one test: YES
  - No orphan tests: YES
  - All tests use Given/When/Then: YES

Run generated tests now to confirm red phase? [y/N]
> n

Done. ATDD artifact ready at .gaia/artifacts/test-artifacts/atdd-E3-S7.md

Batch mode

> /gaia-atdd

Scanning epics-and-stories.md for high-risk stories...

  Found 3 high-risk stories:
    1. E3-S7   User registration            (risk: high, 3 ACs)
    2. E3-S12  Password reset flow           (risk: high, 5 ACs)
    3. E5-S3   Payment processing webhook    (risk: high, 7 ACs)

[all / select / skip]
> select
Enter story numbers (comma-separated): 1,3

Processing E3-S7 (1/2)...
  Loaded 3 ACs. Generating test skeletons...
  Artifact written to: .gaia/artifacts/test-artifacts/atdd-E3-S7.md (generated)

Processing E5-S3 (2/2)...
  Loaded 7 ACs. Generating test skeletons...
  Overwriting existing ATDD artifact at .gaia/artifacts/test-artifacts/atdd-E5-S3.md
  Artifact written to: .gaia/artifacts/test-artifacts/atdd-E5-S3.md (overwritten)

Batch summary:
  Generated:   1 (E3-S7)
  Overwritten: 1 (E5-S3)
  Skipped:     1 (E3-S12 -- not selected)

Run generated tests now to confirm red phase? [y/N]
> n

Done.

What to run next

  • /gaia-dev-story -- implement the story. For high-risk stories, the ATDD gate is now satisfied and development can begin.
  • /gaia-edit-test-plan -- add the generated acceptance tests to the project test plan if your project maintains one.
  • /gaia-test-strategy -- review or create the overall test strategy if one does not exist yet.

Troubleshooting

"Invalid story key format"

The story key must match the E{n}-S{n} pattern (for example, E3-S7). Keys like S7 or E3S7 are rejected. Include the full epic prefix.

"Story {key} not found in epics-and-stories.md"

The key you provided does not appear in .gaia/artifacts/planning-artifacts/epics-and-stories.md. Verify the key is correct. The command does not fall back to batch mode when a specific key is given -- if you intended batch discovery, invoke /gaia-atdd without arguments.

"Story file not found for {story_key}"

The story key exists in epics-and-stories.md but no corresponding file was found under .gaia/artifacts/implementation-artifacts/. Run /gaia-create-story {key} to create the story file first.

"No acceptance criteria found for {story_key}"

The story file exists but its ## Acceptance Criteria section is missing or empty. Edit the story file to add ACs before running ATDD, or use /gaia-fix-story to address validation findings.

"No high-risk stories found -- nothing to generate"

Batch mode found no stories with risk: high in epics-and-stories.md. If you want to generate ATDD for a specific medium- or low-risk story, use single-story mode: /gaia-atdd E3-S7.

"Cannot read .gaia/artifacts/planning-artifacts/epics-and-stories.md"

The epics file is missing or unreadable. Run /gaia-create-epics to create the breakdown first.

"Test runner not configured -- skipping red-phase execution"

You opted to run red-phase tests, but no test runner is configured in config/test-environment.yaml or the Test Execution Bridge is disabled. The ATDD artifact is still written -- only the optional execution step is skipped. Configure a test runner or enable the bridge to use this feature.

"ATDD output exceeds 10KB"

The story has many acceptance criteria (typically 20+) and the generated artifact is large. This is a warning only -- no content is truncated. Review the artifact for completeness and consider whether the story should be split into smaller stories.

I keep seeing the GAIA orchestration warning every time I start this command

The warning is shown once per session, so if it fires again that's a new session -- not a per-skill repeat. If you want to silence it entirely, enable Mode B (full-fidelity orchestration via Agent Teams). Both of these conditions must be true:

  • echo $CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS returns 1 (not empty)
  • .gaia/config/project-config.yaml contains:
    orchestration:
      mode: team

If either is missing the framework silently uses Mode A and re-emits the warning each session.