Introduction to TDD Guard
Relevant source files
The following files were used as context for generating this wiki page:
TDD Guard is an automated enforcement tool designed for Claude Code to ensure adherence to Test-Driven Development (TDD) principles. It operates as a hook that intercepts file operations—specifically Edit, MultiEdit, and Write—to analyze code changes against current test results. By validating these changes using an AI model, TDD Guard prevents developers (or AI agents) from skipping the "Red" phase of TDD or over-implementing features beyond what is required by failing tests.
The system maintains the integrity of the Red-Green-Refactor cycle by blocking operations that violate core TDD rules, such as adding multiple tests at once or implementing logic without a corresponding failing test. It provides actionable feedback to guide the developer back to a disciplined TDD workflow.
Sources: CLAUDE.md:1-12, README.md:9-15, src/validation/prompts/system-prompt.ts:1-10
Core Architecture and Data Flow
TDD Guard is structured as a TypeScript CLI application supported by various language-specific "reporters" that capture test results from different environments.
Operational Flow
The system follows a sequential pipeline to validate file operations:
- Interception: Captures Claude Code tool usage (Write, Edit, MultiEdit).
- Context Building: Aggregates the proposed code changes, current test results (from
.claude/tdd-guard/data/test.json), and linting status. - AI Validation: Sends the context to an AI model (via Anthropic API or Claude SDK) using specialized prompts.
- Enforcement: Based on the AI's decision, it either allows the operation (null) or blocks it with an explanation.
This flow is represented in the diagram below:
The diagram shows how TDD Guard intercepts operations to validate them against test results before allowing file system modifications.
Sources: CLAUDE.md:5-12, CLAUDE.md:32-48, src/validation/prompts/response.ts:1-15
Components and Structure
| Component | Description | Location |
|---|---|---|
| CLI Hook | Entry point for Claude Code hooks (PreToolUse, SessionStart). | src/cli/ |
| Reporters | Language-specific plugins (Go, Jest, Pytest, etc.) that save test results. | reporters/ |
| Validator | Core logic that communicates with AI models to judge TDD compliance. | src/validation/validator.ts |
| Storage | Abstractions for reading/writing configuration and test data. | src/storage/ |
| Prompts | Instructions and rules defined for the AI evaluator. | src/validation/prompts/ |
Sources: CLAUDE.md:32-48, README.md:144-188
TDD Validation Rules
The "Guard" enforces the Red-Green-Refactor cycle through specific rules categorized by the type of file and operation.
Red Phase: Test-First Enforcement
- Adding Tests: Adding exactly one new test to a test file is always allowed. This initiates the TDD cycle.
- Multiple Tests: Adding more than one test at a time is a violation.
- Relevant Source Files: Test files are identified by patterns like
.test.,.spec., or presence in atest/directory.
Green Phase: Minimal Implementation
Implementation files can only be modified if there is evidence of a failing test in the captured test results. The implementation must be "minimal":
- If the test fails because a class is "not defined", the agent is only allowed to create an empty stub.
- If the test fails on an assertion (e.g.,
expected 0 to be 4), the agent can then implement the logic. - Adding extra features, error handling, or methods not yet tested is considered "Over-Implementation".
Refactor Phase
Refactoring is only permitted when all relevant tests are passing. The AI checks the test.json data to ensure the "Green" state is reached before allowing structural changes.
Sources: src/validation/prompts/rules.ts:4-37, src/validation/prompts/file-types.ts:4-40, src/validation/prompts/operations/edit.ts:1-40
Reporter Integration
Reporters are critical for providing the "truth" about the current state of the codebase. They normalize output from various test runners into a standard JSON format located at .claude/tdd-guard/data/test.json.
Example: Go Reporter Implementation
The Go reporter (tdd-guard-go) pipes go test -json output, formats it for the user, and extracts test states (pass/fail) to the storage layer.
The sequence diagram illustrates how the Go reporter intercepts test output to update the global TDD state while maintaining standard console feedback.
Sources: reporters/go/cmd/tdd-guard-go/main.go:28-52, README.md:120-130
Configuration and Environment
TDD Guard uses a Config class to manage project roots and communication preferences. It supports multiple model types and validation clients.
| Option | Env Var | Default | Description |
|---|---|---|---|
projectRoot | CLAUDE_PROJECT_DIR | process.cwd() | Absolute path to the project root. |
validationClient | VALIDATION_CLIENT | cli | Client used: sdk, cli, or api. |
modelType | MODEL_TYPE | claude_cli | Legacy mapping for validation client. |
dataDir | - | .claude/tdd-guard/data | Directory for storing internal state. |
Sources: src/config/Config.test.ts:24-60, src/config/Config.test.ts:200-260
Decision Logic and Responses
The AI validator returns a JSON response that determines if an operation proceeds.
{
"decision": "block",
"reason": "Over-implementation violation. Test fails with 'Calculator is not defined' but implementation adds both class AND method. Create only an empty class first."
}
Response Criteria
- Block: Triggered by multiple test additions, over-implementation, or refactoring with failing tests.
- Null (Allow): Triggered by single test additions, minimal fixes, or refactoring with passing tests.
Sources: src/validation/prompts/response.ts:4-35
Conclusion
TDD Guard provides a robust mechanism for enforcing TDD discipline within AI-assisted development workflows. By leveraging a combination of local test reporters and LLM-based code analysis, it ensures that every line of implementation code is justified by a failing test and that the development process remains incremental and high-quality.