No description
Find a file
bob-boat 3a586f38a9 Address Bob's notes 2 and 3 with documenting comments
Note 2: poll_fallback_seconds==0 silently means 'use default'. Document
in example yaml; no v1 way to disable polling, and we don't think
anyone needs that.

Note 3: Writer.locks grows unbounded. Bounded in practice (<10 agents);
add a comment for the future maintainer who may need to evict.

Notes 1 and 4 left unchanged: missingkey=zero is the friendlier choice
(produces a visible '<no value>' in the inbox rather than a silent
500); fsnotify double-fire is already handled by os.ErrNotExist on
second-read.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 16:47:40 -04:00
cmd/agent-watcher Collector milestone 5: end-to-end integration tests 2026-05-06 16:23:34 -04:00
docs/channels Add Channels reference docs snapshot for Layer 2 implementation 2026-05-06 16:04:32 -04:00
examples Address Bob's notes 2 and 3 with documenting comments 2026-05-06 16:47:40 -04:00
internal Address Bob's notes 2 and 3 with documenting comments 2026-05-06 16:47:40 -04:00
spec Initial: README, spec/agent-watcher.md v1 (signed off by Bob 2026-05-06), .gitignore 2026-05-06 14:36:45 -04:00
systemd Collector milestone 6: packaging — install.sh, systemd unit, docs 2026-05-06 16:26:16 -04:00
.gitignore Initial: README, spec/agent-watcher.md v1 (signed off by Bob 2026-05-06), .gitignore 2026-05-06 14:36:45 -04:00
go.mod Collector milestone 4: config loader + main wiring (binary builds) 2026-05-06 16:22:03 -04:00
go.sum Collector milestone 4: config loader + main wiring (binary builds) 2026-05-06 16:22:03 -04:00
INSTALL.md Collector milestone 6: packaging — install.sh, systemd unit, docs 2026-05-06 16:26:16 -04:00
install.sh Collector milestone 6: packaging — install.sh, systemd unit, docs 2026-05-06 16:26:16 -04:00
README.md Collector milestone 6: packaging — install.sh, systemd unit, docs 2026-05-06 16:26:16 -04:00

agent-watcher

Push-delivery layer for agent-ping. The "secondary nervous system" for Claude Code agents on this network.

agent-ping queues messages in inbox files; agent-watcher notices them (and other external events) and wakes the recipient agent without a human in the loop.

Two layers:

  • Collector (this repo, Go) — small daemon under systemd --user. Always on, brain-blind. Converts external events (HTTP webhooks, drop-folder file arrivals) into ping inbox writes. Runs whether or not any agent is alive.
  • MCP Watcher (Python, in progress) — Claude Code MCP subprocess declared in each agent's mcp.json. Watches the agent's inbox via inotify and surfaces events into the live session via Channels. Provides reply tools (ack, respond, mark_handled).

Filesystem is the queue. OpenBrain is not involved.

Spec

spec/agent-watcher.md. Read that for architecture, decisions, scope.

Channels reference docs (snapshot of Anthropic's official docs, used by Layer 2): docs/channels/.

Status

Layer Lane Status
Spec v1 Signed off by Bob 2026-05-06
Layer 1: Collector Foreman / Go v0 working: 43 tests passing. End-to-end exercised; binary builds. systemd unit + INSTALL.md ready.
Layer 2: MCP Watcher Bob / Python In progress — sandbox CC session being set up on VPS for testing.

Install (Layer 1)

git clone https://git.botbought.ai/foreman/agent-watcher ~/agent-watcher
cd ~/agent-watcher
./install.sh

Then edit ~/.config/agent-watcher/collector.yaml and systemctl --user restart agent-watcher.

See INSTALL.md for verify steps, troubleshooting, and the loginctl enable-linger step required to keep the daemon running across logouts.

Per CLAUDE.md rule #2, Angus runs the install commands — agents do not modify their own configuration.

Quick reference (Layer 1)

Inputs                          Output
─────────                       ──────
HTTP POST → port 18790      ┐
              (routed via   │   <recipient>.inbox  (JSONL, ping-shaped)
               YAML table)  │   identical format to
                            ├─→ what `ping <recipient> <payload>` writes;
File drop in                │   the existing UserPromptSubmit hook and the
~/Nyx/workspace/incoming/   │   future MCP Watcher consume the stream
*.json                      ┘   without distinguishing source.

/health on the same webhook port returns {received, emitted, errors, uptime_sec} for journalctl correlation.