# 交付通知丢失:企微WS凌晨断连 + fire-and-forget架构 ## 事件:2026-07-09 职业卫生+舜珙血压计两份合同交付无通知 ### 时间线 - 01:23:06 — 最后一条成功发送(gateway → doro) - 01:25~01:27 — WS断连(原因未知,WeCom服务端) - 01:27:23 — 首次846609 "aibot websocket not subscribed" - 01:28:01 — 职业卫生监督thread=end,final_review尝试通知→失败 - 01:30:44 — WS reconnected - 02:04:16 — 成功发送(QiuTing),说明短暂恢复 - 02:12:29 — 舜珙thread=end,通知可能在02:05-02:12期间尝试 - 02:15:50 — WS再次断开 - 持续不稳定直到 06:36 ### 根因链 1. WeCom WS凌晨不稳定(每30-60min断一次,服务端维护/长连接超时) 2. Gateway自动重连成功但846609持续("not subscribed"是服务端状态滞后) 3. workflow 24/7运行,final_review完成时间不可控 4. final_review通知是fire-and-forget:`_send_wecom(extra, 'doro', msg)` 调一次,失败即丢弃 ### 通知机制分析 ``` final_review procedure step 3: cd ~/.hermes/hermes-agent && source venv/bin/activate && python -c " from tools.send_message_tool import _send_wecom ...asyncio.run(_send_wecom(extra, 'doro', msg))..." ``` `_send_wecom`实现: - 创建**新的** WeComAdapter实例 - connect() → send() → disconnect() - 独立WS连接,不依赖gateway的WS - 但用的是同一个WeCom API,846609是服务端状态,新连接一样受影响 - 失败返回 `{"error": "..."}` 给LLM,LLM可能仍标记notification_sent=true ### 7月8日也有相同模式 - 01:13 Timeout → 03:07 reconnect失败 → 06:04 gateway重启才恢复 - 约5小时不可用窗口 ### 解决方案(待实施) **推荐方案B:watchdog补发** - watchdog cron(每20min)增加逻辑: 1. 扫描tracker中 `status=delivered` + `delivered_at > 30min前` + `notification_sent != true` 2. 用 `wecom_dm.py --to doro` 补发通知(独立WS连接) 3. 成功后写 `notification_sent=true` + `notification_at=timestamp` 4. 失败则 `notification_attempts += 1`,下次tick继续重试 5. attempts > 6(即2小时)仍失败→日志告警不再重试 **tracker字段扩展**: ```json { "notification_sent": false, "notification_at": null, "notification_attempts": 0 } ``` **wecom_dm.py优势**: - 独立WS连接,不受gateway状态影响 - 有明确的返回值(success/fail) - 凌晨WS虽然不稳定但有恢复窗口(如02:04成功发送) - 20min tick间隔 × 多次重试,大概率能命中一个可用窗口 ### 临时止血 当发现合同delivered但Doro没收到通知时: ```bash python3 ~/.hermes/scripts/wecom_dm.py --to doro --text "合同审查完成通知(补发): ..." ```