1仕組みと動作原理
設計思想:ウォッチドッグのライフサイクルを premise state(前提状態)にバインドします。存在理由が消滅した場合(Wi-Fi 切断、ユーザーによる対象アプリの終了、前提条件の喪失)、手動で disable されるのを待つのではなく、自発的に stand down する必要があります。本スキルの根本理念は「ウォッチドッグ自身を新たな障害にしないこと」です。
**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 → 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 秒 = 30分→2時間→6時間)にバックオフして沈黙します。
space-separated escalating tiers, seconds. Default "1800 7200 21600"
停止セマンティクスにおける非推奨トラップの明確化:Ventura 以降の unload は、plist が残っており RunAtLoad があるとジョブが復活してしまいます。そのため、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
再起動防止ゲート:修復処理で URL スキーム、open -a、または GUI アプリの再起動を用いる場合、事前にプロセス生存チェックを行い、-g(フォアグラウンドを奪わない)を付与する必要があります。これを行わないと、ウォッチドッグが「ユーザーが終了させたのに勝手に再起動する」迷惑な挙動を示します。
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外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| 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推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: scripts/new-launchagent.sh(インストールフェーズ: bootout/plist 書き込み/bootstrap)
- 本地工作目录: ファイルの読み書きおよび成果物の出力: ~/Library/LaunchAgents/<label>.plist(または sudo /Library/LaunchDaemons/<label>.
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…