feat(狀態回報): 收尾寫一筆 skill-end 事件
現行紀錄只記「被叫用」,沒有成敗也沒有結束碼。跑完整輪的技能與開場就 中止的技能,在紀錄裡長得一模一樣。 start 由技能用量 hook 順手發,不必改技能文件。end 只能由技能自己在收尾 步驟寫——hook 接在技能工具呼叫上,而實際工作發生在之後的模型輪次,它在 原理上看不到成敗。有 start 沒有配對的 end,就是那一輪中止了。 status 五選一,每支技能各自寫明什麼情況選哪一個。找不到回報腳本就安靜 跳過,回報失敗一律不改變技能自己的結論。
This commit is contained in:
+12
-12
@@ -7,37 +7,37 @@
|
|||||||
| 項目 | 內容 |
|
| 項目 | 內容 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 觸發時機 | 一次技能執行留下可重用的教訓時,用 record 模式記錄。要跑某支技能之前,用 consult 模式查過去的教訓。工時與 Token 紀錄不走這支,走 worklog |
|
| 觸發時機 | 一次技能執行留下可重用的教訓時,用 record 模式記錄。要跑某支技能之前,用 consult 模式查過去的教訓。工時與 Token 紀錄不走這支,走 worklog |
|
||||||
| 關鍵步驟 | record 模式收齊日期、技能、CLI、情境、教訓、下次做法這六欄、從 `git remote get-url origin` 解出 `{owner}/{repo}`、用 `hash-id` 算出完整 40 碼大寫的 `{HASH}`、用 `wiki-repo LEARN` 解出教訓頁存取庫、開 sub agent 讀 `LEARN_{HASH}`、依 `wiki-get` 的退出碼分支(0 在表尾追加一列、4 才用 `templates/learn-page.md` 建頁、7 與 8 停止並回報)、取 `wiki-url` 的絕對網址並寫成 `[{頁名}]({絕對網址})`、把該網址交給 `link-check.sh` 驗證(0 才寫入、1 有 DEAD 就不寫並回報那幾筆、2 沒給網址、3 未設 `GITEA_HOST`、7 金鑰被拒就停下)、同一輪跑 `wiki-contents.sh upsert LEARN 1 {owner}/{repo}` 更新落在 CONTENTS 存取庫的 `LEARN_CONTENTS`、依它的退出碼分流(0 已寫、1 寫入失敗、2 參數錯、3 未設 `JSC_WIKI_REPO_CONTENTS`、4 缺範本、7 金鑰失效、8 其他 API 失敗)、寫入失敗重試一次;consult 模式算出 `{HASH}`、從 CONTENTS 存取庫讀 `LEARN_CONTENTS`、從 LEARN 存取庫讀 `LEARN_{HASH}`、依列上的絕對網址讀頁、挑出「技能」欄相符的列、整理每一列的「下次做法」交給呼叫端 |
|
| 關鍵步驟 | record 模式收齊日期、技能、CLI、情境、教訓、下次做法這六欄、從 `git remote get-url origin` 解出 `{owner}/{repo}`、用 `hash-id` 算出完整 40 碼大寫的 `{HASH}`、用 `wiki-repo LEARN` 解出教訓頁存取庫、開 sub agent 讀 `LEARN_{HASH}`、依 `wiki-get` 的退出碼分支(0 在表尾追加一列、4 才用 `templates/learn-page.md` 建頁、7 與 8 停止並回報)、取 `wiki-url` 的絕對網址並寫成 `[{頁名}]({絕對網址})`、把該網址交給 `link-check.sh` 驗證(0 才寫入、1 有 DEAD 就不寫並回報那幾筆、2 沒給網址、3 未設 `GITEA_HOST`、7 金鑰被拒就停下)、同一輪跑 `wiki-contents.sh upsert LEARN 1 {owner}/{repo}` 更新落在 CONTENTS 存取庫的 `LEARN_CONTENTS`、依它的退出碼分流(0 已寫、1 寫入失敗、2 參數錯、3 未設 `JSC_WIKI_REPO_CONTENTS`、4 缺範本、7 金鑰失效、8 其他 API 失敗)、寫入失敗重試一次;consult 模式算出 `{HASH}`、從 CONTENTS 存取庫讀 `LEARN_CONTENTS`、從 LEARN 存取庫讀 `LEARN_{HASH}`、依列上的絕對網址讀頁、挑出「技能」欄相符的列、整理每一列的「下次做法」交給呼叫端;兩種模式都以 `jsc-hooks/tools/report-status.sh skill-end jsc-log:learn {status} {結束碼} {detail}` 收尾,腳本不在這台機器上就安靜跳過 |
|
||||||
| 外部呼叫 | `jsc-gitea/tools/hash-id`、`jsc-gitea/tools/gitea.sh wiki-repo LEARN` 與 `wiki-repo CONTENTS` 與 `wiki-url`、`jsc-gitea/tools/link-check.sh`(寫入前驗證連結)、`jsc-gitea/tools/wiki-contents.sh upsert`(目錄頁那一列)、`jsc-gitea:wiki`(其餘 wiki 讀寫)、`git remote get-url origin`、`templates/learn-page.md`、`templates/learn-contents.md` |
|
| 外部呼叫 | `jsc-gitea/tools/hash-id`、`jsc-gitea/tools/gitea.sh wiki-repo LEARN` 與 `wiki-repo CONTENTS` 與 `wiki-url`、`jsc-gitea/tools/link-check.sh`(寫入前驗證連結)、`jsc-gitea/tools/wiki-contents.sh upsert`(目錄頁那一列)、`jsc-gitea:wiki`(其餘 wiki 讀寫)、`git remote get-url origin`、`templates/learn-page.md`、`templates/learn-contents.md` |
|
||||||
| 完成條件 | record 模式要 sub agent 回報兩頁都寫入成功,主代理確認新列在 `LEARN_{HASH}` 上,原有的列一列不少,寫入前 `link-check.sh` 回 0,`wiki-contents.sh` 回 0 並印出 `updated` 或 `added`。`link-check.sh` 回 1 就不寫目錄頁,改回報 DEAD 清單。consult 模式要兩頁都讀到,或以退出碼 4 回報頁面不存在,或在 5、7、8 停止並回報狀態 |
|
| 完成條件 | record 模式要 sub agent 回報兩頁都寫入成功,主代理確認新列在 `LEARN_{HASH}` 上,原有的列一列不少,寫入前 `link-check.sh` 回 0,`wiki-contents.sh` 回 0 並印出 `updated` 或 `added`。`link-check.sh` 回 1 就不寫目錄頁,改回報 DEAD 清單。consult 模式要兩頁都讀到,或以退出碼 4 回報頁面不存在,或在 5、7、8 停止並回報狀態。收尾一定要寫一筆 `skill-end` 狀態事件:兩頁都成功是 `ok`,內容頁寫成功但目錄頁沒更新是 `degraded`,連結驗證回 1 或讀寫回 7、8 是 `failed`,雜湊工具缺席或 wiki 存取庫沒設定是 `blocked`,使用者中止或根本沒有可記的教訓是 `aborted` |
|
||||||
| 可驗證跡象 | LEARN 存取庫的 `LEARN_{HASH}` 表尾多一列教訓;CONTENTS 存取庫的 `LEARN_CONTENTS` 上該 repo 那一列的「最後更新時間」換新,且「教訓紀錄」欄是 `[{頁名}]({絕對網址})`,頁面上沒有 `[[...]]` 這種同 wiki 寫法。頁面原本不存在時,會新建 `LEARN_{HASH}` 或 `LEARN_CONTENTS`。連結驗證不過就兩頁都沒有新內容,只有 DEAD 清單的回報。consult 模式無寫入跡象,只有回報內容 |
|
| 可驗證跡象 | LEARN 存取庫的 `LEARN_{HASH}` 表尾多一列教訓;CONTENTS 存取庫的 `LEARN_CONTENTS` 上該 repo 那一列的「最後更新時間」換新,且「教訓紀錄」欄是 `[{頁名}]({絕對網址})`,頁面上沒有 `[[...]]` 這種同 wiki 寫法。頁面原本不存在時,會新建 `LEARN_{HASH}` 或 `LEARN_CONTENTS`。連結驗證不過就兩頁都沒有新內容,只有 DEAD 清單的回報。consult 模式在 wiki 上無寫入跡象,只有回報內容。兩種模式跑完,`$JSC_HOME/usage/events.jsonl` 都會多一筆 `{kind:skill,phase:end}` 事件,`name` 欄是 `jsc-log:learn`,`status` 欄是那五個值之一;`jsc-hooks` 不在這台機器上時沒有這一筆,技能本身照樣跑完 |
|
||||||
|
|
||||||
## report
|
## report
|
||||||
|
|
||||||
| 項目 | 內容 |
|
| 項目 | 內容 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 觸發時機 | 有人要一段期間的工作總結時用,期間分年、月、週、日四種。單一工作包的紀錄不走這支,走 worklog |
|
| 觸發時機 | 有人要一段期間的工作總結時用,期間分年、月、週、日四種。單一工作包的紀錄不走這支,走 worklog |
|
||||||
| 關鍵步驟 | 呼叫端沒指定期間就依 `jsc-ask:ask` 問、跑 `tools/report-range.sh` 取得起訖日與標籤、平行做四件事(`tools/report-template.sh resolve` 解出範本、從 CONTENTS 存取庫讀 `LOG_CONTENTS` 並照列上的絕對網址逐頁讀回工作日誌、年報另外讀 `LEARN_CONTENTS` 並用 `wiki-repo LEARN` 解出教訓內容頁的存取庫、解出 REPORT 的 wiki repo)、把頁面內容存成檔案後跑 `tools/log-aggregate.sh` 算出條目數、涵蓋 repo、花費時間、Token 用量、任務狀態、從存活條目挑出阻塞與未完成工作包、照範本的標題與表格填出報告、用 `hash-id "{REPORT wiki 存取庫}/{period}"` 算出完整 40 碼頁名、讀 `REPORT_{HASH}` 後把本期當成新章節追加在最前、取 `wiki-url` 的絕對網址並依它的退出碼分流(4 是頁還沒寫、5 是頁上沒有 `html_url`、7 與 8 一律停下並回報金鑰或 API 狀態,不得當成 4)、章節內與目錄列的連結一律寫成 `[{文字}]({絕對網址})` 並在寫入前全數交給 `link-check.sh` 驗證(0 才寫入、1 有 DEAD 就不寫並回報那幾筆、2 沒給網址、3 未設 `GITEA_HOST`、7 金鑰被拒就停下)、最後跑 `wiki-contents.sh upsert REPORT 2 {HASH}` 更新落在 CONTENTS 存取庫的 `REPORT_CONTENTS`(鍵取第 2 欄的裸 HASH,不取第 1 欄那個帶主機名的連結) |
|
| 關鍵步驟 | 呼叫端沒指定期間就依 `jsc-ask:ask` 問、跑 `tools/report-range.sh` 取得起訖日與標籤、平行做四件事(`tools/report-template.sh resolve` 解出範本、從 CONTENTS 存取庫讀 `LOG_CONTENTS` 並照列上的絕對網址逐頁讀回工作日誌、年報另外讀 `LEARN_CONTENTS` 並用 `wiki-repo LEARN` 解出教訓內容頁的存取庫、解出 REPORT 的 wiki repo)、把頁面內容存成檔案後跑 `tools/log-aggregate.sh` 算出條目數、涵蓋 repo、花費時間、Token 用量、任務狀態、從存活條目挑出阻塞與未完成工作包、照範本的標題與表格填出報告、用 `hash-id "{REPORT wiki 存取庫}/{period}"` 算出完整 40 碼頁名、讀 `REPORT_{HASH}` 後把本期當成新章節追加在最前、取 `wiki-url` 的絕對網址並依它的退出碼分流(4 是頁還沒寫、5 是頁上沒有 `html_url`、7 與 8 一律停下並回報金鑰或 API 狀態,不得當成 4)、章節內與目錄列的連結一律寫成 `[{文字}]({絕對網址})` 並在寫入前全數交給 `link-check.sh` 驗證(0 才寫入、1 有 DEAD 就不寫並回報那幾筆、2 沒給網址、3 未設 `GITEA_HOST`、7 金鑰被拒就停下)、最後跑 `wiki-contents.sh upsert REPORT 2 {HASH}` 更新落在 CONTENTS 存取庫的 `REPORT_CONTENTS`(鍵取第 2 欄的裸 HASH,不取第 1 欄那個帶主機名的連結)、最後跑 `jsc-hooks/tools/report-status.sh skill-end jsc-log:report {status} {結束碼} {detail}` 記下本輪結果,腳本不在這台機器上就安靜跳過 |
|
||||||
| 外部呼叫 | `tools/report-range.sh`、`tools/report-template.sh`、`tools/log-aggregate.sh`、`jsc-gitea/tools/gitea.sh wiki-repo`(CONTENTS、LOG、LEARN、REPORT)與 `hash-id` 與 `wiki-url`、`jsc-gitea/tools/link-check.sh`(寫入前驗證連結)、`jsc-gitea/tools/wiki-contents.sh upsert`(目錄頁那一列)、`jsc-gitea:wiki`、`jsc-ask:ask`、`templates/report-{period}.md`、`templates/report-contents.md` |
|
| 外部呼叫 | `tools/report-range.sh`、`tools/report-template.sh`、`tools/log-aggregate.sh`、`jsc-gitea/tools/gitea.sh wiki-repo`(CONTENTS、LOG、LEARN、REPORT)與 `hash-id` 與 `wiki-url`、`jsc-gitea/tools/link-check.sh`(寫入前驗證連結)、`jsc-gitea/tools/wiki-contents.sh upsert`(目錄頁那一列)、`jsc-gitea:wiki`、`jsc-ask:ask`、`templates/report-{period}.md`、`templates/report-contents.md` |
|
||||||
| 完成條件 | 回報頁面 URL,或回報跳過寫入與它的原因,或在讀取回 7、8 時停下並回報狀態。每次寫入前 `link-check.sh` 要回 0,回 1 就不寫該頁並回報 DEAD 清單。`wiki-contents.sh upsert` 要回 0,回 1、2、3、4、7、8 就照該碼回報且不得謊報已寫入。收尾要講出期間標籤、條目數、涵蓋的 repo、範本來源、頁面 URL、帶到下一期的未完成工作包清單,以及 `ELAPSED_MISSING` 與 `TOKEN_MISSING` |
|
| 完成條件 | 回報頁面 URL,或回報跳過寫入與它的原因,或在讀取回 7、8 時停下並回報狀態。每次寫入前 `link-check.sh` 要回 0,回 1 就不寫該頁並回報 DEAD 清單。`wiki-contents.sh upsert` 要回 0,回 1、2、3、4、7、8 就照該碼回報且不得謊報已寫入。收尾要講出期間標籤、條目數、涵蓋的 repo、範本來源、頁面 URL、帶到下一期的未完成工作包清單,以及 `ELAPSED_MISSING` 與 `TOKEN_MISSING`。收尾一定要寫一筆 `skill-end` 狀態事件:章節與目錄列都到位是 `ok`(範圍內沒有條目、`log-aggregate.sh` 回 3 也算 `ok`,`detail` 帶 `ENTRIES=0`),報告本文交出去但 wiki 沒寫全是 `degraded`,連結驗證回 1 或讀寫回 7、8 是 `failed`,期間算不出來或範本與存取庫沒設定是 `blocked`,使用者中止是 `aborted` |
|
||||||
| 可驗證跡象 | REPORT 存取庫的 `REPORT_{HASH}`(雜湊取自 REPORT wiki 存取庫的 `{owner}/{repo}` 加期間,不是程式碼存取庫)多一個本期章節;CONTENTS 存取庫的 `REPORT_CONTENTS` 該列的「最新一期」、「期數」、「最後更新」換新,且「報表頁」欄是 `[{頁名}]({絕對網址})`、「HASH」欄是不帶連結的裸 HASH,兩頁都找不到 `[[...]]` 這種同 wiki 寫法。連結驗證不過就沒有新章節,也沒有新的目錄列,只有 DEAD 清單的回報。重跑同一期間只換掉那一列,不會多出第二列。本機留下工作日誌頁面內容的暫存檔,供 `log-aggregate.sh` 讀取。沒設定 REPORT wiki repo 時不寫 wiki,只印出報告本文;沒設定 `JSC_WIKI_REPO_CONTENTS` 時內容頁照寫,只有目錄頁那一列沒動 |
|
| 可驗證跡象 | REPORT 存取庫的 `REPORT_{HASH}`(雜湊取自 REPORT wiki 存取庫的 `{owner}/{repo}` 加期間,不是程式碼存取庫)多一個本期章節;CONTENTS 存取庫的 `REPORT_CONTENTS` 該列的「最新一期」、「期數」、「最後更新」換新,且「報表頁」欄是 `[{頁名}]({絕對網址})`、「HASH」欄是不帶連結的裸 HASH,兩頁都找不到 `[[...]]` 這種同 wiki 寫法。連結驗證不過就沒有新章節,也沒有新的目錄列,只有 DEAD 清單的回報。重跑同一期間只換掉那一列,不會多出第二列。本機留下工作日誌頁面內容的暫存檔,供 `log-aggregate.sh` 讀取。沒設定 REPORT wiki repo 時不寫 wiki,只印出報告本文;沒設定 `JSC_WIKI_REPO_CONTENTS` 時內容頁照寫,只有目錄頁那一列沒動。跑完 `$JSC_HOME/usage/events.jsonl` 會多一筆 `{kind:skill,phase:end}` 事件,`name` 欄是 `jsc-log:report`,`status` 與 `exit` 兩欄對得上上一列講的判準;`jsc-hooks` 不在這台機器上時沒有這一筆,技能本身照樣跑完 |
|
||||||
|
|
||||||
## stats
|
## stats
|
||||||
|
|
||||||
| 項目 | 內容 |
|
| 項目 | 內容 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 觸發時機 | 使用者問某支技能用了幾次,或問技能之間的呼叫鏈用了幾次。Token 與工時統計不走這支,走 worklog |
|
| 觸發時機 | 使用者問某支技能用了幾次,或問技能之間的呼叫鏈用了幾次。Token 與工時統計不走這支,走 worklog |
|
||||||
| 關鍵步驟 | 直接跑 `tools/usage-stats.sh skills` 或 `tools/usage-stats.sh chains`、需要時加 `--cli` 篩選單一 CLI、先讀退出碼再看輸出、退出碼 0 就把每一行印成表格一列、一行都沒印也是退出碼 0,代表次數為零,要說明 `jsc-hooks` 還沒經 `jsc-hooks:hooks-install` 安裝接線且不出表、退出碼 2 代表子指令或 `--cli` 參數被拒,改正參數後重跑 |
|
| 關鍵步驟 | 直接跑 `tools/usage-stats.sh skills` 或 `tools/usage-stats.sh chains`、需要時加 `--cli` 篩選單一 CLI、先讀退出碼再看輸出、退出碼 0 就把每一行印成表格一列、一行都沒印也是退出碼 0,代表次數為零,要說明 `jsc-hooks` 還沒經 `jsc-hooks:hooks-install` 安裝接線且不出表、退出碼 2 代表子指令或 `--cli` 參數被拒,改正參數後重跑、最後跑 `jsc-hooks/tools/report-status.sh skill-end jsc-log:stats {status} {結束碼} {detail}` 記下本輪結果,腳本不在這台機器上就安靜跳過 |
|
||||||
| 外部呼叫 | `tools/usage-stats.sh`;資料由 `jsc-hooks/hooks/skill-usage.sh` 持續寫進 `$JSC_HOME/usage/*.jsonl`,這支技能只讀不寫 |
|
| 外部呼叫 | `tools/usage-stats.sh`;資料由 `jsc-hooks/hooks/skill-usage.sh` 持續寫進 `$JSC_HOME/usage/*.jsonl`,這支技能只讀不寫 |
|
||||||
| 完成條件 | 讀到退出碼,並走完該退出碼指定的分支 |
|
| 完成條件 | 讀到退出碼,並走完該退出碼指定的分支。收尾一定要寫一筆 `skill-end` 狀態事件:退出碼 0 是 `ok`(一行都沒印也是 `ok`,`detail` 帶 `count=0`),只答出一半的統計是 `degraded`,退出碼 2 是 `failed`(那一輪什麼都沒讀到,不得當成次數為零),統計腳本不在這台機器上是 `blocked`,使用者中止或問的其實是工時與 Token 是 `aborted` |
|
||||||
| 可驗證跡象 | 無寫入跡象,只有回報內容 |
|
| 可驗證跡象 | 統計本身無寫入跡象,只有回報內容。跑完 `$JSC_HOME/usage/events.jsonl` 會多一筆 `{kind:skill,phase:end}` 事件,`name` 欄是 `jsc-log:stats`;`jsc-hooks` 不在這台機器上時沒有這一筆,技能本身照樣跑完 |
|
||||||
|
|
||||||
## worklog
|
## worklog
|
||||||
|
|
||||||
| 項目 | 內容 |
|
| 項目 | 內容 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 觸發時機 | implement 或 maintain 階段每結束一項任務就寫一筆。一項任務是一個工作包、一輪 PR 意見修正,或一次獨立的修正提交。下一項任務開始前就要寫完。規劃階段的筆記不走這支 |
|
| 觸發時機 | implement 或 maintain 階段每結束一項任務就寫一筆。一項任務是一個工作包、一輪 PR 意見修正,或一次獨立的修正提交。下一項任務開始前就要寫完。規劃階段的筆記不走這支 |
|
||||||
| 關鍵步驟 | 全程由 sub agent 收集與寫入、平行取得十項事實(`git remote get-url origin` 的 repo、`git branch --show-current` 的分支、PLAN 頁絕對連結、ANALYZE 頁工作包絕對連結、`session-timer.sh report` 的花費時間、`token-usage.sh` 的各 CLI Token、任務狀態、細節與產出、困難與解法、PR 目標分支)、平行解出 LOG wiki repo(只供內容頁)與完整 40 碼大寫的 `{HASH}`、跑 `tools/worklog-target.sh` 取得頁名與本週五日期、用 `templates/log-entry.md` 填出單筆條目檔、跑 `tools/worklog-pending.sh merge` 併入待寫內容(同時收編同一個 `{HASH}` 的「`H` 加前 7 碼」舊目錄)、跑 `tools/worklog-pending.sh orphans` 掃出現行規則定址不到的暫存目錄(0 就安靜帶過,4 就把每一列回報給使用者並繼續本輪)、讀 `PAGE` 後依退出碼分支(0 追加在頁尾、4 才建頁、7 與 8 停止且不建頁)、寫入前把 `MERGED` 裡的每個連結交給 `link-check.sh` 驗證(0 才寫入、1 有 DEAD 就不寫並回報那幾筆、2 沒給網址、3 未設 `GITEA_HOST`、7 金鑰被拒就停下)、同一輪用 `wiki-repo CONTENTS` 解出目錄頁存取庫、取 `wiki-url` 的絕對網址並寫成 `[{頁名}]({絕對網址})`、同樣先過 `link-check.sh` 才跑 `wiki-contents.sh upsert LOG 2 {HASH}` 更新 `LOG_CONTENTS`(鍵取第 2 欄的裸 HASH,不取第 1 欄那個帶主機名的連結)並依 0、1、2、3、4、7、8 各自分流、最後依成敗跑 `worklog-pending.sh commit` 或 `abort` |
|
| 關鍵步驟 | 全程由 sub agent 收集與寫入、平行取得十項事實(`git remote get-url origin` 的 repo、`git branch --show-current` 的分支、PLAN 頁絕對連結、ANALYZE 頁工作包絕對連結、`session-timer.sh report` 的花費時間、`token-usage.sh` 的各 CLI Token、任務狀態、細節與產出、困難與解法、PR 目標分支)、平行解出 LOG wiki repo(只供內容頁)與完整 40 碼大寫的 `{HASH}`、跑 `tools/worklog-target.sh` 取得頁名與本週五日期、用 `templates/log-entry.md` 填出單筆條目檔、跑 `tools/worklog-pending.sh merge` 併入待寫內容(同時收編同一個 `{HASH}` 的「`H` 加前 7 碼」舊目錄)、跑 `tools/worklog-pending.sh orphans` 掃出現行規則定址不到的暫存目錄(0 就安靜帶過,4 就把每一列回報給使用者並繼續本輪)、讀 `PAGE` 後依退出碼分支(0 追加在頁尾、4 才建頁、7 與 8 停止且不建頁)、寫入前把 `MERGED` 裡的每個連結交給 `link-check.sh` 驗證(0 才寫入、1 有 DEAD 就不寫並回報那幾筆、2 沒給網址、3 未設 `GITEA_HOST`、7 金鑰被拒就停下)、同一輪用 `wiki-repo CONTENTS` 解出目錄頁存取庫、取 `wiki-url` 的絕對網址並寫成 `[{頁名}]({絕對網址})`、同樣先過 `link-check.sh` 才跑 `wiki-contents.sh upsert LOG 2 {HASH}` 更新 `LOG_CONTENTS`(鍵取第 2 欄的裸 HASH,不取第 1 欄那個帶主機名的連結)並依 0、1、2、3、4、7、8 各自分流、最後依成敗跑 `worklog-pending.sh commit` 或 `abort`、再跑 `jsc-hooks/tools/report-status.sh skill-end jsc-log:worklog {status} {結束碼} {detail}` 記下本輪結果,腳本不在這台機器上就安靜跳過 |
|
||||||
| 外部呼叫 | `jsc-hooks/hooks/session-timer.sh report`、`tools/token-usage.sh`、`tools/worklog-target.sh`、`tools/worklog-pending.sh`、`jsc-gitea/tools/gitea.sh wiki-repo`(LOG 與 CONTENTS)與 `wiki-url`、`jsc-gitea/tools/link-check.sh`(寫入前驗證連結)、`jsc-gitea/tools/wiki-contents.sh upsert`(目錄頁那一列)、`jsc-gitea/tools/hash-id`、`jsc-gitea:wiki`、`jsc-ask:ask`、`git remote get-url origin`、`git branch --show-current`、`templates/log-entry.md`、`templates/log-contents.md` |
|
| 外部呼叫 | `jsc-hooks/hooks/session-timer.sh report`、`tools/token-usage.sh`、`tools/worklog-target.sh`、`tools/worklog-pending.sh`、`jsc-gitea/tools/gitea.sh wiki-repo`(LOG 與 CONTENTS)與 `wiki-url`、`jsc-gitea/tools/link-check.sh`(寫入前驗證連結)、`jsc-gitea/tools/wiki-contents.sh upsert`(目錄頁那一列)、`jsc-gitea/tools/hash-id`、`jsc-gitea:wiki`、`jsc-ask:ask`、`git remote get-url origin`、`git branch --show-current`、`templates/log-entry.md`、`templates/log-contents.md` |
|
||||||
| 完成條件 | 兩次寫入前 `link-check.sh` 都回 0,`MERGED` 的每一筆條目都在 `PAGE` 上,原有條目逐字不動,`wiki-contents.sh upsert` 回 0 且 `CONTENTS` 該列帶著本週五日期、其他列不動,`worklog-pending.sh` 的 `commit` 或 `abort` 其中一個跑過並回報退出碼,`orphans` 也跑過且回 0 或已把孤兒清單回報出去。`link-check.sh` 回 1 或 `upsert` 回非 0 就照該碼回報,並把步驟七當成失敗處理,讓待寫內容留著 |
|
| 完成條件 | 兩次寫入前 `link-check.sh` 都回 0,`MERGED` 的每一筆條目都在 `PAGE` 上,原有條目逐字不動,`wiki-contents.sh upsert` 回 0 且 `CONTENTS` 該列帶著本週五日期、其他列不動,`worklog-pending.sh` 的 `commit` 或 `abort` 其中一個跑過並回報退出碼,`orphans` 也跑過且回 0 或已把孤兒清單回報出去。`link-check.sh` 回 1 或 `upsert` 回非 0 就照該碼回報,並把步驟七當成失敗處理,讓待寫內容留著。收尾一定要寫一筆 `skill-end` 狀態事件:兩頁都到位是 `ok`(`orphans` 掃到孤兒仍算 `ok`,但 `detail` 要帶筆數,因為孤兒屬於別的存取庫,不影響本輪結論),內容頁寫成功而 `LOG_CONTENTS` 沒更新是 `degraded`,連結驗證回 1 不寫是 `failed`,雜湊工具或日期運算缺席、wiki 存取庫沒設定是 `blocked`,使用者中止或這一輪根本沒有任務結束是 `aborted` |
|
||||||
| 可驗證跡象 | LOG 存取庫的 `LOG_{HASH}` 頁尾多一筆條目,條目裡的計畫名稱、工作包編號、PR 目標分支三欄都是 `[{文字}]({絕對網址})`;CONTENTS 存取庫的 `LOG_CONTENTS` 該列的「條目數」與「最後更新」換新,且「日誌頁」欄是 `[{頁名}]({絕對網址})`,頁面上沒有 `[[...]]` 這種同 wiki 寫法,「HASH」欄是不帶連結的裸 HASH。連結驗證不過就兩頁都沒有新內容,待寫檔原樣保留。重跑同一頁只換掉那一列,不會多出第二列。`$JSC_HOME/worklog-pending/{HASH}` 底下的待寫檔在 `commit` 後清空,`abort` 後原樣保留;該目錄名是 40 碼大寫十六進位,或尚未遷移的舊暫存那種 8 碼大寫十六進位、`H` 加 7 碼大寫十六進位;推得出對映的舊目錄會連同新目錄一起被清掉。暫存區留下非 40 碼的目錄時,該輪的回報上看得到 `orphans` 印出的那幾列。本機留下填好的條目檔 |
|
| 可驗證跡象 | LOG 存取庫的 `LOG_{HASH}` 頁尾多一筆條目,條目裡的計畫名稱、工作包編號、PR 目標分支三欄都是 `[{文字}]({絕對網址})`;CONTENTS 存取庫的 `LOG_CONTENTS` 該列的「條目數」與「最後更新」換新,且「日誌頁」欄是 `[{頁名}]({絕對網址})`,頁面上沒有 `[[...]]` 這種同 wiki 寫法,「HASH」欄是不帶連結的裸 HASH。連結驗證不過就兩頁都沒有新內容,待寫檔原樣保留。重跑同一頁只換掉那一列,不會多出第二列。`$JSC_HOME/worklog-pending/{HASH}` 底下的待寫檔在 `commit` 後清空,`abort` 後原樣保留;該目錄名是 40 碼大寫十六進位,或尚未遷移的舊暫存那種 8 碼大寫十六進位、`H` 加 7 碼大寫十六進位;推得出對映的舊目錄會連同新目錄一起被清掉。暫存區留下非 40 碼的目錄時,該輪的回報上看得到 `orphans` 印出的那幾列。本機留下填好的條目檔。跑完 `$JSC_HOME/usage/events.jsonl` 會多一筆 `{kind:skill,phase:end}` 事件,`name` 欄是 `jsc-log:worklog`,`status` 與 `exit` 兩欄對得上上一列講的判準,孤兒筆數落在 `detail` 欄;`jsc-hooks` 不在這台機器上時沒有這一筆,技能本身照樣跑完 |
|
||||||
|
|||||||
@@ -87,3 +87,23 @@ Run before a skill run, to apply past lessons.
|
|||||||
|
|
||||||
Done when both pages are read, or reported missing under exit 4, or the run stopped on 5, 7 or 8.
|
Done when both pages are read, or reported missing under exit 4, or the run stopped on 5, 7 or 8.
|
||||||
3. Surface every row whose 技能 matches the skill about to run, and summarize each matched 下次做法 for the caller to apply. Done when the matched rows (or 「無相符教訓」) are reported.
|
3. Surface every row whose 技能 matches the skill about to run, and summarize each matched 下次做法 for the caller to apply. Done when the matched rows (or 「無相符教訓」) are reported.
|
||||||
|
|
||||||
|
## Close: record how the run ended
|
||||||
|
|
||||||
|
Both modes end here, as the very last thing this skill does:
|
||||||
|
|
||||||
|
`jsc-hooks/tools/report-status.sh skill-end jsc-log:learn {status} {exit} "{detail}"`
|
||||||
|
|
||||||
|
Resolve that path the way this file already resolves `jsc-gitea/tools/hash-id` and the other sibling plugin scripts — the sibling plugin directory, no separate lookup rule for this one call. **A missing script is not a failure here: skip this step in silence and let the run end as it stands.** The script swallows its own write errors and exits 0 even then, so nothing branches on its code either. A lesson that was recorded stays recorded whether or not the recorder of recorders was installed.
|
||||||
|
|
||||||
|
| status | This skill's case |
|
||||||
|
| --- | --- |
|
||||||
|
| `ok` | record — both pages carry the new row and every row that was there before is still there. consult — both pages were read, or a page was reported absent under exit 4, and the matched 下次做法 lines reached the caller |
|
||||||
|
| `blocked` | The run never reached a page: `hash-id` exit 1 (no SHA-1 helper), `wiki-repo LEARN` or `wiki-repo CONTENTS` exit 3 (no wiki repo configured for that page type), or `link-check.sh` exit 3 (`GITEA_HOST` unset) |
|
||||||
|
| `degraded` | record — the lesson row is on `LEARN_{HASH}` but `wiki-contents.sh upsert` did not land the directory row (exit 1, 3, 7 or 8), so the lesson is on the wiki and nothing points at it. consult — one of the two pages was read and the other stopped the run, so the caller got part of the lesson set and knows it |
|
||||||
|
| `failed` | An API call answered with something unexpected after the work started: `link-check.sh` exit 1 on a DEAD link, a `wiki-get` that came back 7 or 8, or a page write that failed its retry as well. Nothing reached `LEARN_{HASH}` |
|
||||||
|
| `aborted` | The user stopped the run, or record mode was called with nothing reusable to record, so the six facts never formed an entry and no write was attempted |
|
||||||
|
|
||||||
|
`{exit}` is the exit code of whatever decided the status, `0` for `ok`. `{detail}` is one short line well under 200 characters: the mode plus counts and exit codes, never the lesson text, page names, branch names, or personal data.
|
||||||
|
|
||||||
|
Done when the command has run, or the script was absent and this step was skipped.
|
||||||
|
|||||||
@@ -116,3 +116,21 @@ Done when the page URL is reported, or the skipped write is reported with its re
|
|||||||
State the period label, entry count, repositories covered, template source, and the page URL. Name every unfinished work package that carried over — that list is what the next period starts from. State `ELAPSED_MISSING` and `TOKEN_MISSING` whenever either is above 0, so a small total is read as missing data rather than a light week.
|
State the period label, entry count, repositories covered, template source, and the page URL. Name every unfinished work package that carried over — that list is what the next period starts from. State `ELAPSED_MISSING` and `TOKEN_MISSING` whenever either is above 0, so a small total is read as missing data rather than a light week.
|
||||||
|
|
||||||
Done when those five facts, the carry-over list and the two missing-data counts are stated.
|
Done when those five facts, the carry-over list and the two missing-data counts are stated.
|
||||||
|
|
||||||
|
Then record how the run ended, as the very last thing this skill does:
|
||||||
|
|
||||||
|
`jsc-hooks/tools/report-status.sh skill-end jsc-log:report {status} {exit} "{detail}"`
|
||||||
|
|
||||||
|
Resolve that path the way this file already resolves `jsc-gitea/tools/link-check.sh` and the other sibling plugin scripts — the sibling plugin directory, no separate lookup rule for this one call. **A missing script is not a failure here: skip this step in silence and let the run end as it stands.** The script swallows its own write errors and exits 0 even then, so nothing branches on its code either. A report that was produced stays produced whether or not the recorder was installed.
|
||||||
|
|
||||||
|
| status | This skill's case |
|
||||||
|
| --- | --- |
|
||||||
|
| `ok` | The period's section is on `REPORT_{HASH}` and the `REPORT_CONTENTS` row carries this period. `log-aggregate.sh` exit 3 stays `ok`: an empty range is an answer, and section 2 requires the report to be produced anyway — put `ENTRIES=0` in `{detail}` so the zero is read as a counted zero, not a run that quit |
|
||||||
|
| `blocked` | Nothing could be summarised and nothing was: `report-range.sh` exit 4 (this machine's `date` does no date arithmetic), `report-template.sh resolve` exit 3 (neither template exists), `wiki-repo CONTENTS` or `wiki-repo LOG` exit 3 (no directory or log pages to read), `hash-id` exit 1, or `link-check.sh` exit 3 or 7 |
|
||||||
|
| `degraded` | The report body is finished and handed to the caller but did not fully land: `wiki-repo REPORT` exit 3 skipped the wiki write entirely, or the section landed and `wiki-contents.sh upsert` did not, or `wiki-repo LEARN` exit 3 left the yearly 全年教訓 section filled with 無. Say which part is missing in `{detail}` |
|
||||||
|
| `failed` | The collection or the write broke part-way: `link-check.sh` exit 1 on a DEAD link, a `jsc-gitea:wiki` read or a `wiki-url` call that came back 7 or 8, `log-aggregate.sh` exit 4 on an unreadable page file, or a write that failed its retry as well |
|
||||||
|
| `aborted` | The user stopped the run, most often at the period question in section 1, so no range was ever fixed and no page was read |
|
||||||
|
|
||||||
|
`{exit}` is the exit code of whatever decided the status, `0` for `ok`. `{detail}` is one short line well under 200 characters: the period plus counts and exit codes, never report text, page names, branch names, or personal data.
|
||||||
|
|
||||||
|
Done when the command has run, or the script was absent and this step was skipped.
|
||||||
|
|||||||
@@ -25,3 +25,20 @@ Data is recorded continuously by `jsc-hooks/hooks/skill-usage.sh` under `$JSC_HO
|
|||||||
| 2 | The subcommand or the `--cli` argument was rejected — the subcommand is neither `skills` nor `chains`, or `--cli` came with no value. Fix the argument and rerun. Never rerun the same command unchanged, and never report the counts as zero: nothing was read |
|
| 2 | The subcommand or the `--cli` argument was rejected — the subcommand is neither `skills` nor `chains`, or `--cli` came with no value. Fix the argument and rerun. Never rerun the same command unchanged, and never report the counts as zero: nothing was read |
|
||||||
|
|
||||||
Done when the exit code was read and the branch it names was taken.
|
Done when the exit code was read and the branch it names was taken.
|
||||||
|
2. Record how the run ended, as the very last thing this skill does:
|
||||||
|
|
||||||
|
`jsc-hooks/tools/report-status.sh skill-end jsc-log:stats {status} {exit} "{detail}"`
|
||||||
|
|
||||||
|
Resolve that path the way this file already names `jsc-hooks/hooks/skill-usage.sh` — the sibling plugin directory, no separate lookup rule for this one call. **A missing script is not a failure here: skip this step in silence and let the run end as it stands.** The script swallows its own write errors and exits 0 even then, so nothing branches on its code either. This skill only reads counts; it must never fail because a count of its own could not be written.
|
||||||
|
|
||||||
|
| status | This skill's case |
|
||||||
|
| --- | --- |
|
||||||
|
| `ok` | The tool exited 0 and every printed line reached the report. A run that printed no line is `ok` as well — the count really is zero, so say `count=0` in `{detail}` rather than dressing an empty data file up as a problem |
|
||||||
|
| `blocked` | `tools/usage-stats.sh` is not on this machine, which is a partial plugin install rather than a zero count. No number was ever read, so none is reported |
|
||||||
|
| `degraded` | The caller asked for both counts and only one sub-command answered, so the report covers half of what was asked. Name the half that is missing in `{detail}` |
|
||||||
|
| `failed` | Exit 2 — the sub-command or the `--cli` value was rejected, so nothing was read. This is the one case that must never be reported as a count of zero, and recording it as `failed` is what keeps the two apart in the event stream too |
|
||||||
|
| `aborted` | The user stopped the run, or the request turned out to be about elapsed time or token usage, which belong to `jsc-log:worklog`; this skill then stops before it counts anything |
|
||||||
|
|
||||||
|
`{exit}` is the exit code of whatever decided the status, `0` for `ok`. `{detail}` is one short line well under 200 characters: the sub-command plus counts and exit codes, never branch names or personal data.
|
||||||
|
|
||||||
|
Done when the command has run, or the script was absent and this step was skipped.
|
||||||
|
|||||||
@@ -115,3 +115,20 @@ The `{HASH}` in every page name above is computed with `jsc-gitea/tools/hash-id`
|
|||||||
| 2 | The claim path is not the one `merge` produced, or it points outside this `{HASH}`'s pending directory. Rerun from step 4 with the `CLAIM` value that `merge` printed; never pass a hand-written path |
|
| 2 | The claim path is not the one `merge` produced, or it points outside this `{HASH}`'s pending directory. Rerun from step 4 with the `CLAIM` value that `merge` printed; never pass a hand-written path |
|
||||||
|
|
||||||
Done when one of the two ran and its exit code was reported.
|
Done when one of the two ran and its exit code was reported.
|
||||||
|
8. Record how this run ended, as the very last thing this skill does:
|
||||||
|
|
||||||
|
`jsc-hooks/tools/report-status.sh skill-end jsc-log:worklog {status} {exit} "{detail}"`
|
||||||
|
|
||||||
|
Resolve that path the way row 5 already resolves `jsc-hooks/hooks/session-timer.sh` — the sibling plugin directory, no separate lookup rule for this one call. **A missing script is not a failure here: skip this step in silence and let the run end as it stands.** The script swallows its own write errors and exits 0 even then, so nothing branches on its code either. A run whose result could not be recorded still had that result, and a work log that fails because the recorder is absent is worse than no recording.
|
||||||
|
|
||||||
|
| status | This skill's case |
|
||||||
|
| --- | --- |
|
||||||
|
| `ok` | Steps 5 and 6 both wrote and step 7 cleared the pending area. `orphans` exit 4 stays `ok`: an orphan directory belongs to some other repository and changes nothing about this entry — carry its line count in `{detail}` so the count is on record even though the run passed |
|
||||||
|
| `blocked` | Nothing could be written and nothing was: `hash-id` exit 1 (no SHA-1 helper on this machine), `worklog-target.sh friday` exit 4 (no date arithmetic), `wiki-repo LOG` exit 3 (no LOG wiki repo configured), or `link-check.sh` exit 3 (`GITEA_HOST` unset) or exit 7 (token rejected). The gate stopped the run before a page was touched |
|
||||||
|
| `degraded` | The entry is on `LOG_{HASH}` but the close-out is short: `wiki-contents.sh upsert` returned non-zero so `LOG_CONTENTS` still carries the old row, or `worklog-pending.sh commit` exited 1 so the pending files survive a successful write and the next run merges them again |
|
||||||
|
| `failed` | Nothing reached the wiki after the run started working: `link-check.sh` exit 1 stopped the write on a DEAD link, the `PAGE` read came back 7 or 8, or `worklog-pending.sh merge` exited 1 |
|
||||||
|
| `aborted` | The user stopped the run, or the trigger turned out not to hold — no task ended here, so there is no entry to write and none was attempted |
|
||||||
|
|
||||||
|
`{exit}` is the exit code of whatever decided the status, `0` for `ok`. `{detail}` is one short line well under 200 characters: counts and exit codes only, never entry text, page names, branch names, or personal data.
|
||||||
|
|
||||||
|
Done when the command has run, or the script was absent and this step was skipped.
|
||||||
|
|||||||
Reference in New Issue
Block a user