Phase 05: Task Dispatch - 5 plans in 3 waves - 3 parallel (Wave 1), 1 sequential (Wave 2), 1 sequential (Wave 3) - Ready for execution Requirements covered: - AGENT-06: Message queue for agent questions - TASK-01: Task status visibility - TASK-04: Dependency-ordered dispatch - TASK-05: Work queue for agents
5.6 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous
| phase | plan | type | wave | depends_on | files_modified | autonomous | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 05-task-dispatch | 04 | execute | 2 |
|
|
true |
Purpose: TASK-04 requires dependency-ordered dispatch, TASK-05 requires work queue. Implement the DispatchManager adapter that checks task dependencies before dispatch and manages the work queue. Output: DispatchManager adapter with dependency algorithm, queue management, and tests.
<execution_context>
@/.claude/get-shit-done/workflows/execute-plan.md
@/.claude/get-shit-done/templates/summary.md
</execution_context>
@.planning/phases/05-task-dispatch/05-01-SUMMARY.md @.planning/phases/05-task-dispatch/05-03-SUMMARY.md
@src/dispatch/types.ts @src/db/schema.ts @src/db/repositories/task-repository.ts @src/agent/types.ts @src/events/types.ts
Task 1: Implement dependency checking algorithm src/dispatch/manager.ts Create DefaultDispatchManager class implementing DispatchManager interface.Constructor dependencies (inject via constructor):
- taskRepository: TaskRepository
- messageRepository: MessageRepository (from 05-01)
- agentManager: AgentManager
- eventBus: EventBus
Implement core dependency algorithm:
-
queue(taskId):
- Fetch task and its dependencies from task_dependencies table
- Add to internal queue (use Map<string, QueuedTask>)
- Emit TaskQueuedEvent
-
getNextDispatchable():
- Get all queued tasks
- For each, check if ALL dependencies have status='completed'
- Filter to only ready tasks (all deps complete)
- Sort by priority (high > medium > low), then by queuedAt (oldest first)
- Return first or null
-
completeTask(taskId):
- Update task status to 'completed' via taskRepository
- Remove from queue
- Emit TaskCompletedEvent
- Note: dependent tasks automatically become ready on next getNextDispatchable call
-
blockTask(taskId, reason):
- Update task status to 'blocked' via taskRepository
- Emit TaskBlockedEvent
Use simple in-memory queue (Map). Production could use persistent queue but in-memory is fine for v1. npm run build passes Dependency checking algorithm implemented
Task 2: Implement dispatchNext and queue state src/dispatch/manager.ts Complete DispatchManager implementation:-
dispatchNext():
- Call getNextDispatchable() to get next task
- If null, return { success: false, taskId: '', reason: 'No dispatchable tasks' }
- Find available agent (status='idle') via agentManager.list()
- If no available agent, return { success: false, taskId, reason: 'No available agents' }
- Get task details from taskRepository
- Spawn agent with task: agentManager.spawn({ name: generateAgentName(), taskId, prompt: task.description || task.name })
- Update task status to 'in_progress'
- Emit TaskDispatchedEvent
- Return { success: true, taskId, agentId }
-
getQueueState():
- Return { queued: [...allQueuedTasks], ready: [...readyTasks], blocked: [...blockedTasks] }
- Uses internal queue state
Helper: generateAgentName():
- Generate unique name for agent (e.g., 'agent-${nanoid(6)}' or use Vancouver neighborhood names: 'gastown', 'yaletown', 'kitsilano', etc.)
- For v1: simple 'agent-${taskId.slice(0,6)}' is fine
Handle edge cases:
- Task not found: throw error
- Circular dependencies: not checked in v1 (assume valid DAG) npm run build passes dispatchNext and getQueueState implemented
-
Setup:
- Create in-memory database with createTestDatabase helper
- Create mock/real repositories and EventBus
- Create test tasks with dependencies
-
Test cases:
- queue adds task to queue and emits event
- getNextDispatchable returns null when queue empty
- getNextDispatchable returns task when dependencies complete
- getNextDispatchable returns null when dependencies incomplete
- getNextDispatchable respects priority ordering
- completeTask updates status and emits event
- blockTask updates status and emits event
- dispatchNext returns failure when no tasks ready
- dispatchNext returns failure when no agents available
- getQueueState returns correct state
-
Test dependency scenario:
- Task A (no deps)
- Task B (depends on A)
- Task C (depends on A)
- Queue all three
- Only A should be dispatchable
- Complete A
- B and C should become dispatchable
Update index.ts to export DefaultDispatchManager class. npm test -- src/dispatch/manager.test.ts passes Tests pass, DispatchManager exported
Before declaring plan complete: - [ ] npm run build succeeds - [ ] npm test passes all tests - [ ] Dependency ordering works correctly - [ ] Queue state accurately reflects task readiness<success_criteria>
- DefaultDispatchManager implements DispatchManager interface
- Dependency checking prevents premature dispatch
- Priority ordering respected
- All dispatch events emitted correctly
- Tests cover core scenarios </success_criteria>