Skip to content

feat(watchdog): productize same-machine peer wake (revive sleeping colleagues)#34

Merged
ThinkOffApp merged 2 commits into
mainfrom
feat/peer-wake-watchdog
Jul 14, 2026
Merged

feat(watchdog): productize same-machine peer wake (revive sleeping colleagues)#34
ThinkOffApp merged 2 commits into
mainfrom
feat/peer-wake-watchdog

Conversation

@ThinkOffApp

Copy link
Copy Markdown
Owner

Directive

Petrus, 2026-07-14: "Put this in iak: agents on the same computer can wake up sleeping colleagues with computer."

What existed

scripts/team-watchdog.mjs already implemented the core mechanism: an always-on watchdog reads the room, computes each roster agent's last-seen, and for a stale agent runs a wake path — a same-machine localWake (idle-guarded GUI nudge), a cross-machine gate POST, or a room @mention. It was, however, a machine-specific one-off pointed at a dead host, unrunnable without hand-wiring, and untested.

What this adds (the productization)

  • Stale-host fix — the API base was https://antfarm.world/api/v1 (dead legacy host); changed to https://groupmind.one/api/v1, which every other call site uses. A test asserts the constant so it can't regress.
  • Testability seam — exported the pure helpers (loadRoster, lastSeen, ageMinutes, isStale), made key/roster/state resolution lazy, and guarded the loop to run only when invoked directly (node scripts/team-watchdog.mjs), never on import. Import is now side-effect-free. Added test/team-watchdog.test.mjs (8 cases: host constant, last-seen matching, staleness math, roster parsing from env / file / missing).
  • Runnableexamples/team-watchdog-launchd.plist: a parameterized launchd unit (REPLACE_WITH_IAK_ROOT + documented sed, no hardcoded /Users/... paths, no tailnet IPs — the Wake-guard convergence: per-injection idle rechecks + ack-after-success delivery (#28 + #29) #30 review blocker class), KeepAlive true, plus the documented ONCE=1/StartInterval one-shot variant for laptops that sleep (the in-process timer stalls across sleep).
  • Roster scaffoldconfig/watchdog-roster.example.json with placeholder handles/paths showing all three entry types. The real config/watchdog-roster.json stays gitignored (config/*.json).
  • Opt-in install — a guarded step in scripts/install.sh (IAK_INSTALL_WATCHDOG=1, roster-gated, off by default) + a README "Peer wake" section documenting the model, roster format, safety, and install.

Idle-guard safety guarantee

localWake GUI-types into the target app, so every wake script the watchdog invokes routes through tools/human-idle-guard.sh: it refuses to inject keystrokes unless the machine has been idle past IDLE_THRESHOLD_S (default 60s), fails closed when idle state is unknown, and --waits for an idle window rather than dropping the nudge. The shipped scripts/claude-gui-wake.sh and tools/codex_gui_nudge.sh already call it (and also refuse a locked screen / non-frontmost window); the docs require any custom localWake target to as well. No keystroke-over-human risk is reintroduced.

The model (and its one limit)

A watchdog directly revives only agents whose IDE runs on its own machine (localWake) — this works even with no network. Cross-machine wake (gate, the wake_remote primitive) still needs the target machine awake with its receiver alive. A laptop that is asleep cannot be woken over the network without Wake-on-LAN — run a watchdog on each machine so every agent has a local reviver.

Tests

npm test128/128 pass (120 prior + 8 new). node --check scripts/team-watchdog.mjs, bash -n scripts/install.sh, and plutil -lint on the plist all clean.

Review

@codexmb — requesting an adversarial review per the cross-model rule before merge. You're a primary consumer here: the MacBook watchdog's localWake path revives @codexmb when its webhook tunnel dies (the Jul 9-12 silent-death case this backstops). Please poke especially at the idle-guard contract for localWake targets and the direct-invocation guard.

🤖 Generated with Claude Code

…lleagues)

Petrus directive (2026-07-14): "Put this in iak: agents on the same
computer can wake up sleeping colleagues with computer."

team-watchdog.mjs already implemented the core same-machine wake (roster
localWake -> idle-guarded GUI nudge). This productizes it and closes the
gaps that kept it a machine-specific one-off:

- Fix stale host: antfarm.world -> groupmind.one (the live host every
  other call site uses). Guarded by a test asserting the constant.
- Testability seam: export pure helpers (loadRoster, lastSeen,
  ageMinutes, isStale) + lazy key/roster/state resolution + a
  run-only-when-invoked-directly guard, so import is side-effect-free.
  Add test/team-watchdog.test.mjs (8 cases: host, last-seen, staleness,
  roster parsing from env/file/missing).
- examples/team-watchdog-launchd.plist: parameterized launchd unit
  (REPLACE_WITH_IAK_ROOT + documented sed; no hardcoded paths / tailnet
  IPs), KeepAlive, plus the ONCE=1/StartInterval laptop-sleep variant.
- config/watchdog-roster.example.json: placeholder scaffold showing all
  three entry types (localWake / gate / gateless). Real roster stays
  gitignored (config/*.json).
- Opt-in installer step in scripts/install.sh (IAK_INSTALL_WATCHDOG=1,
  roster-gated, off by default) + README "Peer wake" section.

Safety: localWake GUI-types, so every wake script the watchdog runs
routes through tools/human-idle-guard.sh (fail-closed, waits for an idle
window) — the shipped claude-gui-wake.sh / codex_gui_nudge.sh already do,
and the docs require any custom localWake target to as well. No
keystroke-over-human risk reintroduced.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6287266d2e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/team-watchdog.mjs Outdated
The opt-in install writes ide-agent-kit.json and the plist only sets
IAK_ROOT, so KEY()'s macbook.json-only default threw every tick on a
fresh install (no peer wakes ever fired). Now resolves in order:
GROUPMIND_KEY/ANTFARM_KEY env -> IAK_CONFIG -> $REPO/ide-agent-kit.json
-> legacy config/macbook.json, with a clear error if none has
poller.api_key. Plist example also sets IAK_CONFIG explicitly (codex
review, #34).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ThinkOffApp ThinkOffApp merged commit d3b52cb into main Jul 14, 2026
3 checks passed
ThinkOffApp pushed a commit that referenced this pull request Jul 14, 2026
Ships the two responsiveness features (SessionStart self-arm #33, peer-wake
watchdog #34) and refreshes the README What's-new to address all three
multi-agent pain points: unresponsive IDEs, prompting-vs-buttons, typing-over.
142 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant