TDD Pair Programming Loop
This skill defines the methodology for running a strict TDD pair programming session with three coordinating agents: Driver, Navigator, and Researcher.
Core Principle
Red → Green → Refactor, one test at a time, with strict role boundaries.
- •The Driver writes ONE failing test (RED)
- •The Navigator writes MINIMAL code to pass it (GREEN)
- •The Navigator optionally refactors (REFACTOR, tests stay GREEN)
- •Repeat until the problem is fully solved
Agent Roles and Boundaries
| Agent | Writes | Cannot Touch | Runs Tests |
|---|---|---|---|
| Driver | *.test.ts only | Implementation files | Yes — must confirm RED |
| Navigator | Implementation files only | Test files | Yes — must confirm GREEN |
| Researcher | Nothing | All files | No |
These boundaries are absolute. No exceptions.
The TDD Cycle (Step by Step)
Phase 1: SETUP (Orchestrator Only)
- •Select or receive a LeetCode problem
- •Determine difficulty level and create directory:
leetcode/{difficulty}/{number}-{name}/ - •Create
README.mdwith problem statement from LeetCode using pure markdown (no HTML elements — see Markdown Standards below) - •Create empty implementation file:
{name}.tswith a stub export - •Create empty test file:
{name}.test.tswith describe block and import - •Create a git branch:
tdd/{number}-{name}
Stub Implementation File
// {name}.ts
export function functionName() {
// TODO: implement via TDD
throw new Error('Not implemented');
}
Stub Test File
// {name}.test.ts
import { describe, it, expect } from 'vitest';
import { functionName } from './{name}';
describe('{Problem Name}', () => {
// Tests will be added one at a time by the Driver
});
Phase 2: TDD LOOP (Repeat)
Step A — Driver (RED)
- •Driver reads the problem statement and any previous HANDOFF context
- •Driver writes exactly ONE new
it()block in the test file - •Driver runs:
npx vitest run {test-file} --reporter=verbose - •Driver confirms the new test FAILS (RED)
- •Driver outputs a HANDOFF block
Step B — Researcher (OPTIONAL)
Only triggered if the Driver or Navigator includes RESEARCH: in their HANDOFF.
- •Researcher reads the question
- •Researcher looks up: techniques, patterns, existing repo examples, docs
- •Researcher returns concise findings
- •Orchestrator passes findings to the next agent (Navigator or Driver)
Step C — Navigator (GREEN + optional REFACTOR)
- •Navigator reads the Driver's HANDOFF (and Researcher findings if any)
- •Navigator writes the MINIMAL code change to make the failing test pass
- •Navigator runs:
npx vitest run {test-file} --reporter=verbose - •Navigator confirms ALL tests PASS (GREEN)
- •(Optional) Navigator refactors, then runs tests again to confirm still GREEN
- •Navigator outputs a HANDOFF block
Step D — Loop Decision
- •If more behaviors need testing → go to Step A (Driver writes next test)
- •If all acceptance criteria are met → proceed to Phase 3
Phase 3: POST-MORTEM
- •Copy
POST_MORTEM_TEMPLATE.mdto the problem directory asPOST_MORTEM.md - •An expert reviewer agent fills out the post-mortem using the
review-solutionskill:- •Problem description in own words
- •Solution exploration: approaches considered, final analysis
- •Time and space complexity with explanation
- •Pattern recognition and key insight
- •Related problems (2-3 similar ones)
- •Edge cases handled and missed
- •Retrospective and key takeaways
- •Self-rating rubric
- •Run quality checks:
- •
npx eslint {impl-file}— fix any issues - •
npx prettier --write {impl-file} {test-file}— format code - •
npx markdownlint leetcode/{difficulty}/{number}-{name}/README.md— fix any violations - •
npx markdownlint leetcode/{difficulty}/{number}-{name}/POST_MORTEM.md— fix any violations - •
npx vitest run {test-file}— final confirmation all tests pass
- •
Phase 4: UPDATE ROOT README
Update the root README.md:
- •Increment the LeetCode "Problems Solved" count in the Overview table
- •Increment the difficulty-specific count in the appropriate
<summary>tag (e.g., "Easy Problems (N solved)") - •Add the problem link in the correct difficulty section and category subsection
- •If the problem matches a pattern in "Problems by Pattern", add it there too
- •Run
npx markdownlint README.md— fix any violations
Phase 5: PULL REQUEST
- •
Stage all changed files:
git add leetcode/{difficulty}/{number}-{name}/ README.md - •
Commit with message:
feat: solve {Problem Name} (#{number}) via TDD - •
Push branch:
git push -u origin tdd/{number}-{name} - •
Create PR:
bashgh pr create \ --title "feat: solve {Problem Name} (#{number})" \ --body "## Problem\n{link}\n\n## Approach\n{summary from post-mortem}\n\n## Complexity\n- Time: O(...)\n- Space: O(...)\n\n## TDD Cycles\n{number of red-green cycles completed}" \ --label "code challenge" - •
PR is assigned to the user for review
HANDOFF Schema
Every Driver and Navigator output MUST include a HANDOFF block. This is the contract that makes agent coordination work.
Driver HANDOFF (RED phase)
## HANDOFF
- **Phase**: RED
- **Cycle**: {number}
- **Test file**: {path}
- **New test**: {test name}
- **What behavior is specified**: {one sentence}
- **Test output**: {vitest FAIL output}
- **Next step**: {what Navigator should implement | DONE}
- **Research needed**: {question | none}
Navigator HANDOFF (GREEN/REFACTOR phase)
## HANDOFF
- **Phase**: GREEN | REFACTOR
- **Cycle**: {number}
- **Implementation file**: {path}
- **What was implemented**: {one sentence}
- **Approach**: {algorithm/technique}
- **Test output**: {vitest PASS output}
- **All tests passing**: YES | NO
- **Refactored**: YES | NO — {what changed}
- **Next step**: {ready for next test | DONE}
- **Research needed**: {question | none}
Completion Criteria
The TDD loop is DONE when:
- •All examples from the problem statement have corresponding tests
- •Key edge cases are covered (empty input, single element, boundaries)
- •All tests pass
- •The solution is correct and handles the problem's constraints
- •At least 4-5 meaningful test cycles have been completed
Conventions
File Naming
- •Directory:
{4-digit-number}-{kebab-case-name}(e.g.,0001-two-sum) - •Implementation:
{kebab-case-name}.ts(e.g.,two-sum.ts) - •Test:
{kebab-case-name}.test.ts(e.g.,two-sum.test.ts) - •README:
README.md - •Post-mortem:
POST_MORTEM.md
Branch Naming
- •
tdd/{4-digit-number}-{kebab-case-name}(e.g.,tdd/0015-3sum)
Commit Message
- •
feat: solve {Problem Name} (#{number}) via TDD
Test Command
- •
npx vitest run {test-file} --reporter=verbose - •Never use watch mode during TDD cycles (use single-run mode)
Markdown Standards
All .md files created during TDD must use pure markdown formatting:
- •No HTML elements: Do not use
<p>,<code>,<strong>,<em>,<pre>,<ul>,<li>,<ol> - •Allowed HTML (per
.markdownlint.json):<details>,<summary>,<sup>,<sub>,<br>,<img> - •Convert LeetCode HTML to markdown:
- •
<strong>text</strong>→**text** - •
<em>text</em>→*text* - •
<code>text</code>→`text` - •
<pre>...</pre>→ fenced code blocks (```) - •
<ul><li>→ markdown lists (-) - •
<p>→ blank lines between paragraphs - •
<sup>N</sup>→^Nor use<sup>N</sup>(allowed)
- •
- •Validation: Run
npx markdownlint {file}on every markdown file before committing - •Auto-fix: Use
npx markdownlint --fix {file}for auto-fixable violations