# 階段回報 — 四個階段收尾都要交的東西 規劃、分析、實作、維護跑完,最後兩件事固定是這兩筆:先給使用者看的階段回報,再給機器看的 結束事件。階段回報由 `tools/stage-report.sh` 彙整產出,技能只負責把事實餵進去:寫過哪些 wiki 頁、有沒有寫工作日誌、實作階段的工作目錄與三條分支。結束事件見本頁最後一節。 ## 什麼時候回報 階段結束就回報,**提前停下來也算結束**:模型閘門擋下、工作包閘門擋下、沒有可選的計畫或工作包、 來源分支在遠端找不到——這些情況一樣要回報,而且更需要。停在半路卻沒有回報,看起來就跟沒跑過一樣。 ## 每個階段都要回報的三項 | 項目 | 來源 | 沒有時怎麼辦 | | --- | --- | --- | | 模型能力標籤 | `jsc-hooks/hooks/sdlc-gate.sh report`,腳本自己讀 | 回報「查不到閘門狀態」,並要求重跑 `lock {stage}` | | 工作日誌連結 | `--worklog` 給頁名、`--worklog-heading` 給條目標題,組成導向該條目的錨點連結 | 警告使用者檢查,並把內容暫存(見下節) | | 所有寫入的 wiki 連結 | 每寫一頁就記一筆,收尾時用 `--page TYPE:PAGE` 全部餵進去 | 沒寫任何頁就據實回報「本階段沒有寫入任何 wiki 頁」 | `--page` 的 `TYPE` 是頁名前綴(`PLAN`、`ANALYZE`、`DELIVER`、`REPO`、`MAINTAIN`、`LOG`)。腳本用它解析 該類型的 wiki 存取庫,再換成絕對網址,所以跨存取庫的頁面也連得到。目錄頁(`*_CONTENTS`)也算寫入,要列。 ## 連結驗證 連結一律寫成 `[{文字}]({連結})`,網址取自 `jsc-gitea/tools/gitea.sh wiki-url`,不自行組路徑, 也不用 `[[頁名]]` 或 `[[顯示文字|頁名]]`。寫進任何頁面之前,每個連結先交給 `jsc-gitea/tools/link-check.sh`,結束碼 0 才寫入;有 DEAD 就不寫,把連不到的清單回報給使用者。 `stage-report.sh` 印出來的那張連結清單也會再驗一次,逐列標「通過、無可查端點、連不到、未驗證」。 這一道是複查,不是上面那道關卡的替代品:頁面在收尾之前就寫完了,所以這裡只註記、不阻擋。 金鑰失效(`link-check.sh` 結束碼 7)標成「未驗證」,不標成「連不到」——把金鑰問題寫成死連結, 下一手就會照著去刪還活著的頁。 ## 實作階段多回報四項 | 項目 | 選項 | 腳本自己查的部分 | | --- | --- | --- | | 工作目錄 | `--worktree PATH` | 無,原樣列出 | | 來源分支 | `--source-branch NAME` | 遠端有沒有這一條。遠端找不到就標「只有本機」 | | 工作分支 | `--work-branch NAME` | 相對來源分支的 commit 數、推送狀態(未 push、或還有幾個 commit 沒 push) | | 目標分支 | `--target-branch NAME`、`--pr URL` | 省略目標分支時等同來源分支;沒有 PR 連結就列為警告 | ## 沒寫工作日誌就暫存 每完成一個任務就要寫一筆工作日誌(一個工作包、一輪 PR 留言修正、一個獨立的修正提交各算一個), 所以做完事情的階段收尾時本來就有日誌可連。本節講的是**還沒完成任何任務就停下**的那種階段。 暫存不等於已寫入。內容只留在對話裡,換一個工作階段就沒了,所以: 1. 把這個階段要記的日誌內容寫成一個檔案。 2. 收尾時一起餵進去:`--pending-file {檔案} --log-hash {LOG_{HASH} 的 HASH}`。 3. 腳本轉呼叫 `jsc-log/tools/worklog-pending.sh add`,把內容存進 `$JSC_HOME/worklog-pending/{HASH}/`,並在回報裡印出存放路徑。 4. 下次 `jsc-log:worklog` 寫入時,會先把暫存區的內容一併寫進日誌頁,寫成功才清掉暫存。 `{HASH}` 用 `jsc-gitea/tools/hash-id` 對程式碼存取庫的 `{owner}/{repo}` 算出來,和 `LOG_{HASH}` 同一個值。 ## 結束碼 | 碼 | 意思 | 呼叫端要做的事 | | --- | --- | --- | | 0 | 回報完整 | 把輸出原樣貼給使用者 | | 1 | 有警告(缺工作日誌、實作階段沒有 PR、或清單裡有連不到的連結) | 一樣把輸出貼給使用者,連不到的連結照著修。**這是警告不是阻擋**,階段的工作已經做完了 | | 2 | 用法錯誤 | 修正參數重跑 | | 3 | 找不到 `gitea.sh` 或 `sdlc-gate.sh` | 修好相依關係再重跑 | ## 結束事件 — 階段回報之後那一筆 階段回報是給人看的,結束事件是給機器看的。跑完階段回報,緊接著跑 `jsc-hooks/tools/report-status.sh skill-end jsc-sdlc:{技能名} {status} {結束碼} [detail]`, 一筆寫進 `$JSC_HOME/usage/events.jsonl`。腳本名怎麼寫,比照各技能既有寫 `jsc-hooks/hooks/sdlc-gate.sh` 的方式,不另立一套。 為什麼非得由技能自己寫:配對的 `skill-start` 由 jsc-hooks 自己記,但那個 hook 接在技能工具 呼叫之後就觸發,實際工作還在後面的模型輪次,所以**沒有任何 hook 看得到階段怎麼結束**。 有 `start` 沒有配對的 `end`,在紀錄裡就是中止;收尾少寫這一筆,跑完的階段每一次都會被算成中止。 | 項目 | 規則 | | --- | --- | | `status` | `ok`、`blocked`、`failed`、`degraded`、`aborted` 五選一。哪一種情況選哪一個,各技能 SKILL.md 的收尾步驟有自己的對應表,那張表是唯一判準 | | 模型閘門擋下 | 一律 `blocked`,不是 `failed`。閘門擋下不合格的模型是閘門在做事,記成失敗會讓下一手去找一個不存在的缺陷 | | `{結束碼}` | 判定該狀態的那支腳本的結束碼;沒有任何腳本回非 0 就填 `0`,`ok` 與 `aborted` 都是這種 | | `[detail]` | 選填,繁體中文單行,講清楚是什麼決定了這個狀態。腳本截到 200 字元,長內容不要塞 | | 失敗怎麼辦 | **這一步失敗不改變本次階段的結論。** 找不到腳本就安靜跳過,不回報也不重跑任何步驟。三個記錄子命令本來就設計成寫檔失敗也回 0,所以回非 0 只代表呼叫本身寫錯了(`2` 是用法錯誤),修一次參數就好 |