Files
Hermes-Skills/okx-auto-position/references/forwarder-rule-2026-08-06-session-postmortem.md

7.3 KiB

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 看到 找到源聊天: <chat_name>
2 (forwarder→目标群) 同上,关键看 处理转发规则 ID: <N> 或 规则 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 反查

修复时用的命令清单 (备查)

# 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 模式 (没主动告警) — 未来需加守护