Owen is a decision engine that runs continuously and picks the highest-value next action. Here's how it works.

The Big Picture

┌─────────────────────────────────────────────────────────┐
│                    External Services                     │
│  Gmail API │ GitHub API │ Jira API │ Google Calendar    │
└─────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│                      Owen Core                           │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐  │
│  │  Heartbeat  │───▶│   Gather    │───▶│   Decide    │  │
│  │   (60s)     │    │   State     │    │   Engine    │  │
│  └─────────────┘    └─────────────┘    └─────────────┘  │
│                                               │          │
│                                               ▼          │
│                                        ┌─────────────┐  │
│                                        │   Actions   │  │
│                                        └─────────────┘  │
└─────────────────────────────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────┐
│                     Local State                          │
│      tasks/    │    memory/    │    heartbeat-state     │
└─────────────────────────────────────────────────────────┘

Component Breakdown

Heartbeat Loop

The main loop runs every 60 seconds (5 seconds in dev mode). It's deliberately simple:

while True:
    state = gather_state()
    action = decide(state)
    execute(action)
    sleep(interval)

No event-driven complexity. No message queues. Just a loop.

State Gatherer

Collects context from everywhere:

  • Gmail — unread count, important emails
  • GitHub — PRs awaiting review, CI status
  • Jira — tasks in each state
  • Calendar — upcoming meetings
  • Local tasks — files in tasks/open, tasks/doing, etc.

Outputs a unified state JSON that the decision engine consumes.

Decision Engine

A 14-rule priority ladder. First match wins:

  1. CI red / incident → Fix it
  2. Teammate blocked → Unblock them
  3. Active task → Continue it
  4. Meeting in 2h → Prep
  5. PR feedback → Address it
  6. Tasks in review → Review them
  7. PR review requested → Do it
  8. Email eligible → Triage
  9. Slack eligible → Check
  10. Open tasks → Pick one
  11. Uncommitted changes → Commit
  12. Generate tasks → Expand queue
  13. Surface debt → Flag tech debt
  14. Idle → Nothing to do

No AI in the decision layer. Pure if/else logic. Fast, predictable, debuggable.

Actions

Execute the decision:

  • Gmail — archive, flag, draft responses
  • GitHub — comment on PRs, approve/request changes
  • Jira — transition states, add comments
  • Local — move task files, update memory

Actions update state, which affects the next decision cycle.

Why This Works

Deterministic > smart. The decision engine doesn't try to be clever. It follows rules I can debug.

Local > cloud. Everything runs on my machine. No latency, no API limits, no privacy concerns.

Stateless decisions. Each heartbeat is independent. Crash recovery is trivial — just restart.

Observable. Every decision is logged. I can replay any cycle and understand exactly why it made that choice.

The Numbers

  • 360 tests covering edge cases
  • 8 packages (core, heartbeat, decision, owenai, actions, updater, service, dashboard)
  • 7 integrations (Gmail, GitHub, Jira, Calendar, Slack, X, local tasks)
  • 10 phases shipped over 4 days

The full source is at github.com/owendevereaux/owen.

React to this post: