| name | tdd-enforcer |
| description | Test-Driven Development enforcement. Use when implementing new features, fixing bugs, or adding business logic. Triggers on "write tests", "implement with TDD", "add tests then code", or any implementation request for business logic where the user has not provided pre-existing failing tests. Also activates automatically before Phase 4 of the spec-architect skill. |
TDD Enforcer Skill
The Rule
No implementation code before failing tests. Zero exceptions.
If tests are written after the code, they test the implementation, not the requirement.
That is not testing. That is documentation that happens to run.
Claude's default behavior without this skill: implementation-first, happy path,
edge cases discovered in production. This skill fixes that structural failure.
Red Phase — Write Failing Tests First
Before writing any implementation:
-
Identify all behaviors the implementation must satisfy:
- Happy path (expected inputs → expected outputs)
- Boundary conditions (empty, null, zero, max, min, threshold crossings)
- Error paths (invalid input, missing dependencies, external failures)
- Business rule invariants (payroll-specific — see below)
-
Write one test per behavior. Each test must:
- Have a name that states WHAT it verifies (not HOW)
✅ "calculates biweekly gross correctly for mid-period hire"
❌ "test_gross_pay_calc"
- Be completely independent (no shared mutable state between tests)
- Run and FAIL before any implementation exists
-
Do not proceed until:
- All tests are written
- All tests are confirmed failing
- Failing reason is correct (wrong answer, not compile error)
Green Phase — Minimal Implementation
Write the minimum code to make all tests pass.
Rules:
- No code that is not required to pass a test
- No "future-proofing" unless a test demands it
- No abstractions that don't have a failing test as justification
- When all tests pass: STOP. Do not add more code.
The next feature starts a new Red phase.
If you write a line of code and no test required it, delete that line.
Refactor Phase — Improve Without Breaking
After Green:
- Remove duplication (in tests AND implementation)
- Clarify naming (functions, variables, parameters)
- Extract well-named functions if a function exceeds ~25 lines
- Consolidate related logic if it improves clarity
Rules:
- All tests must pass after EVERY refactor step (not just at the end)
- Never modify a test to accommodate a refactor
If a refactor breaks a test, the refactor is wrong — not the test
- One refactor at a time, run tests between each
Payroll-Specific Test Patterns
For payroll business logic, ALWAYS include tests for:
Pay period boundaries:
- First day of period, last day, day before period starts, day after period ends
- Mid-period hire: exact start date, next day, previous day
YTD accumulator thresholds:
- Test the exact crossing value (e.g., $160,200 SS wage base)
- One cent below threshold
- One cent above threshold
- Already crossed threshold (no further accumulation)
Garnishments:
- Zero earnings period (no deduction should occur)
- Earnings below protected minimum (no deduction)
- Earnings where cap is hit mid-period (partial deduction)
- Multiple garnishments (priority ordering)
Multi-state:
- Same employee, same pay period, two different states
- State that was added mid-year
- State with different supplemental withholding rules
Overtime:
- Exactly 40.00 hours (no OT)
- 39.99 hours (no OT)
- 40.01 hours (OT on 0.01 hours)
- Exempt employee (no OT regardless of hours)
Monetary precision:
- All calculations verified to the cent
- Rounding direction matches IRS rules (round half up for withholding)
Required Output Format
Label each phase explicitly in your output:
🔴 RED: [N] tests written. All failing.
Test file: [path]
Behaviors covered: [list]
🟢 GREEN: All [N] tests passing.
Implementation: [files created/modified]
Lines added: [approximate count]
🔵 REFACTOR: [What was improved]. All [N] tests still passing.
When NOT to Use TDD
Genuinely exploratory code — throwaway prototypes, one-time data scripts,
proof-of-concept spikes — can skip TDD with explicit acknowledgment:
"This is exploratory. TDD skipped. This code will not be committed as-is."
If in doubt: use TDD. The discipline cost is 10 minutes.
The bug-discovery cost in production is incalculable for payroll.