From 4ad99230206aaae733899661c76a415495b08458 Mon Sep 17 00:00:00 2001 From: hmo Date: Mon, 10 Aug 2026 15:23:02 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=A7=84=E8=8C=83v1.1=EF=BC=88?= =?UTF-8?q?=E5=8D=95=E4=BE=8B=E5=AE=88=E5=8D=AB/=E8=B6=85=E6=97=B6/LLM?= =?UTF-8?q?=E5=AE=B9=E9=94=99/=E9=83=A8=E7=BD=B2=E8=A7=84=E8=8C=83?= =?UTF-8?q?=EF=BC=89+=20=E7=B3=BB=E7=BB=9F=E5=AE=A1=E8=AE=A1=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E5=8D=81~=E5=8D=81=E4=B8=80=E7=AB=A0=20+=20=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E6=96=B9=E6=A1=88=E5=AE=8C=E6=95=B4=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/DEVELOPMENT_STANDARDS.md | 83 ++++++++++++++++++++- docs/deployment-plan-predictive-oversold.md | 56 ++++++++++++++ docs/system-audit-20260810.md | 74 ++++++++++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) diff --git a/docs/DEVELOPMENT_STANDARDS.md b/docs/DEVELOPMENT_STANDARDS.md index 9f273bc7..d2cbbb13 100644 --- a/docs/DEVELOPMENT_STANDARDS.md +++ b/docs/DEVELOPMENT_STANDARDS.md @@ -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 或部署文档 + --- ## 六、开发流程 diff --git a/docs/deployment-plan-predictive-oversold.md b/docs/deployment-plan-predictive-oversold.md index 71b3eeff..9d0f6f96 100644 --- a/docs/deployment-plan-predictive-oversold.md +++ b/docs/deployment-plan-predictive-oversold.md @@ -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 内 +- 一个脚本一个调度 diff --git a/docs/system-audit-20260810.md b/docs/system-audit-20260810.md index 579ed9f8..313a4bf2 100644 --- a/docs/system-audit-20260810.md +++ b/docs/system-audit-20260810.md @@ -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 不稳定→简报静默失败,部署新策略需监控此链路。