---
name: build-tdd
description: "Use when writing production code (post-harden, Phase 6) and the user asks to add a feature, fix a bug, or add tests for new behavior. Drives strict RED-GREEN-REFACTOR with integration coverage at module boundaries. Triggers on phrases like 'add test for', 'TDD this', 'write a failing test', 'implement <feature>'. Skip during prototype phases (Phase 4 iterate-prototype) where mock-heavy tests under-catch wiring bugs."
---

# Test-Driven Development (TDD)

## Overview

Write the test first. Watch it fail. Write minimal code to pass.

**Core principle:** If you didn't watch the test fail, you don't know if it tests the right thing.

**Announce at start:** "I'm using the build-tdd skill to implement this with strict TDD."

## When to Use

This skill is the Phase 6 (production-build) discipline. Phase 4 (prototype) is exempt — that work runs through `build-prototype` / `iterate-prototype` with manual click-through verification instead.

**Within Phase 6:** New features, bug fixes, behavior changes.

**Refactoring:** Always — but if existing tests already cover the code being refactored (passing coverage), use them as the safety net directly. Write characterization tests only for untested code paths. The Iron Law still applies to any *new behavior*. For pure refactoring (no behavior change), existing passing tests serve as the failing-test equivalent — if they break, the refactoring changed behavior.

**Exceptions (ask your human partner):** Throwaway prototypes, generated code, configuration files.

## The Iron Law

```
NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
```

Write code before the test? Delete it. Start over. Do not keep it as "reference." Do not "adapt" it while writing tests.

## The Cycle

| Step | What | Mandatory verification |
|---|---|---|
| **RED** | Write one minimal failing test for the next behavior | Run the test — confirm it fails because the feature is missing (not syntax/import errors) |
| **GREEN** | Write the simplest code that passes | Run the test — confirm new test passes AND existing tests still pass |
| **REFACTOR** | Clean up after green; remove duplication, improve names | Keep tests green; do not add behavior |

The detailed methodology — examples per step, common rationalizations, red flags, when-stuck guidance — is canonical in `agents/builder.md`. **When this skill runs inline, Read `agents/builder.md` before starting and follow its protocol exactly.** When this skill dispatches the **builder** subagent, the agent loads that methodology automatically.

## Wiring Coverage

After GREEN, if the slice crosses a module boundary defined in architecture artifacts, write one contract or integration test that exercises the real wiring (no mocks at the boundary). If you can't, that's a wiring-test debt; record in `support-gotcha`.

Module boundaries from `harden`'s slice graph commonly include: CLI entry points, filesystem reads/writes, child-process invocations, manifest I/O, external service calls. Unit-level tests with mocks at these seams are necessary but not sufficient — the load-bearing question is whether the real components compose correctly. If every boundary in the slice has at least one no-mock test somewhere in the suite, the slice is wired; if any boundary is mock-only across the whole suite, file a `support-gotcha` entry naming the boundary and the missing test so the next pass can close it.

## Execution Mode

This skill dispatches the **builder** subagent or executes inline, based on persisted manifest state.

Read `execution.mode` from `.forge/work/{type}/{name}/manifest.yaml` (set by `plan-task-decompose` during execution handoff):

| Manifest state | Mode |
|---|---|
| `execution.mode: subagent` | Dispatch **builder** subagent with the task + architecture artifacts inline in prompt |
| `execution.mode: inline` | Execute RED-GREEN-REFACTOR directly in current session — Read `agents/builder.md` first |
| No manifest or no field | Inline (default) |

When dispatching **builder**, pass the task and required artifacts ONLY. Do NOT include TDD methodology in the prompt; builder owns that methodology inline.

Do not ask the user. The decision was persisted at task decompose handoff.

## Architecture Constraints

When architecture artifacts exist (from `plan-architecture` or `harden`), use them to set unit-test expectations for shapes, constraints, and error behavior. Treat those contracts as the source of truth for assertions at the unit boundary. Integration tests at boundaries identified by `harden`'s slice graph are required per the Wiring Coverage subsection above — they are not optional even when the task description omits them.

## Oracle Satisfaction

When `harden` (Phase 5) ran, it captured prototype behavior as integration-test oracles at `aiwiki/oracles/{slug}.md` — one per slice or subsystem. These are the load-bearing contract: production code must reproduce the oracle's `Setup → Trigger → Assertions`. They close the wiring gap that mock-heavy unit tests miss — the failure mode where unit tests pass against mocks but real integration breaks because no test exercised the actual wiring boundary.

**Before writing the first RED test for a slice:**

1. Read every oracle whose `slug` or `prototype_path` matches the slice being built (the slice graph entry produced by harden references its oracles).
2. For each oracle, design at least one test that exercises its `Setup → Trigger → Assertions`. That test counts as the boundary integration test for Wiring Coverage above — so the oracle test and the wiring test are usually the same test.
3. If the slice crosses a wiring boundary (CLI ↔ filesystem, process exec, manifest I/O, external services) and **no oracle exists for that boundary**, halt and surface to the user. Do NOT invent oracles inline; do NOT proceed against an empty oracle directory. Missing oracles mean harden has not closed — re-run harden to capture them, or surface to the user that the slice is being built without a verified prototype contract.

When this skill dispatches the **builder** subagent (manifest's `execution.mode: subagent`), the agent enforces the same discipline (see [agents/builder.md](../../agents/builder.md) "Oracles Are Load-Bearing"). When running inline, the orchestrator (this skill) is responsible — load the oracles before the first RED.

If `phase_plan.codify: skipped` for this work item (typical for trivial bugfixes that bypass harden), no oracles are expected — note the skip in the work-item notes and proceed.

## Codex Integration

**Mode:** Delegate | **Protocol:** `protocols/codex.md`

**When:** Before the task execution loop begins. User explicitly requests: "Use Codex as builder for this feature."

**All-or-nothing:** If the user chooses Codex as builder, ALL tasks in the feature use Codex. No per-task or per-phase mixing. To switch back to Claude mid-feature, the user says "switch to Claude builder" — completed Codex tasks are kept, remaining tasks proceed with Claude.

**Context to pass:**
- Path to the specific task description from `tasks.md`
- Path to `architecture/` directory (all artifacts)
- Path to `codebase-analysis.md` (if existing project)
- Path to `agents/builder.md` — Codex reads and follows the TDD methodology

**Prompt focus:** "Implement the following task using strict TDD methodology as defined in agents/builder.md. Architecture artifacts are at [paths]. Write the failing test first, verify it fails, then implement minimally to pass."

**Quality gate:** Every Codex-built task goes through:
1. Tests pass (test runner from project profile)
2. Coverage meets threshold (80%+, 100% for critical paths)
3. `quality-code-review` by Claude (cross-review — Claude reviews Codex's work)
