Task Selection¶
Task selection determines which task cub executes next. The algorithm ensures work happens in the right order while respecting dependencies and priorities.
Selection Algorithm¶
When cub needs a task, it follows this process:
flowchart TD
start[Get All Tasks] --> filter_status[Filter: status == open]
filter_status --> filter_deps[Filter: all dependencies closed]
filter_deps --> filter_epic{Epic<br/>Filter?}
filter_epic -->|Yes| apply_epic[Filter: parent == epic]
filter_epic -->|No| filter_label
apply_epic --> filter_label{Label<br/>Filter?}
filter_label -->|Yes| apply_label[Filter: has label]
filter_label -->|No| sort
apply_label --> sort[Sort by Priority]
sort --> select[Select First Task]
select --> done([Return Task])
style start fill:#4CAF50,color:white
style done fill:#4CAF50,color:white Step by Step¶
- Get all tasks from the backend
- Filter by status: Only
opentasks are considered - Filter by dependencies: All
dependsOntasks must beclosed - Apply epic filter: If
--epicspecified, only tasks with matchingparent - Apply label filter: If
--labelspecified, only tasks with that label - Sort by priority: P0 first, then P1, P2, P3, P4
- Select first: Take the highest-priority ready task
Priority Ordering¶
Tasks are sorted by priority, with lower numbers meaning higher urgency:
| Priority | Description | Use Case |
|---|---|---|
| P0 | Critical | Blocking issues, security fixes |
| P1 | High | Important features, urgent bugs |
| P2 | Medium | Standard work (default) |
| P3 | Low | Nice-to-haves, minor improvements |
| P4 | Backlog | Future work, ideas |
Priority Examples¶
Given these tasks:
| ID | Title | Priority | Dependencies | Status |
|---|---|---|---|---|
| A | Fix security hole | P0 | - | open |
| B | Add login page | P1 | - | open |
| C | Update readme | P3 | - | open |
| D | Implement auth | P0 | B | open |
Selection order:
- A (P0, no deps)
- B (P1, no deps) - D is P0 but blocked by B
- D (P0, B now closed)
- C (P3, no deps)
Dependencies Override Priority
Task D has P0 priority but runs after B (P1) because D depends on B. Dependencies always take precedence.
Dependency Resolution¶
A task is ready when all its dependencies are closed.
Checking Dependencies¶
# Beads - show what blocks a task
bd show cub-042 --json | jq '.blocks'
# JSON - show dependsOn
jq '.tasks[] | select(.id == "myproj-042") | .dependsOn' prd.json
Dependency States¶
flowchart LR
A[Task A<br/>closed] --> B[Task B<br/>ready]
C[Task C<br/>open] --> D[Task D<br/>blocked]
style A fill:#9E9E9E
style B fill:#4CAF50,color:white
style C fill:#FFC107
style D fill:#FF5722,color:white - Task B is ready (depends on A, which is closed)
- Task D is blocked (depends on C, which is open)
Epic Filtering¶
Limit execution to tasks within a specific epic:
Only tasks where parent == "cub-epic-001" are considered.
Epic Hierarchy¶
Epics can contain nested epics:
cub-epic-001 (Q1 Features)
+-- cub-epic-002 (User Auth)
| +-- cub-task-001
| +-- cub-task-002
+-- cub-epic-003 (Dashboard)
+-- cub-task-003
To run all of Q1:
To run only Auth tasks:
Label Filtering¶
Run only tasks with specific labels:
Common Label Patterns¶
| Label | Purpose |
|---|---|
frontend | UI/UX work |
backend | Server-side work |
model:haiku | Use fast model |
model:opus | Use most capable model |
urgent | High priority |
needs-review | Requires human check |
Model Selection via Labels¶
Use model: labels to route tasks to specific AI models:
When cub runs task cub-042, it passes haiku to the harness. This helps manage costs:
| Model | Best For | Token Cost |
|---|---|---|
haiku | Simple tasks, docs, tests | Lowest |
sonnet | Standard development | Medium |
opus | Complex architecture, debugging | Highest |
Selection with Model Labels¶
# Run all tasks, respecting model labels
cub run
# Override model for all tasks
cub run --model sonnet
CLI flag overrides task labels.
Viewing Ready Tasks¶
Before running, see what's ready:
# List ready tasks
cub run --ready
# With epic filter
cub run --ready --epic cub-epic-001
# With label filter
cub run --ready --label backend
Output:
Ready Tasks
+----------+----------+---------+---------------------------+---------+
| ID | Priority | Type | Title | Labels |
+----------+----------+---------+---------------------------+---------+
| cub-042 | P1 | feature | Add user authentication | backend |
| cub-043 | P2 | task | Write auth tests | backend |
| cub-044 | P2 | feature | Add login page | frontend|
+----------+----------+---------+---------------------------+---------+
Total: 3 ready tasks
Running Specific Tasks¶
Bypass selection and run a specific task:
This:
- Ignores priority ordering
- Ignores label/epic filters
- Still checks the task is open
- Still executes only that task
Use for:
- Testing a specific task
- Rerunning a failed task
- Working on a particular piece in isolation
Selection in Parallel Mode¶
When running parallel (cub run --parallel 3):
- Find all ready tasks (same algorithm as above)
- Filter to independent tasks (no shared dependencies)
- Take up to N tasks
- Create worktrees and run concurrently
See Parallel Execution for details.
Troubleshooting¶
No ready tasks but open tasks exist
Check dependencies:
Ensure blocking tasks are closed.Wrong task selected
Check priorities:
Verify filters aren't excluding expected tasks.Task keeps getting skipped
Ensure dependencies are satisfied and status is open:
Label filter not working
Verify label is set correctly:
Labels are case-sensitive.Best Practices¶
- Use P0 sparingly: Reserve for truly critical work
- Set P2 as default: Most tasks should be medium priority
- Chain with dependencies: Use deps for order, not just priority
- Label consistently: Establish label conventions in your team
- Check ready before running: Use
--readyto verify selection
Next Steps¶
-
How tasks are marked complete and verified.
-
Control execution order with dependencies.