Claude
Skills
Sign in
Back

tdd

Included with Lifetime
$97 forever

This skill should be used when the user wants to implement features or fix bugs using test-driven development. Enforces the RED-GREEN-REFACTOR cycle with vertical slicing, context isolation between test writing and implementation, human checkpoints, and auto-test feedback loops. Uses multi-agent orchestration with the Task tool for architecturally enforced context isolation. Supports Jest, Vitest, pytest, Go test, cargo test, PHPUnit, and RSpec.

AI Agentsscripts

What this skill does


# Test-Driven Development — Multi-Agent Orchestration

Enforce disciplined RED-GREEN-REFACTOR cycles using **separate subagents** for test writing and implementation. The core innovation: **the Test Writer never sees implementation code, and the Implementer never sees the specification.** This prevents the LLM from leaking implementation intent into test design.

## When to Use

- User requests TDD, test-first, or red-green-refactor workflow
- User says `/tdd` with a feature description or bug report
- User wants to add a feature with test coverage enforced from the start
- User wants to fix a bug by first writing a reproducing test

## Invocation Modes

| Invocation | Behavior |
|-----------|----------|
| `/tdd <feature>` | Interactive mode — pause for approval at slices and each RED checkpoint |
| `/tdd --auto <feature>` | Autonomous mode — run all slices without pausing; stop ONLY on unrecoverable errors |
| `/tdd --resume` | Resume from `.tdd-state.json` in project root |
| `/tdd --dry-run <feature>` | Validation mode — runs Phase 0 + Phase 1 fully, renders all prompts, but skips `Task()` calls. No code is written. |

In `--auto` mode, skip all `[HUMAN CHECKPOINT]` steps. Print status lines instead:

```
[auto] RED  slice 1/4: "validates email format" — test failing as expected
[auto] GREEN slice 1/4: passing (attempt 1)
[auto] REFACTOR slice 1/4: 1 suggestion applied, 0 skipped
```

Stop and ask the user ONLY when:
- Implementation fails after 5 attempts
- Regressions cannot be auto-fixed after 3 attempts
- A script error makes it impossible to continue (missing binary, permission denied, etc.)

In `--dry-run` mode, validate the entire orchestration pipeline without executing any subagents or writing any code:

1. **Phase 0 runs fully**: detect framework, verify baseline, extract API, discover docs, create state file
2. **Phase 1 runs fully**: decompose into slices (still requires user approval)
3. **For each slice**: render all three agent prompts (Test Writer, Implementer, Refactorer) with actual variables. Print rendered prompts to the user with character counts.
4. **No `Task()` calls are made**. No test files are written. No implementation code is generated.
5. **Validate**: check that all template variables resolve (no `{UNRESOLVED}` placeholders), all scripts execute without error, and the state file is well-formed.
6. **Report summary**:

```
DRY RUN COMPLETE: {feature name}

Phase 0:
  Framework: {framework}
  Language: {language}
  Baseline: {pass|greenfield}
  API surface: {line count} lines
  Doc context: {line count} lines (or "none")

Phase 1:
  Slices: {N} ({layer breakdown})

Prompts rendered: {N * 3} (all variables resolved)
  Test Writer:   {char count} chars
  Implementer:   {char count} chars
  Refactorer:    {char count} chars

State file: .tdd-state.json written
No code was modified.
```

This mode is useful for:
- Validating that scripts work in the project's environment
- Reviewing prompt content before committing to a full TDD run
- Testing skill changes without side effects

## Architecture Overview

```
ORCHESTRATOR (you, reading this file)
├─ Phase 0: Setup — detect framework, extract API, create state file
├─ Phase 1: Decompose into vertical slices → user approves
│
├─ FOR EACH SLICE:
│   ├─ Phase 2 (RED):    Task(Test Writer)  ← spec + API only
│   ├─ Phase 3 (GREEN):  Task(Implementer)  ← failing test + error only
│   └─ Phase 4 (REFACTOR): Task(Refactorer) ← all code + green results
│
└─ Summary
```

### Context Boundaries (the key constraint)

| Agent | Sees | Does NOT See |
|-------|------|-------------|
| **Test Writer** | Slice spec, public API signatures, framework conventions, layer constraints | Implementation code, other slices, implementation plans |
| **Implementer** | Failing test code, test failure output, file tree, existing source, layer constraints | Original spec, slice descriptions, future plans |
| **Refactorer** | All implementation + all tests + green results, layers touched | Original spec, decomposition rationale |

## Workflow

### Phase 0: Setup (once per session)

**Step 1**: Detect framework and test runner.

```
Check for: package.json (jest/vitest), pyproject.toml/pytest.ini (pytest),
go.mod (go test), Cargo.toml (cargo test), Gemfile (rspec), composer.json (phpunit)
```

If ambiguous, ask: "What command runs your tests? (e.g., `npm test`, `pytest`)"

**Step 2**: Detect language from source files (for agent prompts):

```
TypeScript (.ts/.tsx), JavaScript (.js/.jsx), Python (.py), Go (.go), Rust (.rs), Ruby (.rb), PHP (.php)
```

**Step 3**: Verify green baseline.

```bash
bash ~/.claude/skills/tdd/scripts/run_tests.sh {FRAMEWORK} "{TEST_COMMAND}"
```

Parse the JSON output.

- If `status` is `"pass"`: proceed.
- If `status` is `"fail"`: stop — "Existing tests are failing. TDD starts from a green baseline."
- If `status` is `"error"` AND `total` is 0: **greenfield project** — no tests exist yet. This is fine. Proceed.

**Step 4**: Extract the public API surface.

```bash
bash ~/.claude/skills/tdd/scripts/extract_api.sh {SOURCE_DIR}
```

Save the output — this is what the Test Writer will see. If empty (greenfield), that's expected.

**Step 5**: Discover project documentation.

```bash
bash ~/.claude/skills/tdd/scripts/discover_docs.sh {PROJECT_ROOT} --lang {LANGUAGE}
```

This searches for:
- **Documentation files**: README, ARCHITECTURE.md, docs/ folder, DESIGN.md, SPEC files, ADRs
- **API specifications**: OpenAPI/Swagger, GraphQL schemas, .proto files
- **Source docstrings**: JSDoc, Python docstrings, Go doc comments, Rust `///` comments

Save the output as `{DOC_CONTEXT}`. This feeds into:
- **Phase 1** — so slice decomposition is informed by documented behavior and API contracts
- **Phase 2** — so the Test Writer writes tests aligned with documented intent, not just code signatures

If empty (no docs found), that's fine — proceed without doc context.

**Step 6**: Create the state file `.tdd-state.json` in the project root:

```json
{
  "feature": "user's feature description",
  "framework": "jest|vitest|pytest|go|cargo|rspec|phpunit",
  "language": "typescript|javascript|python|go|rust|ruby|php",
  "test_command": "the full test command",
  "source_dir": "src/",
  "doc_context": "output from discover_docs.sh (or empty string)",
  "auto_mode": false,
  "dry_run": false,
  "slices": [],
  "current_slice": 0,
  "phase": "setup",
  "layer_map": {},
  "files_modified": [],
  "test_files_created": []
}
```

Each slice in the `slices` array includes a `layer` field: `"domain"`, `"domain-service"`, `"application"`, or `"infrastructure"`. See Phase 1 for how layers are assigned.

The `layer_map` maps directory prefixes to layers. Built during Phase 1 from project structure:

```json
{
  "layer_map": {
    "src/domain/": "domain",
    "src/services/": "domain-service",
    "src/application/": "application",
    "src/infrastructure/": "infrastructure",
    "src/adapters/": "infrastructure",
    "src/controllers/": "infrastructure"
  }
}
```

If the project has no clear directory-layer mapping (flat structure), set `layer_map` to `{}` and skip path-based validation.

**Step 5a** (auto-detect layer_map): If `layer_map` is empty, scan the source directory for common DDD/layered architecture directory names and auto-populate:

```
Common directory → layer mappings (check if directories exist):
  */domain/       → "domain"
  */models/       → "domain"          (ORM models often serve as domain entities)
  */entities/     → "domain"
  */value_objects/ → "domain"
  */services/     → "application"     (unless clearly infrastructure)
  */application/  → "application"
  */use_cases/    → "application"
  */core/         → "application"
  */infrastructure/ → "infrastructure"
  */adapters/     → "infrastructure"
  */controllers/  → "infrastructure"
  */api/          → "infrastructure"
  */bot/          → "infrastructure"  (Telegram/Discord bot handlers)
  */handlers/     → "infrastructure"
  */reposito
Files: 26
Size: 145.2 KB
Complexity: 84/100
Category: AI Agents

Related in AI Agents