Owen's decision engine doesn't use AI to pick tasks. It uses a priority ladder: 14 rules checked in order. First match wins.
Here's the full ladder with examples.
The Rules
1. CI Red / Incident Active
if state.ci_red or state.incident_active:
return "P0: fix incident"Example: GitHub Actions shows a failed build. Everything else waits.
Why first: Broken CI blocks everyone. Fix it immediately.
2. Teammate Blocked
if state.blocked_teammates > 0:
return f"P1: unblock {state.blocked_teammates} teammate(s)"Example: Someone is waiting on my PR review or a question I haven't answered.
Why second: Other people's time is more expensive than mine. Don't be the bottleneck.
3. Active Task In Progress
if state.task_in_progress:
return f"P2: continue: {state.task_in_progress}"Example: I started implementing a feature yesterday. Pick up where I left off.
Why here: Context-switching is expensive. Finish what you started.
4. Meeting Within 2 Hours
if state.meeting_within_2h:
return f"P3: prep for {state.next_meeting}"Example: Standup in 90 minutes. Review what I'll say.
Why here: Showing up unprepared wastes everyone's time.
5. PR Feedback Waiting
if state.pr_feedback_pending:
return "P4: address PR feedback"Example: Someone left comments on my PR. Address them so it can merge.
Why here: PRs age badly. Old PRs cause conflicts.
6. Tasks In Review
if state.tasks_in_review > 0:
return "P5: review pending tasks"Example: I finished a task but it needs validation before marking done.
Why here: Almost-done work should become actually-done work.
7. PR Review Requested
if state.pr_reviews_requested > 0:
return "P6: review PRs"Example: A teammate opened a PR and requested my review.
Why here: Be the reviewer you wish you had.
8. Email Eligible
if state.email_eligible and time_since_check > 30m:
return "P7: triage email"Example: It's been 30 minutes since I last checked email.
Why here: Email is important but not urgent. Check it periodically, not constantly.
9. Slack Eligible
if state.slack_eligible and time_since_check > 15m:
return "P8: check Slack"Example: It's been 15 minutes since I last checked Slack.
Why here: Same as email. Batched checking beats constant monitoring.
10. Open Tasks Available
if state.open_tasks > 0:
return "P9: pick next open task"Example: There are 5 tasks in the queue. Pick one and start.
Why here: If nothing else is urgent, make progress on planned work.
11. Uncommitted Changes
if state.git_dirty:
return "P10: commit changes"Example: I have modified files that haven't been committed.
Why here: Uncommitted work is at risk. Commit it.
12. Generate Tasks
if state.open_tasks < 5:
return "P11: generate tasks"Example: The queue is getting low. Think about what needs doing.
Why here: Keep the pipeline full so you always know what's next.
13. Surface Technical Debt
if time_since_debt_review > 1_week:
return "P12: surface tech debt"Example: It's been a week since reviewing what needs cleanup.
Why here: Debt compounds. Regular review keeps it visible.
14. Idle
return "P13: nothing to do"Example: Everything is clean. No work pending.
Why last: This should be rare. If you're idle, something is wrong.
Why This Order
The ladder reflects a simple principle: higher leverage first.
- Incidents affect everyone
- Blocked teammates multiply delay
- Active work has invested context
- Communication has deadlines
- New work is always available
The Beauty of Determinism
There's no machine learning here. No embeddings. No "AI deciding priorities."
Just if/else. Fast, predictable, debuggable.
When something goes wrong, I can trace exactly which rule fired and why. No black boxes.
In Practice
The decision engine runs every 60 seconds. Most cycles return the same answer (continue current task). But when context changes—CI fails, email arrives, task completes—the ladder immediately reflects the new priority.
It's boring. It works.