--- name: ms-watch description: 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. disable-model-invocation: false --- # ms-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 ```bash MOSAIC_AGENT_SEND="/absolute/checkout/tools/tmux/agent-send.sh" \ /absolute/checkout/tools/agent-watch/agent-watch.sh start \ --name --session \ [--socket ] # REQUIRED for mosaic-fleet seats using tmux --when '' # 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 # what it did and why agent-watch.sh stop # retire + clean state ``` Use the actual checkout path in place of `/absolute/checkout`. The CLI otherwise uses a sender under `$HOME/.config/mosaic`, which may not be this repository's reviewed transport. No timers or meta-watch are installed merely by loading this skill. Live watch operations require assignment authority. `list` and `status` can write stale-notice claims and send messages; they are not read-only probes. The CLI's `status [--json]` returns 0 for clean, 3 for stale/dead meta-watch, and 6 for an unreachable systemd user bus. Do not infer health from a failed query. ## Rules 1. **Name it for the thing watched** (`ci-pr1350-green`, `peer-orch-01-reply`), not for yourself — names appear in `[watch:]` 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. **Transport is not application acceptance.** The current watcher treats sender exit 0 and 2 as terminal for retry purposes. Exit 0 means transport dispatched, application acceptance unknown; exit 2 does not prove submission or receipt. Its legacy `delivered` log wording is not an acknowledgement. Other sender failures retry twice, then retire; do not add blind resends. 6. **A broken condition (exit ≠ 0/1) retires the watch** with a terminal-log note. Check `log ` 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`. Socket selection is explicit option, then MOSAIC_TMUX_SOCKET, then unique discovery; ambiguity refuses. ## 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 ` says which | | `[watch:x] ... timeout after Ns` | retired; re-arm only if still relevant | | delivered (rc=2) in log | legacy retry classification, not proof of receipt; reconcile through authorized records, not private-pane inspection | | delivery failed rc=1 after 3 attempts | your session was gone; restart it, then re-arm |