Files
assist/templates/monitor-contents.md
jiantw83 311cdc611a feat(wiki): 巡檢目錄頁改成一台機器一個大標題區塊
巡檢目錄頁的版面從 markdown 表格換成「大標題加條列」:一台機器一個大標題
區塊,標題就是那一台機器監控頁的實際頁名,欄位改成標題底下的一層條列。
範本、技能敘述、行為清單與說明文件一併跟上,目錄頁上不再留任何表格。

表格的欄位組合是整頁共用的,表頭跟著建頁那一台機器走,之後每一台只改自己
那一列。欄位一增減,只有跑到新版的機器寫得出新的格數,同一張表就混著兩種
格數,多出來的那一格對不到任何欄名,而目錄頁又沒有整頁改寫的路可以走——
整頁覆蓋等於刪掉別台機器的紀錄。條列一筆一個區塊,欄位各自獨立,加一條只
動到自己那一個區塊。

比對鍵從裸雜湊那一格改成大標題本身,標題寫成監控頁的實際頁名。頁名只由
主機名與登入帳號決定,換主機位址、換專用存取庫或換一種頁名編碼都動不到
它;含網址的那一條連結照樣留著給人點,但不當鍵。呼叫改成拿頁名當鍵,欄號
那個參數只在舊表格頁轉檔時用得到。範本原本用二階標題寫的說明區段全部搬進
引言,否則轉檔後會被當成一筆真紀錄讀進去。

範圍是助理的巡檢目錄頁與 assistant 技能的敘述。
2026-09-02 17:21:12 +08:00

77 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 助理巡檢目錄
> 由 `jsc-assist` 維護。這是目錄頁 `MONITOR_CONTENTS`,落在 `JSC_WIKI_REPO_CONTENTS` 解出的專用存取庫,和監控頁不同庫。
> 一個區塊代表一台機器。雜湊來源是 `{主機名}/{登入帳號}`,主機名取短的那一段,所以一台機器一個區塊、一頁,換一支 CLI 不另開區塊。
> `MONITOR_{HASH}` 的 `{HASH}` 執行 `jsc-gitea/tools/hash-id {主機名}/{登入帳號}` 取得,原樣採用它印出的完整 40 碼大寫十六進位,不截短、不加前綴(共用 wiki hash 規則,演算法見 `jsc-meta` 的 `references/guidelines.md`)。
>
> 版面固定三段:H1 頁名、這一段引言,然後每一台機器一個 H2 區塊。H2 標題就是那一台機器的內容頁頁名 `MONITOR_{HASH}`,標題不放連結、不放網址、不加前後綴、不加日期。欄位一行一條,格式 `- {欄位名}:{值}`,順序照這段引言的「欄位說明」從上到下。H2 與第一條之間空一行,區塊之間空一行。這一頁不放 markdown 表格。
>
> 連結寫法:一律寫成 `[{文字}]({絕對網址})`,網址取 `jsc-gitea/tools/gitea.sh wiki-url` 印出的那一個,不自己組路徑。wiki 自己那種雙中括號寫法只在同一個 wiki 裡解得開,寫錯不會報錯,畫面上看起來像正常文字或死連結。
>
> 寫入前驗證:這一個區塊要放進去的連結,先交給 `jsc-gitea/tools/link-check.sh`,結束碼 0 才寫。有 DEAD 就不寫這一個區塊,把連不到的那幾筆回報出去。驗證走 API,不看網頁狀態碼——私有存取庫的網頁網址對未登入請求一律回 404,拿狀態碼判會把還在的頁判成死連結。
>
> 比對鍵:H2 標題,也就是內容頁頁名 `MONITOR_{HASH}`,純文字,不帶連結、不帶網址。「監控頁」那一條的連結是給人點的,不當鍵。
>
> 欄位說明:條列的順序就是下面這幾條從上到下的順序,一條都不能少。鍵在 H2 標題出現過,「監控頁」與「HASH」照樣各留一條,資料才不會少。
>
> - **監控頁**:指向 `MONITOR_{HASH}` 的連結,寫成 `[{頁名}]({絕對網址})`,給人點的,不當比對鍵。少了它就要人自己算雜湊才翻得到內容頁;絕對網址在哪一個存取庫都連得過去,寫入前也驗得起來。
> - **HASH**:`hash-id` 印出的完整 40 碼大寫十六進位,純文字,不加連結、不加網址。這一條只跟 `{主機名}/{登入帳號}` 有關,換主機位址、換存取庫、換一種網址編碼都不會變。H2 標題就是 `MONITOR_` 接上這一串,所以這一條也是標題的來源。
> - **主機**:這台機器的短主機名,與雜湊第一段相同。一眼看出這一個區塊是哪一台機器。
> - **帳號**:助理執行時的登入帳號,與雜湊第二段相同。同一台機器換帳號就是另一個巡檢對象,雜湊也會不同。
> - **心跳**:巡檢當下(本輪寫入前)的心跳判定,判準只看 `ts` 距現在有沒有超過門檻,預設 300 秒。一眼看出這台機器上一輪巡檢有沒有跑完,不必逐頁翻。
> - **最後巡檢**:該頁最新一輪的時間戳。心跳由巡檢寫,兩條理當一致;差很多就代表有一輪寫了心跳卻沒寫頁,那是缺陷。
> - **待辦筆數**:待辦簿現有筆數。心跳新鮮而筆數為 0,代表助理空轉,沒有東西可跑。
> - **連續失敗項**:待辦簿裡 `fail_count` 大於 0 的筆數。待辦簿的項目失敗不會自動暫停,每輪都重試,這一條讓壞掉的項目在目錄頁就現形。
>
> 為什麼沒有「本輪非 ok 事件數」這一條:執行狀態事件的筆數只放在監控頁的「執行狀態事件」那一節,這一頁不加條。兩個理由:
>
> - **同一頁上會出現兩種欄位組合。** 每一個區塊由那一台機器自己那一輪寫,別台機器的區塊要到它下一輪才會重寫。新加一條,只有跑到新版的機器寫得出來,其餘機器的區塊還是舊的那幾條,而讀的人分不出「這台機器本輪沒有非 ok 事件」與「這台機器的版本還沒寫這一條」。目錄頁也沒有整頁改寫的路可以走:整頁覆蓋等於刪掉別台機器的紀錄。
> - **這個數字離開監控頁就會被讀錯。** 它算的是「上一次排空之後到這一輪之間」的事件,視窗長度隨巡檢週期與上一輪的成敗變動。放在監控頁上,同一節裡就有事件總數、未配對的 `start` 與明細表可以對照;抽一個數字放到目錄頁,0 會被讀成「這台機器很健康」,但它同樣可能只是那一段時間沒有任何技能跑過。
>
> 要判斷一台機器有沒有問題,這一頁上的「心跳」與「最後巡檢」就夠帶人往下翻;細節一律回監控頁看。
>
> 寫入規則:這一頁是共用目錄,別台機器的區塊一律原樣保留。寫入一律用 `jsc-gitea/tools/wiki-contents.sh upsert`,不手工改頁。
>
> ```mermaid
> flowchart TD
> A[監控頁已經寫成] --> B[gitea.sh wiki-url 取監控頁絕對網址]
> B --> C[組出本機那一個區塊,網址換掉佔位]
> C --> V{link-check.sh 驗這一個區塊的連結}
> V -- 結束碼 0 --> D[wiki-contents.sh upsert MONITOR,H2 標題 MONITOR_HASH 當鍵]
> V -- 有 DEAD 或其他非 0 --> W[不寫這一個區塊,回報連不到的那幾筆]
> D --> E{舊頁讀得回來}
> E -- 是 --> F{找得到同名的 H2 標題}
> F -- 是 --> G[整塊換掉那一個區塊]
> F -- 否 --> H[附加一個區塊到頁尾]
> E -- 頁不存在 --> I[用範本建頁,再附加一個區塊]
> E -- 金鑰失效或 API 失敗 --> J[中止:不建頁、不寫入]
> G --> K[整頁寫回,別台機器的區塊原樣送回]
> H --> K
> I --> K
> ```
>
> - 連結一律 `[{文字}]({絕對網址})`,網址取 `gitea.sh wiki-url`。這一個區塊要放進去的每一個連結,寫入前先過 `link-check.sh`,結束碼 0 才寫;結束碼 1 就不寫這一個區塊,把 DEAD 那幾筆回報出去。結束碼 3 是 `GITEA_HOST` 沒設定,補設定再驗,不准跳過驗證;結束碼 7 是金鑰失效,停下來回報金鑰問題,不要當成死連結——金鑰過期時私有存取庫的回應和「頁不存在」分不出來,混為一談會把還在的頁整批判死。
> - 存取庫走 `gitea.sh wiki-repo CONTENTS`:先 `JSC_WIKI_REPO_CONTENTS`,再 `JSC_WIKI_REPO`,都沒設就結束碼 3,不退回監控頁那一支變數。
> - `upsert` 的位置參數是 `MONITOR`、`{key-col}`、`{key}`、`{區塊檔}`、`{範本}`:
> - `{key-col}` 只在舊頁還是 markdown 表格時才用得到,指舊表格中持有身分的那一欄序號(1 起算)。本頁的舊表格是第 1 欄「監控頁」,那一格是 `[MONITOR_{HASH}](網址)`,轉檔時只取文字當 H2 標題。頁面已經是條列格式時這個參數完全用不到。
> - `{key}` 是這一個區塊的 H2 標題文字,也就是內容頁頁名 `MONITOR_{HASH}`。用來找既有的區塊。
> - `{區塊檔}` 是整個 H2 區塊的 markdown:`## MONITOR_{HASH}` 那一行、空行,然後各條 `- {欄位名}:{值}`。
> - 比對鍵是 H2 標題,原樣比對標題文字(去頭尾空白後完全相等)。鍵取 `collect` 印的 `page=`,自己重打會對不上,結果是同一台機器多出第二個區塊。
> - 「監控頁」那一條的連結不當鍵:那一條含 `GITEA_HOST` 與頁名的網址編碼,主機位址改掉、`JSC_WIKI_REPO_MONITOR` 換了存取庫、或 Gitea 的網址編碼有差,整條文字就變了,鍵跟著對不上。這一頁每 15 分鐘寫一次,對不上的那一刻起每輪多附一個區塊,舊區塊再也不會更新。頁名只由 `{主機名}/{登入帳號}` 決定,那三件事都動不到它。
> - 找得到相同的 H2 標題就換掉那一個區塊,找不到才附加一個區塊。
> - 只動自己那一個區塊,別台機器的區塊一個字都不改。禁止整頁覆蓋——整頁覆蓋等於刪掉別台機器的紀錄。
> - 只有「頁不存在」才准用範本建頁。金鑰失效或 API 失敗一律中止:那兩種情況舊內容是未知的,拿範本蓋上去就是把活著的紀錄整份刪掉。
> - 舊頁還是 markdown 表格時,`upsert` 自己先把整頁轉成 H2 區塊再做這一次寫入,資料列的順序原樣保留。這一頁不再留任何 markdown 表格。
> - 內容頁 `MONITOR_{HASH}` 的寫入語意不同:那頁固定三塊,最新一輪整塊換掉,摘要表一輪一列、最新的在最上面、超過 24 列丟最舊的。內容頁維持表格,兩者不要混用。
## MONITOR_{HASH}
- 監控頁:[MONITOR_{HASH}]({wiki-url 印出的絕對網址})
- HASH:{HASH}
- 主機:{主機名}
- 帳號:{登入帳號}
- 心跳:{新鮮、過期、不存在 三選一}
- 最後巡檢:{yyyy-MM-dd HH:mm}
- 待辦筆數:{n}
- 連續失敗項:{n}