feat(ingest-hash-trigger): 凍結 collector/ingest schema+Go collector 骨架(issue #5, SDD task 1+2)

- schemas/collector-trigger.v1.schema.json:collector→named-webhook 觸發 payload(source_hash/r2_key/renamed/R6 warnings)
- schemas/kbdb-ingest-request.v1.schema.json:source_hash 必填缺=400;儲存映射走 metadata_json.$.source_hash(守 kbdb 表不變鐵律);同 hash 重送=200 already_ingested
- schemas/MIGRATION-webhook-payload.md:舊 Gitea push payload 逐欄對照(給 task 4 改寫 workflow)
- collector/:Go module(純 stdlib)——manifest 讀寫+mtime fast-path 掃描+renamed hash 配對+40% 大量刪除防呆;CLI collector scan
- go test ./... 全綠 7/7(added/modified/removed/renamed/防呆五情境+fast-path+manifest 往返)
- Node 版 collector 標 legacy 並存(SDD task 4 拆除)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 20:31:11 +08:00
parent eff30bd741
commit bb96bceb04
6 changed files with 790 additions and 1 deletions
+34 -1
View File
@@ -1,4 +1,37 @@
# collector — 收集端骨架(rag-wave1 T3+T4
# collector
> ⚠️ **本目錄有兩代 collector 並存(2026-07-19**
>
> - **新(現役開發線)= Go 版 hash 偵測 collector**`*.go`SDD `ingest-hash-trigger` task 2)——
> 變更偵測回歸檔案系統,manifestcontent hash**不經 git、不經 Gitea**。見下方「Go 版」段。
> - **舊(legacy,待 SDD task 4 拆除)= Node 版 Gitea push 鏈**`index.js`/`transform.js`/`git-sync.js`/`config.js`
> rag-wave1 T3/T4 產物)——watch → git commit/push → Gitea webhook。這正是 de-Gitea 要取代的鏈,
> 保留只為現行本機 demo 鏈還在用;新功能一律做在 Go 版。
## Go 版:hash 偵測 collectorSDD ingest-hash-trigger
```
collector scan --root <知識資料夾> --manifest <manifest.json> [--max-removed-ratio 0.4] [--dry-run]
```
一次掃描:走訪資料夾(先只認 .md/.markdown/.txt/.docx/.pptx/.pdf)→ mtime+size fast-path
(沒變→沿用 manifest hash;變了才算 sha256)→ 對照 manifest 產出事件 → 事件 JSON
(符合 `schemas/collector-trigger.v1.schema.json`)輸出 stdout → 更新 manifest`--dry-run` 不寫)。
- **事件分類順序(design §3**:先把本輪 removed×added 以 content_hash 配對成 `renamed`
(只更新路徑映射,不 retire、不重萃);再分 added / modified / removed。
- **大量刪除防呆(R6**removed 數 > manifest 條目 × 40%`--max-removed-ratio` 可調)→
removed 全部不執行、manifest 條目保留、輸出 `mass_delete_guard` 警告。
- **重試語意**`ingested_hash` 只會在(未來的)上傳/ingest 成功後回寫;本階段永不寫它,
所以「偵測過但未成功 ingest」的檔每輪都會重發 added/modified——這是設計(design §2),不是 bug。
- **本階段不接網路**daemon 常駐(launchd)、R2 上傳、打 arcrun named-webhook=之後的 task
SDD task 3/4、journeys/user-onboarding 環 6)。
測試:`go test ./...`added / modified / removed / renamed / 大量刪除防呆五情境+fast-pathmanifest 往返)。
---
# legacyNode 版收集端骨架(rag-wave1 T3+T4
> design.md §4;跑在**客戶端機器**(NAS/VM,或導入者代管的 VPS),不是 arcrun workflowarcrun 零件禁檔案系統,見 CLAUDE.md 紅線)。
> ⚠️ **本骨架端到端(真實 NAS/VM + 真實 Gitea remote + systemd 常駐)需在本機/客戶環境驗,雲端 sandbox 沒有這些條件**——這裡只做得到:程式邏輯本身可跑、對本機臨時目錄的煙測(見下方「已驗證」)。