feat(daemon-beta B2): 萃取品質 lint(H1–H6)重新接到現行 direct.go
Gitea #24:分支 work/b2-quality-lint-0726(2f3e9ec)躺在 main 外兩週, 今天重新整合進現行 direct.go(原分支落後 main 130+ 筆,direct.go 本身 差 667 行,需要真正的整合工作而非硬併,見 wiki status.md 與頂層 daemon-beta/tasks.md 已記載的殘項)。 - collector/lint.go/lint_test.go:package main → package collector (main.go 在 4a26856/v0.18.9 已從兩支執行檔併成一支,整個 collector/ 目錄已改名 package collector;分支停在改名之前)。 - collector/main.go:func main() → func Run(args []string) int (同一次重構),新增 case "lint" 呼叫 runLint。 - collector/direct.go:DirectConfig.LintStrict 欄位+extractor 萃完、 POST rag_ingest_card 前掛 LintCard 閘(硬缺→不送標 rejected; 軟項→照送帶 quality:low+quality_warnings);CLI --strict 旗標。 - 既有測試共用的 cardFixture(direct_extract_test.go)/direct_pacing_test.go 三處 inline 卡片,從「兩段最簡卡」補成 B2 合格四段卡——不是新增例外, 是 lint 正確地在做它的事,舊卡片本來就不合格。 驗證:go build/vet/test ./... 全綠;另以真實 PDF(docs/onboarding/封測說明.pdf, 2MB 二進位)跑過完整 direct.go 同步鏈,證實送進 Gemini 的 prompt 是 5,071 字乾淨中文(0 個控制字元/NUL),不是原始位元組——ConvertToText (t73)已完整解決 900b895 想止血的問題,故該分支的 looksLikeText 二進位止血、Windows 交叉編譯腳本判定作廢,不併。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+22
-8
@@ -12,12 +12,25 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// cardFixture 組出一張最簡知識卡(含一條三元組關聯)。
|
||||
// cardFixture 組出一張 B2 合格四段卡(H1 段名齊全且順序正確+H2 一句話定義恰一行+
|
||||
// H3 3–12 條要點+H4 3–8 條端點閉合三元組——2026-08-09 併入品質 lint 後,minimal
|
||||
// 兩段卡會被 H1 硬擋,這裡改成全段合格卡,讓所有沿用 cardFixture 的既有測試自動過關)。
|
||||
// 三元組的分隔符在原始碼裡用組字串的方式產生,避免被 arcrun 意圖 guard 誤判成工作流的邊。
|
||||
func cardFixture(subject, object string) string {
|
||||
sep := strings.Repeat(">", 2)
|
||||
return "# " + subject + "\n## 一句話定義\n測試卡\n## 關聯\n- " +
|
||||
subject + " " + sep + " 屬於 " + sep + " " + object + "\n"
|
||||
return "# " + subject + "\n" +
|
||||
"## 一句話定義\n" + subject + "是一張測試用的自包含知識卡。\n" +
|
||||
"## 要點\n" +
|
||||
"- 第一個要點含具體條件\n" +
|
||||
"- 第二個要點含具體條件\n" +
|
||||
"- 第三個要點含具體條件\n" +
|
||||
"## 關鍵實體\n" +
|
||||
"- **" + subject + "** — 測試主體\n" +
|
||||
"- **" + object + "** — 測試客體\n" +
|
||||
"## 關聯\n" +
|
||||
"- " + subject + " " + sep + " 屬於 " + sep + " " + object + "\n" +
|
||||
"- " + subject + " " + sep + " 關聯到 " + sep + " " + object + "\n" +
|
||||
"- " + object + " " + sep + " 對應 " + sep + " " + subject + "\n"
|
||||
}
|
||||
|
||||
// gemmaCardStub 讓 Gemini 替身回傳一張以 pageName 命名的卡片(t176 起產品只走 gemma 路,
|
||||
@@ -56,7 +69,8 @@ func TestDirectExtractorModeE2E(t *testing.T) {
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
// Gemini 替身:把原稿萃成卡
|
||||
// Gemini 替身:把原稿萃成卡(B2 合格四段卡,否則新增的品質 lint 會擋下——
|
||||
// 本測試聚焦 ingest 路,非 lint,lint 自身測試見 lint_test.go)
|
||||
defer gemmaCardStub(t, cardFixture("報銷規則", "財務"))()
|
||||
|
||||
cfg := &DirectConfig{
|
||||
@@ -119,8 +133,8 @@ func TestDirectExtractorRemovedClearsLocalCard(t *testing.T) {
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
// Gemini 替身:萃卡落地
|
||||
defer gemmaCardStub(t, "# 報銷規則\n## 一句話定義\n測試卡\n")()
|
||||
// Gemini 替身:萃卡落地(B2 合格四段卡,過品質 lint)
|
||||
defer gemmaCardStub(t, cardFixture("報銷規則", "財務"))()
|
||||
|
||||
cfg := &DirectConfig{
|
||||
WatchFolders: []string{root},
|
||||
@@ -174,14 +188,14 @@ func TestDirectExtractorRemovedNoLocalCardOK(t *testing.T) {
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"success": true})
|
||||
}))
|
||||
defer srv.Close()
|
||||
defer gemmaCardStub(t, "# a\n## 一句話定義\n卡\n")()
|
||||
defer gemmaCardStub(t, cardFixture("a", "b"))()
|
||||
cfg := &DirectConfig{
|
||||
WatchFolders: []string{root},
|
||||
Manifest: filepath.Join(t.TempDir(), "m.json"),
|
||||
CypherURL: srv.URL, Namespace: "demo", APIKey: "demo",
|
||||
Extractor: "gemma", ExtractorExplicit: true, GeminiAPIKey: "k-test",
|
||||
CardIngestWF: "rag_ingest_card", RemovedWF: "rag_takedown_direct",
|
||||
MaxRemoved: 1.0,
|
||||
MaxRemoved: 1.0,
|
||||
}
|
||||
if _, exit, _ := RunDirectOnce(cfg, false); exit != 0 {
|
||||
t.Fatal("第一輪失敗")
|
||||
|
||||
Reference in New Issue
Block a user