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.

React to this post: