← 归档索引 · 2026-11-02 17:09 · crash-auto-diagnose
# Cron Job: crash-auto-diagnose
**Job ID:** fd5d8aa41300
**Run Time:** 2026-11-02 17:09:54
**Schedule:** 0 8 * * *
**Prompt Characters:** 4873
## Prompt
[IMPORTANT: You are running as a scheduled cron job. DELIVERY: Your final response will be automatically delivered to the user — do NOT use send_message or try to deliver the output yourself. Just produce your report/output as your final response and the system handles the rest. SILENT: If there is genuinely nothing new to report, respond with exactly "[SILENT]" (nothing else) to suppress delivery. [SILENT] is a literal ASCII control token — never translate or rephrase it, whatever language the rest of your answer uses. Never combine [SILENT] with content — either report your findings normally, or say [SILENT] and nothing more. FAILURE: If a delegated child fails and this cron run must be recorded as failed, put [CRON_FAILURE] on the first line by itself, then explain the child failure on following lines. RECURSION: This is a run of an EXISTING scheduled job — execute the task now. NEVER create or update a cron job because of recurring or future-schedule language in the task prompt below; treat phrasing like "each Monday" or "every day at 9" as context for this run, not as a request to schedule another job.]
## Output from job 'edb0a7f09bc2'
The following is the most recent output from a preceding cron job. Use it as context for your analysis.
```
# Cron Job: 数据底座六源探测-每日3:40(P1-4)
**Job ID:** edb0a7f09bc2
**Run Time:** 2026-11-02 03:41:47
**Mode:** no_agent (script)
---
wind edb ❌ 0.1s search failed: unknown
✅ 已保存: capability_matrix.json(81 项能力)
✅ 已保存: capability_details.json(全详情,供 hub.get_capability_probe() 查询)
矩阵: {"MX": ["realtime", "daily", "finance", "news", "us", "fund", "board", "select", "stock_select", "zixuan_query", "moni_assets"], "mootdx": [], "tushare": ["daily", "weekly", "monthly", "daily_basic", "fina_indicator", "income", "stk_limit", "top10_holders", "index_daily", "stock_basic", "trade_cal", "adj_factor", "margin", "ths_index", "block_trade", "stock_company", "lhb", "macro", "forecast", "express", "concept", "ths_daily", "ths_member", "index_classify", "tdx_index"], "westock": ["cli_mark
📊 因果基因(脚本自证)
- 数据源: 四主源mootdx/tushare/mx/westock + 补充源gf_skills/ifind 全方法探测(probe_sources.py --save)
- 分析路径: 逐源逐方法探测可用性 → 回显探测摘要 → 刷新data/capability_matrix.json能力掩码供自动路由
- 判断: rc=0=能力矩阵已更新;rc非0=输出[ALERT]探测失败并以1退出,交看门狗归因
```
## Output from job '8da391caf5a0'
The following is the most recent output from a preceding cron job. Use it as context for your analysis.
```
# Cron Job: 每日独立市场扫描-06:45
**Job ID:** 8da391caf5a0
**Run Time:** 2026-11-02 06:45:34
**Mode:** no_agent (script)
---
数据完整度: 3/3 段可用
📡 独立市场扫描 · 11/02 06:45
🌍 海外
韩国综合指数(KS11.GI)(指数) → -3.485% → - → -
纳斯达克(IXIC.GI)(指数) → -2.856% → - → -
日经225(N225.GI)(指数) → -2.118% → - → -
台湾加权(TWII.GI)(指数) → -2.494% → - → -
恒生指数(HSI.HI)(指数) → 1.462% → 146.9亿手 → 2143亿港元
📊 大盘
指数 → 收盘 → 涨跌幅% → 成交额(亿)
上证指数 → 3599.02 → -1.44 → 76,423
沪深300 → 3985.50 → -1.39 → 45,686
科创50 → 1160.84 → -5.48 → 7,037
(数据日 20261030)
(源: tushare — 非交易时段按老板令换源,本段不调用 mx)
📂 板块
板块 → 点位 → 涨跌幅%
半导体 → 12057.81 → -5.44
创新药 → 1158.98 → -0.56
银行 → 1441.61 → +0.77
保险 → 8268.59 → +0.85
航天装备 → 2825.01 → -1.41
通信设备 → 1487.17 → -3.55
(数据日 20261030;同花顺指数名未匹配: 光纤光缆)
(源: tushare — 非交易时段按老板令换源,本段不调用 mx)
📊 因果基因(脚本自证)
- 数据源: 海外段=妙想 mx_data.py(tushare index_global 不覆盖韩/纳指);大盘+板块段=tushare(mx_daily_scan_tushare.py index_daily / ths_index+ths_daily)——2026-10-13 老板令「mx 实时数据只在交易时段用,非交易时段换 tushare,海外除外」,本 cron 06:45 属非交易时段故换源
- 分析路径: 三段取数 → clean_table规整 → 「数据完整度 N/3」头 + 分段输出
- 判断: 海外/大盘/板块涨跌成交额概览;缺失段显式降级解读,全失败不发空壳
```
你是崩溃自动诊断agent。monitor 输出显示 crash_reports 有【新报告】(对比上次tick有变化), 按以下步骤处理新增的那份/那几份:
1. 读取新报告全文, 定位崩溃的脚本/cron job。
2. 用日志(journalctl / ~/.hermes/logs/errors.log / 脚本自身log)复现根因。
3. 根因明确且修复≤10行 → 直接修 + 本地复跑验证 + 三行报备。
修复>10行或涉及架构 → 只出根因分析+方案, 不动手。
4. 修复后把对应旧报告改名加 .resolved 后缀(防止重复诊断)。
5. 无新增报告(monitor diff 为空时本agent根本不会被唤醒) → 不跑。
## Run Context
## MONITOR CHANGE DETECTED
The monitored source's output changed since the last run.
### Diff (previous → current)
```diff
--- previous
+++ current
@@ -1,4 +1,4 @@
latest crash reports:
+20261102_145035_intraday_1440_tail_degraded rc=1.md sha1=9235a39edd5fdbf0f07e6e918c54e91183d0e9a5
20261101_063126_daily_health_wrapper.resolved sha1=6bd65cad4f7082781f0083669da2bfc4abb37179
20261030_145106_intraday_1440_tail_degraded rc=1.md sha1=050fda6b6ca8dde86c3c1ae5e418712352b330fa
-20261029_232644_daily_reports_to_ima_wrapper.sh.md sha1=d8b3ccf1770e730b32a53607824236e2f694af3f
```
### Current output
```
latest crash reports:
20261102_145035_intraday_1440_tail_degraded rc=1.md sha1=9235a39edd5fdbf0f07e6e918c54e91183d0e9a5
20261101_063126_daily_health_wrapper.resolved sha1=6bd65cad4f7082781f0083669da2bfc4abb37179
20261030_145106_intraday_1440_tail_degraded rc=1.md sha1=050fda6b6ca8dde86c3c1ae5e418712352b330fa
```
**Response Characters:** 3463
## Response
## 崩溃诊断报告:`intraday_1440_tail_degraded rc=1`(2026-11-02 14:50:35)
**结论一句话**:不是新故障,是**自 10/12 起每个交易日必发的慢性病**——14:40 尾盘数据层三段里 dynamic、mainforce 两段在盘中双双超过 180s 段超时,韧性层降级交付后按设计发软失败 → 每天生成一份 crash report(crash_reports 里该脚本累计 **70 份**)。今天更糟一层:10:30 的缓存也被打穿,dynamic 连兜底都没有。
---
### 一、根因链(数据源 → 分析路径 → 判断)
**① 现场(crash report + 快照 + 韧性日志)**
- 韧性日志 `/tmp/cron_errors/intraday_1440_tail_resilience.log`:
`14:40:27 第1次尝试(480s) → 14:46:30 失败 rc=1(363s,输出2420字,指纹22a1f666)→ 14:46:32 第2次(仅剩235s) → 14:50:27 被外层超时杀(输出60字=只剩[数据层失败]一行)→ 14:50:35 预算600s耗尽 → 降级交付`
- 363s ≈ breadth(~3s) + dynamic 180s + mainforce 180s,两段**都跑满超时**。
- 快照 `cache/snapshots/20261102/尾盘决策_20261102_数据层.md`:breadth ✅、上游链 ✅;`dynamic [不可用: TimeoutExpired 180s 且无同日可用缓存]`、`mainforce [不可用: TimeoutExpired 180s]`。
**② 为什么 dynamic 没兜底**:`/tmp/dynamic_scan.json` mtime=10:40、内容 `error:"timeout_or_empty"` —— 10:30 cron 的 `timeout 600 python3 dynamic_scan.py` 10:30+600s=10:40 正好打穿(同文件10:40落占位符);`_dynamic_cache_usable()` 规则「error 占位不算可用」正确拒绝。附带:executions.db 显示该 cron `10:30:27→12:31:25 status=unknown, treated as wedged`(跑挂2小时)。
**③ 为什么两段超时(复现实测,盘后强制走盘中取数路径 `_is_trading_hours=True`)**
| 实验 | 结果 |
|---|---|
| dynamic_scan.py 全量166只(盘中路径) | **222.5s > 180s 超时线**,57次 westock「服务限频」,限频单码 4.2~4.9s(正常0.7s) |
| dynamic 10:30 生产(600s预算) | **>600s**(10:40 才落占位符) |
| mainforce_scan.py 盘中路径(盘后) | 62~78s ✅;但**盘中生产 180s 100% 打穿** |
| mainforce 与 dynamic 并发(盘后) | 62s ✅ |
- profile(cProfile,78s):`dadian_boost 40s + get_finance(mootdx含32次0.9s sleep) 31s + get_daily 60次 26s + industry_overview 18s`。
- 判断:**盘中 westock/mootdx 网络延迟+限频把单调用从 0.7s 抬到 ~4.5s,60次 get_daily + 10次 get_finance 放大 2.5~3×** → mainforce 盘中 ~230-300s、dynamic ~222s+,双双超 180s。盘后实测 62-78s 与生产 100% 超时的差值即盘中膨胀系数(盘后无法 1:1 复现盘中限频,标注为推断)。
**④ 为什么重试救不回来**:第1次烧掉363s → 第2次只剩235s < 必需363s → 必被截断成零信息 → 预算耗尽。韧性层的「确定性故障停重试」指纹机制失效(第2次输出被杀成空,SIG="" ≠ 上次指纹)。
### 二、重复性(报告问题4)
- errors.log:`intraday_1440_tail_degraded` **10/20、21、22、23、26、27、28、29、30、11/02 连续10个交易日每天一条**;更早 10/16-10/19 一批。
- 快照库统计(98份):**主力三问段 TimeoutExpired 自 10/12 起 16 个交易日 100% 失败**(09:30闸门 + 14:40尾盘两时点全中);10/12 之前全部 MF_OK(当时超时线还只有90s)。
- 本脚本 crash_reports 累计 70 份 → 每天唤醒诊断 agent 重诊同一病。
### 三、影响
14:40 尾盘决策 AI 层**每天缺「动态扫描」+「主力三问」两个数据段**(dynamic 仅在 10:30 cron 成功时能靠同日缓存补回,10/28-30 即如此;今天连缓存都没了)。breadth 与上游链路正常,属降级非中断。
### 四、方案(未动手,理由在后)
**方案A·调预算(≈4行,但需盘中验证)**
`intraday_chain.py`:`DYNAMIC_RUN_TIMEOUT_S 180→240`、`MAINFORCE_RUN_TIMEOUT_S 180→300`;`intraday_1440_tail.sh`:`ATTEMPT_TIMEOUT 480→560`。
⚠️ 算术红线:段超时上限和(breadth90+dyn240+mf300=630)必须 < TOTAL_BUDGET 600,否则外层中途 kill → stdout 全空 → 比降级更糟的 `no_output` 整单丢失(脚本内注释已记录该陷阱)。**上限和压到 600 内只剩几秒余量,且无法保证 240s 装得下盘中的 dynamic**(10:30 实测 >600s)。
**方案B·根治(架构级)**
① dynamic 14:00/14:40 改「同日缓存优先、跳过注定超时的直跑」(盘中直跑 100% 失败,直跑后再兜底=白烧180s);② mainforce 盘中降采样(get_finance/dadian 段按盘中延迟自适应跳过);③ westock 限频时同一码不再 primary+fallback 连打两次(单码 4.5s 中约一半是二次尝试);④ 10:30 dynamic cron 的 wedged(跑2小时)单独立案。
**方案C·监控降噪(1行,需老板裁决)**
degraded 路径实为**退出码0的按设计降级**(report 头「退出码: 0」),却每天生成 crash report 唤醒本 agent。可改为「已知慢性病去重/节流」而非静默删除——静默=掩盖数据不全,违反坏结果照报,故未动。
### 五、为什么按规则「只出分析+方案,不动手」
1. 方案A/B 均 **>10 行或跨文件预算重构**,且踩「外层超时杀→整单无输出」的既有陷阱;
2. 任何超时调整**必须盘中(下一交易日 9:30 后)实测才能验收**,盘后复跑只能证明 62-78s < 新上限,证不了盘中 230-300s 是否装得下——现在改=未验证即宣告完成;
3. 报告**未改名 .resolved**(未修复不标记,防止后续误判已解决)。
**三行报备**:✅查清根因=盘中限频使 dynamic/mainforce 超180s段超时+10:30缓存被打穿,慢性复发16个交易日;✅验证=盘后强制盘中路径复现 dynamic 222.5s/57次限频、mainforce 62-78s,快照/韧性日志/ executions.db 三方对齐;⏳未修=方案A/B超10行且需盘中验收,等裁决后下一交易日实测再动手。