feat(狀態回報): 收尾寫一筆 skill-end 事件
現行紀錄只記「被叫用」,沒有成敗也沒有結束碼。跑完整輪的技能與開場就 中止的技能,在紀錄裡長得一模一樣。 start 由技能用量 hook 順手發,不必改技能文件。end 只能由技能自己在收尾 步驟寫——hook 接在技能工具呼叫上,而實際工作發生在之後的模型輪次,它在 原理上看不到成敗。有 start 沒有配對的 end,就是那一輪中止了。 status 五選一,每支技能各自寫明什麼情況選哪一個。找不到回報腳本就安靜 跳過,回報失敗一律不改變技能自己的結論。
This commit is contained in:
@@ -27,6 +27,15 @@
|
||||
| 待辦筆數 | 待辦簿現有筆數 | 心跳新鮮而筆數為 0,代表助理空轉,沒有東西可跑 |
|
||||
| 連續失敗項 | 待辦簿裡 `fail_count` 大於 0 的筆數 | 待辦簿的項目失敗不會自動暫停,每輪都重試。這一欄讓壞掉的項目在目錄頁就現形 |
|
||||
|
||||
### 為什麼沒有「本輪非 ok 事件數」這一欄
|
||||
|
||||
執行狀態事件的筆數只放在監控頁的「執行狀態事件」那一節,這一頁不加欄。兩個理由:
|
||||
|
||||
- **這一頁的欄不是自己一台機器說了算。** 每一列是一台機器,欄位卻是共用的:表頭跟著建頁的那一台走,之後每一台只更新自己那一列。新加一欄,只有跑到新版的機器會寫出多一格的列,其餘機器的列還是舊的格數,表頭也還是舊的——同一張表混著兩種格數,多出來的那一格對不到任何欄名。目錄頁沒有整頁改寫的路可以走:整頁覆蓋等於刪掉別台機器的紀錄。
|
||||
- **這個數字離開監控頁就會被讀錯。** 它算的是「上一次排空之後到這一輪之間」的事件,視窗長度隨巡檢週期與上一輪的成敗變動。放在監控頁上,同一節裡就有事件總數、未配對的 `start` 與明細表可以對照;抽一個數字放到目錄頁,0 會被讀成「這台機器很健康」,但它同樣可能只是那一段時間沒有任何技能跑過。
|
||||
|
||||
要判斷一台機器有沒有問題,這一頁上的「心跳」與「最後巡檢」就夠帶人往下翻;細節一律回監控頁看。
|
||||
|
||||
## 寫入規則
|
||||
|
||||
這一頁是共用目錄,別台機器的列一律原樣保留。寫入一律用 `jsc-gitea/tools/wiki-contents.sh upsert`,不手工改頁。
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[巡檢一輪] --> B[收攏四項結果]
|
||||
A[巡檢一輪] --> B[收攏各項結果]
|
||||
B --> C[讀回舊頁]
|
||||
C --> D[換掉最新一輪那一塊]
|
||||
D --> E[本輪摘要列插到表格最上面,截到 24 列]
|
||||
@@ -35,7 +35,7 @@ flowchart LR
|
||||
|
||||
這一塊每輪整塊換掉,只留最新那一輪的完整內容。再往前的軌跡看下面的摘要表。
|
||||
|
||||
六個子節固定都寫;某個來源讀不到,就在那個子節寫明是哪個路徑讀不到,不要整節略過。還沒實作的子節也照寫,寫明「這一輪不做這一項」——空表格會被讀成「查過了,沒問題」。
|
||||
七個子節固定都寫;某個來源讀不到,就在那個子節寫明是哪個路徑讀不到,不要整節略過。還沒實作的子節也照寫,寫明「這一輪不做這一項」——空表格會被讀成「查過了,沒問題」。
|
||||
|
||||
| 項目 | 內容 |
|
||||
| --- | --- |
|
||||
@@ -58,7 +58,7 @@ flowchart LR
|
||||
|
||||
這一欄讀到的是**上一輪**巡檢寫的心跳:心跳由巡檢寫,本輪那一次要等這一頁寫成之後才寫。
|
||||
|
||||
心跳的判準只看 `ts` 距現在有沒有超過門檻,預設 300 秒。不看 pid 存活:五支 CLI 與容器裡的行程互相看不到彼此的 pid。閘門的判定留在 hook,助理只維持心跳。心跳新鮮代表上一輪巡檢跑完了,不代表那一輪四項都成功——那要看這一塊上面的「本輪判定」。
|
||||
心跳的判準只看 `ts` 距現在有沒有超過門檻,預設 300 秒。不看 pid 存活:五支 CLI 與容器裡的行程互相看不到彼此的 pid。閘門的判定留在 hook,助理只維持心跳。心跳新鮮代表上一輪巡檢跑完了,不代表那一輪各項都成功——那要看這一塊上面的「本輪判定」。
|
||||
|
||||
### 技能與呼叫鏈使用統計
|
||||
|
||||
@@ -68,6 +68,40 @@ flowchart LR
|
||||
| --- | --- | ---: | ---: |
|
||||
| {技能名或呼叫鏈} | {技能、呼叫鏈 二選一} | {n} | {n} |
|
||||
|
||||
### 執行狀態事件
|
||||
|
||||
資料出自 `$JSC_HOME/usage/events.jsonl`,由 `jsc-hooks` 的 `tools/report-status.sh drain` 排空,位移記在 `$JSC_HOME/usage/scan-state/events.offset`。排空之後緊接著跑一次 `rotate`。
|
||||
|
||||
技能的 `start` 由 hook 記,`end` 只能由技能自己在收尾時寫。**所以有 `start` 沒有配對的 `end` 就是那一輪中止了**,那也是這一整套機制唯一分得出中止的訊號。配對以 `session` 加 `name` 為鍵:五支 CLI 併發時同一支技能會有好幾個工作階段同時在跑,只比對 `name` 會讓 A 工作階段的 `end` 去配掉 B 工作階段的 `start`。
|
||||
|
||||
| 項目 | 內容 |
|
||||
| --- | --- |
|
||||
| 本輪事件數 | {n} |
|
||||
| 非 ok 事件數 | {n} |
|
||||
| 有 start 沒有 end(開超過 {門檻} 秒,疑似中止) | {n} |
|
||||
| 有 start 沒有 end(未達門檻,還在跑) | {n} |
|
||||
| 事件流輪替 | {rotated、not-needed、failed、skipped 四選一} |
|
||||
|
||||
#### 非 ok 事件明細
|
||||
|
||||
`status` 五種:`ok` 全部達成、`blocked` 被閘門或前置條件擋下、`failed` 做到一半失敗、`degraded` 做完了但有部分沒達成、`aborted` 使用者中止或前提不成立而主動停止。這一表只列不是 `ok` 的那幾筆。
|
||||
|
||||
| 時間 | 類別 | 名稱 | status | 結束碼 | detail |
|
||||
| --- | --- | --- | --- | ---: | --- |
|
||||
| {yyyy-MM-ddTHH:mm:ssZ} | {skill、hook 二選一} | {技能寫 domain:skill,hook 寫腳本檔名加子命令} | {blocked、failed、degraded、aborted 四選一} | {n} | {一行,最多 200 字;沒有就寫「-」} |
|
||||
|
||||
一筆都沒有就寫「本輪沒有 status 不是 ok 的事件」,不要留空表格。列太多時只列前面幾筆,並寫明總筆數與原始事件檔的路徑。
|
||||
|
||||
#### 有 start 沒有配對的 end
|
||||
|
||||
| 名稱 | 類別 | session | start 時間 | 已開著(秒) |
|
||||
| --- | --- | --- | --- | ---: |
|
||||
| {domain:skill} | {skill、hook 二選一} | {工作階段代號} | {yyyy-MM-ddTHH:mm:ssZ} | {n} |
|
||||
|
||||
只列開著超過心跳門檻的那幾筆。未達門檻的多半只是還在跑,另外算一個數字就好。沒配對到的 `start` 留在 `$JSC_HOME/assistant/events-open.tsv` 跨輪繼續配對;不跨輪的話,跑超過一個巡檢週期的技能每一輪都會被報成中止,而巡檢週期預設只有兩分鐘。
|
||||
|
||||
排空或輪替失敗時,這一節寫明是哪一步失敗、結束碼多少,那一項標成失敗。**這一節失敗一律不中止那一輪**:回報鏈自己壞掉,不可以把被回報的那一輪也拖下去。`drain` 回 3 是「沒有新事件」,那是正常狀態,多數輪次本來就沒有新事件。
|
||||
|
||||
### hook 執行期錯誤
|
||||
|
||||
資料出自 `jsc-hooks` 的 `tools/scan-hook-errors.sh` 與 `tools/scan-logs.sh`。助理只記錄與發動 `jsc-hooks:repair`,不自己改 hook。
|
||||
@@ -116,17 +150,19 @@ flowchart LR
|
||||
|
||||
| 項目 | 來源子節 | 建議入口 |
|
||||
| --- | --- | --- |
|
||||
| {一句話講完要處理什麼} | {上面六個子節之一} | {技能名或指令} |
|
||||
| {一句話講完要處理什麼} | {上面七個子節之一} | {技能名或指令} |
|
||||
|
||||
## 近 24 輪摘要
|
||||
|
||||
一輪一列,最新的在最上面,超過 24 列就丟掉最舊的那一列。
|
||||
|
||||
| 巡檢時間 | 本輪判定 | 四項成敗 | 待人處理 | 警示來源 |
|
||||
| 巡檢時間 | 本輪判定 | 各項成敗 | 待人處理 | 警示來源 |
|
||||
| --- | --- | --- | ---: | --- |
|
||||
| {yyyy-MM-dd HH:mm} | {正常、警示、異常 三選一} | {成功項數}/{總項數} | {待人處理筆數} | {警示原因,多個用頓號串;沒有就寫「無」} |
|
||||
|
||||
「警示來源」那一欄不能省。四項讀取全部成功、但讀到的內容有警示時,判定是警示而成敗欄是 4/4,沒有這一欄的話,看的人不知道警示哪來。理由要短,一眼讀完,像「心跳過期」「版本查詢失敗」「重啟閘門未清」「上一輪逾時被接手」。
|
||||
「警示來源」那一欄不能省。各項讀取全部成功、但讀到的內容有警示時,判定是警示而成敗欄是滿分,沒有這一欄的話,看的人不知道警示哪來。理由要短,一眼讀完,像「心跳過期」「版本查詢失敗」「重啟閘門未清」「上一輪逾時被接手」「有技能只有 start 沒有 end」。
|
||||
|
||||
第三欄的欄名寫「各項成敗」,不寫項數。巡檢項目會增加,欄名寫死數字就要跟著改,而舊頁那些列的欄名不會跟著改,同一張表就會有兩種欄名。
|
||||
|
||||
## 寫入規則
|
||||
|
||||
@@ -141,3 +177,4 @@ flowchart LR
|
||||
- 整頁寫成之後,才回頭更新目錄頁自己那一列,寫入交給 `jsc-gitea/tools/wiki-contents.sh upsert`,別台機器的列一個字都不動。目錄頁那一欄的連結同樣先驗過才寫。
|
||||
- 這一頁沒寫成就不寫心跳,讓它過期。心跳代表的是「這一輪的結果記在這一頁上了」。
|
||||
- 目錄頁只是索引。目錄頁的存取庫沒設定(結束碼 3)時照樣寫心跳,並把那一筆列進待人處理;其餘寫入失敗才不寫心跳。
|
||||
- 執行狀態事件那一節的內容由 `tools/patrol.sh collect` 排空、彙整好,寫頁的人原樣採用,不自己再跑一次 `drain`。`drain` 是消耗性讀取:它一讀完就把位移往前推,同一批事件不會再出現第二次,第二次跑只會拿到 3,或者把下一輪的事件提前吃掉。
|
||||
|
||||
Reference in New Issue
Block a user