Decomposed "Foundation Setup - Install Dependencies & Configure Tailwind" phase into 6 executable tasks: 1. Install Tailwind CSS, PostCSS & Autoprefixer 2. Map MUI theme to Tailwind design tokens 3. Setup CSS variables for dynamic theming 4. Install Radix UI primitives 5. Initialize shadcn/ui and setup component directory 6. Move MUI to devDependencies and verify setup Tasks follow logical dependency chain with final human verification checkpoint before proceeding with component migration. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
332 lines
11 KiB
Markdown
332 lines
11 KiB
Markdown
# Tasks Module
|
|
|
|
Beads-inspired task management optimized for multi-agent coordination. Unlike beads (Git-distributed JSONL), this uses centralized SQLite for simplicity since all agents share the same workspace.
|
|
|
|
## Design Rationale
|
|
|
|
### Why Not Just Use Beads?
|
|
|
|
Beads solves a different problem: distributed task tracking across forked repos with zero coordination. We don't need that:
|
|
|
|
- All Workers operate in the same workspace under one `cw` server
|
|
- SQLite is the single source of truth
|
|
- tRPC exposes task queries directly to agents and dashboard
|
|
- No merge conflicts, no Git overhead
|
|
|
|
### Core Agent Problem Solved
|
|
|
|
Agents need to answer: **"What should I work on next?"**
|
|
|
|
The `ready` query solves this: tasks that are `open` with all dependencies `closed`. Combined with priority ordering, agents can self-coordinate without human intervention.
|
|
|
|
---
|
|
|
|
## Data Model
|
|
|
|
### Task Entity
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `id` | TEXT | Primary key. Hash-based (e.g., `tsk-a1b2c3`) or UUID |
|
|
| `parent_id` | TEXT | Optional. References parent task for hierarchies |
|
|
| `initiative_id` | TEXT | Optional. Links to Initiatives module |
|
|
| `phase_id` | TEXT | Optional. Links to initiative phase (for grouped approval) |
|
|
| `project_id` | TEXT | Optional. Scopes task to a project |
|
|
| `title` | TEXT | Required. Short task name |
|
|
| `description` | TEXT | Optional. Markdown-formatted details |
|
|
| `type` | TEXT | `task` (default), `epic`, `subtask` |
|
|
| `status` | TEXT | `open`, `in_progress`, `blocked`, `closed` |
|
|
| `priority` | INTEGER | 0=critical, 1=high, 2=normal (default), 3=low |
|
|
| `assigned_to` | TEXT | Agent/worker ID currently working on this |
|
|
| `assigned_at` | INTEGER | Unix timestamp when assigned |
|
|
| `metadata` | TEXT | JSON blob for extensibility |
|
|
| `created_at` | INTEGER | Unix timestamp |
|
|
| `updated_at` | INTEGER | Unix timestamp |
|
|
| `closed_at` | INTEGER | Unix timestamp when closed |
|
|
| `closed_reason` | TEXT | Why/how the task was completed |
|
|
|
|
### Task Dependencies
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `task_id` | TEXT | The task that is blocked |
|
|
| `depends_on` | TEXT | The task that must complete first |
|
|
| `type` | TEXT | `blocks` (default), `related` |
|
|
|
|
### Task History
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `id` | INTEGER | Auto-increment primary key |
|
|
| `task_id` | TEXT | The task that changed |
|
|
| `field` | TEXT | Which field changed |
|
|
| `old_value` | TEXT | Previous value |
|
|
| `new_value` | TEXT | New value |
|
|
| `changed_by` | TEXT | Agent/user ID |
|
|
| `changed_at` | INTEGER | Unix timestamp |
|
|
|
|
---
|
|
|
|
## SQLite Schema
|
|
|
|
```sql
|
|
CREATE TABLE tasks (
|
|
id TEXT PRIMARY KEY,
|
|
parent_id TEXT REFERENCES tasks(id),
|
|
initiative_id TEXT,
|
|
phase_id TEXT,
|
|
project_id TEXT,
|
|
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
type TEXT NOT NULL DEFAULT 'task' CHECK (type IN ('task', 'epic', 'subtask')),
|
|
|
|
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'in_progress', 'blocked', 'closed')),
|
|
priority INTEGER NOT NULL DEFAULT 2 CHECK (priority BETWEEN 0 AND 3),
|
|
|
|
assigned_to TEXT,
|
|
assigned_at INTEGER,
|
|
|
|
metadata TEXT,
|
|
|
|
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
closed_at INTEGER,
|
|
closed_reason TEXT
|
|
);
|
|
|
|
CREATE TABLE task_dependencies (
|
|
task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
depends_on TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
type TEXT NOT NULL DEFAULT 'blocks' CHECK (type IN ('blocks', 'related')),
|
|
PRIMARY KEY (task_id, depends_on),
|
|
CHECK (task_id != depends_on)
|
|
);
|
|
|
|
CREATE TABLE task_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
field TEXT NOT NULL,
|
|
old_value TEXT,
|
|
new_value TEXT,
|
|
changed_by TEXT,
|
|
changed_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
);
|
|
|
|
CREATE INDEX idx_tasks_status ON tasks(status);
|
|
CREATE INDEX idx_tasks_priority ON tasks(priority);
|
|
CREATE INDEX idx_tasks_assigned ON tasks(assigned_to);
|
|
CREATE INDEX idx_tasks_project ON tasks(project_id);
|
|
CREATE INDEX idx_tasks_initiative ON tasks(initiative_id);
|
|
CREATE INDEX idx_tasks_phase ON tasks(phase_id);
|
|
CREATE INDEX idx_task_history_task ON task_history(task_id);
|
|
|
|
-- The critical view for agent work discovery
|
|
-- Tasks are ready when: open, no blocking deps, and phase approved (if linked)
|
|
CREATE VIEW ready_tasks AS
|
|
SELECT t.* FROM tasks t
|
|
LEFT JOIN initiative_phases p ON t.phase_id = p.id
|
|
WHERE t.status = 'open'
|
|
AND (t.phase_id IS NULL OR p.status IN ('approved', 'in_progress'))
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM task_dependencies d
|
|
JOIN tasks dep ON d.depends_on = dep.id
|
|
WHERE d.task_id = t.id
|
|
AND d.type = 'blocks'
|
|
AND dep.status != 'closed'
|
|
)
|
|
ORDER BY t.priority ASC, t.created_at ASC;
|
|
```
|
|
|
|
---
|
|
|
|
## Status Workflow
|
|
|
|
```
|
|
┌──────────────────────────────────────┐
|
|
│ │
|
|
▼ │
|
|
[open] ──claim──▶ [in_progress] ──done──▶ [closed]
|
|
│ │
|
|
│ │ blocked
|
|
│ ▼
|
|
└───────────── [blocked] ◀─────unblock───┘
|
|
```
|
|
|
|
| Transition | Trigger | Notes |
|
|
|------------|---------|-------|
|
|
| `open` → `in_progress` | Agent claims task | Sets `assigned_to`, `assigned_at` |
|
|
| `in_progress` → `closed` | Work completed | Sets `closed_at`, `closed_reason` |
|
|
| `in_progress` → `blocked` | External dependency | Manual or auto-detected |
|
|
| `blocked` → `open` | Blocker resolved | Clears assignment |
|
|
| `open` → `closed` | Cancelled/won't do | Direct close without work |
|
|
|
|
---
|
|
|
|
## CLI Reference
|
|
|
|
All commands under `cw task` subcommand.
|
|
|
|
### Core Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `cw task ready` | List tasks ready for work (open + no blockers) |
|
|
| `cw task list [--status STATUS] [--project ID]` | List tasks with filters |
|
|
| `cw task show <id>` | Show task details + history |
|
|
| `cw task create <title> [-p PRIORITY] [-d DESC]` | Create new task |
|
|
| `cw task update <id> [--status STATUS] [--priority P]` | Update task fields |
|
|
| `cw task close <id> [--reason REASON]` | Mark task complete |
|
|
|
|
### Dependency Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `cw task dep add <task> <depends-on>` | Task blocked by another |
|
|
| `cw task dep rm <task> <depends-on>` | Remove dependency |
|
|
| `cw task dep tree <id>` | Show dependency graph |
|
|
|
|
### Assignment Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `cw task assign <id> <agent>` | Assign task to agent |
|
|
| `cw task unassign <id>` | Release task |
|
|
| `cw task mine` | List tasks assigned to current agent |
|
|
|
|
### Output Flags (global)
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `--json` | Output as JSON (for agent consumption) |
|
|
| `--quiet` | Minimal output (just IDs) |
|
|
|
|
---
|
|
|
|
## Agent Workflow
|
|
|
|
Standard loop for Workers:
|
|
|
|
```
|
|
1. cw task ready --json
|
|
2. Pick highest priority task from result
|
|
3. cw task update <id> --status in_progress
|
|
4. Do the work
|
|
5. cw task close <id> --reason "Implemented X"
|
|
6. Loop to step 1
|
|
```
|
|
|
|
If `cw task ready` returns empty, the agent's work is done.
|
|
|
|
---
|
|
|
|
## Integration Points
|
|
|
|
### With Initiatives
|
|
- Tasks can link to an initiative via `initiative_id`
|
|
- When initiative is approved, tasks are generated from its technical concept
|
|
- Closing all tasks for an initiative signals initiative completion
|
|
|
|
### With Orchestrator
|
|
- Orchestrator queries `ready_tasks` view to dispatch work
|
|
- Assignment tracked to prevent double-dispatch
|
|
- Orchestrator can bulk-create tasks from job definitions
|
|
|
|
### With Workers
|
|
- Workers claim tasks via `cw task update --status in_progress`
|
|
- Worker ID stored in `assigned_to`
|
|
- On worker crash, Supervisor can detect stale assignments and reset
|
|
|
|
### tRPC Procedures
|
|
|
|
```typescript
|
|
// Suggested tRPC router shape
|
|
task.list(filters) // → Task[]
|
|
task.ready(projectId?) // → Task[]
|
|
task.get(id) // → Task | null
|
|
task.create(input) // → Task
|
|
task.update(id, input) // → Task
|
|
task.close(id, reason) // → Task
|
|
task.assign(id, agent) // → Task
|
|
task.history(id) // → TaskHistory[]
|
|
task.depAdd(id, dep) // → void
|
|
task.depRemove(id, dep) // → void
|
|
task.depTree(id) // → DependencyTree
|
|
```
|
|
|
|
---
|
|
|
|
## Task Granularity Standards
|
|
|
|
A task must be specific enough for execution without interpretation. Vague tasks cause agents to guess, leading to inconsistent results.
|
|
|
|
### Quick Reference
|
|
|
|
| Too Vague | Just Right |
|
|
|-----------|------------|
|
|
| "Add authentication" | "Add JWT auth with refresh rotation using jose, httpOnly cookie, 15min access / 7day refresh" |
|
|
| "Create the API" | "Create POST /api/projects accepting {name, description}, validates name 3-50 chars, returns 201" |
|
|
| "Handle errors" | "Wrap API calls in try/catch, return {error: string} on 4xx/5xx, show toast via sonner" |
|
|
|
|
### Required Task Components
|
|
|
|
Every task MUST include:
|
|
|
|
1. **files** — Exact paths modified/created
|
|
2. **action** — What to do, what to avoid, WHY
|
|
3. **verify** — Command or check to prove completion
|
|
4. **done** — Measurable acceptance criteria
|
|
|
|
See [task-granularity.md](task-granularity.md) for comprehensive examples and anti-patterns.
|
|
|
|
### Context Budget
|
|
|
|
Tasks are sized to fit agent context budgets:
|
|
|
|
| Complexity | Context % | Example |
|
|
|------------|-----------|---------|
|
|
| Simple | 10-20% | Add form field |
|
|
| Medium | 20-35% | Create API endpoint |
|
|
| Complex | 35-50% | Implement auth flow |
|
|
| Too Large | >50% | **SPLIT REQUIRED** |
|
|
|
|
See [context-engineering.md](context-engineering.md) for context management rules.
|
|
|
|
---
|
|
|
|
## Deviation Handling
|
|
|
|
When Workers encounter unexpected issues during execution, they follow deviation rules:
|
|
|
|
| Rule | Action | Permission |
|
|
|------|--------|------------|
|
|
| Rule 1: Bug fixes | Auto-fix | None needed |
|
|
| Rule 2: Missing critical (validation, auth) | Auto-add | None needed |
|
|
| Rule 3: Blocking issues (deps, imports) | Auto-fix | None needed |
|
|
| Rule 4: Architectural changes | ASK | Required |
|
|
|
|
See [deviation-rules.md](deviation-rules.md) for detailed guidance.
|
|
|
|
---
|
|
|
|
## Execution Artifacts
|
|
|
|
Task execution produces artifacts:
|
|
|
|
| Artifact | Purpose |
|
|
|----------|---------|
|
|
| Commits | Per-task atomic commits |
|
|
| SUMMARY.md | Record of what happened |
|
|
| STATE.md updates | Position tracking |
|
|
|
|
See [execution-artifacts.md](execution-artifacts.md) for artifact specifications.
|
|
|
|
---
|
|
|
|
## Future Considerations
|
|
|
|
- **Compaction**: Summarize old closed tasks to reduce DB size (beads does this with LLM)
|
|
- **Labels/tags**: Additional categorization beyond type
|
|
- **Time tracking**: Estimated vs actual time for capacity planning
|
|
- **Recurring tasks**: Templates that spawn new tasks on schedule
|