Collector milestone 6: packaging — install.sh, systemd unit, docs

systemd/agent-watcher.service: --user unit with on-failure restart,
ProtectSystem=strict, ProtectHome=read-write, NoNewPrivileges=yes,
PrivateTmp=yes. JSON logs to journald. Survives reboot via
'loginctl enable-linger'.

examples/collector.yaml: working starter config for both sources with
inline comments, per-route examples, and the spec §3.1.2 schema for
drop files.

install.sh: idempotent installer following the agent-ping pattern.
Builds the binary, installs it + the unit, drops the example config if
absent, reloads systemd, enables, and (unless --no-start) starts the
service. Adds drop-folder lifecycle artifacts (*.tmp, .dead-letter/)
to workspace .stignore so they don't replicate during processing.
Skips Syncthing-related steps gracefully when ~/Nyx/workspace is not
present.

INSTALL.md: prerequisites, install, configure, verify (drop-file +
webhook end-to-end probes), survive-logout, uninstall, troubleshooting
table.

README.md: rewritten to reflect actual status — v0 working with 43
tests, packaging ready, Layer 2 in progress on Bob's side.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
bob-boat 2026-05-06 16:26:16 -04:00
parent e7d4ea036a
commit 4ff8c3f78d
5 changed files with 324 additions and 6 deletions

View file

@ -1,13 +1,13 @@
# agent-watcher
Push-delivery layer for [`agent-ping`](http://localhost:3300/angus/agent-ping). The "secondary nervous system" for Claude Code agents on this network.
Push-delivery layer for [`agent-ping`](https://git.botbought.ai/foreman/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** — small Go daemon, `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** — 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 (research preview). Provides reply tools (`ack`, `respond`, `mark_handled`).
- **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.
@ -15,10 +15,42 @@ Filesystem is the queue. OpenBrain is not involved.
[`spec/agent-watcher.md`](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/`](docs/channels/).
## Status
v1 spec signed off by Bob (VPS) 2026-05-06. Implementation pending.
| 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
## Install (Layer 1)
Per CLAUDE.md rule #2, **Angus runs the install commands** — agents do not modify their own configuration. Install script will land alongside `INSTALL.md` once the binaries are built.
```sh
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`](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.