What: - 新增 tools/patrol.sh,三個子命令:collect 收集、finish 收尾、abort 中止。這一輪的巡檢項目是四項純讀取:使用統計、版本落差與重啟閘門、階段鎖與工作包鎖、心跳自述。 - 心跳的寫入從排程移到巡檢收尾。排程只呼叫巡檢,不再直接寫心跳。 - 排程週期由心跳門檻推導,不再寫死。install heartbeat 這個工作代號改為拒絕。 Why: - 排程直接寫心跳的話,心跳新鮮只證明排程活著。巡檢整個壞掉、每輪都失敗,心跳照樣新鮮,閘門照樣放行,而且沒有任何錯誤訊息——這是無聲失效,是最難發現的一種。 - 改成巡檢寫,心跳新鮮才等於上一輪真的跑完了。閘門判的才是工作訊號,不是行程存活訊號。 - 門檻是讀取端的設定,心跳檔裡不存它。所以週期與門檻各寫死一個數字一定會撞:門檻五分鐘、巡檢十五分鐘,心跳永遠是過期的。 How: - 週期取「滿足漏掉一輪還算新鮮、漏掉兩輪才過期」的最大值,並且要能整除一小時。要拉長巡檢週期就調大門檻,週期自動跟著長,兩個數字不會各走各的。 - 心跳只看「這一輪有沒有把結果記下來」,不看四項的成敗。四項有失敗但監控頁寫成了就寫心跳,頁上判定標警示;頁寫不成就中止,一定不寫,讓心跳自己過期。頁每輪都寫失敗卻照樣寫心跳,等於把這次要修掉的缺陷原封不動搬過去。 - 整輪拿一把目錄鎖,搶不到就讓開,不排隊也不並行。並行兩輪會在同一頁附兩節,還會互相蓋掉用量快照。鎖逾時可被下一輪搶走,被搶走的那一輪收尾時對不上就不寫心跳——它沒跑到底,不該蓋章。 - 任一項失敗不影響其餘項目。失敗要在監控頁上看得出來是失敗,不是沒資料;來源是空的則明寫「那是零次,不是故障」。 - 版本盤點照抄腳本原字。抄到查詢失敗就寫查詢失敗,不改寫成相符、也不自己補查遠端版本——查不到是沒有證據,不是版本沒問題。 Who: 助理落地的第四塊。排程那一輪留下的問題在這裡解掉了。
6.4 KiB
6.4 KiB
jsc-assist 技能行為清單
本頁記錄 jsc-assist 每支技能的行為基準,供技能驗證比對。技能異動時,在同一個 PR 內一起更新這一頁。
assistant
| 項目 | 內容 |
|---|---|
| 觸發時機 | 要啟動助理、要停止助理、要跑一輪巡檢,或要問助理現在還在不在跑、待辦簿剩下哪幾筆時用。四個操作 start、status、patrol、stop 都走這一支。排程每一輪叫起來的也是這一支的 patrol。執行環境健檢不走這支,走 jsc-cli:doctor。技能使用次數不走這支,走 jsc-log:stats |
| 關鍵步驟 | 先認出使用者要的是哪一個操作,patrol 那一路全程不問人。start:先照 patrol 的每一步跑完一輪巡檢,第一次心跳由那一輪寫、不另外寫、跑不完就不算啟動、跑 heartbeat.sh report 確認 state=fresh、跑 tools/schedule.sh install patrol 裝巡檢那一筆排程、依結束碼選一段收尾訊息印出——排程接上、排程寫進去了但 cron 沒在跑、排程沒接上三種各一段。心跳那一筆不裝了,install heartbeat 一律回 6。patrol:跑 tools/patrol.sh collect 取鎖並讀四項來源、結束碼 4 就讓開不寫任何東西、結束碼 1 與 3 照樣把那一節寫上監控頁、hash 是空的就 abort、把 section_file 交給 jsc-gitea:wiki 附加到 MONITOR_{HASH}、頁不存在(唯有結束碼 4)才用 newpage_file 建頁、把 contents_file 的 row 更新到 MONITOR_CONTENTS 自己那一列、兩次寫入任一失敗就 abort 且不寫心跳、全部寫成才跑 tools/patrol.sh finish 寫心跳、最後印出四項結果與待人處理列。status:跑 heartbeat.sh report 取心跳現況、把 state 對映成新鮮、過期、心跳檔損壞、不存在、不自己解析心跳檔也不自己判定、從 file= 解出助理目錄後列出 tasks/ 底下每一個檔案並解析 state、title、next_run、fail_count、跑 tools/schedule.sh status 取排程現況與週期、印成心跳、排程、待辦三塊、fail_count 大於 0 的列標上「已連續失敗 N 次」、心跳與排程兜起來會誤讀的四種組合各補一句話。stop:先跑 heartbeat.sh report 留下原本的狀態、再跑 tools/schedule.sh remove all 移除排程與舊版遺留的心跳條目、最後才跑 heartbeat.sh clear 清掉心跳、印出停止訊息並說明心跳清掉之後閘門會擋人、同時說明閘門還沒接線所以現在擋不到人 |
| 外部呼叫 | jsc-hooks/hooks/heartbeat.sh 的 write、report、clear 三個子命令,六個結束碼各有處置:0 往下走、1 與 3 印「助理未運行」、2 回報判不出狀態並停下、4 當成不新鮮並回報心跳檔損壞、5 是嚴重狀況要吵出來且不得回報成功、6 是呼叫寫錯要更正後重跑。write 只由 tools/patrol.sh finish 呼叫,技能自己不呼叫。本 domain 的 tools/schedule.sh 的 install、remove、status 三個子命令,七個結束碼各有處置:0 往下走、1 是條目裝了但 cron 沒在跑要照實講不會執行、2 是缺 jsc-hooks 導致門檻讀不到、3 是這台機器沒有排程機制、4 是排程操作失敗要原樣引用 stderr、5 是回讀驗證失敗要叫人自己去看 crontab -l、6 是呼叫寫錯,含 install heartbeat 與週期塞不進門檻。本 domain 的 tools/patrol.sh 的 collect、finish、abort 三個子命令,七個結束碼各有處置:0 往下走、1 部分失敗照樣寫頁、2 是 finish 找不到 heartbeat.sh 要回報「記下來了但沒有心跳」、3 是四項全失敗照樣寫頁且判定異常、4 是讓開或鎖被搶走一律不寫心跳、5 是檔案系統失敗要吵出來、6 是呼叫寫錯。巡檢那四項讀 jsc-log/tools/usage-stats.sh、jsc-hooks/hooks/version-guard.sh report、jsc-hooks/hooks/restart-gate.sh report、$JSC_HOME/sessions/*.stage、$JSC_HOME/wp/*.pr、heartbeat.sh report,全部只讀,任一項失敗不影響其餘三項。wiki 讀寫一律經 jsc-gitea:wiki,技能自己不拼 API 呼叫。crontab 與 schtasks 一律經 tools/schedule.sh。另外唯讀 $JSC_HOME/assistant/tasks/ 底下的檔案。呼叫端沒講清楚要哪一個操作時走 jsc-ask:ask 的決策樹問,但 patrol 那一路一律不問。不參與閘門判定 |
| 完成條件 | start 要那一輪巡檢的 finish 回 0 且 report 回 state=fresh,才算啟動成功;巡檢沒寫成心跳一律回報失敗並停下,不得宣稱啟動;schedule.sh install patrol 回 1 要講明條目不會被執行與 sudo service cron start,不得宣稱排程會定時執行。patrol 要四項各自有 status、監控頁附加成功、目錄頁那一列更新成功、finish 回 0,才算一輪跑完;collect 回 4 是讓開,不算失敗也不寫任何東西;監控頁或目錄頁任一沒寫成就 abort,回報「這一輪沒有結果」,心跳一定不寫。status 要印出現況表,或印出「助理未運行」並說明原因;心跳不存在、待辦簿目錄不存在、待辦簿零筆、排程沒裝,四種都算正常結束。stop 要 schedule.sh remove all 先回 0、clear 再回 0,並印出帶三段話的停止訊息;remove 非 0 就回報排程還在、助理停不掉,不清心跳也不印停止訊息;clear 回 5 就回報心跳檔還在、助理沒有確實停掉,不印停止訊息 |
| 可驗證跡象 | start 之後 $JSC_HOME/assistant/heartbeat 存在,ts 是剛才那一輪的時間,crontab -l 找得到一筆帶 # jsc-assist:assistant patrol 的條目,而且只有一筆,帶 # jsc-assist:assistant heartbeat 的舊條目一筆都不剩。patrol 跑完之後 wiki 的 MONITOR_{HASH} 多一節、節標題帶時間戳、舊的節一字不改,MONITOR_CONTENTS 只有自己那一列變動,$JSC_HOME/assistant/patrol/ 底下有本輪的 section.md、newpage.md、contents.tsv,$JSC_HOME/assistant/usage-prev.tsv 換成本輪的累計數,$JSC_HOME/assistant/patrol.lock 已經放掉。讓開的那一輪沒有任何寫入跡象。stop 之後心跳路徑不存在,crontab -l 找不到任何 # jsc-assist:assistant 條目。以上都不動別人的排程條目,條目數量前後相同。status 無寫入跡象,只有回報內容。四個操作都不動 tasks/ 底下的檔案,也不動 worktree 與程式碼存取庫。排程的 log 一律在 $JSC_HOME/assistant/schedule.log,不落在任何存取庫 |