Files
stack/skills/ms-agent-watch/SKILL.md
T
jason.woltje 9fd16b9739 feat(release): recursion guard for the health gate; run-task drift warning; M20 packages/* decision recorded (#39)
- release.sh health gate runs with MOSAIC_ENSURE_SKIP=1: the gated task run
  cannot re-enter release self-determination
- run-task.sh warns on release drift instead of silently using a stale image
- ROADMAP: M20 decision recorded (packages/* monorepo at usurpation,
  continuity-first); restructure sequenced as M20 phase 1

Closes #39
2026-09-03 15:58:46 -05:00

3.4 KiB

name, description, disable-model-invocation
name description disable-model-invocation
ms-agent-watch Use for all instances where a watch, wait, or agentic status check is needed. This skill avoid the need for wait cycles and other methods used to wait for an action outcome. false

ms-agent-watch — self-armed condition watches

One CLI call arms an isolated systemd --user transient timer per watch. Each tick is a fresh, cgroup-isolated process; no loop, no script, no orphan. You never sleep, never write a watch script, never background anything.

Tool

tools/agent-watch/agent-watch.sh start \
  --name <lowercase-id> --session <your-tmux-session> \
  [--socket <tmux-socket>]            # REQUIRED for mosaic-fleet seats using tmux
  --when '<shell command>'            # exit 0 = met; quote it
  --message "text delivered to you" \
  [--class actionable|reaction|human|digest|terminal-log] \
  [--interval 30] [--timeout 3600] [--repeat] [--quiet-timeout]

agent-watch.sh list                   # your host's watches
agent-watch.sh log <name>             # what it did and why
agent-watch.sh stop <name>            # retire + clean state

Rules

  1. Name it for the thing watched (ci-pr1350-green, peer-orch-01-reply), not for yourself — names appear in [watch:<name>] message prefixes and in systemctl list-timers 'agent-watch-*'.
  2. Interval floor is 10s. A watcher is a fallback cadence. If you find yourself wanting 1s polls, the real fix is an event, not a faster watch.
  3. Timeout is real (default 1h): on expiry you get one terminal-log note (unless --quiet-timeout) and the watch retires. A watch is never forever; re-arm deliberately if the condition is still pending.
  4. Conditions are cron-style: clean-ish environment, cwd=$HOME. Use absolute paths. Do NOT rely on ambient credentials — resolve tokens through the git credential helper or absolute service-credential paths.
  5. rc=2 delivery is DELIVERED (text reached your pane as a draft — FLEET-COMMS E7); the watcher never retries it. Real failures retry twice then retire loudly.
  6. A broken condition (exit ≠ 0/1) retires the watch with a terminal-log note. Check log <name> before re-arming — re-arming a broken condition without fixing it just burns another timeout.
  7. --repeat re-arms after every delivery. Default is one-shot on purpose: each watch should correspond to one pending fact.
  8. Retire your watches when the mission closes (stop). list shows stale-state entries whose timer is gone; stop removes those too.
  9. Fleet seats MUST pass --socket mosaic-fleet — the default is the default socket and the delivery will not reach you.

When NOT to watch

  • Waiting on another SEAT: send them a message (agent-send / comms) instead — a watch polling their output is a loop wearing a hat.
  • Waiting on yourself: just do the next thing.
  • Something that already has a wake path (fleet watcher injects comms automatically): those arrive without any watch.

Failure model (what you'll see)

Symptom Meaning
started watcher ... then nothing, timer inactive condition broke (exit ≠ 0/1) or timeout hit — log <name> says which
[watch:x] ... timeout after Ns retired; re-arm only if still relevant
delivered (rc=2) in log delivered as draft into your pane — go read the pane
delivery failed rc=1 after 3 attempts your session was gone; restart it, then re-arm