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
This commit is contained in:
+38
-3
@@ -1,18 +1,23 @@
|
||||
# MoFin 开发规范
|
||||
|
||||
> 版本: v1.0 | 更新: 2026-07-19 | 基于 AgentsMeeting 样板重构
|
||||
> 版本: v2.0 | 更新: 2026-07-20 | 基于 AgentsMeeting 样板重构 + 冗余事件复盘
|
||||
>
|
||||
> 📋 样板参考: [AgentsMeeting TEMPLATE-GUIDE.md](../AgentsMeeting/docs/TEMPLATE-GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
## 五条红线
|
||||
## 十条红线
|
||||
|
||||
1. **先读/写 Spec,再写代码** — 新增功能先写 spec 再实现;修改已有功能先读对应 spec 了解架构和约束再动手。没有 spec 的模块在 Dashboard 不可见,视为未完成
|
||||
2. **部署必验** — 部署后不打开 Dashboard F Tab 验证 = 部署未完成
|
||||
3. **不可见即不存在** — 组件不在 Dashboard 中显示 = 等于没部署。离线不告警 = 监控缺陷
|
||||
4. **实现后同步 Spec** — 每轮开发完毕后,必须将 `specs/{module}.json` 更新为与实际实现一致的状态。文档过期 = 等于没写
|
||||
5. **部署目标即验收标准** — 所有代码必须以部署目标环境(Linux 246)为基准编写和测试。禁止使用 Windows 专属 API(`tasklist`、`netstat`、`schtasks`、`wmic`)在 246 部署的代码中
|
||||
6. **单一事实源(SSOT)** — 每个文件全系统只有一个权威位置,其他位置只允许硬链接(同 inode),**禁止独立副本**。权威位置:`deploy/profile-scripts/`(cron 脚本)、`/home/hmo/MoFin/`(被 import 的库)、`deploy/bot/`(XMPP bot)。修改任何文件后若存在硬链接关系被破坏(scp/编辑器换 inode),必须立即跑 `deploy/profile-scripts/sync_profile_scripts.sh` 重建
|
||||
7. **数据路径必须绝对** — 引用数据文件/数据库时,必须写绝对路径并指向权威位置(`/home/hmo/MoFin/data/`)。**禁止**用 `Path(__file__).parent / "data"` 这类相对解析——同一个模块被硬链接到不同位置时会解析出不同的数据库(2026-07-20 三库事件的根因)
|
||||
8. **备份/遗留物禁止留在生产数据目录** — `.bak`、`decisions_backup_*`、迁移残留 JSON、废弃 DB,必须在迁移/变更完成时移到 `archive/`。生产数据目录(`MoFin/data` = `web-dashboard/data`)只放活文件。监控脚本扫描生产目录时,遗留物就是未来的假警报
|
||||
9. **死模块必须收尸** — 宣布模块废弃时,必须在同一轮操作中完成收尸六步:①杀进程 ②stop+disable systemd 服务 ③删 cron job ④归档脚本到 `archive/` ⑤归档数据文件 ⑥从期望矩阵/监控中移除。只说"已废弃"不收尸 = 没废弃(小果 bot 以 root 白跑 8 天 2.5GB 的教训)
|
||||
10. **监控查"活"不查"在"** — 健康检查必须验证**数据新鲜度**(DB 表 MAX(时间列))而非"文件存在/进程存在"。文件 mtime、进程存活都不构成健康证据——数据 24h 不更新才是事故。禁止拿遗留文件的 mtime 当管道健康指标("数据管道停滞14天"假警报的根因)
|
||||
|
||||
---
|
||||
|
||||
@@ -80,6 +85,7 @@ specs/{module}.json
|
||||
| dashboard | `specs/dashboard.json` | Dashboard 自身 | ✅ |
|
||||
| health | `specs/health.json` | 健康监控管线 | ✅ |
|
||||
| xmpp_monitor | `specs/xmpp_monitor.json` | XMPP 通信可观测性 | ✅ |
|
||||
| hygiene | `specs/hygiene.json` | 系统卫生审计(防冗余) | ✅ |
|
||||
| price_monitor | `specs/price_monitor.json` | 价格监控 cron | 📋 |
|
||||
| strategy_lifecycle | `specs/strategy_lifecycle.json` | 策略生命周期 | 📋 |
|
||||
|
||||
@@ -87,7 +93,36 @@ specs/{module}.json
|
||||
|
||||
---
|
||||
|
||||
## 二、验证闭环
|
||||
## 二、文件位置宪法(2026-07-20 冗余事件后确立)
|
||||
|
||||
| 内容类型 | 唯一权威位置 | 其他位置的合法形态 |
|
||||
|---------|-------------|------------------|
|
||||
| cron 脚本(被调度直接执行) | `deploy/profile-scripts/` | profile scripts 目录硬链接(经 `sync_profile_scripts.sh` 同步) |
|
||||
| 被 import 的库(mo_*/mofin_*/strategy_*/technical_*) | `/home/hmo/MoFin/`(根目录) | 禁止副本;deploy/profile-scripts 中的同名库文件只能是对 root 的硬链接 |
|
||||
| XMPP bot | `deploy/bot/` | `/home/hmo/xmpp_zhiwei_bot.py` 符号链接 |
|
||||
| Dashboard 服务 | `web-dashboard/server.py`(= `/home/hmo/MoFin/server.py` 硬链接) | — |
|
||||
| 数据文件/数据库 | `/home/hmo/MoFin/data/`(= `web-dashboard/data` 硬链接) | **禁止**任何第二个数据目录 |
|
||||
| 归档 | `archive/<主题>-<日期>/` | — |
|
||||
| 待销毁 | `trashbox/` | 定期人工清空 |
|
||||
|
||||
**禁止出现的位置**:`MoFin/scripts/*.py`、`MoFin/` 根目录的 cron 脚本副本、`.hermes/*/scripts/data/`(任何 profile 本地 data 目录存业务数据)、`projects/` 下与生产同名的项目副本。
|
||||
|
||||
### 死模块收尸清单(红线9 的执行版)
|
||||
|
||||
```
|
||||
宣布模块 X 废弃时,同一轮操作内必须完成:
|
||||
□ 杀进程:pkill 或 systemctl stop(确认 ps 无残留)
|
||||
□ 服务:systemctl disable + rm unit 文件 + daemon-reload
|
||||
□ cron:两个 jobs.json 中删除 X 的 job,确认无残留
|
||||
□ 脚本:移到 archive/<模块>-retired-<日期>/
|
||||
□ 数据文件:同上
|
||||
□ 监控:从期望矩阵/健康检查注册表中移除 X
|
||||
□ 记录:CHANGELOG 写明收尸动作
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、验证闭环
|
||||
|
||||
```
|
||||
┌────────────┐ ┌──────────┐ ┌──────────┐
|
||||
|
||||
Reference in New Issue
Block a user