sqlew 3.1.1 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -0
- package/README.md +12 -2
- package/assets/schema.sql +28 -1
- package/dist/database.d.ts +65 -0
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +190 -0
- package/dist/database.js.map +1 -1
- package/dist/index.js +36 -6
- package/dist/index.js.map +1 -1
- package/dist/migrations/add-decision-context.d.ts +28 -0
- package/dist/migrations/add-decision-context.d.ts.map +1 -0
- package/dist/migrations/add-decision-context.js +125 -0
- package/dist/migrations/add-decision-context.js.map +1 -0
- package/dist/migrations/add-task-dependencies.d.ts +26 -0
- package/dist/migrations/add-task-dependencies.d.ts.map +1 -0
- package/dist/migrations/add-task-dependencies.js +94 -0
- package/dist/migrations/add-task-dependencies.js.map +1 -0
- package/dist/migrations/index.d.ts +3 -1
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +32 -2
- package/dist/migrations/index.js.map +1 -1
- package/dist/schema.js +2 -2
- package/dist/schema.js.map +1 -1
- package/dist/tests/migrations/test-v3.2-migration.d.ts +6 -0
- package/dist/tests/migrations/test-v3.2-migration.d.ts.map +1 -0
- package/dist/tests/migrations/test-v3.2-migration.js +191 -0
- package/dist/tests/migrations/test-v3.2-migration.js.map +1 -0
- package/dist/tests/tasks.dependencies.test.d.ts +7 -0
- package/dist/tests/tasks.dependencies.test.d.ts.map +1 -0
- package/dist/tests/tasks.dependencies.test.js +613 -0
- package/dist/tests/tasks.dependencies.test.js.map +1 -0
- package/dist/tools/context.d.ts +21 -2
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +110 -3
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/tasks.d.ts +23 -0
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +298 -8
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +44 -21
- package/dist/tools/utils.js.map +1 -1
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/AI_AGENT_GUIDE.md +25 -3
- package/docs/DECISION_CONTEXT.md +474 -0
- package/docs/TASK_ACTIONS.md +311 -10
- package/docs/TASK_DEPENDENCIES.md +748 -0
- package/docs/TASK_LINKING.md +188 -8
- package/docs/WORKFLOWS.md +25 -3
- package/package.json +4 -2
|
@@ -0,0 +1,748 @@
|
|
|
1
|
+
# Task Dependencies - Managing Blocking Relationships
|
|
2
|
+
|
|
3
|
+
**Version:** 3.2.0
|
|
4
|
+
**Feature:** Task Dependency Management (GitHub Issue #16)
|
|
5
|
+
**Last Updated:** 2025-10-18
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Overview](#overview)
|
|
10
|
+
2. [Core Concepts](#core-concepts)
|
|
11
|
+
3. [Dependency Actions](#dependency-actions)
|
|
12
|
+
4. [Validation Rules](#validation-rules)
|
|
13
|
+
5. [Circular Dependency Detection](#circular-dependency-detection)
|
|
14
|
+
6. [Enhanced Query Actions](#enhanced-query-actions)
|
|
15
|
+
7. [Usage Examples](#usage-examples)
|
|
16
|
+
8. [Best Practices](#best-practices)
|
|
17
|
+
9. [Token Efficiency](#token-efficiency)
|
|
18
|
+
10. [Related Documentation](#related-documentation)
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
|
|
22
|
+
Task Dependencies introduce **blocking relationships** between tasks, enabling workflow coordination and task ordering in AI-driven development. Unlike simple task links (decision/constraint/file), dependencies enforce directional relationships where one task must be completed before another can proceed.
|
|
23
|
+
|
|
24
|
+
**Key Features:**
|
|
25
|
+
- **Blocking Relationships**: Task A blocks Task B (B cannot proceed until A is done)
|
|
26
|
+
- **Bidirectional Queries**: Find both blockers and blocking tasks
|
|
27
|
+
- **Circular Detection**: Prevents deadlocks with recursive CTE algorithm
|
|
28
|
+
- **Cascade Deletion**: Dependencies auto-delete when tasks are deleted
|
|
29
|
+
- **Token Efficient**: Metadata-only queries by default, detailed info optional
|
|
30
|
+
|
|
31
|
+
**Use Cases:**
|
|
32
|
+
- Sequential feature development (auth before dashboard)
|
|
33
|
+
- Infrastructure before application code
|
|
34
|
+
- Database migrations before schema-dependent features
|
|
35
|
+
- API contracts before client implementations
|
|
36
|
+
|
|
37
|
+
## Core Concepts
|
|
38
|
+
|
|
39
|
+
### Blocker vs Blocked Tasks
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Task A (blocker) → blocks → Task B (blocked)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Terminology:**
|
|
46
|
+
- **Blocker Task**: The task that must be completed first
|
|
47
|
+
- **Blocked Task**: The task that is waiting/dependent
|
|
48
|
+
- **Blockers**: Tasks that block this task (what I'm waiting for)
|
|
49
|
+
- **Blocking**: Tasks that this task blocks (what's waiting for me)
|
|
50
|
+
|
|
51
|
+
**Example:**
|
|
52
|
+
```javascript
|
|
53
|
+
// Task #1: Implement JWT authentication (blocker)
|
|
54
|
+
// Task #2: Add user profile page (blocked - needs auth)
|
|
55
|
+
|
|
56
|
+
{
|
|
57
|
+
action: "add_dependency",
|
|
58
|
+
blocker_task_id: 1, // JWT auth must complete first
|
|
59
|
+
blocked_task_id: 2 // Profile page waits for auth
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Bidirectional Queries
|
|
64
|
+
|
|
65
|
+
Dependencies can be queried from either direction:
|
|
66
|
+
|
|
67
|
+
**From Blocked Task's Perspective:**
|
|
68
|
+
```javascript
|
|
69
|
+
// "What's blocking me from starting?"
|
|
70
|
+
{
|
|
71
|
+
action: "get_dependencies",
|
|
72
|
+
task_id: 2 // Profile page
|
|
73
|
+
}
|
|
74
|
+
// Returns:
|
|
75
|
+
// - blockers: [Task #1] (auth implementation)
|
|
76
|
+
// - blocking: [] (nothing waits for me)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**From Blocker Task's Perspective:**
|
|
80
|
+
```javascript
|
|
81
|
+
// "What's waiting for me to finish?"
|
|
82
|
+
{
|
|
83
|
+
action: "get_dependencies",
|
|
84
|
+
task_id: 1 // Auth implementation
|
|
85
|
+
}
|
|
86
|
+
// Returns:
|
|
87
|
+
// - blockers: [] (nothing blocks me)
|
|
88
|
+
// - blocking: [Task #2] (profile page waits)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Cascade Deletion
|
|
92
|
+
|
|
93
|
+
When a task is deleted, all its dependencies are automatically removed:
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
// Before deletion:
|
|
97
|
+
// Task #1 blocks Task #2
|
|
98
|
+
// Task #1 blocks Task #3
|
|
99
|
+
|
|
100
|
+
// After deleting Task #1:
|
|
101
|
+
// Dependencies automatically removed
|
|
102
|
+
// Task #2 and #3 are now unblocked
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Dependency Actions
|
|
106
|
+
|
|
107
|
+
### add_dependency
|
|
108
|
+
|
|
109
|
+
Add a blocking relationship between two tasks.
|
|
110
|
+
|
|
111
|
+
**Parameters:**
|
|
112
|
+
- `action`: "add_dependency" (required)
|
|
113
|
+
- `blocker_task_id` (required, number): Task ID that blocks
|
|
114
|
+
- `blocked_task_id` (required, number): Task ID that is blocked
|
|
115
|
+
|
|
116
|
+
**Validations:**
|
|
117
|
+
- No self-dependencies (task cannot block itself)
|
|
118
|
+
- No circular dependencies (direct or transitive)
|
|
119
|
+
- Both tasks must exist
|
|
120
|
+
- Neither task can be archived
|
|
121
|
+
|
|
122
|
+
**Example:**
|
|
123
|
+
```javascript
|
|
124
|
+
{
|
|
125
|
+
action: "add_dependency",
|
|
126
|
+
blocker_task_id: 1,
|
|
127
|
+
blocked_task_id: 2
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Response:**
|
|
132
|
+
```javascript
|
|
133
|
+
{
|
|
134
|
+
success: true,
|
|
135
|
+
message: "Dependency added: Task #1 blocks Task #2"
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Error Examples:**
|
|
140
|
+
```javascript
|
|
141
|
+
// Self-dependency
|
|
142
|
+
{
|
|
143
|
+
action: "add_dependency",
|
|
144
|
+
blocker_task_id: 1,
|
|
145
|
+
blocked_task_id: 1
|
|
146
|
+
}
|
|
147
|
+
// Error: "Self-dependency not allowed"
|
|
148
|
+
|
|
149
|
+
// Circular dependency (direct)
|
|
150
|
+
// Task #1 blocks Task #2
|
|
151
|
+
{
|
|
152
|
+
action: "add_dependency",
|
|
153
|
+
blocker_task_id: 2,
|
|
154
|
+
blocked_task_id: 1
|
|
155
|
+
}
|
|
156
|
+
// Error: "Circular dependency detected: Task #2 already blocks Task #1"
|
|
157
|
+
|
|
158
|
+
// Archived task
|
|
159
|
+
{
|
|
160
|
+
action: "add_dependency",
|
|
161
|
+
blocker_task_id: 10, // archived
|
|
162
|
+
blocked_task_id: 2
|
|
163
|
+
}
|
|
164
|
+
// Error: "Cannot add dependency: Task #10 is archived"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### remove_dependency
|
|
168
|
+
|
|
169
|
+
Remove a blocking relationship between two tasks.
|
|
170
|
+
|
|
171
|
+
**Parameters:**
|
|
172
|
+
- `action`: "remove_dependency" (required)
|
|
173
|
+
- `blocker_task_id` (required, number): Task ID that blocks
|
|
174
|
+
- `blocked_task_id` (required, number): Task ID that is blocked
|
|
175
|
+
|
|
176
|
+
**Idempotent:** Succeeds silently if dependency doesn't exist.
|
|
177
|
+
|
|
178
|
+
**Example:**
|
|
179
|
+
```javascript
|
|
180
|
+
{
|
|
181
|
+
action: "remove_dependency",
|
|
182
|
+
blocker_task_id: 1,
|
|
183
|
+
blocked_task_id: 2
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Response:**
|
|
188
|
+
```javascript
|
|
189
|
+
{
|
|
190
|
+
success: true,
|
|
191
|
+
message: "Dependency removed: Task #1 no longer blocks Task #2"
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Use Cases:**
|
|
196
|
+
- Task completed early (unblock dependent tasks)
|
|
197
|
+
- Requirements changed (dependency no longer needed)
|
|
198
|
+
- Refactoring workflow (restructure task order)
|
|
199
|
+
|
|
200
|
+
### get_dependencies
|
|
201
|
+
|
|
202
|
+
Query dependencies for a task bidirectionally.
|
|
203
|
+
|
|
204
|
+
**Parameters:**
|
|
205
|
+
- `action`: "get_dependencies" (required)
|
|
206
|
+
- `task_id` (required, number): Task to query dependencies for
|
|
207
|
+
- `include_details` (optional, boolean): Include full task metadata (default: false)
|
|
208
|
+
|
|
209
|
+
**Example (Metadata-Only):**
|
|
210
|
+
```javascript
|
|
211
|
+
{
|
|
212
|
+
action: "get_dependencies",
|
|
213
|
+
task_id: 2
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Response (Metadata-Only):**
|
|
218
|
+
```javascript
|
|
219
|
+
{
|
|
220
|
+
task_id: 2,
|
|
221
|
+
blockers: [1, 3], // Task IDs only
|
|
222
|
+
blocking: [5, 7] // Task IDs only
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Example (With Details):**
|
|
227
|
+
```javascript
|
|
228
|
+
{
|
|
229
|
+
action: "get_dependencies",
|
|
230
|
+
task_id: 2,
|
|
231
|
+
include_details: true
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Response (With Details):**
|
|
236
|
+
```javascript
|
|
237
|
+
{
|
|
238
|
+
task_id: 2,
|
|
239
|
+
blockers: [
|
|
240
|
+
{
|
|
241
|
+
task_id: 1,
|
|
242
|
+
title: "Implement JWT authentication",
|
|
243
|
+
status: "in_progress",
|
|
244
|
+
priority: "high"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
task_id: 3,
|
|
248
|
+
title: "Design user schema",
|
|
249
|
+
status: "done",
|
|
250
|
+
priority: "medium"
|
|
251
|
+
}
|
|
252
|
+
],
|
|
253
|
+
blocking: [
|
|
254
|
+
{
|
|
255
|
+
task_id: 5,
|
|
256
|
+
title: "Add profile page",
|
|
257
|
+
status: "todo",
|
|
258
|
+
priority: "medium"
|
|
259
|
+
}
|
|
260
|
+
]
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Validation Rules
|
|
265
|
+
|
|
266
|
+
### 1. No Self-Dependencies
|
|
267
|
+
|
|
268
|
+
Tasks cannot block themselves.
|
|
269
|
+
|
|
270
|
+
```javascript
|
|
271
|
+
// ❌ Invalid
|
|
272
|
+
{
|
|
273
|
+
action: "add_dependency",
|
|
274
|
+
blocker_task_id: 1,
|
|
275
|
+
blocked_task_id: 1
|
|
276
|
+
}
|
|
277
|
+
// Error: "Self-dependency not allowed"
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 2. No Direct Circular Dependencies
|
|
281
|
+
|
|
282
|
+
If Task A blocks Task B, then Task B cannot block Task A.
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
// Existing: Task #1 blocks Task #2
|
|
286
|
+
|
|
287
|
+
// ❌ Invalid
|
|
288
|
+
{
|
|
289
|
+
action: "add_dependency",
|
|
290
|
+
blocker_task_id: 2,
|
|
291
|
+
blocked_task_id: 1
|
|
292
|
+
}
|
|
293
|
+
// Error: "Circular dependency detected: Task #2 already blocks Task #1"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 3. No Transitive Circular Dependencies
|
|
297
|
+
|
|
298
|
+
Prevents cycles in dependency chains.
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
// Existing dependencies:
|
|
302
|
+
// Task #1 blocks Task #2
|
|
303
|
+
// Task #2 blocks Task #3
|
|
304
|
+
|
|
305
|
+
// ❌ Invalid (would create cycle)
|
|
306
|
+
{
|
|
307
|
+
action: "add_dependency",
|
|
308
|
+
blocker_task_id: 3,
|
|
309
|
+
blocked_task_id: 1
|
|
310
|
+
}
|
|
311
|
+
// Error: "Circular dependency detected: Task #3 → 1 → 2 → 3"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Cycle Detection Algorithm:**
|
|
315
|
+
- Uses recursive CTE (Common Table Expression)
|
|
316
|
+
- Traverses dependency chain from blocked task
|
|
317
|
+
- Detects if blocker appears in chain
|
|
318
|
+
- Depth limit: 100 levels (prevents infinite loops)
|
|
319
|
+
|
|
320
|
+
### 4. Both Tasks Must Exist
|
|
321
|
+
|
|
322
|
+
Both blocker and blocked tasks must exist in the database.
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
// ❌ Invalid
|
|
326
|
+
{
|
|
327
|
+
action: "add_dependency",
|
|
328
|
+
blocker_task_id: 999, // doesn't exist
|
|
329
|
+
blocked_task_id: 2
|
|
330
|
+
}
|
|
331
|
+
// Error: "Blocker task #999 not found"
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### 5. Neither Task Can Be Archived
|
|
335
|
+
|
|
336
|
+
Archived tasks cannot participate in dependencies.
|
|
337
|
+
|
|
338
|
+
```javascript
|
|
339
|
+
// ❌ Invalid
|
|
340
|
+
{
|
|
341
|
+
action: "add_dependency",
|
|
342
|
+
blocker_task_id: 1,
|
|
343
|
+
blocked_task_id: 10 // archived
|
|
344
|
+
}
|
|
345
|
+
// Error: "Cannot add dependency: Task #10 is archived"
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**Rationale:** Archived tasks are completed/inactive. Dependencies only apply to active workflow.
|
|
349
|
+
|
|
350
|
+
## Circular Dependency Detection
|
|
351
|
+
|
|
352
|
+
### Algorithm Overview
|
|
353
|
+
|
|
354
|
+
sqlew uses a **recursive CTE (Common Table Expression)** to detect circular dependencies efficiently.
|
|
355
|
+
|
|
356
|
+
**Steps:**
|
|
357
|
+
1. Start from the task that would be blocked
|
|
358
|
+
2. Follow the chain of dependencies recursively
|
|
359
|
+
3. Check if the blocker appears anywhere in the chain
|
|
360
|
+
4. If yes, reject with detailed cycle path
|
|
361
|
+
|
|
362
|
+
### SQL Implementation
|
|
363
|
+
|
|
364
|
+
```sql
|
|
365
|
+
WITH RECURSIVE dependency_chain AS (
|
|
366
|
+
-- Base case: Start from blocked task
|
|
367
|
+
SELECT blocked_task_id as task_id, 1 as depth
|
|
368
|
+
FROM t_task_dependencies
|
|
369
|
+
WHERE blocker_task_id = ?
|
|
370
|
+
|
|
371
|
+
UNION ALL
|
|
372
|
+
|
|
373
|
+
-- Recursive case: Follow dependency chain
|
|
374
|
+
SELECT d.blocked_task_id, dc.depth + 1
|
|
375
|
+
FROM t_task_dependencies d
|
|
376
|
+
JOIN dependency_chain dc ON d.blocker_task_id = dc.task_id
|
|
377
|
+
WHERE dc.depth < 100 -- Prevent infinite loops
|
|
378
|
+
)
|
|
379
|
+
SELECT task_id FROM dependency_chain WHERE task_id = ?
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Example: Transitive Cycle
|
|
383
|
+
|
|
384
|
+
```javascript
|
|
385
|
+
// Existing dependencies:
|
|
386
|
+
// Task #1 blocks Task #2
|
|
387
|
+
// Task #2 blocks Task #3
|
|
388
|
+
// Task #3 blocks Task #4
|
|
389
|
+
|
|
390
|
+
// Attempt to create cycle:
|
|
391
|
+
{
|
|
392
|
+
action: "add_dependency",
|
|
393
|
+
blocker_task_id: 4,
|
|
394
|
+
blocked_task_id: 1
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Detection process:
|
|
398
|
+
// 1. Start from Task #1 (would be blocked)
|
|
399
|
+
// 2. Follow chain: 1 → 2 → 3 → 4
|
|
400
|
+
// 3. Found Task #4 in chain (the blocker)
|
|
401
|
+
// 4. Reject with path
|
|
402
|
+
|
|
403
|
+
// Error message:
|
|
404
|
+
"Circular dependency detected: Task #4 → 1 → 2 → 3 → 4"
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Performance Characteristics
|
|
408
|
+
|
|
409
|
+
- **Time Complexity:** O(D) where D is dependency depth
|
|
410
|
+
- **Depth Limit:** 100 levels (prevents runaway recursion)
|
|
411
|
+
- **Index Support:** `idx_task_deps_blocked` on `blocked_task_id`
|
|
412
|
+
- **Typical Depth:** 2-5 levels in real workflows
|
|
413
|
+
|
|
414
|
+
## Enhanced Query Actions
|
|
415
|
+
|
|
416
|
+
### list (Enhanced)
|
|
417
|
+
|
|
418
|
+
**New Parameter:**
|
|
419
|
+
- `include_dependency_counts` (optional, boolean): Add dependency counts to metadata
|
|
420
|
+
|
|
421
|
+
**Example:**
|
|
422
|
+
```javascript
|
|
423
|
+
{
|
|
424
|
+
action: "list",
|
|
425
|
+
status: "in_progress",
|
|
426
|
+
include_dependency_counts: true
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Response:**
|
|
431
|
+
```javascript
|
|
432
|
+
{
|
|
433
|
+
tasks: [
|
|
434
|
+
{
|
|
435
|
+
task_id: 2,
|
|
436
|
+
title: "Add user profile page",
|
|
437
|
+
status: "in_progress",
|
|
438
|
+
priority: "medium",
|
|
439
|
+
blocked_by_count: 2, // 2 tasks block this
|
|
440
|
+
blocking_count: 1 // This blocks 1 task
|
|
441
|
+
},
|
|
442
|
+
// ... more tasks
|
|
443
|
+
],
|
|
444
|
+
count: 1
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Use Cases:**
|
|
449
|
+
- Identify bottleneck tasks (high `blocking_count`)
|
|
450
|
+
- Find blocked tasks (high `blocked_by_count`)
|
|
451
|
+
- Prioritize unblocking tasks
|
|
452
|
+
|
|
453
|
+
### get (Enhanced)
|
|
454
|
+
|
|
455
|
+
**New Parameter:**
|
|
456
|
+
- `include_dependencies` (optional, boolean): Include full dependency arrays
|
|
457
|
+
|
|
458
|
+
**Example:**
|
|
459
|
+
```javascript
|
|
460
|
+
{
|
|
461
|
+
action: "get",
|
|
462
|
+
task_id: 2,
|
|
463
|
+
include_dependencies: true
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Response:**
|
|
468
|
+
```javascript
|
|
469
|
+
{
|
|
470
|
+
task: {
|
|
471
|
+
task_id: 2,
|
|
472
|
+
title: "Add user profile page",
|
|
473
|
+
// ... other task fields
|
|
474
|
+
dependencies: {
|
|
475
|
+
blockers: [1, 3], // Task IDs blocking this
|
|
476
|
+
blocking: [5, 7] // Task IDs this blocks
|
|
477
|
+
},
|
|
478
|
+
linked_decisions: [...],
|
|
479
|
+
linked_constraints: [...],
|
|
480
|
+
linked_files: [...]
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
**Token Efficiency:**
|
|
486
|
+
- Metadata-only by default (just IDs)
|
|
487
|
+
- Use `get_dependencies` with `include_details` for full info
|
|
488
|
+
|
|
489
|
+
## Usage Examples
|
|
490
|
+
|
|
491
|
+
### Sequential Feature Development
|
|
492
|
+
|
|
493
|
+
```javascript
|
|
494
|
+
// Create tasks
|
|
495
|
+
{action: "create", title: "Implement JWT auth"}
|
|
496
|
+
// Returns: {task_id: 1}
|
|
497
|
+
|
|
498
|
+
{action: "create", title: "Add user profile page"}
|
|
499
|
+
// Returns: {task_id: 2}
|
|
500
|
+
|
|
501
|
+
{action: "create", title: "Implement settings page"}
|
|
502
|
+
// Returns: {task_id: 3}
|
|
503
|
+
|
|
504
|
+
// Add dependencies (auth must complete first)
|
|
505
|
+
{action: "add_dependency", blocker_task_id: 1, blocked_task_id: 2}
|
|
506
|
+
{action: "add_dependency", blocker_task_id: 1, blocked_task_id: 3}
|
|
507
|
+
|
|
508
|
+
// Query what's blocked by auth
|
|
509
|
+
{action: "get_dependencies", task_id: 1}
|
|
510
|
+
// Returns:
|
|
511
|
+
// blockers: []
|
|
512
|
+
// blocking: [2, 3] // Profile and settings wait
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Multi-Layer Infrastructure
|
|
516
|
+
|
|
517
|
+
```javascript
|
|
518
|
+
// Create infrastructure tasks
|
|
519
|
+
{action: "create", title: "Setup PostgreSQL", layer: "data"}
|
|
520
|
+
// Returns: {task_id: 10}
|
|
521
|
+
|
|
522
|
+
{action: "create", title: "Create user schema", layer: "data"}
|
|
523
|
+
// Returns: {task_id: 11}
|
|
524
|
+
|
|
525
|
+
{action: "create", title: "Implement auth service", layer: "business"}
|
|
526
|
+
// Returns: {task_id: 12}
|
|
527
|
+
|
|
528
|
+
{action: "create", title: "Add login UI", layer: "presentation"}
|
|
529
|
+
// Returns: {task_id: 13}
|
|
530
|
+
|
|
531
|
+
// Add layer dependencies (bottom-up)
|
|
532
|
+
{action: "add_dependency", blocker_task_id: 10, blocked_task_id: 11}
|
|
533
|
+
{action: "add_dependency", blocker_task_id: 11, blocked_task_id: 12}
|
|
534
|
+
{action: "add_dependency", blocker_task_id: 12, blocked_task_id: 13}
|
|
535
|
+
|
|
536
|
+
// Result: data → business → presentation
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### API Contract Dependencies
|
|
540
|
+
|
|
541
|
+
```javascript
|
|
542
|
+
// Create API contract task
|
|
543
|
+
{action: "create", title: "Define REST API contract"}
|
|
544
|
+
// Returns: {task_id: 20}
|
|
545
|
+
|
|
546
|
+
// Create implementation tasks
|
|
547
|
+
{action: "create", title: "Implement server endpoints"}
|
|
548
|
+
// Returns: {task_id: 21}
|
|
549
|
+
|
|
550
|
+
{action: "create", title: "Implement client SDK"}
|
|
551
|
+
// Returns: {task_id: 22}
|
|
552
|
+
|
|
553
|
+
// Both implementations depend on contract
|
|
554
|
+
{action: "add_dependency", blocker_task_id: 20, blocked_task_id: 21}
|
|
555
|
+
{action: "add_dependency", blocker_task_id: 20, blocked_task_id: 22}
|
|
556
|
+
|
|
557
|
+
// Query contract's impact
|
|
558
|
+
{action: "get_dependencies", task_id: 20, include_details: true}
|
|
559
|
+
// blocking: [
|
|
560
|
+
// {task_id: 21, title: "Implement server endpoints", ...},
|
|
561
|
+
// {task_id: 22, title: "Implement client SDK", ...}
|
|
562
|
+
// ]
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Finding Bottlenecks
|
|
566
|
+
|
|
567
|
+
```javascript
|
|
568
|
+
// List all in-progress tasks with dependency counts
|
|
569
|
+
{
|
|
570
|
+
action: "list",
|
|
571
|
+
status: "in_progress",
|
|
572
|
+
include_dependency_counts: true
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// Response shows blocking_count
|
|
576
|
+
// High blocking_count = bottleneck (many tasks waiting)
|
|
577
|
+
// Prioritize completing these first
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### Unblocking Workflow
|
|
581
|
+
|
|
582
|
+
```javascript
|
|
583
|
+
// Task #1 completed - remove dependencies to unblock
|
|
584
|
+
{action: "update", task_id: 1, new_status: "done"}
|
|
585
|
+
|
|
586
|
+
// Option 1: Let CASCADE delete handle it (tasks auto-unblock)
|
|
587
|
+
{action: "archive", task_id: 1}
|
|
588
|
+
// Dependencies automatically removed
|
|
589
|
+
|
|
590
|
+
// Option 2: Manually remove specific dependencies
|
|
591
|
+
{action: "remove_dependency", blocker_task_id: 1, blocked_task_id: 2}
|
|
592
|
+
{action: "remove_dependency", blocker_task_id: 1, blocked_task_id: 3}
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
## Best Practices
|
|
596
|
+
|
|
597
|
+
### When to Use Dependencies
|
|
598
|
+
|
|
599
|
+
**✅ Use Dependencies For:**
|
|
600
|
+
- Sequential technical requirements (DB before ORM)
|
|
601
|
+
- Ordered feature rollout (API before UI)
|
|
602
|
+
- Cross-layer dependencies (data → business → presentation)
|
|
603
|
+
- Shared infrastructure (auth before protected routes)
|
|
604
|
+
|
|
605
|
+
**❌ Don't Use Dependencies For:**
|
|
606
|
+
- Parallel/independent features
|
|
607
|
+
- Organizational preferences (not technical blockers)
|
|
608
|
+
- Overly granular tasks (creates complex graphs)
|
|
609
|
+
- Long-term strategic planning (use decisions instead)
|
|
610
|
+
|
|
611
|
+
### Dependency Graph Structure
|
|
612
|
+
|
|
613
|
+
**Good: Linear/Tree Structures**
|
|
614
|
+
```
|
|
615
|
+
Task #1 (root)
|
|
616
|
+
├── Task #2
|
|
617
|
+
└── Task #3
|
|
618
|
+
├── Task #4
|
|
619
|
+
└── Task #5
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Bad: Dense Mesh**
|
|
623
|
+
```
|
|
624
|
+
Task #1 ←→ Task #2 ←→ Task #3
|
|
625
|
+
↓ ↓ ↓
|
|
626
|
+
Task #4 ←→ Task #5 ←→ Task #6
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
**Guidelines:**
|
|
630
|
+
- Keep dependency chains short (2-5 levels)
|
|
631
|
+
- Avoid creating many-to-many relationships
|
|
632
|
+
- Use tags for loose grouping, dependencies for hard blocking
|
|
633
|
+
|
|
634
|
+
### Handling Completed Dependencies
|
|
635
|
+
|
|
636
|
+
**Option 1: Archive Completed Tasks**
|
|
637
|
+
```javascript
|
|
638
|
+
// CASCADE deletion automatically removes dependencies
|
|
639
|
+
{action: "archive", task_id: 1}
|
|
640
|
+
// Task #2 and #3 automatically unblocked
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
**Option 2: Keep Task, Remove Dependencies**
|
|
644
|
+
```javascript
|
|
645
|
+
// Keep task history but unblock dependents
|
|
646
|
+
{action: "update", task_id: 1, new_status: "done"}
|
|
647
|
+
{action: "remove_dependency", blocker_task_id: 1, blocked_task_id: 2}
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
**Recommendation:** Archive completed tasks to keep task board clean and auto-unblock dependents.
|
|
651
|
+
|
|
652
|
+
### Avoiding Deadlocks
|
|
653
|
+
|
|
654
|
+
**Problem: Circular Dependencies**
|
|
655
|
+
```javascript
|
|
656
|
+
// ❌ Creates deadlock
|
|
657
|
+
Task #1 blocks Task #2
|
|
658
|
+
Task #2 blocks Task #1
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
**Solution: Validation Prevents This**
|
|
662
|
+
- sqlew automatically rejects circular dependencies
|
|
663
|
+
- No manual deadlock resolution needed
|
|
664
|
+
|
|
665
|
+
**Best Practice:**
|
|
666
|
+
- Plan dependency graph before creating dependencies
|
|
667
|
+
- Use `get_dependencies` to visualize chains
|
|
668
|
+
- Keep chains unidirectional (no cycles)
|
|
669
|
+
|
|
670
|
+
### Token-Efficient Queries
|
|
671
|
+
|
|
672
|
+
**Metadata-Only (Recommended):**
|
|
673
|
+
```javascript
|
|
674
|
+
// Just IDs - minimal tokens
|
|
675
|
+
{action: "get_dependencies", task_id: 2}
|
|
676
|
+
// ~100 bytes total
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
**With Details (When Needed):**
|
|
680
|
+
```javascript
|
|
681
|
+
// Full task metadata
|
|
682
|
+
{action: "get_dependencies", task_id: 2, include_details: true}
|
|
683
|
+
// ~500-1000 bytes total
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
**Use Counts for Overview:**
|
|
687
|
+
```javascript
|
|
688
|
+
// List with counts - cheapest overview
|
|
689
|
+
{action: "list", include_dependency_counts: true}
|
|
690
|
+
// +16 bytes per task (2 integers)
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
## Token Efficiency
|
|
694
|
+
|
|
695
|
+
### Metadata-Only Queries
|
|
696
|
+
|
|
697
|
+
**Default Behavior:**
|
|
698
|
+
- `get_dependencies`: Returns task IDs only (4-8 bytes per ID)
|
|
699
|
+
- `list` with `include_dependency_counts`: Adds 2 integers (8 bytes)
|
|
700
|
+
- Minimal token consumption for workflow queries
|
|
701
|
+
|
|
702
|
+
**Example Comparison:**
|
|
703
|
+
```javascript
|
|
704
|
+
// Metadata-only
|
|
705
|
+
{task_id: 2, blockers: [1, 3], blocking: [5]}
|
|
706
|
+
// ~30 bytes
|
|
707
|
+
|
|
708
|
+
// With details
|
|
709
|
+
{
|
|
710
|
+
task_id: 2,
|
|
711
|
+
blockers: [
|
|
712
|
+
{task_id: 1, title: "Implement JWT auth", status: "in_progress", priority: "high"},
|
|
713
|
+
{task_id: 3, title: "Design schema", status: "done", priority: "medium"}
|
|
714
|
+
],
|
|
715
|
+
blocking: [
|
|
716
|
+
{task_id: 5, title: "Add profile page", status: "todo", priority: "medium"}
|
|
717
|
+
]
|
|
718
|
+
}
|
|
719
|
+
// ~250 bytes
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
**Savings:** ~88% token reduction with metadata-only approach.
|
|
723
|
+
|
|
724
|
+
### Database Efficiency
|
|
725
|
+
|
|
726
|
+
**Schema Optimizations:**
|
|
727
|
+
- Composite primary key (`blocker_task_id`, `blocked_task_id`)
|
|
728
|
+
- Index on `blocked_task_id` for reverse queries
|
|
729
|
+
- CASCADE deletion (no orphaned dependencies)
|
|
730
|
+
- Minimal storage (3 integers per dependency)
|
|
731
|
+
|
|
732
|
+
**Query Performance:**
|
|
733
|
+
- O(1) lookup for direct dependencies
|
|
734
|
+
- O(D) for circular detection (D = depth)
|
|
735
|
+
- Index-backed bidirectional queries
|
|
736
|
+
|
|
737
|
+
## Related Documentation
|
|
738
|
+
|
|
739
|
+
- [TASK_ACTIONS.md](TASK_ACTIONS.md) - Complete action reference
|
|
740
|
+
- [TASK_LINKING.md](TASK_LINKING.md) - Decision/constraint/file linking
|
|
741
|
+
- [TASK_OVERVIEW.md](TASK_OVERVIEW.md) - Task system overview
|
|
742
|
+
- [WORKFLOWS.md](WORKFLOWS.md) - Multi-agent coordination patterns
|
|
743
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) - Database schema details
|
|
744
|
+
|
|
745
|
+
---
|
|
746
|
+
|
|
747
|
+
**Version History:**
|
|
748
|
+
- 3.2.0 (2025-10-18): Initial release of task dependency feature
|