| name | s-build |
| description | Implement current phase tasks using TDD - RED > GREEN > REFACTOR cycle with commits |
/s:build - TDD Implementation
You are implementing the current phase's tasks using strict Test-Driven Development. Every line of production code must be justified by a failing test. Follow the RED > GREEN > REFACTOR cycle without exception.
Prerequisites
Before starting, read:
.planning/STATE.md - Identify the active phase number (N).
.planning/phases/N/PLAN.md - Get the task list for the active phase.
.planning/ROADMAP.md - Understand how this phase fits the bigger picture.
${CLAUDE_PLUGIN_ROOT}/lib/tdd-protocol.md - Load the TDD protocol into your working memory. Follow it exactly.
If no active phase is set in STATE.md, tell the user: "No active phase found. Run /s:plan first."
If all tasks in the current phase are marked complete, tell the user: "Phase {N} is complete. Moving to phase {N+1}." and update STATE.md accordingly. If there is no next phase, suggest /s:review and /s:verify.
Task Execution Loop
For each incomplete task in the phase plan (in order), execute the following cycle:
Step 1: Announce the Task
Before writing any code, tell the user:
Starting Task {N.M}: {title}
Status: RED (writing failing test)
Step 2: RED - Write Failing Test
-
Determine the test file location. Follow the project's existing test conventions. If none exist, use:
- JavaScript/TypeScript:
__tests__/{module}.test.{ext} or {module}.test.{ext} next to source
- Python:
tests/test_{module}.py
- Go:
{module}_test.go in the same package
- Other:
tests/ directory with appropriate naming
-
Write the test FIRST. The test should:
- Test the specific behavior described in the task's acceptance criteria
- Be minimal: test one thing per test function
- Use descriptive test names that explain the expected behavior
- Import from the production module (which does not exist yet - this is intentional)
-
Run the test. It MUST fail. If it passes, something is wrong:
- The feature might already exist (check before writing)
- The test might not be testing what you think (review it)
- The test setup might be incorrect
-
Show the failure to the user:
RED: {test name} - FAILED as expected
Error: {brief error description}
Step 3: GREEN - Minimal Implementation
-
Write the minimum code to make the failing test pass. This means:
- No extra features
- No premature optimization
- No "while I'm here" additions
- Hard-coded values are acceptable if the test only checks one case
- The simplest possible implementation that satisfies the test
-
Run the test again. It MUST pass now. If it still fails:
- Read the error carefully
- Fix only what the error tells you to fix
- Do NOT add code beyond what the error requires
-
Run ALL existing tests (not just the new one). If any other test broke:
- Your implementation has a side effect
- Fix it without breaking the new test
- If you cannot fix both, STOP and inform the user of the conflict
-
Show the success:
GREEN: {test name} - PASSED
All tests: {pass count} passed, {fail count} failed
Step 4: REFACTOR
-
Review the code you just wrote. Look for:
- Duplication (DRY)
- Unclear naming
- Long functions that should be split
- Missing error handling that tests will eventually require
- Code that violates project conventions
-
Refactor only if there is a clear improvement. Do not refactor for the sake of it. Small, obvious improvements only.
-
Run ALL tests after refactoring. Everything must still pass. If anything breaks, undo the refactor.
-
If no refactoring needed, say so:
REFACTOR: No changes needed. Code is clean.
Step 5: Commit
After each GREEN (and optional REFACTOR), create a git commit:
git add {changed files}
git commit -m "feat({scope}): {what was implemented}
Task {N.M}: {task title}
TDD: RED > GREEN > REFACTOR complete"
Commit message conventions:
feat for new features
fix for bug fixes
refactor for refactoring steps
test for test-only changes
- Scope is the module or component name
Step 6: Update STATE.md
After completing each task, update .planning/STATE.md:
- Mark the task as complete in Current Focus
- Update progress: "Phase {N}: {completed}/{total} tasks done"
- Add to decisions table if any significant decision was made during implementation
Also update .planning/phases/N/PLAN.md:
- Mark the task status as
complete
- Note any deviations from the original plan
Step 7: Move to Next Task
If there are more tasks in the phase, announce the next one and repeat from Step 1.
If a task is blocked (dependency not met, unclear requirement), STOP and tell the user:
BLOCKED: Task {N.M} - {title}
Reason: {why it is blocked}
Suggestion: {what to do about it}
Phase Completion
When ALL tasks in the phase are complete:
Write Phase Summary
Create .planning/phases/N/SUMMARY.md:
# Phase {N} Summary: {Name}
**Status:** complete
**Started:** {date}
**Completed:** {date}
## What Was Built
- {feature/component 1}: {brief description}
- {feature/component 2}: {brief description}
## Test Coverage
- {X} test files created
- {Y} total tests
- All passing
## Key Decisions During Implementation
- {decision 1}: {rationale}
- {decision 2}: {rationale}
## Deviations from Plan
- {deviation 1}: {why}
## Files Created/Modified
- {file list}
## Learnings
- {learning 1}
- {learning 2}
Update STATE.md
- Status:
phase-{N}-complete
- Active Phase:
{N+1} (or complete if this was the last phase)
- Current Focus: "Phase {N} complete. {summary}."
- Add decision entry:
{DATE} | Phase {N} complete | {task count} tasks, {test count} tests
Suggest Next Step
Phase {N}: {name} COMPLETE
- {task count} tasks implemented
- {test count} tests passing
- {commit count} commits made
Next step: Run `/s:review` to review the implementation.
Or: Run `/s:build` again to start Phase {N+1}.
TDD Rules (Non-Negotiable)
These rules come from ${CLAUDE_PLUGIN_ROOT}/lib/tdd-protocol.md and are absolute:
- NEVER write production code without a failing test. No exceptions.
- One test at a time. Write one test, make it pass, then write the next.
- Minimal implementation. The GREEN step implements ONLY what the test requires.
- All tests must pass after every GREEN. If an old test breaks, fix it before moving on.
- Commit after every GREEN. Small, frequent commits. Never commit failing tests.
- Test names describe behavior.
should_return_404_when_user_not_found not test_get_user.
- No test modifications during GREEN. If the test is wrong, go back to RED and fix the test first.
- Refactor does not change behavior. All tests must pass before AND after refactoring.
Handling Edge Cases
- If tests are slow: Split into unit tests (fast) and integration tests (slower). Run unit tests after each GREEN, integration tests after each task.
- If the project has no test framework: Set up the test framework as Task 0 before starting the phase plan.
- If a task is too large: Break it into sub-tasks, each with its own RED > GREEN > REFACTOR cycle. Update the phase plan.
- If requirements are unclear: STOP. Do not guess. Ask the user for clarification. Note the question in STATE.md.
- If you discover a bug in existing code: Note it, but do not fix it unless it blocks the current task. Create a separate task for the fix.
- If you need a library/dependency: Install it, write a minimal test to verify it works, commit, then continue with the task.