Atlas 技術版 > cron 健康檢查
cron 健康檢查(deterministic):偵測 error/delivery failure/stale next run/stuck execution,靜默通過、異常才輸出診斷區塊。
mode=NO_AGENT state=scheduled enabled=1
schedule=30 22 * * 1-5
next_run=2026-10-21T22:30:00 last_run=2026-10-20T22:30:41
deliver=telegram model=— provider=—
script=/Users/exion/.hermes/scripts/cron_healthcheck_deterministic.py
monitor_script=— monitor_url=—
skills=["telegram-format-cron", "cron-self-review"]
workdir=—
prompt_sha256=765654713d05b452… chars=1459
skill_files={}
[IMPORTANT: You are running as a scheduled cron job. DELIVERY: Your final response will be automatically delivered. Do NOT use send_message.]
你是蓓兒丹娣。執行 cron 健康檢查,檢查所有 enabled cron jobs 的狀態。
## 檢查範圍
1. 使用 cronjob(action='list') 取得所有 cron jobs 清單
2. 篩選出 enabled=true 的 jobs
3. 對每個 enabled job,檢查:
- last_status:是否為 "error"
- 若 last_run_at 超過預期執行週期仍未執行(例如每日排程卻超過 48 小時未跑)
4. 最後一次執行是否有 delivery error
## 健康檢查報告格式
**📋 cron 健康檢查報告** (資料時間: {current_date})
✅ 全部正常時:
```
所有 {N} 個 enabled cron jobs 皆正常運作 ✅
```
⚠️ 有錯誤時,列出每個異常 job:
```
❌ 異常 Job #{n}: {job_name}
排程: {schedule}
上次執行: {last_run_at}
狀態: {last_status}
交付錯誤: {last_delivery_error or "無"}
```
## 錯誤摘要區塊(P0 — 給 LLM 診斷用)
如果有任何異常 job,在報告末尾加上以下格式的摘要區塊,讓建智大人可以直接複製貼給 LLM 思考解決方案:
```
=== CRON_ERROR_DIAG ===
Time: {ISO datetime}
Total jobs: {N} | Enabled: {E} | Errors: {Err}
Job: "{job_name}" ({job_id})
Schedule: {schedule}
Script: {script or "none"}
Last run: {last_run_at}
Status: {last_status}
Delivery error: {last_delivery_error or "none"}
Last OK: (last time it ran successfully)
Possible causes:
- (根據 error 類型推測 2-3 個可能原因)
=== END_CRON_ERROR_DIAG ===
```
錯誤類型判斷指引:
- `last_status="error"` + `last_delivery_error=null` → 腳本執行失敗(exit code non-zero)
- `last_status="ok"` + 有 `last_delivery_error` → 腳本成功但交付失敗
- `last_status="error"` + 有 `last_delivery_error` → 雙重失敗
- 長時間未執行(超過排程間隔 2 倍)→ 排程器可能卡住
## 輸出規則
- 全部正常 → 簡潔回報一句話即可
- 有異常 → 輸出完整報告 + 每個異常 job 的診斷區塊
- 不要加不必要的修飾語,建智大人只看事實…| rule | value | source |
|---|---|---|
| JOBS_PATH | /Users/exion/.hermes/cron/jobs.json | CODE_STATIC @cron_healthcheck_deterministic.py:55 |
| EXECUTIONS_PATH | /Users/exion/.hermes/cron/executions.db | CODE_STATIC @cron_healthcheck_deterministic.py:56 |
| HERMES_AGENT_DIR | /Users/exion/.hermes/hermes-agent | CODE_STATIC @cron_healthcheck_deterministic.py:72 |
| SEMANTIC_BUSINESS_FAILED | BUSINESS_EXECUTION_FAILED | CODE_STATIC @cron_healthcheck_deterministic.py:190 |
| SEMANTIC_TERMINAL_ACCOUNTING_UNCONFIRMED | TERMINAL_ACCOUNTING_UNCONFIRMED | CODE_STATIC @cron_healthcheck_deterministic.py:191 |
| SEMANTIC_CONDITIONAL_SKIP | CONDITIONAL_DEPENDENCY_UNAVAILABLE_HONEST_SKIP | CODE_STATIC @cron_healthcheck_deterministic.py:192 |
| SEMANTIC_DELIVERY_CONFIG | DELIVERY_TARGET_UNRESOLVABLE | CODE_STATIC @cron_healthcheck_deterministic.py:193 |
| SEMANTIC_DELIVERY_FAILED | DELIVERY_FAILED | CODE_STATIC @cron_healthcheck_deterministic.py:194 |
| SEMANTIC_STUCK | EXECUTION_STUCK_OR_OVERRUN | CODE_STATIC @cron_healthcheck_deterministic.py:195 |
| SEMANTIC_STALE | SCHEDULE_STALE_NO_SUCCESSFUL_RUN | CODE_STATIC @cron_healthcheck_deterministic.py:196 |
| SEVERITY_FAILURE | FAILURE | CODE_STATIC @cron_healthcheck_deterministic.py:198 |
| SEVERITY_ACCOUNTING_GAP | ACCOUNTING_GAP | CODE_STATIC @cron_healthcheck_deterministic.py:199 |
| SEVERITY_CONDITIONAL_SKIP | CONDITIONAL_SKIP | CODE_STATIC @cron_healthcheck_deterministic.py:200 |
| SEVERITY_DELIVERY | DELIVERY | CODE_STATIC @cron_healthcheck_deterministic.py:201 |
| SEVERITY_STUCK | STUCK | CODE_STATIC @cron_healthcheck_deterministic.py:202 |
| SEVERITY_STALE | STALE | CODE_STATIC @cron_healthcheck_deterministic.py:203 |
| kind | path | name | access |
|---|---|---|---|
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | unknown | |
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | unknown | |
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | read/write | |
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | unknown | |
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | read/write | |
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | unknown | |
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | read/write | |
| SQLITE_DB | /Users/exion/.hermes/cron/executions.db | read/write | |
| SQLITE_TABLE | /Users/exion/.hermes/cron/executions.db | executions | read |
| SQLITE_TABLE | /Users/exion/.hermes/cron/executions.db | executions | read |
| SQLITE_TABLE | /Users/exion/.hermes/cron/executions.db | executions | read |
| SQLITE_TABLE | /Users/exion/.hermes/cron/executions.db | executions | read |
| SQLITE_TABLE | /Users/exion/.hermes/cron/executions.db | executions | write |
| FILE_READ | /Users/exion/.hermes/cron/jobs.json | read | |
| FILE_WRITE | +00:00 | write | |
| CONFIG | UNKNOWN | unknown | |
| CONFIG | UNKNOWN | unknown | |
| CONFIG | UNKNOWN | unknown |
Upstream: —
Downstream: TH-0164 持股參考線自然驗收讀回(一次)、TH-0150 持股 Feed 自然刷新驗收(一次)、TH-0154 Runner參考線自然驗收讀回(一次)
Transitive downstream (21): 13:07 盤中狀態通知 (5410c0495072)、E7×C20 影子策略每日 EOD(ingest→雙帳→月報→通知) (1dba3cb93ead)、DAILY_E7_FORMAL 每日正式訊號 (5b90a48ae44c)、E7 Control vs C20 Prospective Lifetime Shadow (45037d292145)、處置股票狀態查詢 (61f12b08c955)、Shioaji每日股價抓取 (205fea19ed1e)、每日帳戶資產記錄 (198667493819)、週日長紅K回測報告(現行規則:停損+20MA停利) (68ea49353330)、層零市場風險過濾器 (11c1041f48b4)、盤中持股即時快照1300 (d94622a2d6b8)、13:08 盤中決策摘要資料準備 (8f2a6c1d9b44)、13:09 盤中決策摘要 (b7d94e3a1c20) …+9
| type | hard? | from | to | resource | origin | conf | evidence |
|---|---|---|---|---|---|---|---|
| DATA | soft | cron 健康檢查 | TH-0164 持股參考線自然驗收讀回(一次) | sqlite:executions | STATIC | 0.75 | table 'executions' write@41eeb394dee7(line 618) -> read@031bb097c4f2(line 66) |
| DATA | soft | cron 健康檢查 | TH-0150 持股 Feed 自然刷新驗收(一次) | sqlite:executions | STATIC | 0.75 | table 'executions' write@41eeb394dee7(line 618) -> read@4ead92294154(line 62) |
| DATA | soft | cron 健康檢查 | TH-0154 Runner參考線自然驗收讀回(一次) | sqlite:executions | STATIC | 0.75 | table 'executions' write@41eeb394dee7(line 618) -> read@67746172fb4e(line 114) |
failure_streak=0
last_error=—
delivery_error=—
change_risk=CRITICAL