# Milestone Summary: Owl Skill v1.0

**Project:** Owl Live Agent System
**Milestone:** v1.0
**Status:** In progress (4/6 phases complete, 2 remaining: Timed Pulses, Spine Supervisor)
**Generated:** 2026-03-29

---

## 1. Overview

The Owl Skill is a **zero-dependency inter-agent messaging system** for Claude Code. It lets Claude Code agents register file-based inboxes ("perches"), poll for messages, and communicate — using nothing but bash and coreutils. It runs on any machine with a shell: Linux, macOS, Windows via Git Bash.

On top of this messaging layer, the **Live Agent system** adds persistent background agents. A user starts a "live" session with an ID, and the system spawns a **Psyche** — an independent process that monitors the user's agent ("Self") through communal updates and sends contextual nudges ("pulses") when Self may have forgotten something.

**Core value:** Reliable, zero-dependency agent-to-agent messaging that just works.

### What v1.0 delivers today

- Hardened, race-free messaging (atomic writes, collision-resistant IDs, TOCTOU-safe polling)
- ANSI-colored terminal output (cyan for owl, orange for live) with compact Unicode symbols
- Auto-setup of environment variables and cleanup hooks on first use
- Live agent sessions with Self + Psyche (now launched as external `claude` CLI processes)
- Communal updates (COMMUNE) and contextual pulse nudges (PULSE)
- Psyche context persistence across process death
- Session auto-resume on restart
- One-command restart shortcuts (`/owl reboot`, `/live revive`)

### What's still coming in v1.0

- **Phase 3: Timed Pulses** — One-shot reminders at a specific future time (`/live timed-pulse`)
- **Phase 4: Spine Supervisor** — Process supervision that detects dead Psyches and notifies affected agents

---

## 2. Architecture

### System layers

```
+--------------------------------------------------+
|  Skill Layer (SKILL.md, LIVE-SKILL.md)           |  Teaches Claude Code agents what to do
+--------------------------------------------------+
|  Agent Layer (live.sh, psyche.md)                 |  Self/Psyche lifecycle, COMMUNEs, PULSEs
+--------------------------------------------------+
|  Messaging Layer (owl.sh)                         |  Perch lifecycle, message delivery, polling
+--------------------------------------------------+
|  Storage (~/.claude/owlery/)                      |  File-based IPC: directories, .msg files
+--------------------------------------------------+
```

### Key components

| Component | File | Purpose |
|-----------|------|---------|
| **owl.sh** | `owl.sh` (500 lines) | All messaging: setup, poll, deliver, reply, send, list, stop, cleanup, reboot, stash |
| **live.sh** | `live.sh` (500 lines) | Live agent lifecycle: start, stop, revive, commune, list, list-psyches, context persistence |
| **SKILL.md** | `SKILL.md` | Agent instructions for `/owl` commands |
| **LIVE-SKILL.md** | `LIVE-SKILL.md` | Agent instructions for `/live` commands |
| **psyche.md** | `psyche.md` | Psyche agent prompt template with `{{self_id}}`, `{{psyche_id}}`, `{{period}}` variables |
| **owl_agents.json** | `owl_agents.json` | `owl-psyche` agent definition for `claude --agents` |

### Data flow: message delivery

1. Agent B runs `$OWL poll <id> listen --setup` — creates `owlery/<id>/inbox/` + `ready` sentinel
2. Agent A runs `$OWL deliver <B-id> <A-id> <<< "message"` — atomic write via `mktemp` + `mv` into B's inbox
3. B's poll loop detects the `.msg` file, prints contents, deletes it (TOCTOU-safe: retries if file vanishes)
4. B parses the `__REPLY_TO__:<A-id>` header and processes the message body

### Data flow: Psyche external process

1. `$LIVE start <id>` builds agents JSON from `owl_agents.json` + substituted `psyche.md`
2. Launches a background wrapper loop that:
   - Creates the `claude` session: `claude -p --agents <json> --agent owl-psyche --name <session> --model sonnet --fallback-model opus`
   - Loops: `$OWL poll <psyche-id> --psyche --pulse-interval <period>` blocks until message or pulse
   - Feeds output to `claude -p --resume <session>` for processing
3. COMMUNEs arrive as owl messages; pulse triggers arrive from the `--pulse-interval` timer
4. The Psyche evaluates context and optionally sends a PULSE nudge to Self via `$OWL deliver`

---

## 3. Phases

### Phase 1: Foundation & Hardening (Complete)
**Goal:** Race-free messaging, ANSI output, auto-setup, live.sh scaffold

**What was built:**
- Atomic message writes (`mktemp` + `mv` in same directory for guaranteed atomic rename)
- Collision-resistant filenames (`date +%s%N` + PID + `$RANDOM`)
- TOCTOU-safe poll loop (`cat` with retry on vanished file)
- ANSI-colored output: cyan for owl (`_owl_status`), red for errors (`_err`)
- Auto-setup of `~/.claude/settings.json` with OWL/LIVE env vars and SessionEnd cleanup hook
- Session-scoped cleanup via `cleanup-session` command
- `live.sh` scaffold with Self registration and `/live list`

**Verification:** 12/12 must-haves passed. No gaps.

### Phase 2: Psyche Core (Complete)
**Goal:** Live agent sessions with Psyche spawn, COMMUNE/PULSE cycle, graceful stop

**What was built:**
- `--psyche` flag in owl.sh for hidden Psyche listeners
- Auto-setup poll (creates perch without `--setup` flag)
- COMMUNE delivery via `$LIVE commune` (format: `COMMUNE ({timestamp}): {message}`)
- Pulse timer integrated into poll via `--pulse-interval`
- PULSE delivery from Psyche to Self (format: `PULSE ({timestamp}): {reminders}`)
- `psyche.md` agent prompt template (99 lines, all template variables)
- Graceful stop: `$LIVE stop` kills Psyche then Self, no orphans
- Full `/live` documentation in SKILL.md with 4-step start flow, COMMUNE guidance, edge cases

**Verification:** 11/11 must-haves passed. One warning-level `local` misuse fixed.

### Phase 2.1: Live Skill Extraction (Complete)
**Goal:** Standalone `/live` skill file, separate from `/owl`

**What was built:**
- `LIVE-SKILL.md` as standalone skill with `name: live` frontmatter
- `SKILL.md` trimmed to owl-only content (145 lines)
- Bidirectional cross-references between skill files
- Updated `DEPLOY.md` with LIVE-SKILL.md in all file operations

**Verification:** 5/5 must-haves passed. No gaps.

### Phase 2.2: Owl & Live Hardening (Complete)
**Goal:** Race condition fixes, signal lifecycle, Psyche persistence, session resume, restart shortcuts

**What was built:**
- BUSY PID state prevents GC from cleaning perches between polls
- Signal traps: TERM/USR1 for graceful exit, USR2 for live status query
- Signal-based stop: `kill -USR1` → `sleep` → `kill -9` in all stop paths
- `/owl gsd-setup` for GSD project integration
- Listener intelligence: SKILL.md instructs naming subagents and checking background tasks
- Psyche context persistence: `context-save`, `psyche-download`, `clear-psyche`
- SessionStart hook: auto-detects dead listeners, outputs `OWL_RESUME` for Claude
- `/owl reboot`: one-command listener restart preserving all flags
- `/live revive`: one-command Self+Psyche restart
- `/owl stash`: persistent payload file for cross-context continuity

**Verification:** 13/13 must-haves passed. No gaps.

### Phase 3: Timed Pulses (Not started)
**Goal:** One-shot timed reminders via PULSE REQUEST/TIMED PULSE

### Phase 4: Spine Supervisor (Not started)
**Goal:** Spine/Touch process supervision for multi-agent deployments
**Risk:** Subagent nesting may be blocked — Spine must have fallback to absorb Touch

---

## 4. Key Decisions

| Decision | Rationale |
|----------|-----------|
| **External Psyche processes** | Psyches now launch as independent `claude -p` processes instead of in-session Agent subagents. Eliminates disruptive task notifications, survives `/clear`, decouples lifecycle from Self. |
| **Atomic writes via mktemp+mv** | Same-directory atomic rename guarantees concurrent readers never see partial messages |
| **ANSI color + Unicode symbols** | Scannable terminal output without emoji; cyan for owl, orange for live |
| **BUSY PID state** | Non-numeric `"pid":"BUSY"` in info.json prevents GC from cleaning perches in the re-poll gap |
| **Signal-first shutdown** | USR1 for graceful exit before force-kill-9; every stop path uses this pattern |
| **Foreground blocking polls** | Claude Code `run_in_background` has token-bomb bug (#11716); all loops use foreground sleep |
| **Session-scoped cleanup** | info.json includes `session_id`; SessionEnd hook cleans only that session's perches |
| **Psyche context persistence** | `~/.claude/psyche-contexts/{self_id}.md` survives process death; revived Psyches download prior context |
| **Generation tracking** | Counter file at `~/.claude/owlery/.psyche-gen-{id}` increments on each start/revive; session named `{id}-psyche-{gen}-{HH}-{MM}` |
| **No jq dependency** | Pure bash JSON escaping in `_json_escape()` to maintain zero-dependency constraint |

---

## 5. Requirements Traceability

**v1.0 requirements:** 49 total
- **Complete:** 37 (HARD-01..03, FMT-01..03, SETUP-01..03, LIVE-01..11, SKILL-01..03, EXTRACT-01..04, HARDEN-01..10)
- **Pending:** 12 (TPULSE-01..03, SPINE-01..09)

All completed requirements have been verified against the codebase with line-number evidence in their respective VERIFICATION.md files.

**Out of scope (intentional):**
- Network-based messaging (local filesystem IPC only)
- Encrypted messages (same-machine, same-user)
- Persistent message queues (messages are ephemeral)
- Multi-hop routing (direct point-to-point only)
- GUI/web dashboard (zero-dependency constraint)
- Automatic Psyche restart by Spine (Self owns its Psyche)

---

## 6. Tech Debt & Known Issues

| Item | Severity | Details |
|------|----------|---------|
| **Subagent nesting uncertainty** | Medium | Spine (Phase 4) spawning Touch as sub-subagent may be blocked. Fallback: Spine absorbs Touch. Must test empirically. |
| **COMMUNE context growth** | Low | Psyche context may grow large over long sessions. `context-save` limits to 2000 chars, but `--resume` session context is unbounded. Monitor in practice. |
| **`sed`-based JSON patching** | Low | Auto-setup patches `settings.json` via `sed` — fragile for non-standard formatting. Works in practice. |
| **No automated tests** | Low | All verification is code-inspection-based. No test framework or test suite. Acceptable for a 2-file bash project. |
| **Windows `kill` process group** | Low | `kill -- -$PID` for process group kill may not work on all Git Bash versions. Fallback `kill $PID` catches most cases. |

---

## 7. Getting Started

### Install

```bash
# Clone or copy the skill files
cp SKILL.md LIVE-SKILL.md owl.sh live.sh psyche.md owl_agents.json ~/.claude/skills/owl/
cp LIVE-SKILL.md ~/.claude/skills/live/SKILL.md
chmod +x ~/.claude/skills/owl/owl.sh ~/.claude/skills/owl/live.sh
```

Environment auto-configures on first use. Or manually add to `~/.claude/settings.json`:
```json
{
  "env": {
    "OWL": "bash ~/.claude/skills/owl/owl.sh",
    "LIVE": "bash ~/.claude/skills/owl/live.sh"
  }
}
```

### Basic messaging

```bash
# Agent A: listen for messages
$OWL poll agentA listen --setup

# Agent B: send a message to A
echo "Hello from B" | $OWL deliver agentA agentB
```

### Start a live agent session

In a Claude Code session, say `/live <id>` or run:
```bash
$LIVE start myagent
# Psyche launches automatically as external process
# Run the POLL_CMD output to start your listener
$OWL poll myagent listen --setup --live
```

### Key commands

| Command | Purpose |
|---------|---------|
| `$OWL poll <id> listen --setup` | Start listening for messages |
| `$OWL deliver <target> <from>` | Send a message (pipe body via stdin) |
| `$OWL send <target> <from>` | Send and wait for reply |
| `$OWL list` | Show active agents |
| `$LIVE start <id>` | Start live agent with Psyche |
| `$LIVE commune <id> <msg>` | Send communal update to Psyche |
| `$LIVE stop <id>` | Stop live agent + Psyche |
| `$LIVE revive <id>` | Restart with new Psyche generation |

### Project structure

```
owl.sh              # Messaging runtime (500 lines)
live.sh             # Live agent lifecycle (500 lines)
psyche.md           # Psyche agent prompt template
owl_agents.json     # claude --agents definition for owl-psyche
SKILL.md            # /owl skill instructions
LIVE-SKILL.md       # /live skill instructions
docs/DEPLOY.md      # Deployment guide
docs/SKILL_SPEC-LIVE.md  # Original design spec
```

---

*Generated: 2026-03-29 | Milestone: v1.0 | Phases complete: 4/6*
