D-20260820-02|Graphify manifest 內容決定化¶
背景與驅動力¶
四個程式 repo 刻意追蹤 graphify-out/manifest.json,但 Graphify 0.9.25 寫入的 mtime、物件
插入順序與平台換行會因 clone 位置、檔案系統及執行環境而變動。這些差異不是來源內容或知識圖
語意的變更,卻會造成跨機器噪音 diff,也讓 freshness 把時間戳誤當成跨 repo 契約。
考慮過的選項¶
- 停止追蹤 manifest:會失去 clone 後可離線判斷來源覆蓋與內容 freshness 的 metadata,否決。
- 保留
mtime並容忍差異:仍會產生機器相依 diff,無法形成穩定成品,否決。 - 保留追蹤 manifest,改以內容 MD5 判 freshness,並由成功 finalizer 決定性正規化(採納)。
決定¶
- 四個程式 repo 繼續追蹤
graphify-out/manifest.json;它是可重建的檢索 metadata,不是 canon 權威,也不取代來源檔或 Specs。 - 每列最終只保留
ast_hash與semantic_hash;path 依 ordinal 排序,row key 固定為ast_hash、semantic_hash,輸出使用 UTF-8 無 BOM、LF、兩空格縮排與單一檔尾換行。 - freshness 不再讀取
mtime。Git repo 只對 Git 變更候選計算來源 bytes 的 MD5;非 Git repo 對 manifest 覆蓋的候選全部計算。缺檔、新檔、hash 缺失或格式錯誤、manifest 結構錯誤均 fail closed。 - 非決定性但結構有效的 manifest 視為 stale,由正常 finalizer 做一次正規化;PowerShell freshness checker 不直接改檔。
- adapter 只能在 Graphify 操作成功且 graph health 有效後正規化 manifest。失敗路徑不得執行
最終正規化;semantic cache、
.graphify_labels.json與其他生成物的格式及追蹤邊界不變。
後果與影響¶
不同機器對相同來源會得到穩定 manifest bytes,clone 後的 timestamp 差異不再造成 stale;實際
內容變更仍由 hash 精準偵測。既有四個 manifest 需各經一次正常 finalizer 遷移,之後重跑應為
no-op。Graphify 內部若仍暫時使用 mtime 作快速路徑,只能存在於成功正規化前的執行階段,不能
成為被追蹤的最終契約。