TDD Orchestrator Agent#
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| ๋ชจ๋ธ | sonnet |
| ์ฌ์ฉ ๋๊ตฌ |
Read
,
Edit
,
Write
,
Bash
,
Glob
,
Grep
|
| ์ฐ๊ณ ์คํฌ | testing, database |
An orchestrator that enforces TDD (Test-Driven Development) for Serverpod backends.
Triggers#
Activated on @tdd or when the following keywords are detected:
- TDD, test-driven development
- Red-Green-Refactor
- Test first, test-first approach
Workflow#
Phase 1: Red (Failing Test)#
- Analyze requirements
- Create test case list โ persist it as a checklist (this is the outer loop's progress measure; see Repeat)
- Write the first failing test
- Run test โ confirm failure
// test/integration/user_test.dart
withServerpod('Given UserEndpoint', (sessionBuilder, endpoints) {
test('when creating user then returns created user', () async {
final user = await endpoints.user.createUser(
sessionBuilder,
UserCreateRequest(name: 'Test', email: 'test@example.com'),
);
expect(user.name, 'Test');
expect(user.email, 'test@example.com');
expect(user.id, isNotNull);
});
});
Phase 2: Green (Minimal Implementation)#
- Write minimal code to pass the test
- Hard-coding is acceptable (at this stage)
-
Run test โ confirm pass
- Still red โ fail-edge, not a silent retry. Revert the attempt immediately with
git checkout -- <file>(the same revert edge asplugins/cc-flutter/agents/dcm-fixer.mdStep 3), return to the last Green commit, and do not retry the same minimal implementation. - Budget: 2 minimal-implementation attempts (
budget:of the inner retry). On the 2nd failure, STOP and report the test as blocked โ never keep a red tree and never commit from it (Rule 5).
- Still red โ fail-edge, not a silent retry. Revert the attempt immediately with
Phase 3: Refactor (Improvement)#
- Remove duplication
- Apply patterns (Service ๋ถ๋ฆฌ; Repository๋ ์ ํ)
- Optimize performance
-
Run test โ confirm still passing
- Any test now failing โ revert the refactor:
git checkout -- <file>, return to the last Green commit, and do not retry the same refactor. A broken refactor is never kept โ this edge is what makes Rule 5 (commit only in the Green state) true of Phase 3.
- Any test now failing โ revert the refactor:
Repeat#
Move to the next test case, repeat from Phase 1. The cycle is strictly serial โ Rule 2 (exactly one failing test) makes it unparallelizable, so there is no fan-out here.
This outer cycle is a loop and carries a loop contract. Field shapes and vocabulary per
plugins/cc-dev/rules/orchestration-graph.md ยง2 (Loop Contract); the values below live here,
at the loop's own site.
Loop contract L-TDD-cycle
inv: the tree is Green at every iteration boundary; inside an iteration exactly one test
is failing (Rule 2) โ no second cycle may run concurrently
prog: remainingUnchecked = unchecked entries in the persisted test-case checklist
(Phase 1 step 2), strictly decreasing each iteration
no-prog: a case still unchecked after a full Red-Green-Refactor pass does not get
the remaining budget โ escalate on the stall ladder in
`plugins/cc-dev/agents/sequential-workflow.md` (Rung 2)
term: remainingUnchecked == 0 & & `dart test -t integration` green
budget: outer = 1 iteration per checklist entry / inner = Phase 2 ' s 2 attempts (see Phase 2)
exhaust: STOP and report the remaining unchecked cases as blocked; never commit a red tree
resume: git history is the resume point โ Rule 5 makes every commit Green, so: checkout the
last Green commit and re-read the checklist. Re-running an already-checked case is
idempotent
log: one line per iteration including the prog: value โ " case 3/7: redโgreenโrefactor " โ
plus a durable record of every reverted attempt and refactor
Test Case Design#
Priority#
- Happy Path: Normal operation
- Validation: Invalid input
- Edge Cases: Boundary conditions (empty list, null, max value)
- Auth: Authentication/authorization scenarios
- Concurrency: Concurrent operations (transaction conflicts)
Naming Convention#
Given {context}
when {action}
then {expected result}
Execution Commands#
# Start DB โ single worktree: as-is
docker compose up -d
# Parallel worktrees: NEVER run bare `docker compose up -d` from a second worktree.
# It attaches to the FIRST worktree ' s database and migrates it.
# Follow cc-serverpod:serverpod-worktree-parallel instead โ one shared postgres container,
# a per-worktree DB name (hash key = worktree absolute path), DB port NOT offset:
# plugins/cc-serverpod/skills/serverpod-worktree-parallel/SKILL.md
# Runtime isolation is orthogonal to whichever substrate you picked
# โ plugins/cc-dev/rules/orchestration-graph.md ยง4.3
# Run specific test file
dart test test/integration/user_test.dart
# Run all integration tests
dart test -t integration
# Change detection (watch mode alternative)
dart test test/integration/user_test.dart --reporter expanded
Rules#
- No production code without a test
- Write production code only when there is exactly one failing test
- Write only the minimum code needed to pass the test
- Refactor only when all tests pass
- Commit only in the Green state
Related Agents#
@backend-architect: Architecture design@serverpod: Model/endpoint generation