Skip to main content
← Back to Work

This is a sample deliverable. It shows the structure and depth of technical documentation I produce. This is based on real documentation for a decision engine I built.

Heartbeat Decision Engine

Technical Documentation • Version 2.0 • Last updated March 2026

Overview

The Heartbeat Decision Engine is a single-action task picker that evaluates current state and returns exactly one action to take. It removes decision fatigue by encoding priorities once and letting the system decide what to work on next.

Key Concepts

  • Single Action: Always returns exactly one action, never a list
  • Priority Ladder: Actions evaluated in order; first eligible wins
  • Cooldowns: Prevents action spam by enforcing minimum intervals
  • State-Based: Decisions based on current git status, task counts, calendar, etc.

Quick Start

# Clone and run
git clone https://github.com/owendevereaux/heartbeat.git
cd heartbeat
./decide.py

# Output: A single action prompt to execute

Architecture

Data Flow

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”     ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”     ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  gather-state   │ ──▶ │    decide.py    │ ──▶ │  Single Action  │
│  (shell script) │     │ (priority eval) │     │   (execute it)  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜     ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜     ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
        │                       │                       │
        ā–¼                       ā–¼                       ā–¼
   JSON state             Priority ladder         Action prompt
   - git dirty?           - 16 conditions         - Human-readable
   - task counts          - First match wins      - Ready to execute
   - calendar             - Cooldown checks
   - integrations

File Structure

FilePurpose
decide.pyMain decision engine (~200 LOC)
gather-state.shCollects current state as JSON
actions.jsonAction catalog with prompts and priorities
memory/heartbeat-state.jsonPersistent cooldown and state tracking

API Reference

CLI Commands

./decide.py

Run the decision engine and return one action.

$ ./decide.py
Continue working on p1-fix-api-endpoint. You have uncommitted changes.

./decide.py --debug

Include full decision JSON for debugging.

$ ./decide.py --debug
{
  "action": "continue_active_task_dirty",
  "eligible_actions": ["continue_active_task_dirty", "pickup_open_task"],
  "rejected_actions": {"check_email": "cooldown not elapsed (14m remaining)"},
  "state": {"git_dirty": true, "doing_count": 1, "open_count": 8}
}

./decide.py --status

Show current state without making a decision.

./decide.py --run <action_id>

Force a specific action, bypassing eligibility checks.

$ ./decide.py --run check_email
Triage unread emails. Archive if no action needed, flag if urgent.

Configuration

Priority Ladder

Actions are evaluated in this order. First eligible action wins.

PriorityActionTriggers When
1fix_ciCI status is "failure"
2site_downSite health check fails
3unblock_teammateUrgent mention detected
4continue_active_task_dirtyTask in doing/ with uncommitted changes
5expand_workloadUnder max capacity, tasks available
6continue_active_task_cleanTask in doing/, clean git state
7prep_for_meetingMeeting within 2 hours
8check_emailUnread email + cooldown elapsed

Cooldowns

Minimum time between repeated actions. Edit in decide.py:

COOLDOWNS = {
    "email": 30,      # minutes
    "slack": 15,
    "status": 60,
    "expand_workload": 2,
}

Thresholds

MAX_CONCURRENT_TASKS = 3    # Max tasks in doing/
TARGET_OPEN_TASKS = 10      # Auto-generate when below this
MIN_OPEN_THRESHOLD = 9      # Trigger auto-generate below this

Troubleshooting

āŒ "No eligible actions found"

Cause: All actions are on cooldown or conditions not met.

Fix: Run ./decide.py --debug to see rejected actions and reasons. Check cooldowns in memory/heartbeat-state.json.

āŒ Same action repeating

Cause: Cooldown not being updated after action execution.

Fix: Ensure the action updates cooldown in state file. Check lastChecks timestamps.

āŒ State file corruption

Cause: Invalid JSON in state file.

Fix: Delete memory/heartbeat-state.json. A fresh state file will be created on next run.

Need documentation like this?

Clear technical docs that developers actually read. Architecture guides, API references, troubleshooting.

Let's Talk