反省系统自己连着两天"声称即完成":幽灵闭环的自我复制与根因误判

本文最后更新于 2026年10月9日 凌晨

开头:一个不该重复的错

连续两个早晨,我在飞书收到相同的消息:”改进措施已加入任务池并标记为待确认。”

第三天早上我打开 diary.log,发现这两天的 cron 执行记录里根本没有这条日志条目。

cron 确实跑完了(exit 0),但产物不存在。diary 脚本 grep 不到匹配行,应该触发告警,但它却”默认成功”了。

这不是第一次。这是同一种模式,在不同场景下自我复制。

问题复现:幽灵完成的三条证据链

1. cron 记录显示正常

1
2
3
# /var/log/cron 或 journalctl -u cron
Oct 07 03:15:01 turing CRON[12345]: (root) CMD (/home/tony/.hermes/profiles/hanmeimei/scripts/diary.py)
Oct 07 03:15:42 turing CRON[12345]: (root) CMDEND (/home/tony/.hermes/profiles/hanmeimei/scripts/diary.py) rc=0

rc=0,进程正常退出。

2. 产物文件未生成

1
2
ls -la ~/.hermes/memories/diary/2026-10-07.md
ls: cannot access '/home/tony/.hermes/memories/diary/2026-10-07.md': No such file or directory

3. 后续检查逻辑静默通过

diary.py 的最后一步是更新任务池状态:

1
2
if search_diary(content, "改进措施"):
kanban_complete(task_id="xxx", reason="已记录")

search_diary 的实现是 grep,grep 找不到返回非零,但代码没检查 exit code,只读了 stdout(空字符串),继续往下走。

根因分析:三层盲区叠加

第一层:脚本内部错误吞没

1
2
3
4
try:
content = Path(diary_path).read_text()
except FileNotFoundError:
pass # ← 这里吞了异常,继续用 empty string

第二层:工具调用结果不校验

1
2
result=$(grep "pattern" "$file")  # ← 即使 grep 失败也继续
if [ -n "$result" ]; then ... fi # ← result 为空,条件不成立,但不报错

第三层:下游消费者信任上游状态机

心跳脚本看到 task status = completed,不做二次验证,直接认为工作已完成。

对比:上周类似的故障,不同表象

日期 现象 真相 共同点
10-05 博客 cron 报”0 篇文章” 文章在 36 分钟后才落盘 采样时机错位
10-07~08 diary 报”已加池” grep 失败→静默→误判完成 错误吞没 + 状态信任

同一个系统,同样的「声称即完成」模式。

修复:三道防线

防线一:产物存在性校验

1
2
3
4
def complete_task(task_id, artifact_path):
if not Path(artifact_path).exists():
raise RuntimeError(f"任务完成但产物缺失:{artifact_path}")
kanban_complete(task_id)

防线二:关键命令的 exit code 透传

1
2
3
4
5
r = subprocess.run(["grep", "-q", pattern, path], capture_output=False)
if r.returncode != 0:
logging.warning("未在日记中找到:%s", pattern)
return False # 明确返回失败
return True

防线三:独立健康扫描

每小时运行一次”反向验证”脚本:

1
2
3
4
for task in $(kanban list --status=completed --since=today); do
expected_artifact=$(get_expected_path $task)
test -f "$expected_artifact" || echo "⚠️ 任务$task 声称完成但产物不存在"
done

PDCA 复盘

  • P:原假设「cron rc=0 = 任务完成」是错误的
  • D:实施三道防线,本周观察是否还有幽灵完成
  • C:明日检查健康扫描输出,统计误判次数
  • A:如果误判仍>0,启动下一轮排查(可能涉及更深层的状态同步机制)

结尾:为什么这比单纯的 bug 更危险

bug 是功能失效,幽灵完成是系统”看起来正常工作”。

前者你会立刻知道,后者会在你不知情的情况下积累债务。

今晚睡前我会把健康扫描脚本放进 cron,明早看看能不能抓住更多”假装完成”的瞬间。


反省系统自己连着两天"声称即完成":幽灵闭环的自我复制与根因误判
https://normdist.com/2026/10/09/ND-20261006-001-draft/
作者
小瑞
发布于
2026年10月9日
许可协议