Commit Graph
51 Commits
Author SHA1 Message Date
知微 91885f7623 Merge branch 'session-work' 2026-07-21 13:47:31 +08:00
hmo 5422b0a11d feat(db): 每日DB在线备份(07:50,留14天) + 管道审计malformed重试一次再告警(瞬态WAL损坏防误报) 2026-07-21 13:47:10 +08:00
知微 34337fc5b7 clean: 移除早上健康检查/系统审计中的小果残留引用(二次提交—deploy guard恢复旧版后重新应用) 2026-07-21 12:05:43 +08:00
知微 9d3cab2306 clean: 移除盘中自检/早上健康检查/系统审计中的小果残留引用 2026-07-21 12:03:21 +08:00
知微 c180129a1a fix: add SIGALRM 120s hard timeout to price_monitor lock
price_monitor.py 进程锁无硬超时,LLM策略重评耗时9-10分钟时
锁文件阻止后续*/2 cron执行,造成10分钟监控盲区。

新增:
- _handle_sigalrm: SIGALRM处理器,自动清理锁后退出
- signal.alarm(120): 获锁后设120s硬上限
- signal.alarm(0): 正常完成时取消定时器
2026-07-21 11:29:06 +08:00
知微 f6d10a41af Merge branch 'session-work'
# Conflicts:
#	deploy/profile-scripts/intraday_health_check.py
2026-07-21 10:43:41 +08:00
hmo 29e0e6c8b4 fix(688775事件): bot不再静默吞消息 + 价格推送分级 + 小果假警报清理
1. bot call_hermes 失败: 10s重试一次, 仍失败回兜底消息(网关暂时不可用)
   ——此前连接被拒时用户消息被静默吞掉(688775事件根因)
2. price_monitor 推送分级: 破止损/重评确认信号/持仓急跌=ACTION直通;
   未确认进区提示=聚合成一条摘要走INFO(30min限1条+8行截断)
   ——今早一秒一条十几连发+思特威英诺特双发
3. alert_helper ACTION 增加5min内容去重(防竞态双发)
4. intraday_health_check 删除小果全部残留检查(已退役, 假警报
   导致知微旧自愈执行器烧150k+token/session去调查并直接改代码)
2026-07-21 10:41:32 +08:00
知微 84d72dfd85 fix: intraday_health_check移除小果残留——check_xiaoguo/8645端口/小果bot/小果信号堆积
小果已全线归档(2026-07-20 Xiaoxiao重构)。盘中自检脚本仍残留:
- check_xiaoguo()函数
- 小果XMPP Bot离线检测
- 8645端口检测
- xiaoguo信号堆积检查(含import socket)
- main()中check_xiaoguo()调用

全部移除,匹配已修复的运行版本。
2026-07-21 09:46:43 +08:00
hmo 1e71a2d852 feat(alerts): alert_helper 统一告警网关——信噪比控制
两级通道:
- ACTION(买入信号/重点推荐/部署验证失败): 直通不限速, 🚨醒目前缀
- INFO(部署/卫生/修复/螺旋报备): 同类30min限1条 + ≤8行截断 +
  24h内容去重(同一问题不重复轰炸) + 压制计数透明披露

6个调用点全部迁移: deploy_guard/hygiene/spiral/self_repair(INFO)
+ batch_reassess/per_stock_reassess 买入信号(ACTION)
解决: 真正有意义的信息(重点推荐操作)不被纯通知淹没
2026-07-21 02:43:57 +08:00
hmo 1806b6a174 fix(SSOT): 4个库文件副本移出git跟踪(红线6:只允许硬链接,不允许独立副本)——硬链与git跟踪本质冲突:checkout重建文件断链→内容与提交版不同→guard判漂移回滚→sync重链→再dirty→merge被阻。移出跟踪后:根目录mofin_db.py/mo_data.py为唯一tracked canonical,副本由sync脚本以硬链重建 2026-07-21 02:09:25 +08:00
hmo 609ef06e6e fix(guard): CODE_PATHS补scripts/整目录+mofin_db/mo_data根文件——覆盖库文件硬链造成的合法dirty 2026-07-21 02:08:23 +08:00
hmo beee453bf3 fix: 同步4个库文件副本的提交内容与根canonical一致——消除deploy_guard回滚↔sync重链拉锯(guard实测抓到漂移并回滚,机制自证有效,但提交内容必须同源) 2026-07-21 02:06:55 +08:00
hmo 3e84cbc17e ux: 系统告警统一加'📟【MoFin系统·XX】(非知微本人)'前缀——告警与知微本人消息可一眼区分 2026-07-21 02:04:55 +08:00
hmo 6d1d4a5164 fix(SSOT): 库文件统一硬链到MoFin根目录canonical——今晚三处改造差点跑在陈旧副本上
- mo_data.py 提升为根目录canonical(含tag修复), deploy/profile-scripts/
  scripts/ profile脚本目录 全部硬链到根
- mofin_db.py 同理(含strategy_history/tag迁移), 四处硬链统一
- sync_profile_scripts.sh 增加库文件链接步骤, merge后自动恢复
- 根因: deploy/profile-scripts/mofin_db.py 是7-20陈旧副本(无snapshot),
  profile脚本目录mo_data.py无tag——hygiene分叉副本检查正确报警
2026-07-21 02:00:26 +08:00
hmo 2054c6e6f9 fix: state.db 时间戳单位自适应(秒/毫秒混存)+ default profile 无sessions表静默跳过 2026-07-21 01:54:59 +08:00
hmo 839c6fc2ff feat(self-heal): 三盲区系统性补丁——自愈体系覆盖今晚三类故障
1. agent_spiral_watchdog.py (新增,10min cron): state.db 检测运行>15min
   且消息>80条的 api session(螺旋特征), XMPP告警+去重。补 603288 事件
   '无watcher看agent会话本身'盲区
2. deploy_guard: 自动merge后自动跑 verify_deployment.py, 失败项立即
   XMPP告警。补'提交级回归无监控'盲区(知微stale提交事件)
3. system_hygiene_audit: 新增第7项检查'指令冻结session'——常驻session
   启动时间早于SOUL.md mtime且6h内仍活跃 → 告警需bump/重启。
   补'system_prompt冻结'盲区; 6h活跃度过滤防误报已遗弃session
2026-07-21 01:53:11 +08:00
hmo ae0c7d1ca3 fix(L3): self_repair 迁移 llm_client(OCG直连无session) 废弃常驻'self-repair' session(指令冻结+上下文累积) 2026-07-21 01:39:54 +08:00
hmo 95d07f6a11 fix(guard): porcelain路径解析健壮化(line[2:].strip + rename格式处理) 2026-07-21 01:19:53 +08:00
hmo a69b246c57 feat(guard): 部署一致性守卫 deploy_guard.py + 知微运维纪律 + 健康JSON移出跟踪
- deploy_guard.py (15min cron): 代码漂移自动回滚(仅未提交改动)+
  session-work可快进时自动merge部署+幂等重链+cron引用完整性,
  状态落盘JSON, 有动作即XMPP报备
- docs/zhiwei-ops-discipline.md: 知微纪律——禁止直接编辑被跟踪代码/
  禁stale提交/禁直调gateway批量LLM; 自愈白名单(rerun/restart/
  sync/switch_key)本不改代码, 与纪律不矛盾; 紧急热修走git流程,
  提交到session-work后guard 15min自动部署
- dev-spec 红线#6 补充部署守卫机制
- static/mofin_health.json 移出git跟踪(运行时产物, 常驻dirty
  会废掉漂移检测)
2026-07-21 01:17:01 +08:00
hmo cd530c2463 fix(llm): 重评直连OCG上游绕过hermes agent运行时 + 全线切flash + prompt输出纪律
事故根因(2026-07-21): hermes gateway /v1/chat/completions 非透传,
每个请求创建带工具的agent会话。一次603288重评螺旋35分钟/44次
terminal调用/输入153k token, 客户端超时后服务端空转, 重试叠加
新会话自我DDoS。

- llm_client 重写: OCG直连为主(key运行时从hermes config.yaml
  ocg-key6读取, 不落盘), gateway兜底(agent模式仅应急)
- REASSESS_MODEL: pro -> flash (A/B实测新prompt下质量差距微弱,
  flash快40%)
- prompt输出纪律: 【建议仓位】不可省略(非买入写'不新建仓'),
  禁止structured_data/XML/JSON块, 禁止寒暄开场白
- batch main 双通道预检(全挂才退出)
2026-07-21 01:00:47 +08:00
hmo 9a8e3344ac restore: candidate_filter busy_timeout + premarket Step1.5 摘要字段(知微17:31 stale提交回滚恢复至7b26c373已验证版本) 2026-07-20 23:53:03 +08:00
hmo de9927a627 重评核心重构:ds-v4-pro + 原策略全文 + strategy_history + 前端三改造
后端(重评管线):
- 新增 llm_client.py 共享客户端: REASSESS_MODEL=deepseek-v4-pro 单点,
  gateway预检(fail-fast), 150s超时+1次重试, 永不抛异常
- batch_reassess/per_stock_reassess: curl/urllib -> call_llm,
  prompt传入原策略全文+当前参数+最近3条变更, 输出 维持/修改判断+
  修改点理由+最终新策略, max_tokens 4096
- mofin_db: 新增 strategy_history 表 + snapshot_strategy_history(),
  write_holding_strategy 覆写前自动快照(保留20条/code)
- mofin_db: holding_strategies 补 tag 列迁移 + 写入保留
  (tag缺席=保留旧值, 显式传''=允许清除), 修复推荐标签被静默丢弃
- mo_data.read_decisions: SELECT 补 tag
- stale_detector/promote_candidates: 子进程超时 240/60 -> 480s

前端:
- 移除 报告Tab -> mofin_health 全部流程/Cron 表加 最后十次 列
  (modal列表->详情), /api/reports 支持 cron+script 多路匹配
  (jobs.json name->id 解析 + 文件名/标题子串兜底)
- 移除 决策库Tab
- 盯盘Tab 重构: 全部持仓+自选, sort_group 分组(推荐/持仓/自选),
  推荐行琥珀高亮+🔥badge+行内策略, 新增 操作策略 列查看
  最近3次完整策略(/api/strategy_history/<code>, 表缺失时降级当前行)
- 提示词Tab: registry.py 数据路径改回 /home/hmo/MoFin/data/prompts
  (红线: 数据只在规范数据根), 空态提示初始化命令
2026-07-20 23:51:24 +08:00
知微 90f07b4eba chore: sync 2026-07-20 22:05:03 +08:00
知微 3eb214f3a6 chore: sync 2026-07-20 21:43:03 +08:00
知微 ad6a416ef4 merge: watchdog agent.log check 2026-07-20 20:56:05 +08:00
知微 c971d6bced chore: watchdog fix 2026-07-20 20:55:34 +08:00
hmo 10a37f10f9 fix(watchdog): gateway session check now uses agent.log scan, not live LLM ping
Gateway看门狗-知微 was erroring (exit -15): its check_session_health did a
live LLM ping with 25s timeout. Cold-start LLM latency is 20-100s so the
ping always timed out -> false '不健康' verdict -> false gateway restart
-> and each 10-min run burned 22k tokens.

Now uses xmpp_logger._scan_agent_log (zero cost, reads real call results):
- ok if last real call succeeded
- unhealthy only if last call explicitly failed
- idle (no recent calls) counts as healthy
Verified: watchdog job now status=ok.

Also: triggered all 6 weekend 'Blocked' jobs via hermes cron run — all
now status=ok, proving the hardlink fix holds.
2026-07-20 20:55:30 +08:00
知微 dae60bb92f chore: sync before briefing merge 2026-07-20 20:37:20 +08:00
知微 9f7198dc9c chore: deploy pipeline auto-sync 2026-07-20 20:27:15 +08:00
hmo 9a359f49bd feat(deploy): automatic hardlink repair built into deployment pipeline
User insight: hardlink breakage only happens at deploy time (scp file
replacement / git checkout-merge), so detection must be welded INTO the
deploy pipeline, not left to daily audit.

Three automatic layers, no reliance on discipline:
1. systemd path watcher (profile-scripts-sync.path): watches
   deploy/profile-scripts/ directory, auto-fires sync_profile_scripts.sh
   on any change. Verified: fires within 4s of file replacement, logs to
   gateway/logs/link_sync.log (runs as hmo user)
2. git hooks (.git/hooks/post-merge + post-checkout on 246 repo):
   auto re-link after git operations
3. Manual fallback: sync_profile_scripts.sh (now self-logging)

dev-spec red line #6 updated: SSOT rule now documents the three layers
and states breakage only happens at deploy time.
2026-07-20 20:27:11 +08:00
知微 e69109fde9 merge: L0-L4 self-check architecture 2026-07-20 19:40:24 +08:00
知微 135bfced5a chore: deployed L0-L4 self-check system 2026-07-20 19:40:23 +08:00
hmo 08eef1e181 feat(self-check): L0-L4 layered self-check architecture with LLM auto-repair
User directive: daily not weekly; clear responsibilities per layer with no
overlap; functional criteria (does the function WORK) not process liveness;
problems get FIXED via LLM with file-and-report discipline (act first,
report after); plus a meta-layer watching the watchers; deeply integrated
into F健康.

Architecture (responsibility matrix in dev-spec.md):
- L0 agents_health_check (5min): port/HTTP/DB liveness + auto_heal executor
- L1 functional_health_check (15min trading): per-module FUNCTIONAL
  criteria — output freshness/validity per REGISTRY (live_prices/market_
  snapshots/mtf_cache/macro_context/bot/LLM/cron engine), not process alive
- L2 system_hygiene_audit (daily 08:20, was weekly): divergence/hardlink/
  zombie/orphan/dead-cron/db-freshness
- L3 self_repair (30min): reads L1/L2 failures -> LLM diagnoses -> executes
  WHITELISTED repair actions directly (rerun_script/restart_service/
  sync_links/switch_llm_key/none) -> repair_log.jsonl + XMPP report.
  Max 2 repairs/module/day anti-loop. LLM unavailable -> rule fallback.
- L4 meta_watchdog (hourly): checks L0-L3 output freshness + L3 cron
  registration + XMPP bridge; direct XMPP alert as last resort

Retired (overlap): Cron监护-高频 (cron_watchdog -> L3), 全局cron健康监控
(cron_health_monitor -> L1).

Dashboard: mofin_health.py now emits self_check section (functional/meta/
hygiene/recent_repairs); mofin_health.html new '🩺 自检体系' tab rendering
L4 layers, L1 module checks, L2 issues, L3 repair history.

E2E verified: stopped xmpp bot -> L1 flagged fail -> systemd recovered ->
L3 LLM correctly diagnosed 'none needed' and logged; rerun_script whitelist
path executes real scripts successfully; meta_watchdog all-green after fix.
2026-07-20 19:39:58 +08:00
知微 54c48dc5d7 chore: deployed cleanup + hygiene system 2026-07-20 19:05:03 +08:00
hmo 4f83ee8a01 feat(hygiene): anti-redundancy enforcement — spec rules + weekly audit
Root cause analysis of the 2026-07-20 redundancy incident:
1. No single-source-of-truth rule -> same file legitimately lived in 4+
   locations, diverging silently
2. Relative path resolution (Path(__file__).parent/'data') -> each
   hardlinked copy of mofin_db.py pointed to a DIFFERENT database
3. 'Backup habit' left .bak/legacy files in production dirs, which
   monitoring then scanned and reported as false alarms
4. Half-done migrations: DB tables created but old JSON writers/readers
   stayed (price_events), old files stayed
5. Dead modules never got buried: xiaoguo 'dead' but bot ran 8 days
   as root eating 2.5GB
6. Monitoring checked 'does it exist' not 'is it alive' -> stale file
   mtime reported as 'pipeline stalled 14 days' (false alarm)
7. No 'system hygiene' as a check category at all

Prevention implemented:
- dev-spec.md v2.0: 五条红线 -> 十条红线
  #6 single source of truth (hardlink only, no independent copies)
  #7 absolute data paths only (no __file__-relative data resolution)
  #8 no backups/legacy in production data dirs (archive immediately)
  #9 dead module burial checklist (6 mandatory steps)
  #10 monitor liveness (DB table freshness) not existence
- File Location Constitution: canonical location per content type
- NEW system_hygiene_audit.py: weekly Monday 07:30 cron checking
  diverged copies / broken hardlinks / zombie processes / orphan data
  files / dead cron scripts / DB freshness -> hygiene_report.json + XMPP
- specs/hygiene.json: module spec per red line #1
- Verified: audit found 5 real issues on first run, all fixed, re-run clean
2026-07-20 19:04:05 +08:00
知微 7f3ff66be4 merge: retire price_events.json 2026-07-20 18:10:40 +08:00
知微 4383c384be chore: deployed JSON retirement 2026-07-20 18:10:35 +08:00
hmo d5b8bec897 refactor: retire price_events.json completely — DB is the only store
User directive: no JSON, retire it fully, fix all related code.

Changes:
- price_monitor.py: record_event writes DB only; removed EVENTS_PATH/
  load_events/save_events entirely
- strategy_feedback.py: price events read from DB only (removed JSON fallback)
- system_health_check.py: removed price_events.json from file-check list,
  DB-only event stats (was showing 0/0 due to wrong-DB resolution)
- mo_config.py: removed dead price_events_path property (no callers)
- mofin_health.py: price_events freshness reads DB table (authoritative now)
- mofin_db.py: DATA_DIR/DB_PATH now ABSOLUTE (/home/hmo/MoFin/data) —
  was relative __file__.parent, so each hardlinked copy of mofin_db.py
  resolved to a DIFFERENT database (canonical vs web-dashboard vs
  profile-local third DB with 0 rows of everything except market_snapshots).
  This fragmentation was the real cause of health checks reading empty tables.
- Unified all 4 mofin_db copies (root/scripts/deploy/profile) via hardlink
- price_events.json archived to trashbox (fully backfilled: 6353 rows in DB)

Verified:
- record_event lands in DB only, JSON not recreated
- system_health_check: 历史事件 6353 / 今日事件 2965 (was 0/0)
- strategy_feedback + price_monitor full runs clean
2026-07-20 18:10:05 +08:00
知微 73520464b6 merge: price_events DB unification 2026-07-20 17:48:27 +08:00
知微 d28a32e244 chore: deployed price_events dual-write 2026-07-20 17:47:29 +08:00
hmo efdfaf956a fix(price_events): unify event storage to DB (dual-write + backfill)
User caught the inconsistency: system claims DB-first but price events
only went to price_events.json, leaving DB table stale since Jul 6.

Root cause chain found:
- record_event() only wrote JSON, never called mofin_db.write_price_event
- price_events.code has FK -> stocks(code); events for unregistered stocks
  (new candidates, HK) silently failed INSERT and were lost to DB
- mofin_db.write_price_event swallows errors (returns False silently)

Fixes:
- record_event now dual-writes: DB (authoritative) + JSON (compat for
  legacy readers mo_config/strategy_feedback/system_health_check)
- auto-registers unknown codes into stocks table before event insert
- one-time backfill: 4064 JSON events -> DB (total 6353 rows, last=today)
- verified: record_event TEST99 lands in both DB and JSON
2026-07-20 17:46:57 +08:00
知微 c02caeb1da merge: pipeline fixes + false-alarm cleanup 2026-07-20 17:32:13 +08:00
知微 c31736a38d chore: deployed pipeline fixes 2026-07-20 17:31:48 +08:00
知微 5d3b8e6fdd chore: capture deployed state 2026-07-20 17:30:43 +08:00
hmo 17305bed0b fix(pipelines): clear today's real cron errors + kill monitoring false alarms
Real errors fixed (all verified by manual run):
- price_monitor.py: shares None -> TypeError at L584 (now completes 3m7s,
  full 39-stock reassess + zone triggers + Dad push)
- market_insight.py: net_inflow None -> TypeError at L142 (now 0.3s, 5 insights)
- promote_candidates.py: add busy_timeout=30s (DB lock under concurrent writes)
- premarket_full_review.py: 12-dim analysis now detached background launch
  (was doomed by cron 120s script timeout no matter what)

Systemic:
- HERMES_CRON_SCRIPT_TIMEOUT=600 drop-in for both gateway services
  (fixes mofin_health SIGTERM, market_watch timeout, memory_guardian timeout)
- sync_profile_scripts.sh: re-hardlink deploy->profile scripts after every
  deploy (scp replaces files = new inode = broken hardlink = cron silently
  runs stale code; this caused promote to keep failing after my first fix)

Monitoring false-alarm fixes (the '花瓶' problem):
- mofin_health.py: legacy JSONs that migrated to DB (multi_tf_cache/
  macro_context/market/live_prices/price_history/macro_risk_state) no longer
  warn 'no readers'; marked as migrated
- NEW db_freshness section: real pipeline health from DB tables
  (mtf_cache 0.4h / macro_context_log 2h / market_snapshots 2h /
  live_prices 0.4h / price_events.json 0.4h — ALL HEALTHY)
- price_events freshness reads live JSON store (DB table is legacy)
- market.json placeholder created (13+ scripts have fallback paths)

Investigation notes: wiki-self-growth 03:04 key1 429 predates full key6
activation on default gateway; current 8642 verified on key6 and working.
Weekend 'Blocked' jobs verified fixed (vacuum_state_db passes).
2026-07-20 17:30:15 +08:00
hmo a40b97f5ca feat(analysis): systematic daily 12-dim LLM analysis for holdings+watchlist
Gap (reported by user via zhiwei): premarket full review updated technical
params but full_analysis (12-dim LLM matrix) was empty for new holdings
and stale for old ones — batch_reassess existed but was never wired into
the daily pipeline and only covered watchlist.

System fix:
- premarket_full_review.py: new Step 1.5 runs batch_reassess --type
  holding --today every trading day 08:10 (force-refresh today's analysis,
  timeout 3600s, result in summary.json)
- batch_reassess.py:
  - coverage: --type holding|watchlist|all (was watchlist-only)
  - staleness: analysis >20h stale gets refreshed (was: skip if any
    analysis exists = forever stale)
  - --today flag: force re-analyze if not reassessed since 04:00 today
  - cash/total read live from portfolio_summary (was hardcoded 321271/
    952879 from weeks ago)
  - HK stock prefix fix (5-digit codes -> hk, was sending sz00700)
- watchlist_12d_backfill.py: wrapper for hermes cron (no args support)
- cron job '批量补全九维分析-一次性' -> '自选12维分析补全-每日午间'
  (daily 12:30 weekdays, covers 109 watchlist stocks missing analysis)

Verified: 300308 got 1920-char 12-dim analysis written to DB at 08:41,
signal=观望, stop/take-profit updated.
2026-07-20 08:48:08 +08:00
hmo 4c669943bd merge: integrate 246-side commits (bot reconnect fix + docs) with session work 2026-07-20 08:28:16 +08:00
hmo 115292bb96 fix(scripts): promote UNIQUE crash + candidate_filter DB lock (morning readiness)
Pre-open error sweep (all verified by manual run):
- promote_candidates.py: INSERT OR IGNORE + only newly-added stocks count
  toward promotion/XMPP (was crashing on first duplicate, never finishing;
  now completes 40s, promoted 74 with correct skip marking)
- candidate_filter.py: PRAGMA busy_timeout=30s (was dying on transient
  'database is locked' under concurrent cron writes; now completes 9.6s)
- price_monitor.py: verified completes 1m55s (< 120s cron timeout) with
  working LLM reassess via key6
- macro_context_collector.py / divergence_detector.py: previously
  'Blocked' by symlink check, now run fine (8.7s / 1m55s)
- memory_guardian.py: completes 1m55s with key6
- preflight sync diff: historical, files now identical

Production proof: 大脑任务执行 (was 429 every 10min) now status=ok at 01:21
2026-07-20 01:34:37 +08:00
知微 b5dade3b65 docs: 记录 XMPP bot 递归重连修复到 CHANGELOG 和 knowledge-log 2026-07-19 21:00:54 +08:00
知微 81c6dd2314 fix: 移除deploy/profile-scripts中错放的bot文件 2026-07-17 23:13:03 +08:00