步骤4阶段1 - 1周核心闭环方案
制定日期: 2026-09-13
观察任务: cron_id=7e8ae2aeca81
当前进度: D1观察中(16次自动运行,100%成功)
任务1:1周排期表
| 日期 |
阶段 |
核心任务 |
验收标准 |
依赖 |
| D1 9/13 |
告警系统上线 |
alert_channel_health + dead_mans_switch + run_with_alert集成 |
D1观察通过(100%成功) |
无 |
| D2 9/14 |
受控测试 |
告警路径、超时路径、Dead-Man、通道健康 |
4项测试全部通过 |
D1 |
| D3 9/15 |
风控熔断 |
总仓位、单票、回撤、流动性熔断 |
熔断逻辑验证通过 |
D2 |
| D4 9/16 |
影子运行 |
双系统并行+比对 |
输出偏差报告 |
D3 |
| D5 9/17 |
2C-1子集 |
裁剪非必要模块 |
核心闭环稳定运行 |
D4 |
| D6 9/18 |
消除重复 |
去重+合并冗余cron |
cron数量≤10个 |
D5 |
| D7 9/19 |
验收 |
全流程回归测试 |
零失败,交付使用 |
D6 |
任务2:受控测试方案(D2)
2.1 测试矩阵
| 测试项 |
注入方式 |
预期结果 |
验证方法 |
耗时 |
| 告警路径 |
jobs.json添加test_alert_path_001 + task_runs插入failed记录 |
[TEST]前缀TG告警 |
检查TG频道 |
1小时 |
| 超时路径 |
修改last_run_at为3天前 |
timeout告警 |
检查TG频道 |
1小时 |
| Dead-Man |
停心跳30分钟 |
dead_man告警 |
检查TG频道 |
15分钟 |
| 通道健康 |
改TG token为错误值 |
channel_error告警 |
检查TG频道 |
1分钟 |
2.2 测试执行流程
# === 前置:备份生产数据 ===
cp C:/Users/Admin/AppData/Local/hermes/cron/jobs.json C:/Users/Admin/AppData/Local/hermes/cron/jobs.json.bak_D2测试
# === 测试1:告警路径 ===
# 1.1 添加测试任务到jobs.json
python -c "
import json
from pathlib import Path
jobs_path = Path('C:/Users/Admin/AppData/Local/hermes/cron/jobs.json')
data = json.loads(jobs_path.read_text(encoding='utf-8'))
# 添加测试任务
data['jobs'].append({
'id': 'test_alert_path_001',
'name': '[TEST] 告警路径测试',
'schedule': '*/15 * * * *',
'command': 'python -c \"import time; time.sleep(1)\"',
'last_status': 'failed',
'last_run_at': '2026-09-14T10:00:00+08:00'
})
jobs_path.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding='utf-8')
print('测试任务已添加')
"
# 1.2 插入failed记录到task_runs
python -c "
import sqlite3
conn = sqlite3.connect('D:/Hermes/data/state/alert_state.db')
conn.execute(\"\"\"
INSERT OR REPLACE INTO task_runs
(task_id, status, start_time, exit_code, error_message, created_at)
VALUES ('test_alert_path_001', 'failed', '2026-09-14T10:00:00', 1, 'test alert trigger', datetime('now'))
\"\"\")
conn.commit()
conn.close()
print('测试记录已插入')
"
# 1.3 等待cron运行(约15分钟),检查TG是否收到[TEST]前缀告警
# 1.4 清理测试数据
python -c "
import json
from pathlib import Path
jobs_path = Path('C:/Users/Admin/AppData/Local/hermes/cron/jobs.json')
data = json.loads(jobs_path.read_text(encoding='utf-8'))
data['jobs'] = [j for j in data['jobs'] if j['id'] != 'test_alert_path_001']
jobs_path.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding='utf-8')
print('测试任务已清理')
"
python -c "
import sqlite3
conn = sqlite3.connect('D:/Hermes/data/state/alert_state.db')
conn.execute(\"DELETE FROM task_runs WHERE task_id = 'test_alert_path_001'\")
conn.commit()
conn.close()
print('测试记录已清理')
"
# === 测试2-4:类似流程,分别注入不同故障 ===
2.3 测试通过标准
- [ ] 告警路径:收到包含
[TEST]前缀的TG消息
- [ ] 超时路径:收到包含
timeout关键词的TG消息
- [ ] Dead-Man:停心跳30分钟后收到dead_man告警
- [ ] 通道健康:改token后收到channel_error告警
- [ ] 清理后:jobs.json恢复原状,task_runs无残留
任务3:并行清单
3.1 可并行任务
| 任务组 |
任务内容 |
并行度 |
说明 |
| A组 |
D1观察 + D2准备 |
高 |
D1观察继续,同时准备D2测试脚本 |
| B组 |
D2测试 + D3设计 |
中 |
D2测试执行时,可并行设计D3风控熔断逻辑 |
| C组 |
D4影子运行 + D5子集裁剪 |
高 |
影子运行时可开始设计2C-1裁剪方案 |
| D组 |
文档编写 + 回归测试 |
中 |
每日观察记录可同时编写 |
3.2 不阻塞核心路径的任务
| 任务 |
优先级 |
说明 |
| 历史数据回填 |
低 |
不影响实时运行,可后台执行 |
| 报告格式优化 |
低 |
用户体验优化,非核心功能 |
| 多源数据融合 |
中 |
长期价值,非D1-D7必须 |
| IC验证引擎 |
中 |
因子有效性验证,可与D3并行 |
任务4:增量迭代计划
4.1 核心闭环上线后边跑边补的模块
| 模块 |
当前状态 |
迭代计划 |
预计完成 |
| alert_channel_health |
✅ 已上线 |
D2验证后稳定运行 |
D2 |
| dead_mans_switch |
✅ 已部署 |
D2验证后稳定运行 |
D2 |
| run_with_alert |
⏳ 待集成 |
D3集成到主流程 |
D3 |
| 风控熔断层 |
❌ 未实现 |
D3设计+实现 |
D3 |
| 影子运行比对 |
❌ 未实现 |
D4设计+实现 |
D4 |
| 2C-1裁剪 |
❌ 未实现 |
D5设计+执行 |
D5 |
| 去重合并 |
❌ 未实现 |
D6执行 |
D6 |
| 全流程回归 |
❌ 未实现 |
D7执行 |
D7 |
4.2 各模块独立排期
模块1:alert_channel_health(D1-D2)
D1: 观察运行(已完成16次,100%成功)
D2: 受控测试(告警路径、超时路径、Dead-Man、通道健康)
验收: 4项测试全部通过
模块2:dead_mans_switch(D1-D2)
D1: 部署验证(心跳写入正常)
D2: 故障注入测试(停心跳30分钟)
验收: 收到dead_man告警
模块3:run_with_alert(D3)
D3: 集成到主评估流程
D3: 验证alert钩子正常工作
验收: 评估完成后触发告警检查
模块4:风控熔断层(D3)
D3: 设计熔断逻辑(总仓位>80%、单票回撤>5%、流动性不足)
D3: 实现熔断检查脚本
D3: 集成到run_with_alert
验收: 触发熔断条件时输出警告
模块5:影子运行比对(D4)
D4: 搭建双系统(原系统 vs 新系统)
D4: 并行运行输出比对报告
D4: 分析偏差>5%的项目
验收: 输出偏差报告,确认新系统无回归
模块6:2C-1子集裁剪(D5)
D5: 识别非必要模块(低频cron、备用数据源)
D5: 执行裁剪(保留核心7个cron)
D5: 验证裁剪后功能完整
验收: cron数量≤10个,核心功能无损
模块7:去重合并(D6)
D6: 扫描重复cron(相同脚本多次调度)
D6: 合并重复任务
D6: 验证合并后正常运行
验收: 无重复调度,cron总数最小化
模块8:全流程回归(D7)
D7: 执行完整回归测试
D7: 验证所有cron正常运行
D7: 输出验收报告
验收: 零失败,交付使用
任务5:不能砍的底线
5.1 P0核心验证(必须完成)
| 验证项 |
验证方法 |
通过标准 |
| 告警系统核心 |
alert_channel_health运行7天 |
100%成功率,无误告警 |
| Dead-Man开关 |
停心跳30分钟注入测试 |
收到告警 |
| 风控熔断 |
模拟触发熔断条件 |
输出警告,不阻断主流程 |
| 回滚方案 |
一键回滚到D0状态 |
<5分钟完成回滚 |
5.2 P1基础保障(强烈建议)
| 保障项 |
保障方法 |
说明 |
| 至少1天影子运行 |
D4双系统并行比对 |
确认新系统无回归 |
| 数据备份 |
每日自动备份alert_state.db |
WAL模式+定时备份 |
| 监控告警 |
cron运行失败立即告警 |
覆盖所有关键cron |
| 日志归档 |
保留30天运行日志 |
便于问题追溯 |
5.3 铁律(不可妥协)
1. 不改生产cron配置 → 新系统并行运行,不替换现有任务
2. 不执行真实交易 → 仅监控+告警,不触发动作
3. 每日备份 → alert_state.db每日备份到独立目录
4. 一键回滚 → 任何阶段发现问题,5分钟内恢复到前阶段状态
5. 证据先行 → 每个阶段输出硬证据(日志路径+脚本路径+时间戳)
附录:当前系统状态
A.1 已部署组件
| 组件 |
文件路径 |
cron_id |
状态 |
| alert_channel_health |
D:/Hermes/scripts/alert_channel_health.py |
7e8ae2aeca81 |
✅ 运行中 |
| dead_mans_switch |
D:/Hermes/scripts/dead_mans_switch.py |
- |
✅ 已部署 |
| run_with_alert |
D:/Hermes/scripts/run_with_alert.py |
- |
⏳ 待集成 |
A.2 D1观察统计
| 指标 |
值 |
| 自动运行次数 |
16次(10:30-14:15) |
| 成功率 |
100% |
| 平均间隔 |
15m05s |
| 心跳记录 |
18条(全部ok) |
| TG通知 |
0次(expected) |
| exit_code |
全部0 |
A.3 待执行检查
| 时间 |
检查内容 |
状态 |
| 20:00 |
晚间检查 |
⏳ 待执行 |
| 次日10:00 |
D1总结 |
⏳ 待执行 |
方案制定: 2026-09-13T14:25:00
下一步: 等待20:00晚间检查 + 次日10:00 D1总结后进入D2