# Create Tdd Tasks

> Transform SDD tasks into test-first TDD task pairs. Reads existing tasks from /create-tasks and generates paired test tasks with RED-GREEN dependencies. Use when user says "create tdd tasks", "add tdd pairs", "convert to tdd", or wants to apply test-first ordering to SDD tasks.

- Skill: `majiayu000/create-tdd-tasks` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/create-tdd-tasks`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/create-tdd-tasks/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/create-tdd-tasks

---


# Create TDD Tasks Skill

Transform existing SDD implementation tasks into test-first TDD task pairs. For each implementation task, this skill creates a paired test task that must complete first, enforcing test-first development at the pipeline level.

This skill bridges the SDD pipeline (`/create-tasks`) and TDD execution (`/execute-tdd-tasks`), converting a standard task list into one where every implementation task is preceded by a failing-test-writing task.

**CRITICAL: Complete ALL 8 phases.** The workflow is not complete until Phase 8: Report is finished. After completing each phase, immediately proceed to the next phase without waiting for user prompts.

## Core Principles

1. **Test-first at the pipeline level** -- Every implementation task gets a paired test task that blocks it. Tests are written before implementation begins.
2. **Preserve existing dependencies** -- TDD pairs are inserted into the existing SDD dependency chain without breaking any original relationships.
3. **Merge mode awareness** -- Re-running this skill on a task list that already has TDD pairs detects and skips existing pairs instead of creating duplicates.
4. **Criteria-to-tests conversion** -- Acceptance criteria from SDD tasks are converted into test descriptions for the paired test task.
5. **Minimal metadata additions** -- Only `tdd_mode`, `tdd_phase`, and `paired_task_id` are added. All existing metadata is preserved.

## Critical Rules

### AskUserQuestion is MANDATORY

**IMPORTANT**: You MUST use the `AskUserQuestion` tool for ALL questions to the user. Never ask questions through regular text output.

- Preview confirmation -> AskUserQuestion
- Anomaly resolution -> AskUserQuestion
- Error recovery options -> AskUserQuestion

Text output should only be used for:
- Presenting TDD pair previews and summaries
- Reporting completion status
- Displaying dependency chain visualizations

**NEVER do this** (asking via text output):
```
Should I proceed with creating 12 TDD task pairs?
1. Yes
2. No
```

**ALWAYS do this** (using AskUserQuestion tool):
```yaml
AskUserQuestion:
  questions:
    - header: "Confirm TDD Pair Creation"
      question: "Ready to create 12 TDD task pairs?"
      options:
        - label: "Yes, create pairs"
          description: "Create test tasks and set TDD dependencies"
        - label: "Show details"
          description: "See full list of pairs before creating"
        - label: "Cancel"
          description: "Don't create TDD pairs"
      multiSelect: false
```

### Plan Mode Behavior

**CRITICAL**: This skill transforms tasks, NOT creates an implementation plan. When invoked during Claude Code's plan mode:

- **DO NOT** create a plan for how to implement TDD
- **DO NOT** defer task transformation to an "execution phase"
- **DO** proceed with the full TDD task generation workflow immediately
- **DO** create test tasks using TaskCreate as normal

The TDD task pairs are planning artifacts themselves -- generating them IS the planning activity.

### Requires tdd-tools Plugin

This skill depends on the `tdd-tools` plugin. Before proceeding with any work, verify the plugin is available. Check for the plugin at `${CLAUDE_PLUGIN_ROOT}/../tdd-tools/` by attempting to read its `README.md`.

If `tdd-tools` is not installed, display a clear error and stop:

```
ERROR: tdd-tools plugin is required but not installed.

The create-tdd-tasks skill depends on the tdd-tools plugin for:
- test-writer agent (generates test files during TDD execution)
- tdd-executor agent (runs the 6-phase RED-GREEN-REFACTOR workflow)
- Test framework detection and patterns

Install tdd-tools:
  Add agent-alchemy-tdd-tools to your .mcp.json or plugin configuration.

Without tdd-tools, TDD task pairs cannot be executed.
```

---

## Phase 1: Validate & Load References

**Goal:** Verify prerequisites and load reference materials.

### Step 1: Check tdd-tools Plugin

Verify the tdd-tools plugin is available by reading:
```
Read: ${CLAUDE_PLUGIN_ROOT}/../tdd-tools/README.md
```

If the file cannot be read, display the error message above and stop. Do not proceed to Phase 2.

### Step 2: Parse Arguments

Check `$ARGUMENTS` for optional `--task-group` filter:
- If `--task-group <group>` is present, extract the group name for filtering
- If no arguments provided, process all tasks

### Step 3: Load Reference Files

Read the TDD decomposition and dependency reference files:

1. `references/tdd-decomposition-patterns.md` -- Task pairing rules, naming conventions, metadata, merge mode detection
2. `references/tdd-dependency-rules.md` -- Dependency insertion algorithm, circular dependency detection and breaking

---

## Phase 2: Read Existing Tasks

**Goal:** Load the current task list and identify tasks to transform.

### Step 1: Get All Tasks

Use `TaskList` to retrieve all current tasks.

### Step 2: Apply Group Filter

If `--task-group` was specified:
- Filter to only tasks where `metadata.task_group` matches the specified group
- Tasks outside the group are not modified

If no `--task-group` specified:
- Process all tasks regardless of group

### Step 3: Validate Task List

Handle empty/missing states:

**Empty task list (no tasks at all):**
```
No tasks found. Please run /create-tasks first to generate implementation tasks from a spec.

Usage:
  /agent-alchemy-sdd:create-tasks <spec-path>
```

**No tasks matching --task-group filter:**
```
No tasks found for group "{group}".

Available task groups:
- {group1} ({n} tasks)
- {group2} ({n} tasks)

Try: /create-tdd-tasks --task-group {group1}
```

### Step 4: Classify Tasks

For each task, determine if it should receive a TDD pair:

**Eligible for TDD pairing:**
- Implementation tasks (subjects like "Create X", "Implement X", "Build X", "Add X")
- Business logic tasks
- API/endpoint tasks
- Data model tasks
- UI/frontend tasks

**Skip (no TDD pair created):**
- Tasks already marked with `tdd_mode: true` in metadata
- Test tasks (subjects like "Add tests for X", "Write tests for X", or tasks with `test` in `task_uid`)
- Configuration/setup tasks (subjects like "Configure X", "Set up X")
- Documentation tasks (subjects like "Document X", "Write docs for X")

Record the classification for each task: eligible, skipped (with reason).

---

## Phase 3: Detect Existing TDD Pairs (Merge Mode)

**Goal:** Identify tasks that already have TDD pairs to avoid duplication.

### Detection Algorithm

For each eligible task, check if it already has a TDD pair using these 4 signals (any match means paired):

1. **Metadata check**: Task has `tdd_mode: true` in metadata
2. **Paired task check**: Task has `paired_task_id` in metadata, and the paired task exists in the task list
3. **UID check**: A task exists with `task_uid` equal to this task's `task_uid` + `:red`
4. **Subject check**: A task with subject `"Write tests for {this task's subject}"` exists in the same `task_group`

### Merge Behavior

For tasks with existing TDD pairs:

| Existing Pair Status | Action |
|---------------------|--------|
| Both tasks pending | Skip -- pair already exists |
| Test completed, impl pending | Skip -- pair progressing normally |
| Test completed, impl completed | Skip -- pair fully done |
| Test completed, impl in_progress | Skip -- pair in progress |
| Test pending, impl completed | Flag as anomaly -- impl completed without tests |
| Only impl exists, test missing | Treat as unpaired -- create the test task |
| Only test exists, impl missing | Flag as orphan -- ask user |

### Report Merge Status

If any existing pairs detected:

```
TDD PAIR STATUS:
- {n} tasks already have TDD pairs (will skip)
- {m} tasks need TDD pairs (will create)
- {k} anomalies detected (need user input)
```

If anomalies exist, use AskUserQuestion to resolve each one:

```yaml
AskUserQuestion:
  questions:
    - header: "TDD Pair Anomaly"
      question: "Task #{id} '{subject}' was completed without its test task. What should I do?"
      options:
        - label: "Create test task anyway"
          description: "Add a test task for documentation/coverage purposes"
        - label: "Skip this task"
          description: "Leave it as-is without a test pair"
      multiSelect: false
```

---

## Phase 4: Generate Test Tasks

**Goal:** Create test task definitions for each eligible unpaired implementation task.

For each eligible task that needs a TDD pair, generate a paired test task.

### Step 1: Determine Test Task Subject

Follow the naming convention:
```
"Write tests for {original task subject}"
```

Examples:
- "Create User data model" -> "Write tests for Create User data model"
- "Implement POST /auth/login endpoint" -> "Write tests for Implement POST /auth/login endpoint"

### Step 2: Infer Test File Path

Determine the test file path based on the implementation task context:
- If implementation task references source files, derive test file path from project conventions
- Common patterns: `src/foo.ts` -> `tests/foo.test.ts`, `src/foo.py` -> `tests/test_foo.py`
- If no source files referenced, use the task subject to infer a path

### Step 3: Detect Test Framework

Determine the test framework using project detection:
1. Check for config files: `jest.config.*`, `vitest.config.*`, `pytest.ini`, `pyproject.toml`, `setup.cfg`
2. Check existing test files for import patterns
3. Check `package.json` for test dependencies
4. Default to the most common framework for the detected language

### Step 4: Convert Acceptance Criteria to Test Descriptions

**If the implementation task HAS acceptance criteria** (`**Acceptance Criteria:**` section):

Convert each criterion into a test description:

```markdown
**Test Descriptions:**

_From Functional Criteria:_
- [ ] Test that {criterion rephrased as test assertion}

_From Edge Cases:_
- [ ] Test that {edge case rephrased as test assertion}

_From Error Handling:_
- [ ] Test that {error scenario rephrased as test assertion}

_From Performance:_ (if applicable)
- [ ] Test that {performance target as measurable assertion}
```

**If the implementation task LACKS acceptance criteria:**

Generate basic test descriptions from the subject and description:

1. Parse the subject for intent ("Create X" -> test X exists and has expected structure)
2. Extract testable statements from description ("should...", "must...", "returns...", "validates...")
3. Generate minimal test descriptions:

```markdown
**Test Descriptions:**

_Inferred from task description:_
- [ ] Test that {subject entity} can be created/initialized
- [ ] Test that {subject entity} has expected structure/interface
- [ ] Test that {described behavior} works as described
```

### Step 5: Build Test Task Definition

Assemble the complete test task:

```
subject: "Write tests for {original subject}"
description: |
  Write failing tests for: {original task subject}

  Test file: {inferred test file path}
  Test framework: {detected framework}
  Original task: #{original_task_id}

  {test descriptions from Step 4}

  **Acceptance Criteria:**

  _Functional:_
  - [ ] All test descriptions converted into runnable test functions
  - [ ] Tests follow project test conventions (naming, structure, fixtures)
  - [ ] Tests are discoverable by the test runner
  - [ ] Tests fail when run without implementation (RED state)

  _Edge Cases:_
  - [ ] Tests handle import errors gracefully when implementation module does not exist

  _Error Handling:_
  - [ ] Test file is syntactically valid even when implementation is missing

  Source: {original source reference}
activeForm: "Writing tests for {original subject}"
metadata:
  tdd_mode: true
  tdd_phase: "red"
  paired_task_id: "{original_task_id}"
  priority: {inherited from original}
  complexity: {S or M -- test files are typically smaller}
  source_section: {inherited from original}
  spec_path: {inherited from original}
  feature_name: {inherited from original}
  task_uid: "{original_task_uid}:red"
  task_group: {inherited from original}
```

### Step 6: Plan Implementation Task Updates

For each original implementation task, plan the metadata update:

```yaml
metadata additions:
  tdd_mode: true
  tdd_phase: "green"
  paired_task_id: "{test_task_id}"  # Will be set after test task creation
```

---

## Phase 5: Set Dependencies

**Goal:** Insert TDD pairs into the existing dependency chain.

Apply the insertion algorithm from `tdd-dependency-rules.md`:

### For Each TDD Pair

Given implementation task `#N` with existing dependencies `blockedBy: [A, B, ...]`:

1. **Test task inherits upstream dependencies**: Test task `#T` gets `blockedBy: [A, B, ...]` (same as original)
2. **Implementation task gains test dependency**: Task `#N` adds `#T` to its `blockedBy` list
3. **Downstream tasks unchanged**: Tasks that depend on `#N` continue to depend on `#N`

### Dependency Insertion Example

```
Before: Model (#1) --> API (#2) --> UI (#3)

After:
  Test-Model (#4) blockedBy: []
  Model (#1) blockedBy: [#4]
  Test-API (#5) blockedBy: [#1]
  API (#2) blockedBy: [#1, #5]
  Test-UI (#6) blockedBy: [#2]
  UI (#3) blockedBy: [#2, #6]
```

### Circular Dependency Detection

After planning all insertions, validate the full dependency graph:

1. Build the complete graph from all tasks (original + new test tasks)
2. Run topological sort
3. If sort fails, a cycle exists

**Breaking cycles** (weakest-link strategy):

Score each dependency link in the cycle:
- TDD pair link (test -> impl): score 1 (weakest)
- Same-feature cross-layer: score 2
- Cross-feature dependency: score 3 (strongest)

Remove the dependency with the lowest score. Log a warning:

```
WARNING: Circular dependency detected after TDD pair insertion.
Cycle: {task chain}
Broken at: {removed link}
Reason: TDD pair link is weakest (score: 1)
Impact: {explanation of what may run out of order}
```

Add `needs_review: true` and `circular_dep_break: true` to the affected task's metadata.

---

## Phase 6: Preview & Confirm

**Goal:** Present the TDD transformation plan and get user approval.

### Display Preview

Present a summary of the planned changes:

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TDD TASK PAIR GENERATION PREVIEW
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SUMMARY:
  Total implementation tasks: {count}
  Eligible for TDD pairing: {eligible}
  Already have TDD pairs: {skipped} (merge mode)
  New TDD pairs to create: {new_pairs}
  Tasks skipped (test/config/docs): {skipped_ineligible}

NEW TDD PAIRS:
  Test Task                              | Blocks        | Phase
  ─────────────────────────────────────────────────────────────
  Write tests for {subject1}             | #{impl_id1}   | RED
  Write tests for {subject2}             | #{impl_id2}   | RED
  ...

DEPENDENCY CHAIN (after insertion):
  {visualization of the dependency chain with TDD pairs inserted}

{If circular deps detected and broken:}
WARNINGS:
  - Circular dependency broken at: {link}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

### Get Confirmation

Use AskUserQuestion to confirm:

```yaml
AskUserQuestion:
  questions:
    - header: "Confirm TDD Pair Creation"
      question: "Ready to create {n} TDD task pairs?"
      options:
        - label: "Yes, create pairs"
          description: "Create test tasks and update implementation tasks with TDD metadata"
        - label: "Show task details"
          description: "See full test task descriptions before creating"
        - label: "Cancel"
          description: "Don't create TDD pairs"
      multiSelect: false
```

If user selects "Show task details":
- Display each test task's full description
- Show the criteria-to-test conversion
- Then ask for confirmation again

If user selects "Cancel":
- Stop without creating any tasks
- Report cancellation

---

## Phase 7: Create Tasks

**Goal:** Create test tasks and update implementation tasks with TDD metadata.

### Step 1: Create Test Tasks

For each planned test task, use `TaskCreate`:

```
TaskCreate:
  subject: "Write tests for {original subject}"
  description: {generated description from Phase 4}
  activeForm: "Writing tests for {original subject}"
  metadata:
    tdd_mode: true
    tdd_phase: "red"
    paired_task_id: "{impl_task_id}"
    priority: {inherited}
    complexity: {estimated}
    source_section: {inherited}
    spec_path: {inherited}
    feature_name: {inherited}
    task_uid: "{original_uid}:red"
    task_group: {inherited}
```

Capture the returned task ID for each created test task.

### Step 2: Update Implementation Tasks

For each paired implementation task, use `TaskUpdate`:

```
TaskUpdate:
  taskId: "{impl_task_id}"
  metadata:
    tdd_mode: true
    tdd_phase: "green"
    paired_task_id: "{test_task_id}"
```

### Step 3: Set Dependencies

For each TDD pair, set the dependency relationships:

```
TaskUpdate:
  taskId: "{impl_task_id}"
  addBlockedBy: ["{test_task_id}"]
```

For test tasks that need upstream dependencies (inheriting from the original impl task):

```
TaskUpdate:
  taskId: "{test_task_id}"
  addBlockedBy: ["{upstream_dep_1}", "{upstream_dep_2}"]
```

### Step 4: Handle Circular Dependency Breaks

If any circular dependencies were detected and broken in Phase 5:

```
TaskUpdate:
  taskId: "{affected_task_id}"
  metadata:
    needs_review: true
    circular_dep_break: true
```

---

## Phase 8: Report

**Goal:** Present the final summary of created TDD task pairs.

### Completion Report

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
TDD TASK PAIR CREATION COMPLETE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Created {n} TDD task pairs
Set {m} dependency relationships

TDD PAIRS CREATED:
  Test Task (RED)                        | Impl Task (GREEN)        | Test Blocks
  ─────────────────────────────────────────────────────────────────────────────────
  #{test_id}: Write tests for {subj}     | #{impl_id}: {subj}       | #{impl_id}
  ...

DEPENDENCY CHAIN:
  {visual representation of the full dependency chain}

{If --task-group was used:}
Group: {group}
Tasks in group: {total}
TDD pairs added: {new}

{If merge mode detected:}
MERGE MODE:
  Existing pairs preserved: {n}
  New pairs created: {m}

{If circular deps broken:}
WARNINGS:
  {n} circular dependencies detected and broken. Review recommended.

NEXT STEPS:
  Run /execute-tdd-tasks to execute TDD pairs with RED-GREEN-REFACTOR workflow.
  Run /execute-tdd-tasks --task-group {group} for group-specific execution.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

## Error Handling

### tdd-tools Not Installed

If the tdd-tools plugin check fails in Phase 1:
- Display the clear error message with installation instructions
- Stop immediately -- do not proceed to any other phase

### Empty Task List

If TaskList returns no tasks:
- Inform user to run `/create-tasks` first
- Provide usage example
- Stop

### No Matching Group

If `--task-group` filter matches zero tasks:
- List available groups with task counts
- Suggest a valid group
- Stop

### All Tasks Already Paired

If merge mode detects that all eligible tasks already have TDD pairs:

```
All eligible tasks already have TDD pairs. Nothing to create.

TDD pair status:
- {n} active TDD pairs
- {m} completed TDD pairs
- {k} tasks skipped (test/config/docs)
```

### TaskCreate Failures

If a TaskCreate call fails:
- Log the failure
- Continue with remaining tasks
- Report partial results in Phase 8 with failed tasks listed

---

## Example Usage

### Convert all tasks to TDD pairs
```
/agent-alchemy-sdd:create-tdd-tasks
```

### Convert a specific group
```
/agent-alchemy-sdd:create-tdd-tasks --task-group user-authentication
```

### Re-run (merge mode)
```
/agent-alchemy-sdd:create-tdd-tasks --task-group user-authentication
```
If TDD pairs already exist for some tasks, they will be detected and skipped.

---

## Important Notes

- Never create duplicate test tasks -- always check merge mode signals first
- Preserve all existing task dependencies -- TDD pairs are inserted, not replacing
- Test tasks always block their paired implementation task
- Test task metadata always inherits `task_group`, `priority`, `feature_name`, `spec_path`, and `source_section` from the original
- Task UIDs for test tasks append `:red` to the original UID
- Always use imperative mood for subjects ("Write tests for X" not "Tests for X")
- Always include activeForm in present continuous ("Writing tests for X")
- Tasks with `tdd_mode: true` are never paired again (prevents double-pairing)

## Reference Files

- `references/tdd-decomposition-patterns.md` -- Task pairing rules, naming conventions, criteria conversion, merge mode
- `references/tdd-dependency-rules.md` -- Dependency insertion algorithm, circular dependency detection and breaking

