docs: 规范v1.1(单例守卫/超时/LLM容错/部署规范)+ 系统审计报告十~十一章 + 部署方案完整准备

This commit is contained in:
hmo
2026-08-10 15:23:03 +08:00
parent 4e10ca9ab1
commit 4ad9923020
3 changed files with 212 additions and 1 deletions
+82 -1
View File
@@ -1,6 +1,7 @@
# MoFin 开发规范
> 版本:1.0 | 日期:2026-07-03 | 维护:Sisyphus + Zhiwei
> 版本:1.1 | 日期:2026-07-031.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_PATHSdeploy/profile-scripts 等),发现未入库改动即回滚到 git HEAD。**
- ❌ 禁止:直接改 246 上 deploy/profile-scripts 的脚本而不 commit → 会被守卫回滚
- ✅ 正确流程:
```
1. 修改脚本(246 或本地)
2. 立即 commitGIT_ALLOW_COMMIT=1 git commit -m 'fix: 说明'
3. pushgit 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 error8/6起)
- 市场精选推荐 7/31后停摆
- 收盘简报 8/7 RuntimeError
- LLM API 不稳定导致简报静默失败(需监控)
- refresh_mtf_cache 等其他定时脚本缺守卫(系统性)
### 11.3 新策略部署 checklistp_oversold
```
□ 1. 研究侧:strategy_lab.py 注册 v_oversold_v1title/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 内
- 一个脚本一个调度
+74
View File
@@ -169,3 +169,77 @@ git.yoin.fun/hmo/MoFin.git ←← 246 的 origin(真正权威远端)
- promote_candidates:分批处理(每批 N 个)+ 缩短 per_stock_reassess 超时 + 加单例守卫
- candidate_filterpass_final 语义修正(分数阈值才 pass,或允许重审)
- 新策略接入:独立 sectorp_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 errorstock_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_progress07-29"调用知微失败timed out")——自愈链路滞留点
### 洞察
- 策略评估链路实际停摆(3天)——评估体系没有真正闭环
- self_repair 也是 600s 超时(与 promote 同类问题)——**系统性超时问题**hermes child_timeout_seconds=600 对重型脚本太短
- 这些与候选管道修复是**同一类问题**(超时),修复模式可复用
## 八、知微链路检修结论(2026-08-10)
| 检查项 | 结论 |
|---|---|
| 知微 bot 进程 | ✅ 运行中(xmpp_zhiwei_bot.py PID 1254814|
| 简报 cron 调度 | ✅ 正常(工作日跑,周末跳过符合预期)|
| 开盘简报 | ✅ oknext 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 lockedpromote 无守卫 |
| **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 killcode -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 不稳定→简报静默失败,部署新策略需监控此链路。