Skip to content
Back to skills

Tdd

ASecurity

Use when implementing features or fixing bugs with test-driven development. Enforces RED→GREEN→REFACTOR cycle with vertical slicing and multi-agent context isolation. Triggers on: 'implement with TDD', 'write tests first', 'red green refactor', 'test-driven', '/tdd <feature>'. Supports Jest, Vitest, pytest, Go test, cargo test, RSpec, PHPUnit.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 9, 2026
ai-agentsjavascripttypescriptpythonrustgojavarubyphpbashnode

Works with

  • api

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add yanacuti1121/Yana-AI --skill tdd --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tdd?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Tdd
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yanacuti1121-tdd/badge)](https://www.skillsdirectory.com/skills/yanacuti1121-tdd)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tdd
description: "Use when implementing features or fixing bugs with test-driven development. Enforces RED→GREEN→REFACTOR cycle with vertical slicing and multi-agent context isolation. Triggers on: 'implement with TDD', 'write tests first', 'red green refactor', 'test-driven', '/tdd <feature>'. Supports Jest, Vitest, pytest, Go test, cargo test, RSpec, PHPUnit."
---

# TDD Skill — Red Green Refactor

Enforce disciplined RED→GREEN→REFACTOR cycles using multi-agent context isolation.
The core constraint: **Test Writer never sees implementation. Implementer never sees the spec.**
This prevents the model from leaking implementation intent into test design.

## Invocation

| Form | Behavior |
|------|----------|
| `/tdd <feature>` | Interactive — pause for approval at each checkpoint |
| `/tdd --auto <feature>` | Autonomous — run all slices, stop only on unrecoverable error |
| `/tdd --resume` | Resume from `.tdd-state.json` in project root |
| `/tdd --dry-run <feature>` | Validate pipeline, render prompts, write no code |

## Architecture

```
ORCHESTRATOR (this skill)
├─ Phase 0: Setup    — detect framework, verify baseline
├─ Phase 1: Decompose — 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
│
└─ Phase 5: Summary
```

### Context Boundaries

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

---

## Phase 0 — Setup

### Step 1: Detect framework

```bash
ls package.json pyproject.toml go.mod Cargo.toml Gemfile composer.json 2>/dev/null
```

Map to framework:
- `package.json` → check scripts for `jest` or `vitest`
- `pyproject.toml` or `pytest.ini` → pytest
- `go.mod` → go test
- `Cargo.toml` → cargo test
- `Gemfile` → rspec
- `composer.json` → phpunit

If ambiguous, ask: "What command runs your tests?"

### Step 2: Verify green baseline

Run the full test suite and show output:

```bash
# Jest/Vitest
npx jest --passWithNoTests 2>&1 | tail -10
# or: npx vitest run 2>&1 | tail -10

# pytest
python -m pytest -q 2>&1 | tail -10

# Go
go test ./... 2>&1 | tail -10

# Cargo
cargo test 2>&1 | tail -10

# RSpec
bundle exec rspec --format progress 2>&1 | tail -10
```

- **All pass** → proceed
- **Tests fail** → STOP. "Existing tests are failing. TDD requires a green baseline before starting."
- **No tests / error with 0 tests** → greenfield project, proceed

### Step 3: Extract public API surface

```bash
# TypeScript/JS — exported symbols
grep -rn "^export " src/ --include="*.ts" --include="*.js" 2>/dev/null | head -60

# Python — public functions/classes
grep -rn "^def \|^class " src/ --include="*.py" 2>/dev/null | grep -v "^.*test" | head -60

# Go — exported identifiers (capital-letter functions/types)
grep -rn "^func [A-Z]\|^type [A-Z]" . --include="*.go" 2>/dev/null | grep -v "_test.go" | head -60
```

Save output as `{API_SURFACE}`. Empty on greenfield — that's fine.

### Step 4: Create state file `.tdd-state.json`

```json
{
  "feature": "<user description>",
  "framework": "<jest|vitest|pytest|go|cargo|rspec|phpunit>",
  "language": "<typescript|javascript|python|go|rust|ruby|php>",
  "test_command": "<full command>",
  "source_dir": "src/",
  "auto_mode": false,
  "slices": [],
  "current_slice": 0,
  "phase": "setup",
  "files_modified": [],
  "test_files_created": []
}
```

---

## Phase 1 — Decompose into Vertical Slices

Break the feature into **ordered, testable behaviors** — one behavior per slice.

### Inside-Out Ordering

Sort slices from innermost to outermost layer:

1. **domain** — pure business logic, no dependencies, no mocks
2. **domain-service** — cross-aggregate operations using real domain objects
3. **application** — use-case orchestration with in-memory fakes for ports
4. **infrastructure** — repos, external APIs, framework adapters

**Why inside-out?** Domain slices produce real objects that later slices use directly. Minimizes mocking, catches integration issues early, ensures business rules exist before infrastructure.

Present to user:

```
I've broken this into N slices (inside-out order):

Domain:
  1. [behavior] — [what the test verifies]

Application:
  2. [behavior] — [what the test verifies]

Infrastructure:
  3. [behavior] — [what the test verifies]

Each slice: RED → GREEN → REFACTOR before the next.
Does this look right?
```

**Wait for approval** — even in `--auto` mode. Slice decomposition always needs sign-off.

Update state: write `slices` array with `layer` field on each.

---

## Phase 2 — RED: Write One Failing Test

### Step 1: Refresh API surface (re-run grep from Phase 0 Step 3)

### Step 2: Launch Test Writer

```
Task(subagent_type="general-purpose", prompt="""
You are the Test Writer. Your ONLY job is to write ONE failing test for this behavior.

BEHAVIOR TO TEST:
{SLICE_SPEC}

PUBLIC API (what you may call):
{API_SURFACE}

LANGUAGE: {LANGUAGE}
TEST FRAMEWORK: {FRAMEWORK}
TEST FILE: {TEST_FILE_PATH}
EXISTING TEST FILE CONTENT (if any): {EXISTING_TEST_CONTENT}

STRICT CONSTRAINTS:
- Write exactly ONE test function
- The test MUST fail because the behavior doesn't exist yet
- Do NOT look at or guess implementation details
- Use real objects — no mocks for domain-layer tests
- Test name must describe the behavior, not the implementation
- For domain layer: never import mocking libraries

Return ONLY a JSON object:
{
  "test_name": "descriptive_test_name",
  "test_file_path": "path/to/test_file",
  "imports_needed": ["import statements"],
  "test_code": "complete test function code",
  "description": "one sentence: what behavior this verifies"
}
""")
```

### Step 3: Write the test file

Apply the test code. If file exists, append the test function. If new, create it.

### Step 4: Run to confirm RED

```bash
# Run only the new test
# Jest: npx jest --testPathPattern=<file> -t "<test_name>"
# pytest: pytest <file>::<test_name> -v
# Go: go test -run <TestName> ./...
```

Show full output.

| Result | Action |
|--------|--------|
| Assertion failure | **Proper RED** — proceed |
| Import/module error | Create minimal stub so import resolves, re-run |
| Test passes | Behavior already exists — log "skip: already implemented", move to next slice |
| Syntax error | Fix test file, re-run. After 2 attempts, ask user |

### Step 5 (interactive only): Present checkpoint

```
RED: Test failing as expected.

Test: {test_name}
File: {test_file_path}
Failure: {error message}
Verifies: {description}

Proceed to GREEN? (or adjust the test?)
```

---

## Phase 3 — GREEN: Minimal Implementation

### Step 1: Collect context (test code + error output only)

```bash
cat {TEST_FILE_PATH}
# + failure output from Phase 2 Step 4
```

### Step 2: Build source file tree

```bash
find {SOURCE_DIR} -type f \( -name "*.ts" -o -name "*.js" -o -name "*.py" -o -name "*.go" -o -name "*.rs" -o -name "*.rb" -o -name "*.php" \) \
  | grep -v test | grep -v spec | grep -v node_modules | grep -v __pycache__ | head -50
```

### Step 3: Launch Implementer

```
Task(subagent_type="general-purpose", prompt="""
You are the Implementer. Your ONLY job is to make this failing test pass.

FAILING TEST:
{FAILING_TEST_CODE}

TEST FAILURE OUTPUT:
{TEST_FAILURE_OUTPUT}

SOURCE FILE TREE:
{FILE_TREE}

EXISTING SOURCE (relevant files):
{EXISTING_SOURCE}

LAYER CONSTRAINT: {LAYER}
- domain: no imports from application or infrastructure
- domain-service: may use domain objects, no infrastructure imports
- application: may use ports/interfaces, no concrete infrastructure
- infrastructure: no restrictions

STRICT CONSTRAINTS:
- Write the MINIMUM code to pass this one test
- Do NOT read the original spec or feature description
- Do NOT implement anything not required by the test
- One file change at a time where possible

Return ONLY a JSON object:
{
  "explanation": "what you implemented and why",
  "files": [
    {
      "path": "relative/path/to/file.ts",
      "action": "create|overwrite|edit",
      "content": "complete file content"
    }
  ]
}
""")
```

### Step 4: Apply changes and verify GREEN

Apply each file. Then run the specific test:

```bash
# Same command as Phase 2 Step 4
```

**Retry loop** (max 5 attempts):
- If still failing: re-launch fresh Implementer with previous attempt's explanation + new error
- If failing after 5 attempts: STOP, present to user

### Step 5: Run full suite — check for regressions

```bash
# Full test command (same as Phase 0 Step 2)
```

- Regressions found → launch fresh Implementer targeting only the regression failures, up to 3 attempts
- Still regressing after 3 → STOP, ask user

### Step 6 (interactive only): Present checkpoint

```
GREEN: Test passing.

Implementation: {explanation}
Files changed: {list}
Full suite: {N} passing, {N} failing

Proceed to REFACTOR? (or adjust?)
```

---

## Phase 4 — REFACTOR

### Step 1: Launch Refactorer

```
Task(subagent_type="general-purpose", prompt="""
You are the Refactorer. Tests are green. Improve the code without changing behavior.

GREEN TEST OUTPUT:
{GREEN_TEST_OUTPUT}

ALL TEST CODE:
{ALL_TEST_CODE}

ALL IMPLEMENTATION CODE:
{ALL_IMPLEMENTATION_CODE}

LAYER(S) TOUCHED: {SLICE_LAYERS}

YOUR JOB:
- Remove duplication
- Improve naming
- Simplify logic
- Fix dependency direction violations (inner layers must not import outer)
- Do NOT add features not tested

Return ONLY a JSON object:
{
  "suggestions": [
    {
      "priority": "high|medium|low",
      "description": "what and why",
      "file": "path/to/file",
      "old_code": "exact code to replace",
      "new_code": "replacement code"
    }
  ]
}
Return empty suggestions array if nothing needs changing.
""")
```

### Step 2: Apply suggestions one at a time (high priority first)

For each suggestion:
1. Apply the edit
2. Run full test suite
3. If any test fails → **revert immediately**, skip this suggestion
4. If all pass → keep the change

### Step 3 (interactive only): Report

```
REFACTOR: {N} applied, {N} skipped (reverted on test failure).
All tests: {count} passing.
```

---

## Phase 5 — Next Slice or Complete

- More slices → increment `current_slice`, return to Phase 2
- All slices done → present summary:

```
TDD Complete: {feature}

Slices: {N}
Tests written: {N}
Files created/modified: {list}
All tests passing: yes
```

Remove `.tdd-state.json` (ask in interactive mode, silent in `--auto`).

---

## Resume Support

`/tdd --resume`:
1. Read `.tdd-state.json`
2. Report: "Found session for '{feature}'. Slice {N}/{total}, phase: {phase}."
3. Resume from current phase of current slice

---

## Dry-Run Mode

For `--dry-run`: run Phase 0 and Phase 1 fully, then for each slice render the three agent prompts with variables filled in but **call no Task() and write no files**. Print prompt sizes and variable resolution status. Report summary. Do not clean up state file.

---

## Edge Cases

**Greenfield**: No tests yet — proceed from Phase 0. Test Writer creates test files and framework config from scratch.

**Bug fix**: Write a test demonstrating the bug (RED confirms bug exists). Fix in GREEN. Verify with `verify-before-done` skill after completing.

**Flaky test**: If a test sometimes passes/fails — stop, report, fix flakiness before continuing.

**User-provided test**: Confirm it fails (RED), skip to Phase 3 (GREEN). Do not modify without asking.

---

## Constraints

- Never write implementation before a failing test exists.
- Never modify a test to make it pass — fix the implementation.
- Never write all tests upfront — one slice at a time.
- Never skip RED phase, even for "trivial" cases.
- Domain code must never import infrastructure — dependency direction is inward only.
- After all slices: run `verify-before-done` skill before claiming done.
- On unexpected errors: use `debug-protocol` skill — do not guess fixes.

---

## Framework Quick Reference

| Framework | Single test | Full suite |
|-----------|------------|------------|
| Jest | `npx jest -t "<name>" <file>` | `npx jest` |
| Vitest | `npx vitest run <file> -t "<name>"` | `npx vitest run` |
| pytest | `pytest <file>::<name> -v` | `pytest -v` |
| Go | `go test -run <Name> ./...` | `go test ./...` |
| Cargo | `cargo test <name>` | `cargo test` |
| RSpec | `rspec <file>:<line>` | `rspec` |
| PHPUnit | `phpunit --filter <name>` | `phpunit` |

---

Attribution: Core RED→GREEN→REFACTOR orchestration pattern and context-isolation architecture adapted from glebis/claude-skills (MIT License). Rewritten for YAMTAM ENGINE — self-contained, no external scripts, integrated with verify-before-done and debug-protocol skills.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…