docs: 规范v1.1(单例守卫/超时/LLM容错/部署规范)+ 系统审计报告十~十一章 + 部署方案完整准备
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# MoFin 开发规范
|
||||
|
||||
> 版本:1.0 | 日期:2026-07-03 | 维护:Sisyphus + Zhiwei
|
||||
> 版本:1.1 | 日期:2026-07-03(1.1 更新 2026-08-10)| 维护:Sisyphus + Zhiwei
|
||||
> 1.1 新增:Cron 单例守卫/600s超时/LLM容错/调度单一(5.3-5.6)+ 部署规范(五·补 D1-D4)
|
||||
|
||||
---
|
||||
|
||||
@@ -113,6 +114,86 @@
|
||||
- `regenerate_all` 可重复运行不产生副作用
|
||||
- 所有写操作支持重复执行
|
||||
|
||||
### 5.3 单例守卫(2026-08-10 新增,铁律)
|
||||
|
||||
**所有定时/常驻脚本必须加单例守卫,防止 cron 重复触发导致多个实例并发。**
|
||||
|
||||
- 实测教训:`refresh_mtf_cache.py` 无守卫,cron 重复触发两个实例 → SQLite `database is locked` 长锁,拖垮候选管道
|
||||
- 必须用 `fcntl.flock(LOCK_EX | LOCK_NB)` 实现(进程级,进程死自动释放)
|
||||
- 示例:
|
||||
```python
|
||||
import fcntl
|
||||
lock_f = open("/tmp/xxx.lock", "w")
|
||||
try:
|
||||
fcntl.flock(lock_f, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except OSError:
|
||||
print("[XXX] 已有实例在运行,退出")
|
||||
return
|
||||
```
|
||||
- 守卫在脚本 `main()` 开头执行,持有到脚本结束
|
||||
|
||||
### 5.4 600s 超时限制(2026-08-10 新增,铁律)
|
||||
|
||||
**hermes cron `child_timeout_seconds=600`,脚本运行超 600s 会被 SIGTERM 杀掉(exit code -15)。**
|
||||
|
||||
- 实测教训:`promote_candidates.py` 处理 240 候选 × 18s/个 >> 600s 被杀
|
||||
- **重型脚本必须控制单次运行时长**:
|
||||
- 分批处理(每批限 N 个,剩余留待下批)
|
||||
- 内部子进程超时缩短(如重评 480s→120s)
|
||||
- 总时长护栏(如 500s,留 100s 余量)
|
||||
- 循环中定期检查 `time.time() - START_TIME > BUDGET`,超时 break
|
||||
|
||||
### 5.5 LLM 依赖容错(2026-08-10 新增)
|
||||
|
||||
**依赖 LLM API 的 cron(简报/洞察/推荐)必须处理"LLM 失败"情况:**
|
||||
|
||||
- 实测教训:开盘简报 LLM 返回空流 → 静默失败无输出,状态未记录
|
||||
- 要求:
|
||||
- LLM 调用失败时输出明确错误标记(非静默)
|
||||
- jobs.json 状态正确记录失败(不显示 ok)
|
||||
- 有重试机制(3次内重试)
|
||||
- 失败时仍输出已生成的模板部分(不整体丢弃)
|
||||
|
||||
### 5.6 调度通道单一(2026-08-10 新增)
|
||||
|
||||
**同一脚本只保留一个调度入口,避免重复触发:**
|
||||
|
||||
- 实测教训:cron_to_xmpp 有主 profile + position-analyst + 系统 crontab 三处调度,可能重复推送
|
||||
- 规范:一个脚本一个调度(选择最优的 profile/crontab),废弃的调度显式移除或禁用
|
||||
|
||||
---
|
||||
|
||||
## 五·补、部署规范(2026-08-10 新增,实战踩坑教训)
|
||||
|
||||
### D1. deploy_guard 机制(必须遵守)
|
||||
|
||||
**deploy_guard 监控 CODE_PATHS(deploy/profile-scripts 等),发现未入库改动即回滚到 git HEAD。**
|
||||
|
||||
- ❌ 禁止:直接改 246 上 deploy/profile-scripts 的脚本而不 commit → 会被守卫回滚
|
||||
- ✅ 正确流程:
|
||||
```
|
||||
1. 修改脚本(246 或本地)
|
||||
2. 立即 commit:GIT_ALLOW_COMMIT=1 git commit -m 'fix: 说明'
|
||||
3. push:git push https://hmo@git.yoin.fun/hmo/MoFin.git master
|
||||
4. 守卫下次运行看到 CODE_PATHS 干净 → 不回滚
|
||||
```
|
||||
|
||||
### D2. 提交白名单
|
||||
|
||||
- pre-commit 钩子要求 `GIT_ALLOW_COMMIT=1` 才放行(知微无此令牌 = 无法提交)
|
||||
- **小小莫本人操作显式携带该令牌**(有 git 写权限)
|
||||
- 知微的修改路径:kanban 提单给小小莫评审执行
|
||||
|
||||
### D3. push 身份
|
||||
|
||||
- **必须用 hmo 身份 push**(`git push https://hmo@git.yoin.fun/...`),store 凭据
|
||||
- ❌ 禁止改 `git config user.name` 为 xxm/mohe(凭据匹配错身份 → push 被拒)
|
||||
|
||||
### D4. 修改后验证
|
||||
|
||||
- 每次修改必须验证:`python3 -u xxx.py` 实际运行(看是否报错/超时/锁冲突)
|
||||
- 验证结果记录到 CHANGELOG 或部署文档
|
||||
|
||||
---
|
||||
|
||||
## 六、开发流程
|
||||
|
||||
@@ -181,3 +181,59 @@ accumulation_scanner → candidates(sector='accumulation')
|
||||
|---|---|
|
||||
| 9f82a9b1 | promote_candidates 超时(限批10+单例守卫+重评120s+护栏500s)|
|
||||
| 79980ce9 | candidate_filter pass_final 死角(低分<7 七天重审)|
|
||||
|
||||
## 十、管道修复验证记录(2026-08-10,全部通过)
|
||||
|
||||
| 验证 | 结果 |
|
||||
|---|---|
|
||||
| candidate_filter 完整跑通 | ✅ 84只重审,无报错无锁冲突 |
|
||||
| promote_candidates 完整跑通 | ✅ 59只处理完,无超时(限批+护栏生效)|
|
||||
| 行为回归(RR门槛/ST排除)| ✅ 59只全RR<2+3只ST拒 → 0提拔合理 |
|
||||
| 守卫不回滚(已入库)| ✅ 两个修复 commit 后保留 |
|
||||
|
||||
**关键确认**:accumulation 候选 RR 普遍<2(本次59只0通过)是**扫描器与门槛的固有冲突**,非bug。我的 p_oversold 策略接入时用专属评估规避。
|
||||
|
||||
## 十一、部署新策略前的完整准备(2026-08-10 最终版)
|
||||
|
||||
### 11.1 系统检修已完成(修复项)
|
||||
| 修复 | commit | 验证 |
|
||||
|---|---|---|
|
||||
| promote_candidates 超时(限批+守卫+护栏)| 9f82a9b1 | ✅ 57候选60s跑完 |
|
||||
| candidate_filter pass_final 死角(7天重审)| 79980ce9 | ✅ 0→84只重审 |
|
||||
| candidate_filter 单例守卫(规范5.3)| 4e10ca9a | ✅ 正常执行 |
|
||||
| 小果残留清理(health_checklist)| 运行时文件 | ✅ 体检无小果误报 |
|
||||
| 规范修正(DEVELOPMENT_STANDARDS v1.1)| 待提交 | ✅ 5.3-5.6+部署规范 |
|
||||
|
||||
### 11.2 已知未修问题(记录,不影响新策略)
|
||||
- 策略评估-每日 Connection error(8/6起)
|
||||
- 市场精选推荐 7/31后停摆
|
||||
- 收盘简报 8/7 RuntimeError
|
||||
- LLM API 不稳定导致简报静默失败(需监控)
|
||||
- refresh_mtf_cache 等其他定时脚本缺守卫(系统性)
|
||||
|
||||
### 11.3 新策略部署 checklist(p_oversold)
|
||||
```
|
||||
□ 1. 研究侧:strategy_lab.py 注册 v_oversold_v1(title/algorithm/rationale/evidence)
|
||||
□ 2. 扫描器:predictive_oversold_scanner.py
|
||||
- 腾讯行情源(对齐 accumulation_scanner)
|
||||
- 大盘门控(mkt_rsi<50 + mkt_dd60<=-5 + 阴跌跳过)
|
||||
- 写 candidates 表 sector='p_oversold' + 当日幂等
|
||||
- 单例守卫(规范5.3)+ 限批/护栏(规范5.4)
|
||||
□ 3. 候选评估:按我的选股逻辑(不复用 accumulation 的 RR>=2)
|
||||
- 方案A:独立评估(推荐)
|
||||
- 方案B:复用管道但改门槛
|
||||
□ 4. 调度:market_watch 链式 或 独立 cron(规范5.6 调度单一)
|
||||
□ 5. 验证:python3 -u xxx.py 实测(规范D4)
|
||||
□ 6. 入库:GIT_ALLOW_COMMIT=1 commit + hmo push(规范D1-D3)
|
||||
□ 7. 健康监控:morning_health_check 注册 p_oversold 项
|
||||
□ 8. 知微交接:简报模板 + 策略文档 + 观察期
|
||||
□ 9. Tab UI:策略/组合Tab 归档区(折叠+延迟加载)
|
||||
□ 10. 观察期:实盘小资金验证
|
||||
```
|
||||
|
||||
### 11.4 部署红线(规范强约束)
|
||||
- 改动必须 commit 入库(deploy_guard 回滚机制)
|
||||
- push 必须 hmo 身份
|
||||
- 定时脚本必须单例守卫
|
||||
- 重型脚本必须控制 600s 内
|
||||
- 一个脚本一个调度
|
||||
|
||||
@@ -169,3 +169,77 @@ git.yoin.fun/hmo/MoFin.git ←← 246 的 origin(真正权威远端)
|
||||
- promote_candidates:分批处理(每批 N 个)+ 缩短 per_stock_reassess 超时 + 加单例守卫
|
||||
- candidate_filter:pass_final 语义修正(分数阈值才 pass,或允许重审)
|
||||
- 新策略接入:独立 sector(p_oversold)+ 考虑绕过通用 6 阶段评分(策略专属评分)或直接复用候选管道
|
||||
|
||||
## 七、检修补充发现(2026-08-10 策略评估/自愈体系)
|
||||
|
||||
### 策略评估/反馈/进化链路(数据正常)
|
||||
- strategy_evaluations 217条 / feedback 222 / history 5513 / research 111 / tracking 311 / lessons 16
|
||||
|
||||
### 🔴 cron 停摆/error
|
||||
| cron | 脚本 | 状态 | 根因 |
|
||||
|---|---|---|---|
|
||||
| 策略评估-每日 | stale_detector.py | 🔴 error(08-06起) | Connection error(stock_quote子进程超时+兜底失败)|
|
||||
| LLM修复循环-L3 | self_repair.py | 🔴 error(今天) | Script timed out after 600s(同promote问题)|
|
||||
| 策略复盘-每日 | strategy_review.py | ⚠️ 08-07后停 | 3天没跑 |
|
||||
| 分支剪枝-每日 | prune_branches.py | ⚠️ 08-07后停 | 3天没跑 |
|
||||
| 系统全局审计 | system_audit.py | ⚠️ 08-07后停 | 3天没跑 |
|
||||
|
||||
### ⚠️ TODO 滞留
|
||||
- todos 表 254 号:宏观风险HIGH TODO 卡 in_progress(07-29"调用知微失败timed out")——自愈链路滞留点
|
||||
|
||||
### 洞察
|
||||
- 策略评估链路实际停摆(3天)——评估体系没有真正闭环
|
||||
- self_repair 也是 600s 超时(与 promote 同类问题)——**系统性超时问题**:hermes child_timeout_seconds=600 对重型脚本太短
|
||||
- 这些与候选管道修复是**同一类问题**(超时),修复模式可复用
|
||||
|
||||
## 八、知微链路检修结论(2026-08-10)
|
||||
|
||||
| 检查项 | 结论 |
|
||||
|---|---|
|
||||
| 知微 bot 进程 | ✅ 运行中(xmpp_zhiwei_bot.py PID 1254814)|
|
||||
| 简报 cron 调度 | ✅ 正常(工作日跑,周末跳过符合预期)|
|
||||
| 开盘简报 | ✅ ok(next 08-11 09:35)|
|
||||
| 收盘简报 | ⚠️ 08-07 error(上周五,需查非紧急)|
|
||||
| 知微洞察 | ✅ next 今天15:35 |
|
||||
| 市场精选推荐 | ✅ next 今天16:00 |
|
||||
| 信息通道 | 简报模板→cron_to_xmpp→知微XMPP,链路完整 |
|
||||
|
||||
## 九、规范差距评估(DEVELOPMENT_STANDARDS.md vs 实际)
|
||||
|
||||
### 规范要求但实际缺失
|
||||
| 规范条目 | 实际状态 |
|
||||
|---|---|
|
||||
| run_all_tests.py 必须通过(6.2)| ❌ **脚本不存在**(只有 TEST_PLAN.md 文档)|
|
||||
| 一次 commit 一个逻辑(6.4)| ✅ 遵守 |
|
||||
| 无重复代码(1.1)| ⚠️ 部分违反(candidate_filter 直接写SQL)|
|
||||
|
||||
### 规范缺失(检修发现需补充)
|
||||
| 缺失内容 | 背景 |
|
||||
|---|---|
|
||||
| **单例守卫铁律** | refresh_mtf_cache 重复实例→db locked;promote 无守卫 |
|
||||
| **deploy_guard 部署流程** | 改 deploy/profile-scripts 必须 commit,否则被回滚(实战踩坑)|
|
||||
| **提交白名单** | GIT_ALLOW_COMMIT=1 令牌 + push 用 hmo 身份 |
|
||||
| **600s 超时限制** | hermes child_timeout_seconds=600,重型脚本需分批/护栏 |
|
||||
|
||||
## 十、知微链路深入检修(2026-08-10 二次)
|
||||
|
||||
### 🔴 今天开盘简报生成失败
|
||||
- 09:35 运行但 LLM API 失败(deepseek-v4-flash 空流 → 180s kill)
|
||||
- 无输出文件,jobs.json 状态未更新
|
||||
- 根因:LLM 通道不稳定 + 失败状态未正确记录
|
||||
|
||||
### 🔴 多个 cron 静默停摆/失败
|
||||
| cron | 问题 |
|
||||
|---|---|
|
||||
| 市场精选推荐 | 7/31后停摆(5交易日)|
|
||||
| 小果市场筛选 | 8/7 kill(code -15)|
|
||||
| 收盘简报 | 8/7 RuntimeError |
|
||||
| 策略评估-每日 | 8/6起 Connection error |
|
||||
|
||||
### ⚠️ cron_to_xmpp 双通道
|
||||
- 主 profile 30908cdc44a8(每分)7/23 停
|
||||
- position-analyst f948702cf5de(每5分)在跑
|
||||
- 系统 crontab */2 跑 deploy 版 → 可能重复
|
||||
|
||||
### 部署启示
|
||||
知微信息 = hermes cron + LLM + XMPP 推送。LLM 不稳定→简报静默失败,部署新策略需监控此链路。
|
||||
|
||||
Reference in New Issue
Block a user