# Forwarder Rule 2 Disable Postmortem (2026-08-06 实战) ## 完整事件链 ### 8/5 17:04 之前 - rule 1 (实盘监控 → 交易信号群) enable=1 - rule 2 (链上监控 → 交易信号群) enable=1 - 一切正常,4 条 chat 4 麻吉/魏神信号入 signal_queue.db (#46-#49) ### 8/5 17:04 - 8/6 00:40 之间 - **rule 2 被某处改成 enable=0**(谁改的未确认) - 期间 chat 4 传来 75+ 条信号(麻吉/狙击手/百分百胜率),**全部不转发** - signal_queue.db 之后没新信号(等正确) - chat 1 实盘监控(rule 1)一直正常 — 6 条消息正常转发 ### 8/5 23:10 (不属于 chat 4 范围) - chat 1 予与实盘传来 2 条加仓信号 - rule 1 转发成功(forwarder 日志显示) - 但 **signal_queue.db 没入库** — **bug 2**(未确诊) ### 8/6 00:31 - 麻吉 ETH 25x 加仓 → chat 4 收到 → rule 2 未启用 → 不转发 - 用户问"币圈跟单的信号怎么都没处理" ### 8/6 00:40 (排查) - `docker logs telegram-forwarder | grep "未启用"` → **关键信号** - `docker exec telegram-forwarder python3 -c "SELECT id, enable_rule FROM forward_rules"` → 看到 rule 2 enable=0 - **根因定位**:rule 2 被 disable ### 8/6 00:41 (修复) - `UPDATE forward_rules SET enable_rule=1 WHERE id=2` - `docker restart telegram-forwarder` (内存刷新) - 链路恢复 ### 8/6 00:50 (后续) - 用户要"把链上监控的规则先删了,是不稳定的" - 删除 rule 2 + 关联 keywords (孤儿)+ 关联 replace_rules - forwarder log 显示 "0 个启用了总结功能的规则" - 备份脚本 `forwarder-rules-backup.sh` 自动 commit `4771032` ## ⚠️ 用户硬性纠正 (2026-08-06) — Mental Model 修复 **用户问**: "为什么禁用了链上监控,会影响到实盘监控群的状态" **agent 错误假设**:可能有一个共享的资源或 queue 在两个 rule 之间,disable rule 2 会阻塞 rule 1 **实际真相**: - rule 1 (实盘监控) 和 rule 2 (链上监控) **完全独立** - disable rule 2 **绝对不影响** rule 1 - 8/5 23:10 那两条 chat 1 予与实盘加仓 **确实成功转发了** (forwarder log 显示),但 **signal_queue.db 没入** — 是 **下游 process_signal 的 bug**,不是 forwarder 的问题 - 用户认为"影响"是因为两段时间信号都断了:8/5 17:04 (rule 2 被 disable) + 8/5 23:10 (chat 1 转发但未入库) **SKILL.md 必须记的教训**: - **规则独立性**: forwarder 多条 rule 之间没有隐式依赖,disable 一条不影响其他 - **disable 影响范围**: forwarder 收到源聊天消息 → 查所有 enabled rule → 匹配源聊天 → 转发。**单一 rule 失效 = 单一源聊天失效** - **未来类似问题**: 不要急着怀疑"全局 bug",先隔离到具体 chat + rule ## 信号链路 4 层诊断 (2026-08-06 完整验证) ``` [TG 源聊天] → [forwarder] → [forwarder 目标群] → [signal_queue.db] → [process_signal] → [OKX API] Layer 1 Layer 2 Layer 3 Layer 4 Layer 5 Layer 6 ``` **每一层都可能断**: - Layer 1: TG 源头没消息 (上游未发布) - Layer 2: forwarder 未收到 (telethon 鉴权 / 网络 / 容器挂) - Layer 3: rule disabled (本节 case) - Layer 4: signal_queue.db 写入失败 (process_signal 异常) - Layer 5: process_signal 解析失败 (format 错) - Layer 6: OKX 下单失败 (余额不足 / 币种不支持) **每层有独立诊断**: | Layer | 诊断命令 | |-------|---------| | 1 (TG 源) | forwarder 日志 `message_listener` 看到 `找到源聊天: ` | | 2 (forwarder→目标群) | 同上,关键看 `处理转发规则 ID: ` 或 `规则 N 未启用` | | 3 (target→queue) | `signal_queue.db` vs forwarder log 时间戳 | | 4 (queue→process_signal) | `signal_queue.db` status 'done' / 'failed' | | 5 (signal 解析) | process_signal.py exit code + 推送内容 | | 6 (OKX) | OKX 持仓 + 余额 + advisor 返回 + execute 反查 | ## 修复时用的命令清单 (备查) ```bash # 1. forwarder 规则诊断 docker exec telegram-forwarder python3 -c " import sqlite3 conn = sqlite3.connect('/app/db/forward.db') for r in conn.execute('SELECT id, source_chat_id, target_chat_id, enable_rule FROM forward_rules').fetchall(): print(r) " # 2. 批量 enable 0→1 docker exec telegram-forwarder python3 -c " import sqlite3 conn = sqlite3.connect('/app/db/forward.db') conn.execute('UPDATE forward_rules SET enable_rule=1 WHERE enable_rule=0') conn.commit() print(f'updated {conn.total_changes} rows') " # 3. 删 rule + 关联 docker exec telegram-forwarder python3 -c " import sqlite3 conn = sqlite3.connect('/app/db/forward.db') # 删 forward_rules conn.execute('DELETE FROM keywords WHERE rule_id=:r', {'r': 2}) conn.execute('DELETE FROM replace_rules WHERE rule_id=:r', {'r': 2}) conn.execute('DELETE FROM forward_rules WHERE id=:r', {'r': 2}) conn.commit() " # 4. 重启 forwarder 刷新内存 docker restart telegram-forwarder # 5. 自动备份 + commit ~/.hermes/scripts/forwarder-rules-backup.sh ``` ## 跟其他 cron / skill 的关系 - `references/v4.5.39-tg-monitor-forwarder-table-bug-and-cron-disconnects.md` — **Layer 2 监听器 bug** (历史) - `references/v4.5.40-gateway-inline-hook-and-cleanup-defense.md` — **Layer 4-5 inline hook 整合** - `references/v4.5.41-signal-queue-done-but-no-order-execute.md` — **Layer 4-6 done 但未 execute** - `references/v4.5.42-insufficient-funds-explicit-notify.md` — **Layer 6 余额不足** - `references/forwarder-rule-enable-killer.md` — **Layer 3 通用 killer** (2026-08-06 主入口) - 本文 (本文件) — **Layer 3 完整 postmortem + 4 层诊断框架** ## 未来 session 提示 如果用户问"信号怎么又没跟了": 1. **不要假设** 上次/全局 bug 2. **先 4 层诊断** (本文件表格) 3. **disable rule 只影响一条 rule**,**不传染** (用户硬纠正) 4. **删 rule 比 disable rule 干净** — 用户偏好 (不稳定的 source 就删) ## 自动备份 local commit ≠ push `forwarder-rules-backup.sh` 用 `git push openclaw main` try,失败时 commit 留本地。 ⚠️ `git.hi6k.com` URL 没设 remote 权限 → push 失败 → commit 留本地。 修复方向 (本次没做): - 在 TelegramForwarder/.git/config 加 openclaw remote with token - 或用 SSH remote (git@git.hi6k.com:mike/TelegramForwarder.git) - 或自己 fork 一个 GitHub repo,推上去 ## signal-queue-retry cron 行为 ⚠️ signal-queue-retry (`a82a3ab0d48d`, 每 5 分钟) — 只读 queue 表处理 pending/failed。 如果 **queue 表本身就是空的** (因为 forwarder Layer 3 没转发过来) → **silently 输出空**,**没报错**。 **这一点是这次 8/6 排查最大的坑**: - 用户问"信号怎么没处理" - signal-queue-retry 一直在跑,一直 silent OK - 我之前误以为"没信号 = 正常" - **实际**: TG 源头有信号,forwarder 收到,rule disabled,目标群没收到,queue 永远空 **以后**: cron silent 不等于"正常",要 cross-check forwarder 最近日志看消息是否在 Layer 1-2 收到。 ## 修复补丁确认 (2026-08-06) - ✅ rule 2 enable=1 (临时恢复) - ✅ rule 2 删除 (用户要求删除 + 链路稳定) - ✅ forwarder-rules-backup.sh cron (7bda8bbfa4c9, 每天 03:00) 自动备份 - ✅ forwarder 重启 - ⚠️ push openclaw 失败 (git.hi6k.com 没权限) — commit 留本地 - ⚠️ push_to_qq daemon 状态未知 (没检查) - ⚠️ signal-queue-retry cron silent 模式 (没主动告警) — 未来需加守护