# 2026-04-22 ## 流程教訓:5 分鐘回報空轉 - 今日回看 long-task watchdog repair 事件,確認最後卡住的真正原因不是技術 blocker,而是**假進度空轉**。 - 具體表現:checkpoint / watchdog 催辦持續送達,但 long task 本體沒有新的檔案變更、驗證輸出、決策產出或 blocker 狀態改變。 - 當時實際新增內容只剩: - 更新 `lastMilestoneAt` - 更新 `lastObservedActivityAt` - 回應 reminder / watchdog 催辦 - 重複回報「仍無新證據」 - 已確認以上都不應再被視為 long task 新進展。 - 因此今日已把規則正式補入 `WORKFLOW.md`: - `No-Fake-Progress Rule` - `Long Task Stop-Clock Gate` - 新規則重點: - 狀態同步不算進度 - 連續 3 次 checkpoint 無新證據即視為空轉 / 停滯 - 一旦空轉,必須改判 `paused` / `blocked`,或停止週期性續報,不得再靠 reminder / watchdog 續命 ## 技術調查:/tmp/fileXXXXXX 臨時執行檔 - 今日確認 `/tmp/fileXXXXXX` 樣本至少有一批是真正可執行 ELF binary。 - 已保留樣本:`/home/alice/tmp-file-samples/filedOXXPd` - 驗證結果: - 可直接執行 - `--version` 顯示 `ls (GNU coreutils) 9.4` - 與 `/usr/bin/ls` 非同檔(hash 不同) - 目前最準確判斷: - 不是本機 `/usr/bin/ls` 被直接改掉 - 更像是某個外部程式 / 執行框架把自帶的 `ls` 落地到 `/tmp/fileXXXXXX` 後執行 - 尚未確認:到底是哪個程式 / runtime 建立了這批臨時執行檔 - 目前此案狀態: - 流程面已修規則 - 技術面暫停,待新 session 繼續追查來源 ## Watchdog skill 處置 - 第一階段已完成:`skills/watchdog-discord-route/` 已自可用 skills 路徑移出,改封存到 `disabled-skills/watchdog-discord-route/`。 - 第二階段已完成:watchdog 相關殘留 docs / prompts / state / scripts 已集中移到 `disabled-watchdog/`。 - 看板中的 watchdog 相關進行中項目已自主列表移除,避免後續再被當成現行工作流入口。 - 目前保留方式:採封存而非硬刪除,之後若要追查舊設計或故障證據,仍可從封存區回看。 ## Long-task governor skill - 依總管指示,已避免直接修改 OpenClaw core / dist,改採可維護、可升級、可抽換的 skill 路線。 - 已新增 `skills/long-task-governor/`,內容包含: - `SKILL.md` - `task-record-template.md` - `checkpoint-template.md` - `_meta.json` - skill 目標:把 `general_chat vs long_task` 判準、狀態機、checkpoint 規格、no-fake-progress、stop-clock gate 收斂到外掛式 workflow layer。 - 已同步更新 `WORKFLOW.md`,要求:只要不是 ordinary single-turn general chat,就必須套用 `long-task-governor`。 - live test 期間實際抓到一個缺口:在 Telegram 上做 long-task checkpoint / next-step 收尾時,我仍可能退回純文字 `1 / 2 / 3` 選單。 - 因此已先補一條 skill 規則:`Telegram interaction guard`,禁止 governed long-task flow 在 Telegram 上用純文字選單收尾;若需要選擇,必須改用 inline buttons,否則直接執行最合理下一步。 - 後續再往前補強到更直接的操作層:新增 `Reply Closure Button Gate` 概念,明確規定只要回覆最後的可執行部分需要總管決定、確認、批准、停止、繼續、重跑或選下一步,就不能只在文字裡說會用按鈕,必須真的送出 inline buttons,或直接執行最合理下一步。 - 在最短回歸測試後又確認一個更前面的根因:不只要「有按鈕」,而是**若需要按鈕,必須讓按鈕先出場**,不能先送普通文字再補按鈕;因此已把規則再收緊成 ordering rule:優先用 `message` 工具送真按鈕,然後回 `NO_REPLY`。 - 在完整 long-task 測試後再驗出更前置的根因:若一開始就可預見最後會進入 owner 的 pass/fail 或 accept/reject 判定,流程本身就必須提早切成 `button-path`,不能等到最後一段才臨時想起要用按鈕。