diff --git a/.agents/skills/unidesk-gc/SKILL.md b/.agents/skills/unidesk-gc/SKILL.md index 54d936de..dedf3d01 100644 --- a/.agents/skills/unidesk-gc/SKILL.md +++ b/.agents/skills/unidesk-gc/SKILL.md @@ -114,9 +114,34 @@ Read `docs/reference/gc.md` before these remote cases: - G14 registry retention, CI workspace retention, k3s/PVC attribution, and safe-stop decisions. - PK01 pikanode temp retention and Docker-provider safe boundaries. -- JD01 k3s/PVC attribution, Web observe artifact retention, Chrome/observer memory growth, and YAML-first source-of-truth checks. +- JD01 k3s/PVC attribution,以及 NC01/JD01 的 Web observe artifact retention、Chrome/observer memory growth 与 YAML-first source-of-truth checks。 -For JD01, Chrome memory growth should first be treated as an observer lifecycle problem: sentinel/quick-verify terminal paths must stop their observer, and runner TTL/maxSamples/artifact caps must come from YAML. Do not solve it by raw killing Chrome or deleting web-observe directories; use controlled observe stop and GC plan candidates. +## Web observe 与 Chrome 逃逸进程 + +- 正常生命周期: + - 远端节点的 Chrome 内存增长应先按 observer 生命周期问题处理; + - sentinel/quick-verify 的全部终态必须停止对应 observer; + - runner 的 TTL、maxSamples 和 artifact cap 必须来自 YAML; + - 归属尚未判清时不得按名称终止 Chrome,也不得删除 web-observe 目录。 +- 保护边界: + - active observer、受控任务仍引用的浏览器会话及其完整进程树始终受保护。 +- 同时满足以下条件的 Playwright `cliDaemon`/Chrome 进程树视为高度可疑的逃逸或泄露进程,可以直接进入精确终止流程: + - 存活时间超过 owning YAML 定义的异常存活窗口; + - 受控 observe/sentinel 状态未显示该进程树归属于 active observer 或在途受控任务; + - manifest、heartbeat、PID/session 记录均不能把它归属到有效 run; + - PID、PPID、session/process group 与后代进程能够闭合为唯一待终止进程树。 +- 精确终止: + - 对已核实的唯一进程树先发送 TERM; + - 按 YAML 定义的有界等待时间重新枚举; + - 仍未退出时,只对复核后残留的同一 session/process tree 发送 KILL。 +- 禁止批量终止: + - 不得使用 `pkill -f chrome`、`killall chrome` 或其他按进程名批量终止方式; + - 证据不完整或归属存在歧义时保持 protected,不得猜测。 +- 终止后验证: + - 确认目标 PID、后代 PID 和 session/process group 全空; + - 确认 active observer 未受影响; + - 重新采集 `MemAvailable`、swap、observer 状态和 Chrome/runner 摘要; + - 结构化记录判定证据、TERM/KILL 结果、残留进程与终止前后资源数据。 JD01 and other remote hosts may use rebuildable tool caches only through explicit opt-in: @@ -135,7 +160,11 @@ Never use these as generic disk relief: - PostgreSQL PGDATA or database trace cleanup without the dedicated `gc db-trace` flow, backup, and maintenance window. - `/var/lib/containerd`, `/var/lib/rancher/k3s`, `/var/lib/kubelet`, PVC paths, registry blobs, runtime snapshots, or k3s/container runtime state. - Codex auth/config/profile state. Codex session cleanup must use `--include-codex-sessions`; large active Codex SQLite log files require `fuser` checks and a dedicated retention decision. -- Active Web observe runs, live observer runners, live Chrome process trees, or web-observe state roots without manifest/heartbeat/pid/open-fd based stale classification. +- 以下 Web observe 与 Chrome 对象: + - active Web observe runs 和 live observer runners; + - ownership 或 stale classification 尚未判清的 Chrome process trees; + - 缺少 manifest/heartbeat/pid/open-fd 依据的 web-observe state roots; + - 只有按“Web observe 与 Chrome 逃逸进程”完成无归属判定的唯一进程树才可精确终止。 - Dirty, active, unmerged, recent, or timeout-protected worktrees. - `backend-core` rebuild/restart/replacement while solving disk pressure unless the user explicitly asks. diff --git a/docs/reference/gc.md b/docs/reference/gc.md index 4a77fc80..ba513a0c 100644 --- a/docs/reference/gc.md +++ b/docs/reference/gc.md @@ -105,7 +105,33 @@ JD01 增长降速 policy 由 `gc remote JD01 policy plan|install|status` 管理 JD01 Web observe artifact 是一等 GC 对象。state root 必须来自 YAML;候选按 run 聚合并读取 `manifest.json`、`heartbeat.json`、`pid`、report sha 和 top files。年龄判定以 manifest/heartbeat 的 started/completed/updated 字段、pid 存活和打开 fd 检查为准,不以目录 mtime 为唯一依据,因为手动 GC 或目录遍历可能刷新 mtime。active run、pid alive、open fd、未生成必要 report 的 run 均为 protected。safe 候选只覆盖超过 YAML retention 且可重建的 raw samples、browser-process、network/trace、screenshot 等大 artifact;长期保留 report summary、report json/md、最终截图或诊断摘要由 YAML cap/retention 策略控制。 -JD01 Chrome 内存治理应优先管理 observer runner 生命周期,而不是孤立清理 Chrome 进程。Web probe sentinel 和 quick-verify 启动 observer 后,所有终态路径(成功、blocked、失败、timeout、异常)都必须执行 YAML 控制的 `web-probe observe stop`/force stop 流程,并验证对应 runner/Chrome process tree 退出;observe runner 自身也必须从 scenario/YAML 获得最大运行时长或 max samples 兜底,即使调用方退出也会停止采样并关闭 browser。browser freeze policy 只能作为异常保护,不替代正常任务生命周期结束后的 stop。 +### Web observe 与 Chrome 逃逸进程 + +- 正常生命周期: + - Chrome 内存治理优先管理 observer runner 生命周期; + - Web probe sentinel 和 quick-verify 启动 observer 后,全部终态都必须执行受控 stop; + - 全部终态包括成功、blocked、失败、timeout 和异常; + - stop 流程由 YAML 控制,并使用 `web-probe observe stop`/force stop; + - stop 后必须验证对应 runner 与 Chrome process tree 已退出; + - observe runner 必须从 scenario/YAML 获得最大运行时长或 max samples 兜底,即使调用方退出也会停止采样并关闭 browser; + - browser freeze policy 只能作为异常保护,不能替代正常终态 stop。 +- 逃逸判定: + - 长时间存活的 Playwright `cliDaemon`/Chrome 进程树是高度可疑对象; + - 存活窗口必须来自 owning YAML,不能写成脚本隐藏默认; + - 必须先证明该进程树不属于 active observer 或其他在途受控任务; + - 归属证据包括受控 observe/sentinel 状态、manifest、heartbeat、PID/session 记录和完整 process tree; + - PID、PPID、session/process group 和后代进程不能闭合为唯一进程树,或任一归属证据存在歧义时,继续标记 protected; + - 只有证据闭合的无归属进程树才能分类为 `suspected-orphan-browser`,并直接进入精确终止流程。 +- 精确终止: + - 先结构化记录 session、root PID、后代 PID、命令摘要、存活时间、归属判定和终止前的 `MemAvailable`/swap; + - 只向已核实的 session/process tree 发送 TERM,并按 YAML 定义的有界等待时间复核; + - TERM 后仍存活时,重新确认残留 PID 仍属于同一棵树,再仅向这些残留进程发送 KILL; + - 禁止使用 `pkill -f chrome`、`killall chrome` 或任何按 `chrome`/`chromium` 名称批量终止的入口。 +- 收口验证: + - 目标 root PID、全部后代 PID 和 session/process group 必须为空; + - 受控 observe/sentinel 状态必须确认 active observer 未受影响; + - 必须重新采集 `MemAvailable`、swap、Chrome/observer process summary 和 web-observe 状态; + - 结果必须结构化记录分类、归属证据、TERM/KILL 动作、残留 PID、终止前后资源数据和复核结论。 JD01 plan 和 status 应同时披露内存压力摘要:active observer 数、Chrome process 数、Chrome RSS、stale observer 数、state root artifact bytes、last cleanup、last stop failure 和 drill-down 命令。GC run 只能执行 plan 中明确标记 safe 的低风险动作,例如 apt/journal/tmp allowlist、dead web-observe raw artifact retention,以及通过受控 observe stop 处理 stale observer;对 PVC、k3s runtime、containerd、Docker volume、Secret 和 auth/config 状态一律保持 protected 或转交专用 retention 入口。