1实现原理 · 为什么它能做到
设计哲学:watchdog 的生命周期绑定 premise state——它存在的理由消失(WiFi 断、用户退掉目标 app、前置状态没了)时必须自己 stand down,而不是等人来 disable;本 skill 的核心教导是『别让 watchdog 变成新扰动』。
**a watchdog's lifecycle is bound to its premise state**. When the condition it exists to fix cannot be fixed by it (broken WiFi, user quit the target app, prerequisite state gone), the watchdog must stand down *by itself*
部署机制走 launchd 原生工具:assets/launchagent.template.plist 作底,new-launchagent.sh 幂等安装(校验 label/interval/program → bootout-if-loaded → 写 plist → plutil -lint → launchctl bootstrap → launchctl print 验证)。
plutil -lint "$tmp_plist" >/dev/null || { echo "Generated plist failed plutil -lint" >&2; rm -f "$tmp_plist"; exit 1; }
冷却逻辑落在应用层而非 ThrottleInterval:watchdog-cooldown.sh 被 source 后提供 paused_any/record_exhausted/clear_exhausted/cmd_pause/cmd_resume,在 state 文件里记录连续 exhausted 轮数并按阶梯(默认 1800/7200/21600 秒 = 30m→2h→6h)退避静默。
space-separated escalating tiers, seconds. Default "1800 7200 21600"
停止语义把 deprecated 陷阱显式化:unload 在 Ventura+ 会因 plist 还在 + RunAtLoad 复活 job,必须用 bootstrap/bootout(现代对)与 disable/enable(跨登录保持停止)。
**Never `launchctl unload`**: deprecated, and on Ventura+ the job re-loads via `RunAtLoad` when the plist stays in place — the "disabled" watchdog fires again
防 resurrect 门禁:修复若用 URL scheme/open -a/重启 GUI app,必须先用进程存活检查把关并加 -g(不抢前台)——否则 watchdog 会表现为『我退了你又给我开回来』。
Gate every such action: check the target process is alive before invoking its scheme, and pass `-g` so a legitimate action never pops a window. If the user quit the app mid-remediation, abort the ladder
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | launchctl(bootstrap/bootout/kickstart/print/list/disable/enable) |
| cli | plutil(plist lint 校验) |
| cli | sudo(--system 路径:/Library/LaunchDaemons + system 域 bootstrap) |
| cli | open / log show / id -u(GUI 域引导、launchd 日志排查) |
4风险提醒 风险提醒:黄色 · 留意使用
- 生成并常驻执行代码的能力 — 本 skill 指引模型编写自愈脚本并注册为 launchd job(--system 可为 root 常驻);脚本内容不受 skill 源码约束。注入面=『要修什么』的用户输入与任何污染该描述的内容;使用者应把安装的脚本当代码审查。
- 系统级持久变更 — LaunchDaemons + sudo 会留下 root 级常驻 job;bootout/disable 语义用错(unload)或 plist 残留会导致 job 复活。删除/禁用需按 stop 语义表精确操作。
- TCC/Full Disk Access 误配给错误解释器 — LaunchAgent 读受保护目录需 FDA 授予实际解释器(Xcode python3 stub 会失败);文档要求用 ProgramArguments 里的确切二进制验证,否则 watchdog 静默失败或误授权。
- 冷却状态文件与日志的本地写入 — state 文件默认在 TMPDIR(重启即失,跨重启冷却需指到持久目录);日志无上限会无限增长(模板要求脚本内轮转 cap ~1MB)。
5第二遍独立确认
- [ok] 四条款契约与真实事故绑定 — SKILL.md 每条 clause 后都带真实案例('Real case: a recovery watcher kept firing for 2h after its premise resolved'、'unthrottled test replay forked 1,041 processes/sec for 7 minutes' 等);war stories 在 references/quiet-watchdog-patterns.md。
- [ok] new-launchagent.sh 校验与安装流程 — label reverse-DNS 校验、interval 整数且 ≥30、program -f/-x 绝对路径、tmp plist + plutil -lint、bootout-if-loaded、launchctl bootstrap + print 验证,全部逐字在源码。
- [ok] cool-down 状态机(1800/7200/21600 阶梯) — watchdog-cooldown.sh 常量与文档默认一致;state 文件 pause/autopause/exhausted.state;提供 cmd_pause/cmd_resume/record_exhausted/clear_exhausted/paused_any。
- [ok] unload 陷阱与 bootstrap/bootout 语义 — SKILL.md 'Never `launchctl unload`' + Ventura+ RunAtLoad 复活机制说明 + bootout/disable 命令表,与脚本实现一致。
- [ok] 运行路径无网络(安全结论基础) — 全目录运行代码无 curl/wget/http 调用;唯一 curl 出现在 evals/iteration-1 fixture broken-heal.sh(评测反例夹具),已在 internal_assets/风险注记中说明非运行路径。
- [ok] 无凭证读取 + plist 密钥警告 — plist 模板 'Never put secrets here; the plist is world-readable.';脚本无 token/API key 处理。
- [ok] 元数据(commit/license/stars) — 本地 HEAD == pin d5c4678cb5d4fd6acc9c922690df035dbd33d247;GitHub API:MIT、stars 1385(2026-09-09 实采)、pushed_at 2026-09-09T12:33:29Z。
6结论
84c303ee98ee57c6…d5c4678cb5