# R1.2.5 任务报告

## 结论

NC01 的自动留存并未失效，真实问题是仓库 owning YAML 已把 `minAgeHours` 从 24 小时调整为 12 小时，但 host timer 安装态仍停留在 24 小时；旧 `policy status` 又不披露期望/安装态差异，导致自动轮次 0 候选被误判为配置未加载。现已通过 YAML-first 受控安装对齐，并增强 CLI 一次性显示配置/runner 指纹、关键留存字段和 `inSync`。Webterm 未执行配置修改、进程终止、会话回收或内存回收。

## 实现

- `gc remote <node> policy status` 新增 `policySync`：
  - 披露期望与安装态配置/runner 的字节数和 SHA-256；
  - 披露 `configId`、namespace、resource、保留窗口、每组保留数和自动单批上限；
  - 直接输出 `inSync` 与 typed drift。
- 自动留存即使零候选，也保留配置身份，避免 `configId=null` 误导。
- owning YAML 的 `previewLimit` 从 10 收敛到 5，`retention plan --limit 500` 默认输出不再超过 stdout 上限；完整披露仍由显式 `--full` 提供。
- GC skill 与长期参考统一要求：YAML 变化后只通过受控 `policy install --confirm` 更新安装态，禁止直接修改 host JSON、runner 或 systemd unit。

## 自动回收实证

- 受控安装后 `policySync.inSync=true`，期望与安装态均为 12 小时，配置和 runner SHA-256 一致。
- 11:17 的自然 systemd timer 自动完成回收：
  - 候选 26；
  - 请求删除 26；
  - 删除成功 26；
  - PipelineRun 对象差 26；
  - `failedCount=0`。
- 回收后同一筛选器再次计划：
  - 扫描 230；
  - eligible 0；
  - active 3、young 220、latest-per-group 7 均被保护。
- `devops-infra` 观测值从 250 PipelineRun、265 TaskRun、266 Pod、255 Secret，变化为 230、245、249、235；期间仍有新 CI 对象创建，因此命名空间净减少量小于 timer 的 26 个根对象删除量。

## 内存实证

- 自动留存前后：
  - `k3s.service` cgroup 从 6,329,176,064 降到 5,859,700,736 字节，约下降 448 MiB；
  - k3s-server RSS 从 3,671,662,592 降到 3,440,320,512 字节，约下降 221 MiB；
  - embedded containerd RSS 从 718,721,024 降到 645,222,400 字节，约下降 70 MiB。
- 随后唯一一次 YAML 允许的受控内存压力 GC：
  - 只向 `k3s.service` 和 `kubepods.slice` 的 cgroup v2 `memory.reclaim` 写入受控请求；
  - 两个候选均成功，cgroup 记账分别下降 1,099,018,240 和 490,749,952 字节；
  - 同一 job 内真实 `/proc/meminfo` `MemAvailable` 从 4,027,912,192 增至 4,086,988,800 字节，净增 59,076,608 字节；
  - 后续并发 workload 回填后为 3,553,939,456 字节，未持续超过 4 GiB。

## 判定

- 内存泄露和历史对象无限增长已分别通过源码修复、owner 滚动与 YAML 定时留存收敛。
- 4 GiB 目标尚未形成稳定余量；证据表明重复 cgroup reclaim 只会被活跃业务快速回填，因此未循环执行。
- 下一步业务优化优先级应是继续降低 k3s 控制面对象总量，并按各 namespace owner 分别设计终态 CI 对象留存；不得把 Webterm、k3s 重启或盲目进程终止当作本任务的 GC 手段。

## 验证

- `python3 -m py_compile scripts/src/gc-remote-runner.py scripts/src/gc-remote-kubernetes-retention.py`
- `bun scripts/cli.ts check --syntax-only`
- `bun scripts/cli.ts gc remote NC01 policy status`
- `bun scripts/cli.ts gc remote NC01 retention plan --limit 500`
- `bun scripts/cli.ts gc remote NC01 memory-distribution`
- `bun scripts/cli.ts gc remote NC01 plan --memory-pressure-only`
- `bun scripts/cli.ts gc remote NC01 run --confirm --memory-pressure-only`
- `bun scripts/cli.ts gc remote NC01 status --job-id nc01-memory-pressure-1784193472-2869303`
