---
title: cron 假成功根治（类5 timeout 包内建 / 类6 假成功文案）· 含一次自造事故
tags: [静默失败, cron, 假成功, pre-commit门禁, 铁律8]
created: 2026-09-12
status: final
---

# cron 假成功根治（类5/类6）

## 起点：一个撤回

上轮我报「13 条 cron 假成功，是真的活问题」→ **不成立**。
逐条比对「输出文件 Run Time」vs「脚本 mtime」→ **13 个脚本全部在该次运行之后被改过**（当天 06:04~13:27）
⇒ 它们是**修复前的历史指纹**，不是当前问题。差一步去修 13 个已修好的 wrapper。

已修检测器此缺陷: `cron_output_guard` 加**陈旧判定**（run_time vs 脚本 mtime）+ 报告分两段 + 退出码只看当前真问题。

## 真源头：pre-commit 门禁（它是对的）

```
类5   timeout 包了 shell 内建 → 命令永远不会执行，cron 记 ok        14 处真
类6   吞掉失败并输出假成功文案 `|| echo "<name>: timeout"`          32 处（5 处帮助文本 echo 疑 FP）
```

**类5 实例**（`backfill_daily.sh`，全脚本仅 3 行）:
```bash
timeout 60 cd ~/stock_workspace && python3 backfill_scheduler.py --today || echo "backfill_daily.sh: timeout"
#         ↑ timeout 去 exec 纯内建 cd → 失败 → && 短路 → payload 从未执行 → 打印假 timeout → rc=0
```
⇒ 该 job 的 payload **从来没跑过**，而 cron 一直记 ok。这就是 `: timeout` 指纹的生成源。

## 修法

```
类5  timeout N cd DIR && REST  →  cd DIR && REST
     timeout N VAR=...         →  VAR=...
类6  CMD || echo "name: timeout" → CMD || bash on_{soft_,}fail.sh "name" $?
     薄 wrapper(≤6 有效行) 用 on_fail(硬失败→cron 记 error)；多步报告用 on_soft_fail(可降级但仍留痕)
补充 `cmd | tail/head || fallback`（管道 rc = tail 的 = 0）→ 手工改写: 先存变量取 rc 再 echo|head
```

批修 19 文件 + 手工修 `logic_consistency_guard.sh`（双重假成功: timeout 包 cd **且** 管道吞 rc）。

**失败支路实测**（payload 注入 `false`）:
```
backfill_daily.sh rc=1 ✅ | self_improvement_daily rc=1 ✅ | post_session_runner rc=1 ✅
proactive_fix_wrapper rc=1 ✅(+webhook 报 failed) | ability_decay rc=1 ✅ | crash_detect rc=1 ✅
ima_sync_wrapper rc=1 ✅ | a_group_data 守卫片段 rc=1 ✅ | logic_consistency_guard rc=1 ✅
成功路径回归全部 rc=0 ✅
```

## ⚠️ 本轮我自己造成的一次事故（已修，记录在案）

批修器 v1 用 `.*$` 匹配行尾 → **吃掉换行符 → 两行被拼成一行**，而 `bash -n` 只查语法**抓不到**:
```
+PYBIN="..." || bash "...on_soft_fail.sh" "x" $?WS="$HOME/stock_workspace"   ← 下一行被吞进来
```
发现于逐行 diff 审阅。已从备份全量回滚 → v2 重写并加**硬门: 改前改后行数必须完全一致**（不一致拒绝写入）。

**教训（并入铁律8）**: 批量改代码的第五条坑 —— **`.*$` 会吃掉换行符，拼行后语法仍合法，`bash -n` 查不出**。
必须用 `[^\n]*` / `(?m)` 锚点，并把「行数不变」作为机械硬门。

## 未完成（如实列）

1. **46 处 `cmd | tail/head || fallback`**（22 文件）= 同类管道吞 rc，只手工修了 1 处（logic_guard）+ 1 处（a_group_data 末两行）；其余未修（部分 `ls | head || echo "无"` 属合法用法，需逐个判）。
2. `auto_scan_wrapper.sh` / `preflight_check.sh` **有语法错误（HEAD 版即存在，非本次引入）**，且不挂任何 cron → 独立既有问题，未修。
3. 类6 的 5 处「帮助文本 echo」疑 FP 未复核。
4. 上述批修尚未等真实 cron 跑一轮验证（下次运行才是终验）。
