9.3 KiB
9.3 KiB
Gateway Recovery Playbook
目標:當 gateway 更新後再次出現綁定錯亂、長任務異常、LINE quota fallback 失效、email 附件壞掉時,可以不用重翻歷史對話試錯,而是按固定順序定位。
0. 先判斷是哪一類故障
A. 綁定 / 寄錯信
症狀:
- 寄到錯 principal 的 email
- Telegram / LINE / OpenWebUI 對應到錯綁定
- fallback email 被 block 或誤放行
先看:
gateway/user_verification.pyplugins/platforms/line/adapter.py
B. LINE 長任務 / 查看答案異常
症狀:
查看答案取不到結果- 一直顯示還在處理中
DELIVERED後 replay 不符合實際交付 surface
先看:
plugins/platforms/line/adapter.pyRequestCache_handle_postback_event(...)
C. LINE quota fallback / email fallback 異常
症狀:
- LINE 429 後沒寄 email
- 有寄 email 但 replay 還假裝 LINE 已成功
- final 已寄 email,附件卻又跑回 LINE 失敗
先看:
plugins/platforms/line/adapter.pygateway/platforms/base.py
D. Email 附件 / 下載連結異常
症狀:
- 沒附件
- 附件沒副檔名
- 下載連結打不開
- 附件過大直接寄失敗
先看:
plugins/platforms/email/adapter.pyhermes_cli/managed_downloads.pyhermes_cli/web_server.py
E. Shared drive workflow 異常
症狀:
- 搜尋找不到明明存在的檔案/資料夾
- 資料夾展開後沒有列出可選檔案
- bundle 沒產生連結或敏感檔沒加密
- 24h 連結被誤判壞掉,其實只是 HEAD / bot-like client 驗證失真
先看:
~/.hermes/scripts/shared_drive_index_query.py~/.hermes/scripts/shared_drive_lookup.py~/.hermes/scripts/shared_drive_delivery_bundle.py~/.hermes/scripts/shared_drive_chat_workflow.pydocs/shared-drive-file-access/shared-drive-file-access-validation-matrix.md
F. 額度 / 權限 / 管理後台異常
症狀:
- dashboard role 消失或全部變 viewer
- principal / identity list 不見
- quota policy / model policy 查不到
- principal usage 不再累積
先看:
gateway/user_verification.pyhermes_cli/web_server.pygateway/principal_profiles.py
1. 第一層:不要先猜,先跑最小測試
venv/bin/pytest -q \
tests/gateway/test_line_plugin.py \
tests/gateway/test_email.py \
tests/gateway/test_approval_prompt_redaction.py \
tests/gateway/test_display_config.py \
tests/hermes_cli/test_managed_downloads.py \
tests/hermes_cli/test_web_verification_admin.py \
tests/gateway/test_principal_profile_routing_phase1.py \
tests/gateway/test_verified_email_handoff_guard_helpers.py
判讀原則
test_line_plugin.py爆:先看 LINE state machine / fallback ownership / file reroutetest_email.py爆:先看 MIME / HTML / attachment handlingtest_managed_downloads.py爆:先看正式網域 URL / token / routetest_approval_prompt_redaction.py爆:先看 approval text fallback / redaction seamtest_display_config.py爆:先看 LINE 是否又被改回 noisy 模式
2. 第二層:live log 定位
主要看:
~/.hermes/logs/gateway.log
綁定問題關鍵字
verified-email mismatchblocked email handoffget_verified_email_for_source
LINE quota fallback 關鍵字
LINE: push send failedLINE Push 額度已滿email_fallbackemail_fallback_pendingRouted LINE attachment delivery to verified email fallbackSkipping LINE media attachment send because quota fallback email already carried
Email 附件問題關鍵字
Sent multi-attachment emailstandalone attachment failedsize limitEmail send failed
Managed downloads 關鍵字
/downloads/invalid_download_signatureexpired_download_tokennot found
Shared drive workflow 關鍵字
verificationshared-driveexpired_download_tokeninvalid_download_signaturefind_by_file_ids
governance / admin 關鍵字
forbiddenunauthenticateddashboard_role_not_persistedprincipal_usage_not_persistedidentity_not_found_after_unbind
3. 第三層:依故障類型對照修復順序
3.1 若是寄錯信 / 綁定錯亂
- 確認 active source 是哪個平台、哪個 external user id
- 查
GatewayUserStore.get_verified_email_for_source(...) - 查
bound_email_matches_source(...) - 確認呼叫端是否用了
explicit_user_requested=True - 若沒有使用者明確指定其他 email,卻仍能寄到不同信箱,視為重大回歸
3.2 若是 LINE pending / show_response 異常
- 看
_pending_buttons是否有建立 - 看
RequestCache狀態是否真的進到READY - 看
_handle_postback_event(...)是否把 payload 當成一般文字,而不是email_fallback* - 若 final surface 已是 email,replay 仍顯示 generic delivered copy,代表 fallback payload 被覆蓋或遺失
3.3 若是 final 已寄 email,但附件又誤走 LINE
- 看
gateway/platforms/base.py - 確認
result.raw_response.kind == email_fallback - 確認
should_route_poststream_files_to_email(chat_id)為真 - 確認
send_email_file_batch_fallback(...)成功後skip_platform_media_delivery = True
3.4 若是附件寄失敗 / 沒副檔名
- 查
_standalone_send(...) - 確認
MIMEMultipart是否建立 - 確認 attachment 的
Content-Disposition filename= - 確認
mimetypes.guess_type(...)結果與 fallback content-type
3.5 若是下載連結壞掉
- 查
build_public_download_url(...) - 查 token 是否可
resolve_signed_download_token(...) - 實際 GET
/downloads/{token} - 若 route 404,先確認:
- URL 是否正式網域
- token 是否重啟後仍可驗證
- staged file 是否存在
3.6 若是 dashboard role / quota / usage 異常
- 先打
/api/admin/verification/role - 再查
/api/admin/verification/roles - 再查
/api/admin/verification/principals - 再查
/api/admin/quota-policies、/api/admin/model-policies - 再查
/api/admin/principal-usage - 若 usage 為空,但聊天明明有跑:
- 查
gateway/run.py的record_usage_for_source(...) - 確認 source 仍能解析 principal context
- 查
3.7 若是 shared drive workflow 壞掉
- 先跑:
python3 ~/.hermes/scripts/shared_drive_chat_workflow.py search <query>
python3 ~/.hermes/scripts/shared_drive_chat_workflow.py children <folder_file_id>
python3 ~/.hermes/scripts/shared_drive_chat_workflow.py bundle --file-ids <file_id> --requester dk96@bremen.com.tw
- 若 search 沒結果:先查 index 是否重建、
shared_drive_index_query.py status是否有資料 - 若 children 空掉:先查該
file_id是否仍是資料夾、parent_dir是否對得上 - 若 bundle 失敗:先查
find_by_file_ids(...)、staging 目錄、manifest 是否落地 - 若外部連結被判失敗:
- 以真實 GET 驗證,不以 HEAD 為準
- 不把 urllib / Cloudflare 1010 當成最終失敗判準
- 確認
verification.ok = true
- 若敏感檔沒加密:查
detect_sensitivity(...)與 bundle payload 的encrypted/password_channel
3.8 若是 principal profile 漂移
- 查
GatewayUserStore.get_principal_context(source)是否還拿得到 principal_id - 查
gateway/principal_profiles.py::resolve_principal_profile(...) - 查
principal_profile_map.json是否被重建或覆蓋 - 若 mapping 漂移,先修 principal context,不要先誤判成單純 delivery bug
4. 更新後固定 smoke checklist
綁定
- LINE 綁定 email 正確
- Telegram 綁定 email 正確
- OpenWebUI / api_server 綁定 email 正確
- system-initiated handoff 不會寄到非 live bound email
LINE 長任務
- pending button / wait notice 正常
查看答案在PENDING/READY/DELIVERED各自回應正確- heartbeat 文案不是 raw tool progress 噪音
quota fallback
- LINE 429 後有 email fallback
- pending 只寄一次等待通知
- final 真正寄到 verified email
- replay 說明仍保留 email fallback 事實
權限 / 額度 / 管理後台
/api/admin/verification/role回應符合預期角色- principals / identities 列表查得到
- quota policy / model policy 還在
- principal usage 持續累積
- audit log 查得到最近治理操作
email 附件 / 下載連結
- 小檔案:附件 + 連結
- 大檔案:只有連結
- 附件有副檔名
- 下載連結可點、可下載、網域正確
shared drive workflow
- search 可列出候選與
file_id - children 可展開資料夾並列出最多 10 檔可選項
- bundle 可產出 24h 連結
- 敏感檔自動轉加密 zip
verification.ok = true
approval
- approval 信 / 訊息為繁中對客版
- raw command / token 未外露
5. 維護建議
必做
- 任何改到上述模組的 PR,都在描述中附上:
- 改了哪條契約
- 跑了哪些 regression tests
- 做了哪些 live smoke
建議
- 之後可再補一份
gateway-change-impact-checklist.md - 讓每次 update / refactor 前先做 preflight 勾選:
- 有無碰 principal binding
- 有無碰 LINE pending/postback
- 有無碰 email MIME / managed downloads
一句話原則
先用契約定位,再用測試驗證,最後才 patch。
不要再回到「翻對話、猜哪裡壞、邊改邊試」那種高 token、低穩定度修法。