feat: convert 新增 --verify 對帳模式 + 修復 Windows CRLF 使 hash 失準
- convert.py --verify:純唯讀 re-hash 全部登記檔並掃未登記檔, 報 missing/mismatch/unregistered,不一致退出碼 1(供刪除/竄改後稽核) - 修 write_text 在 Windows 轉 \n→\r\n 使磁碟 bytes 與登記 SHA-256 不符 (converted md 與 web 快照原始檔),改 write_bytes 寫入所登記的那份 bytes - selfcheck 補 clean/missing/mismatch/unregistered 四情境(全程唯讀斷言) - AGENTS.md §14 raw 完整性與修復流程 + §1.4 hash==磁碟 bytes 不變式 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
46
AGENTS.md
46
AGENTS.md
@@ -26,7 +26,9 @@
|
||||
EmbeddingGemma(Google)或 snowflake-arctic-embed(Snowflake)。
|
||||
4. **raw 層不可變**:`raw/` 內的文件只讀不改。原始檔與轉換後 Markdown 皆登記
|
||||
SHA-256 至 `raw/manifest.json`(結構見 §9),轉換檔條目必須回指原始檔 hash。
|
||||
wiki 頁面引用來源必須帶 `source_ref`(格式見 §3.3)。
|
||||
wiki 頁面引用來源必須帶 `source_ref`(格式見 §3.3)。登記的 hash 必須等於檔案在
|
||||
磁碟上的實際 bytes(UTF-8,換行不轉換——轉換器一律以 write_bytes 寫入所登記的
|
||||
那份 bytes,不受平台 CRLF 影響);完整性以 §14 `--verify` 稽核。
|
||||
5. **HITL 閘門**:所有 wiki 層的變更以 git branch + PR 形式提交,經人工審核後才
|
||||
合併至 main。攝入腳本永遠不直接 commit 到 main。lint 絕不擅自刪檔,一律標記
|
||||
待人工核准。
|
||||
@@ -300,3 +302,45 @@ output**)。單筆修正只治標;規則修正才治本。
|
||||
**有效的跡象**:diff 裡不必要的變更變少、因過度複雜而重寫的次數變少、
|
||||
釐清問題發生在動手**之前**而非犯錯之後、刻意的捷徑是可見的(`ponytail:`)
|
||||
而非沉默的。
|
||||
|
||||
## 14. raw 完整性與修復(對帳)
|
||||
|
||||
raw 層以 manifest 的 SHA-256 為信任根(§1.4、§9)。檔案被**手動刪除**或**就地改動**時,
|
||||
下列為正規稽核與修復流程。核心原則:manifest 是 provenance **真相帳本**、不是 cache——
|
||||
hash 的用途是讓刪除**可復原、可驗證**,故先**復原檔案**,而非改帳本去遷就殘缺的磁碟。
|
||||
|
||||
### 14.1 稽核
|
||||
|
||||
```text
|
||||
python tools/convert/convert.py --verify
|
||||
```
|
||||
|
||||
純唯讀(不改任何檔,含 manifest),re-hash 全部登記檔並掃描 `raw/`,回報三類意外、
|
||||
有不一致以退出碼 1 表示(可當 CI/排程閘門):
|
||||
|
||||
- **missing** — 帳本有登記,磁碟上不見了(手動刪除)。
|
||||
- **mismatch** — 檔案還在但 sha256 與登記值不符(raw 被就地改動,違反 §1.4)。
|
||||
- **unregistered** — `raw/originals`/`raw/converted` 下有檔卻不在帳本。
|
||||
`converted/assets/*`(圖片)由 markdown 連結追蹤而非帳本,故略過;`.gitkeep` 亦略過。
|
||||
|
||||
### 14.2 修復決策(可衍生 vs 信任根)
|
||||
|
||||
<!-- ASSUMPTION: 本決策樹為推論的正規流程,原始需求只定義 raw 不可變與 hash 登記;
|
||||
依「可衍生(converted)優先還原、信任根(original)不可再生」的性質分流。 -->
|
||||
|
||||
1. **先還原,不改帳本**(多數「誤刪」到此為止):`raw/` 進版控,`git restore <path>`
|
||||
取回精確 bytes(或從備份),再跑 §14.1 確認 hash == 登記值。帳本零改動。
|
||||
2. **converted 救不回** → 從 original 重轉。注意兩個陷阱:(a) `convert.py` 以 **original
|
||||
的 hash** 去重,original 條目還在會直接 skip、**不會**因 converted 不見而重生,需先
|
||||
自帳本移除該 converted 條目;(b) 函式庫版本變動可能使重轉 bytes 不同 → converted
|
||||
hash 變 → 連累所有指向它的 wiki `source_ref`。故**能還原就別重轉**;重轉屬實質變更,
|
||||
連同 source_ref 一起走 PR。
|
||||
3. **original 救不回** → 不可逆的 provenance 損失,**不得靜默刪條目**(會連鎖 orphan 掉
|
||||
對應 converted、再斷所有 source_ref);據實記錄該檔遺失並上報人工(HITL,§5)。
|
||||
|
||||
### 14.3 動 manifest 的紀律
|
||||
|
||||
- 任何帳本變更走 **branch + PR**(§5)——manifest 是 provenance 帳本,改它需人工審核。
|
||||
- `log.md` 追加一筆 `edit` 條目(§10),說明對了什麼、為什麼。
|
||||
- 刪任何 `converted` 條目前,先確認沒有 wiki `source_ref` 引用它(否則 §7 的 schema
|
||||
檢查會抓到斷鏈);有引用就改為還原檔案,或同 PR 一併更新引用。
|
||||
|
||||
Reference in New Issue
Block a user