---
phase: 12-phase-task-decomposition
plan: 08
type: execute
wave: 4
depends_on: ["12-05", "12-06", "12-07"]
files_modified:
  - src/test/harness.ts
  - src/test/e2e/decompose-workflow.test.ts
autonomous: true
---

<objective>
Add TestHarness support for decompose mode and E2E tests for the full decomposition workflow.

Purpose: Validate the complete workflow from plan creation through task decomposition and persistence.

Output: E2E tests proving decompose mode works end-to-end.
</objective>

<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md

# Test infrastructure from Phase 11
@.planning/phases/11-architect-agent/11-08-SUMMARY.md

# TestHarness
@src/test/harness.ts
@src/test/e2e/architect-workflow.test.ts
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add TestHarness decompose mode helpers</name>
  <files>src/test/harness.ts</files>
  <action>
Add decompose scenario helpers to TestHarness following architect mode pattern:

```typescript
/**
 * Set decompose complete scenario for an agent.
 * Agent will complete with task array when spawned.
 */
setArchitectDecomposeComplete(agentName: string, tasks: Array<{
  number: number;
  name: string;
  description: string;
  type?: string;
  dependencies?: number[];
}>) {
  this.mockAgentManager.setScenario(agentName, {
    status: 'decompose_complete',
    tasks: tasks.map(t => ({
      ...t,
      type: t.type || 'auto',
      dependencies: t.dependencies || [],
    })),
  });
}

/**
 * Set decompose questions scenario for an agent.
 * Agent will pause with questions when spawned.
 */
setArchitectDecomposeQuestions(agentName: string, questions: Array<{
  id: string;
  question: string;
  options?: Array<{ label: string }>;
}>) {
  this.mockAgentManager.setScenario(agentName, {
    status: 'questions',
    questions,
  });
}
```

Also add convenience methods for creating plans in tests:
```typescript
async createPlan(phaseId: string, name: string, description?: string) {
  return this.caller.createPlan({ phaseId, name, description });
}

async getTasksForPlan(planId: string) {
  return this.caller.listTasks({ planId });
}
```
  </action>
  <verify>npm run build passes</verify>
  <done>TestHarness has decompose scenario helpers and plan convenience methods</done>
</task>

<task type="auto">
  <name>Task 2: Add decompose mode E2E tests</name>
  <files>src/test/e2e/decompose-workflow.test.ts</files>
  <action>
Create E2E test file for decompose workflow:

```typescript
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { TestHarness } from '../harness.js';

describe('Decompose Workflow', () => {
  let harness: TestHarness;

  beforeEach(async () => {
    vi.useFakeTimers();
    harness = await TestHarness.create();
  });

  afterEach(async () => {
    await harness.cleanup();
    vi.useRealTimers();
  });

  describe('spawn decompose agent', () => {
    it('should spawn agent in decompose mode and complete with tasks', async () => {
      // Setup: Create initiative -> phase -> plan
      const initiative = await harness.createInitiative('Test Project');
      const phases = await harness.createPhasesFromBreakdown(initiative.id, [
        { number: 1, name: 'Phase 1', description: 'First phase', dependencies: [] },
      ]);
      const plan = await harness.createPlan(phases[0].id, 'Auth Plan', 'Implement auth');

      // Set decompose scenario
      harness.setArchitectDecomposeComplete('decomposer', [
        { number: 1, name: 'Create schema', description: 'User table', type: 'auto', dependencies: [] },
        { number: 2, name: 'Create endpoint', description: 'Login API', type: 'auto', dependencies: [1] },
      ]);

      // Spawn decompose agent
      await harness.caller.spawnArchitectDecompose({
        name: 'decomposer',
        planId: plan.id,
      });

      // Advance timers for async completion
      await harness.advanceTimers(100);

      // Verify agent completed
      const events = harness.getEmittedEvents();
      expect(events).toContainEqual(
        expect.objectContaining({
          type: 'agent:stopped',
          payload: expect.objectContaining({
            name: 'decomposer',
            reason: 'decompose_complete',
          }),
        })
      );
    });

    it('should pause on questions and resume', async () => {
      const initiative = await harness.createInitiative('Test Project');
      const phases = await harness.createPhasesFromBreakdown(initiative.id, [
        { number: 1, name: 'Phase 1', description: 'First phase', dependencies: [] },
      ]);
      const plan = await harness.createPlan(phases[0].id, 'Complex Plan');

      // Set questions scenario
      harness.setArchitectDecomposeQuestions('decomposer', [
        { id: 'q1', question: 'How granular should tasks be?' },
      ]);

      await harness.caller.spawnArchitectDecompose({
        name: 'decomposer',
        planId: plan.id,
      });

      await harness.advanceTimers(100);

      // Verify paused on questions
      const events = harness.getEmittedEvents();
      expect(events).toContainEqual(
        expect.objectContaining({
          type: 'agent:stopped',
          payload: expect.objectContaining({
            reason: 'questions',
          }),
        })
      );

      // Set completion scenario for resume
      harness.setArchitectDecomposeComplete('decomposer', [
        { number: 1, name: 'Task 1', description: 'Single task', type: 'auto' },
      ]);

      // Resume with answer
      await harness.mockAgentManager.resume('decomposer', { q1: 'Very granular' });
      await harness.advanceTimers(100);

      // Verify completed after resume
      const finalEvents = harness.getEmittedEvents();
      expect(finalEvents.filter(e => e.type === 'agent:stopped')).toHaveLength(2);
    });
  });

  describe('task persistence', () => {
    it('should create tasks from decomposition output', async () => {
      const initiative = await harness.createInitiative('Test Project');
      const phases = await harness.createPhasesFromBreakdown(initiative.id, [
        { number: 1, name: 'Phase 1', description: 'First phase', dependencies: [] },
      ]);
      const plan = await harness.createPlan(phases[0].id, 'Auth Plan');

      // Create tasks from decomposition
      await harness.caller.createTasksFromDecomposition({
        planId: plan.id,
        tasks: [
          { number: 1, name: 'Schema', description: 'Create tables', type: 'auto', dependencies: [] },
          { number: 2, name: 'API', description: 'Create endpoints', type: 'auto', dependencies: [1] },
          { number: 3, name: 'Verify', description: 'Test flow', type: 'checkpoint:human-verify', dependencies: [2] },
        ],
      });

      // Verify tasks created
      const tasks = await harness.getTasksForPlan(plan.id);
      expect(tasks).toHaveLength(3);
      expect(tasks[0].name).toBe('Schema');
      expect(tasks[1].name).toBe('API');
      expect(tasks[2].type).toBe('checkpoint:human-verify');
    });
  });
});
```
  </action>
  <verify>npm test passes with new E2E tests</verify>
  <done>E2E tests cover decompose spawn, Q&A flow, and task persistence</done>
</task>

</tasks>

<verification>
Before declaring plan complete:
- [ ] npm run build succeeds
- [ ] npm test passes all tests including new E2E tests
- [ ] Decompose mode completion tested
- [ ] Decompose Q&A flow tested
- [ ] Task persistence from decomposition tested
</verification>

<success_criteria>
- All tasks completed
- All verification checks pass
- No errors or warnings introduced
- Full E2E coverage for decompose workflow
</success_criteria>

<output>
After completion, create `.planning/phases/12-phase-task-decomposition/12-08-SUMMARY.md`
</output>
