4.3 KiB
name, description, disable-model-invocation
| name | description | disable-model-invocation |
|---|---|---|
| ms-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-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
MOSAIC_AGENT_SEND="/absolute/checkout/tools/tmux/agent-send.sh" \
/absolute/checkout/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
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
- Name it for the thing watched (
ci-pr1350-green,peer-orch-01-reply), not for yourself — names appear in[watch:<name>]message prefixes and insystemctl list-timers 'agent-watch-*'. - 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.
- 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. - 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. - 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
deliveredlog wording is not an acknowledgement. Other sender failures retry twice, then retire; do not add blind resends. - 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. --repeatre-arms after every delivery. Default is one-shot on purpose: each watch should correspond to one pending fact.- Retire your watches when the mission closes (
stop).listshows stale-state entries whose timer is gone; stop removes those too. - 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 <name> 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 |