feat(wiki): 目錄頁專用存取庫、HASH 去除截短與 H 前綴

What:CONTENTS 成為第 15 種頁面類型,解析鏈為 JSC_WIKI_REPO_CONTENTS 到
JSC_WIKI_REPO,刻意不退回型別變數。hash-id 拿掉 8 碼截短與 H 前綴改寫,只留大寫
轉換,輸出完整 40 碼;空輸入改成用法錯誤。新增 page-name.sh、wiki-contents.sh、
migrate-wiki.sh 與 wiki-delete 子命令。

Why:H 前綴會命中 16 個首碼裡的 13 個,還丟掉第 8 碼,把有效熵壓到 28 位元,而且
全庫查不到任何理由紀錄。目錄頁的整列 upsert 原本 14 處只有一處寫成程式,同一段判斷
做 14 次,錯一次就少一筆紀錄。

How:頁名樣式仍收 H 加 7 碼的舊頁,遷移期間讀得到舊頁。wiki-contents.sh 建新頁時
剝掉範本的示範列,否則每個目錄頁第一次建立都會留一列佔位死連結。migrate-wiki.sh
預設只印對照表,--apply 先寫新頁、確認寫成、才刪舊頁;孤兒頁只列不猜,因為 SHA-1
不可逆,新頁名只能靠候選鍵正推。

Who:jsc-gitea
This commit is contained in:
2026-09-02 11:02:07 +08:00
parent a3ce17f98d
commit c40b561589
13 changed files with 826 additions and 53 deletions
+5 -5
View File
@@ -36,11 +36,11 @@
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | 技能組裡任何一次 wiki 頁的讀或寫,都經過這一支。呼叫端有 jsc-ask、jsc-sdlc、jsc-log、jsc-hooks 的 ERROR 頁、jsc-cli 的 CHECK 頁、jsc-meta 的 SKILLSET 與 TOOLING 頁、jsc-assist 的 MONITOR 頁。存放庫裡的程式碼檔案不歸這一支管。 |
| 關鍵步驟 | 確認 GITEA_HOST 有值、用 tools/gitea.sh wiki-repo {TYPE} 依頁名前綴解出 {owner}/{repo}、用 tools/hash-id 算頁名要用的 HASH、再依動作跑 wiki-list、wiki-get、wiki-put 或 wiki-url、每一次呼叫都照結束碼表分流。存放庫的解法是先讀 JSC_WIKI_REPO_{TYPE}、再讀 JSC_WIKI_REPO、兩個都沒有才問使用者,而且不借用別的頁型的存放庫。寫入前一定先 wiki-get 讀回舊內容,把新內容接上去再整頁寫回;只有結束碼 4 才准用範本建新頁。 |
| 外部呼叫 | tools/gitea.sh 的 wiki-repo、wiki-list、wiki-get、wiki-put、wiki-url、tools/hash-id、tools/write-confirm.sh、jsc-ask:ask、Gitea 的 wiki API。 |
| 完成條件 | 讀取動作拿到頁面內容,或拿到一個講得清楚的結束碼。寫入動作通過人工確認、wiki-put 回結束碼 0,而且送出去的是舊內容加上這次的異動,不是整頁覆蓋。結束碼 7 與 8 一律中止整個動作,不建頁、不寫入、不用原參數重試。 |
| 可驗證跡象 | 目標 wiki 存放庫多一頁或改一頁,頁名照命名表,例如 PLAN_{HASH}、LOG_{HASH}、各種 *_CONTENTS。頁面內容是 UTF-8 繁體中文,以 mermaid 圖與 markdown 表格為主,散文每節最多三句。寫入前 tools/write-confirm.sh 會留下一次人工確認。只做讀取的呼叫無寫入跡象,只有回報內容。 |
| 觸發時機 | 技能組裡任何一次 wiki 頁的讀、寫、刪或搬移,都經過這一支。呼叫端有 jsc-ask、jsc-sdlc、jsc-log、jsc-hooks 的 ERROR 頁、jsc-cli 的 CHECK 頁、jsc-meta 的 SKILLSET 與 TOOLING 頁、jsc-assist 的 MONITOR 頁。存放庫裡的程式碼檔案不歸這一支管。 |
| 關鍵步驟 | 確認 GITEA_HOST 有值、用 tools/gitea.sh wiki-repo {TYPE} 解出 {owner}/{repo}、用 tools/hash-id 算頁名要用的 HASH、用 tools/page-name.sh check 驗過頁名、再依動作跑 wiki-list、wiki-get、wiki-put、wiki-delete 或 wiki-url,每一次呼叫都照結束碼表分流。所有 *_CONTENTS 頁一律走型別 CONTENTS,內容頁走自己的型別;存放庫的解法是先讀 JSC_WIKI_REPO_{TYPE}、再讀 JSC_WIKI_REPO、兩個都沒有才問使用者,而且不借用別的頁型的存放庫。目錄頁的整列 upsert 交給 tools/wiki-contents.sh,寫入前一定先 wiki-get 讀回舊內容,只有結束碼 4 才准用範本建新頁;舊頁搬到新規則走 tools/migrate-wiki.sh,不帶 --apply 只印對照表,寫每一個目的地之前也一樣先 wiki-get 讀一次。 |
| 外部呼叫 | tools/gitea.sh 的 wiki-repo、wiki-list、wiki-get、wiki-put、wiki-delete、wiki-url、tools/hash-id、tools/page-name.sh、tools/wiki-contents.sh、tools/migrate-wiki.sh、tools/write-confirm.sh、jsc-ask:ask、Gitea 的 wiki API。 |
| 完成條件 | 讀取動作拿到頁面內容,或拿到一個講得清楚的結束碼。寫入動作通過人工確認、wiki-put 回結束碼 0,而且送出去的是舊內容加上這次的異動,不是整頁覆蓋。結束碼 7 與 8 一律中止整個動作,不建頁、不寫入、不用原參數重試。搬移動作要嘛全部搬完回 0,要嘛把失敗頁、孤兒頁、目的地已有內容的頁、指向被搬頁卻沒被搬的引用方逐條列出來,這四種一律交給人判斷。 |
| 可驗證跡象 | 目標 wiki 存放庫多一頁或改一頁。內容頁的頁名是 {型別}_{40 碼大寫十六進位},目錄頁是 {型別}_CONTENTS 且落在 JSC_WIKI_REPO_CONTENTS 指的那個存放庫。頁面內容是 UTF-8 繁體中文,以 mermaid 圖與 markdown 表格為主,散文每節最多三句;目錄頁與內容頁互指的連結是絕對網址,不是 [[...]]。寫入與刪除前 tools/write-confirm.sh 會各留下一次人工確認。只做讀取的呼叫無寫入跡象,只有回報內容。 |
## wiki-to-issue
+8 -5
View File
@@ -8,17 +8,20 @@ Gitea 採 GitHub/Gollum 慣例:`[[顯示文字|頁名]]`。方向與 MediaWi
> MediaWiki uses [[link|text]], while GitHub uses [[text|link]] … we prefer GitHub syntax
所以 `[[PLAN_H1234567|我的計畫]]` 會顯示成文字 `PLAN_H1234567`,連到一個叫「我的計畫」的頁——這是壞連結。要寫 `[[我的計畫|PLAN_H1234567]]`。
所以 `[[PLAN_CONTENTS|我的計畫]]` 會顯示成文字 `PLAN_CONTENTS`,連到一個叫「我的計畫」的頁——這是壞連結。要寫 `[[我的計畫|PLAN_CONTENTS]]`。
顯示文字與頁名相同時,用不帶豎線的 `[[PLAN_H1234567]]`,這種寫法不會寫錯。
顯示文字與頁名相同時,用不帶豎線的 `[[PLAN_CONTENTS]]`,這種寫法不會寫錯。
## 範圍:`[[...]]` 只在同一個 wiki 內解析
`[[...]]` 與 markdown 相對連結都只在目前這個 wiki 內解析。跨存取庫沒有 wiki 連結語法。
目錄頁全部住在 CONTENTS 專用存取庫,內容頁住在自己型別的存取庫。所以「同型別」不再等於「同存取庫」,判斷要看兩端各自解析到哪一個存取庫。
| 連結 | 同一個 wiki? | 寫法 |
| --- | --- | --- |
| 同頁面類型(例:`PLAN_CONTENTS` → `PLAN_{HASH}`) | 一定同一個:一個類型一個存取庫 | `[[顯示文字\|頁名]]` 或 `[[頁名]]` |
| 不同頁面類型(例:`LOG_{HASH}` → `PLAN_{HASH}`) | **只有兩個類型解析到同一個存取庫時才同一個** | `wiki-url` 給的絕對網址:`[顯示文字](https://…/wiki/PLAN_…)` |
| 目錄頁之間(例:`PLAN_CONTENTS` → `LOG_CONTENTS`) | 一定同一個:目錄頁都在 CONTENTS 存取庫 | `[[顯示文字\|頁名]]` 或 `[[頁名]]` |
| 同型別的內容頁之間(例:`PLAN_{HASH}` → 另一頁 `PLAN_{HASH}`) | 一定同一個:一個型別一個存取庫 | `[[顯示文字\|頁名]]` 或 `[[頁名]]` |
| 目錄頁與內容頁之間,以及跨型別(例:`PLAN_CONTENTS` → `PLAN_{HASH}`、`LOG_{HASH}` → `PLAN_{HASH}`) | **不保證**:兩端各自解析,可能不同 | `wiki-url` 給的絕對網址:`[顯示文字](https://…/wiki/PLAN_…)` |
每個類型各自解析自己的 `JSC_WIKI_REPO_{TYPE}`,所以跨類型連結**一律**用絕對網址:兩個類型剛好同存取庫也照樣正確,不必分兩種寫法。網址一律取自 `tools/gitea.sh wiki-url`,不要自己組路徑。
目錄頁解 `JSC_WIKI_REPO_CONTENTS`,內容頁解自己的 `JSC_WIKI_REPO_{TYPE}`,兩端各解各的。只設 `JSC_WIKI_REPO` 時兩端會落在同一個存取庫,多設一個型別變數就分開了。所以這兩種連結**一律**用絕對網址:兩邊剛好同存取庫也照樣正確,不必分兩種寫法,也不必跟著環境變數改寫法。網址一律取自 `tools/gitea.sh wiki-url`,不要自己組路徑。