跳轉到

證據分類覆核(Evidence Classification Review)

功能群:證據管理|分類生命週期、兩種證據概念、EC_ error code、核心資料模型先讀 功能群總覽

事實基準:兩條線並存——批次線 2026-09-17 從套件 jedi-evidence-classification 與 FE 掃出(FR-107,以 run_uid 定址、檢查點用 part_id + ao_letter、目標集吃 run 的 catalog_snapshot);Drive 線 2026-07-05 掃出(FR-030 v1,以 run_folder_id 定址、檢查點用 {ControlId}[{letter}]、真相在 Drive _state.json)。UI 兩條線共用同一支 EvidenceClassificationReview.vue,只換資料來源

變更紀錄: - 2026-09-30(FR-122):寫明「待人審」的兩種來源與各自呈現(沙箱判定藏字或注入分數高→不送 AI;AI 閘道標記→照送 AI、結果僅供參考)、被閘道擋下與額度用完的檔怎麼顯示、AI 配對與人工配對的區分;分類改經 AI 閘道與檔案沙箱(§11) - 2026-09-29(FR-122.6-D,CM-2336/2337):版面改「一條待辦線」——統計列、待人審黃區、「只看未分類」鈕與狀態下拉收成頁頭四分頁(要你處理/已完成/非證據/全部)+進度條;新增「下一步」卡與人工確認(寫入 reviewed_by/reviewed_at);自動配對門檻可在本頁調整並重挑 AI 配對(存 review_threshold,不重跑 AI);原「AI 把握度 ≥」改名「只顯示 AI 分數 ≥」、僅在「全部」分頁;被安全檢查攔下的檔(needs_review)紅底標「已攔截」排最前;已配對表加「來源」欄;「標為非證據」「從證據池刪除」收進檔名旁 ⋮ 選單 - 2026-09-17(FR-107,CM-1888):右欄配對區由一筆一卡改為一筆一列的表格(已配對與 AI 候選共用 PlacementTable,mode 切換)——完整麵包屑收進代號 tooltip、AI 理由收進展開列、狀態改用左側色線,一屏可比對十筆以上;篩選列「最高信心 ≥」更名為「AI 把握度 ≥」、收件匣鈕「未分類審閱」更名為「只看未分類」,兩者都補上說明 tooltip(原文案看不出是篩選動作),批次線的領域下拉改讀該 run 的 catalog_snapshot(原讀舊 Drive 線的靜態表,列出的領域與本次分類對不上) - 2026-09-17(FR-107):批次線上線——新增以 run_uid 定址的入口(嵌在批次流程頁第③步)、檢查點代號改 part_id/ao_letter、目標集改吃 run 的 catalog_snapshot(凍結快照)、權限鎖專案角色;原 Drive 線(run_folder_id)保留供既有分類結果讀取。批次四步與狀態機見 功能群總覽 §2

1. 功能描述

證據分類覆核頁是 AI 證據自動分類的人工覆核工作區:一個分類 run 跑完後,逐檔檢視 AI 建議的 placement(檔案 → 檢查點的對應),手動新增 / 移除 placement、標記 N/A、刪檔,最後儲存。

同一支元件服務兩條線(見 _overview §2),差別在資料來源與「存完之後去哪」:

批次線(現行主線) Drive 線(既有資料)
入口 批次流程頁第③步嵌入(/project/projects/:id/evidence-batches/:batchUid/review/:runUid) 獨立頁(.../ap/:apUid/classify-evidence/run/:runFolderId)
定址 run_uid(UUID) run_folder_id(Drive 資料夾 ID)
檢查點代號 part_id + ao_letter(如 IA.L1-3.5.1_obj.1) {ControlId}[{letter}](如 AC.L1-3.1.1[a])
目標集(可選的檢查點母體) run 的 catalog_snapshot——分類當下凍結,與這次判定必然對得齊 living SSP 的 in-scope 控制集
存完之後 回批次流程頁按「歸檔進任務」,檔案改綁控制任務、job_evidences 真正寫入一筆 同步回 Drive _state.json,需要時歸檔=把檔複製進 per-AO 資料夾
編輯真相 run 的 state(沒有 Drive) Drive 上的 _state.json,DB state 是鏡像

主要使用者:批次線=專案 manager(寫)/專案參與者(讀,auditor 唯讀);Drive 線=v1 僅 JWT、未鎖專案角色。見 §3。

角色速覽(完整見 _overview §5):

角色 一句話
manager 專案經理 — 觸發分類(上游)並覆核修正;批次線的寫入類動作只有他能做
專案參與者 批次線可讀(auditor 進得去但按鈕整組隱藏,唯讀)
(覆核者) Drive 線的覆核 / 存 / 歸檔僅需 JWT(未鎖專案角色,實驗階段遺留)

1.1 功能總覽(本頁全部功能)

# 功能 說明 位置 詳述
1 分頁切換 要你處理/已完成/非證據/全部,各帶份數;「要你處理」旁紅色小計=其中被安全檢查攔下的份數。預設停「要你處理」,沒有待處理就轉「已完成」 頁頭 ClassificationReviewHeader §4、§10
2 進度與統計 進度條「已處理 N / M 份(非證據不計)· 涵蓋 X / Y 個檢查點」;「統計」展開列出總檔數/已分類數+%/未分類/配對總數+每檔平均/檢查點涵蓋 頁頭 §10
3 自動配對門檻 顯示目前生效門檻(調過會附「原本 X」);點開滑桿 0.40~1.00、按「套用」用既有 AI 分數重挑自動配對 頁頭 §10、§12
4 儲存/捨棄/歸檔 儲存(帶未存項數)、捨棄重載;批次線 embedded 時的「歸檔進任務」/「重新歸檔」(未存時停用、稽核員不顯示) 頁頭右側 UC-EC-01、UC-EC-02
5 篩選列(僅「全部」分頁) 搜尋檔名/領域下拉(批次線列該 run catalog_snapshot 的領域)/配對數(全部/單一/≥2/≥5)/「只顯示 AI 分數 ≥」slider(預設 0,只影響顯示)/重設 ClassificationFilterBar §5
6 檔案清單(左欄) 標題隨分頁;每列一個狀態點+一行原因(紅盾+「已攔截」=安全檢查攔下、橙=AI 沒把握、綠=已配對或已確認、灰=非證據);AI 分數欄、配對數欄可排序;預覽鈕 ClassificationFileList(34%) §5
7 檔案詳情(右欄) header(檔案編號/評估數/配對數、已確認者與時間、確認過的被攔檔顯示灰色「待人審」)+上下一份(j/k、↑↓)+ ⋮ 選單;兩態身:非證據/一般 ClassificationFileDetail(66%) UC-EC-01
8 下一步卡 只在人必須動手時出現(被攔下、未配對、手動配了但未確認):原因+一句要做什麼+「確認這樣分類,下一份」「標為非證據」;被攔下的檔紅框 詳情最上方 UC-EC-01
9 已配對表 一筆一列:檢查點代號(麵包屑在 tooltip)/說明/來源(AI/人工)/AI 分數/狀態(已配對/新加入/已移除)/移除或復原;AI 理由在展開列;標題旁「調整檢查點」 PlacementTable(mode="placed") UC-EC-01
10 AI 候選表 未放置的 AI 建議,預設只列 ≥ 生效門檻,可切「看全部」;操作為「加入」 PlacementTable(mode="candidate") UC-EC-01
11 調整檢查點(AOPickerDialog) 從全部目標集勾選加/減配對(勾=保留、取消=移除、新勾=新增),AI 評過的顯示分數 已配對表標題旁 UC-EC-01
12 標記非證據/復原 整檔標為非證據(確認框)/復原 ⋮ 選單、下一步卡;非證據態「還原」 UC-EC-01
13 從證據池刪除 把檔案移出證據池(is_deleted,確認框) ⋮ 選單 UC-EC-01
14 檔案預覽 開檔預覽(docx/xlsx/pptx/pdf/text/image,<50MB) 清單預覽鈕 → EvidenceFilePreviewDialog §6
15 重跑分類 獨立路由開啟時的 Header 鈕,返回上頁重新觸發(本頁不觸發,router.back()) Header(非 embedded) §12
16 用量費用列 模型/token/粗估費用(僅 DEV_MODE) 頁頭下方 —

UC(§2)只展開 1(逐檔覆核與儲存)、2(歸檔)這些核心操作路徑;統計 / 篩選 / 預覽是輔助檢視。觸發分類本身不在本頁——批次線在批次流程頁第②步,Drive 線在上游專案 / AP 頁(見 §12)。

🔴 批次線的歸檔(第 4 項「歸檔進任務」)是把檔改綁控制任務、寫 job_evidences;Drive 線的歸檔是把檔複製進 Drive 資料夾——兩者名字都叫「歸檔」但做的事不同,見 _overview §2。

2. Use Case

角色速覽(完整見 _overview §5):

角色 一句話
manager 專案經理 — 觸發分類(上游)並覆核修正;批次線的寫入類動作只有他能做
專案參與者 批次線可讀(auditor 進得去但按鈕整組隱藏,唯讀)
(覆核者) Drive 線的覆核 / 存 / 歸檔僅需 JWT(未鎖專案角色,實驗階段遺留)

流程圖視覺慣例:菱形 = 判斷、橘底 = 例外/擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。

UC-EC-01 逐檔覆核分類並儲存

項目 內容
角色 覆核者(v1 JWT)
前置條件 分類 run 已 completed、_state.json 存在
產出 / 後置條件 placement 增減 / N/A / 刪檔在記憶體 → 儲存時 diff → Drive copy/trash + overwrite _state.json + DB 鏡像同步

批次線的主路徑:停在「要你處理」分頁,逐份看「下一步」卡 → 必要時「調整檢查點」或從 AI 候選加入 → 按「確認這樣分類,下一份」(寫 reviewed_by/reviewed_at,自動跳下一份)→ 份數歸零後按儲存 → 歸檔進任務。要整批放寬或收緊自動配對,先在頁頭調門檻再逐份處理。

UC-EC-01 流程:選檔 → 加/減 placement / 標 N/A / 刪檔(記憶體)→ 儲存 diff → Drive copy/trash + _state.json + DB 鏡像

UC-EC-02 歸檔 run(analyze-only → 落檔)

項目 內容
角色 覆核者(v1 JWT)
前置條件 run archive_files=false(analyze-only,placement 檔尚未複製)
產出 / 後置條件 無 placement_drive_id 的 placement copy 進 per-AO 資料夾、填回 id;archive_files=true + archived_at

UC-EC-02 流程:未歸檔警示 → 立即歸檔 → 對無 placement_drive_id 者 copy 進 per-AO 資料夾 → 標 archived

3. 權限矩陣

角色基調見 _overview §5。本頁檢查點:

兩條線的守門不同(這是兩者最大的差異之一):

操作 FE 判定 BE 強制 BE 檢查位置
批次線:建批次 / 上傳 / 刪檔 / 開始分類 / 歸檔 / 清理 canWrite = 專案 manager 且已設定儲存位置 is_project_manager() → EC_403005 套件 app/service/evidence_batch_service.py _require_manager()
批次線:看批次清單 / 流程頁 / 分類結果 auditor 進得去,但按鈕整組隱藏+顯示一行說明 is_project_participant() → EC_403002 同上 _require_participant()
Drive 線:觸發分類(上游) 專案 manager project_participant.role == "manager" → EC_403001 app/evidence_classification/service/evidence_classification_service.py:99-150
Drive 線:讀 state / 存 / 歸檔 / 預覽 能到 URL 即可(無頁內角色判定) 僅 @jwt_required(),未檢專案角色 套件 route(認證由宿主注入的 decorator 套上)

⚠️ Drive 線的覆核權限未鎖(收進 §12):觸發分類鎖 manager,但覆核 / 存 / 歸檔 / 預覽只驗 JWT——FR-030 v1 實驗階段遺留,非資安定案。批次線已改鎖專案角色,這條只影響舊入口。

批次寫入類動作刻意用專用碼 EC_403005(「僅專案管理者可操作證據批次」)而非泛用的 EC_403001:後者文案只講「觸發自動分類」,上傳或刪檔被擋時顯示那句對不上使用者當下做的事。

4. 狀態機與前置條件

分類 run 狀態機見 _overview §2。本頁相關 gate:

條件 效果 出處
批次線:批次 status = review 才進得到第③步確認分類;classifying 時前端每 5 秒輪詢批次詳情,轉 review 自動跳頁 批次狀態機見 _overview §2.1
批次線:run 有 catalog_snapshot 才有目標集可對照;缺快照回 EC_412007(「此 run 無目標集快照,請重新分類」) 套件 run state 讀取
批次線:分類進行中封口 加檔 / 刪檔被擋回 EC_409003,前端顯示「分類進行中不能改檔」 SEALED_ACTIONS
run status = completed 才有可覆核的 _state.json(Drive 線) evidence_classification_service(run state 讀取)
archive_files = false 顯示未歸檔警示 + 立即歸檔鈕;placement placement_drive_id 為 null ClassificationFileDetail / metadata
未存變更 儲存/捨棄鈕啟用,儲存鈕帶未存項數。比對每份檔的配對+非證據+刪除+確認,以及 review_threshold useEvidenceClassification.hasUnsavedChanges
待人審來源①:沙箱判定 檔案沙箱拆檔時發現藏字(hidden_text),或注入分數 ≥ 0.8(injection)→ 不送 AI,needs_review=true、ai_suggested=false、無候選。清單列「{原因} · 沒送 AI」 套件 jedi_evidence_classification/app/service/gateway_classifier.py(INJECTION_SKIP_THRESHOLD,常數不可調)
待人審來源②:AI 閘道標記 送 AI 時閘道命中標記級規則(疑似注入 injection、原文外洩比對 verbatim)→ 照送、照配對,needs_review=true、ai_suggested=true。清單列「{原因} · AI 結果僅供參考」 同上
被閘道擋下(例如檔內含私鑰) 不送 AI、不設 needs_review;error 記擋下原因,無候選,清單列落在橙點「沒有候選」,歸「要你處理」 同上
執行中額度用完 error=quota_exhausted,清單列橙點「額度用完未分類」,歸「要你處理」;額度恢復後可重跑 同上;額度見 AI 額度
分頁歸屬 非證據 → 非證據;已確認(reviewed_at)→ 已完成;needs_review → 要你處理;有配對 → 已完成;其餘 → 要你處理。AI 自動配好的檔不需人確認 reviewBucket.js::fileBucket
確認失效 已確認的檔被加減配對或改非證據 → 清掉 reviewed_by/reviewed_at,回到要你處理 useEvidenceClassification.clearReview

5. UI 設計

📸 實際畫面截圖待補(一律亮色模式拍攝):以 playwright 對 STG 擷取,預計補以下四張到 assets/img/: ① 整頁「要你處理」分頁(頁頭 + 左清單含被攔下的檔 + 右詳情下一步卡)ec-review-overview.png ② 檔案詳情 — 已完成(已配對表含來源欄 + AI 候選表)ec-review-classified.png ③ 頁頭門檻面板展開 ec-review-threshold.png ④ 調整檢查點對話框(AOPickerDialog)ec-review-aopicker.png

版面骨架與區塊職責(2 欄 Splitter,狀態存 localStorage ec-review-splitter;彩色區塊可點跳本頁小節錨點,虛線框=點開或特定分頁才出現):

證據分類覆核頁版面 wireframe:頁頭(分頁+進度+自動配對門檻+儲存/捨棄/歸檔)+門檻面板+「全部」分頁篩選列;左檔案清單 34%(被攔下的檔紅底排最前)/右詳情 66%(下一步卡·已配對表·AI 候選表)

狀態呈現:清單列狀態點(紅盾=被攔下、橙=AI 沒把握、綠=已配對或已確認、灰=非證據);被攔下的檔整列紅底+左側紅條+「已攔截」標籤;AI 分數 tier 色(高 ≥0.85 綠 / 中 ≥0.70 橘 / 低 紅);已配對表來源欄 AI 藍、人工灰。鍵盤 j/k / 上下鍵切檔。無 socket,覆核為前端記憶體操作、存時才寫。

6. API 規格

Envelope:成功 {"status": true, "data": …}、失敗 {"status": false, "error_code": "EC_…", "msg": "…"}。

6.1 總清單(本頁呼叫的全部 endpoint)

分類 Method + Path 說明 完整規格
批次線 載入 GET /classification-run/{run_uid}/state 讀 run 的 state(run_uid 為 UUID,掛載順序在 legacy 那條之前) §6.2
批次線 儲存 PUT /classification-run/{run_uid}/state 存編輯(沒有 Drive,run 的 state 即真相) §6.2
批次線 預覽 GET /classification-run/{run_uid}/file/{file_uid}/preview 走租戶儲存後端取檔 GAI-SD-02
批次線 上游(非本頁) POST /evidence-batches/{batch_uid}/classify・/archive・/purge 開始分類 / 歸檔進任務 / 清理暫存檔(在批次流程頁) _overview §2.1
載入 GET /classification-run/{run_folder_id}/state 讀 _state.json(metadata + files + placements) §6.2
儲存 PUT /classification-run/{run_folder_id}/state 存編輯(BE diff → Drive copy/trash → 覆寫 + DB 鏡像) §6.2
歸檔 POST /classification-run/{run_folder_id}/archive analyze-only run 落檔 §6.2
預覽 GET /classification-run/{run_folder_id}/file/{file_drive_id}/preview Drive 檔預覽 GAI-SD-02
報表 GET .../report/validation・.../report/adjudication DEV 捷徑(下游頁) 驗證報表 / 誤判報表
上游(非本頁) POST /project/{project_uid}/ap/{ap_uid}/classify-evidence、GET .../classify-evidence/jobs 觸發分類 / job 清單(在專案/AP 頁) §12

6.2 分類 run state 類

[GET] /classification-run/{run_folder_id}/state

Response data:{metadata, files[]}——

metadata:

欄位 型別 說明
drive_run_folder_id string Drive run 資料夾 id
drive_run_folder_name string Drive run 資料夾名稱
framework_id string 合規框架(v1 = cmmc-l1)
confidence_threshold number 信心門檻
model string 使用模型
archive_files bool 是否已複製 placement 檔進 per-AO 資料夾
token_usage object token 用量:{total_tokens, cache_read_input_tokens, estimated_cost_usd}
last_edited_at string 最後編輯時間
last_edited_by_user_id int 最後編輯者
archived_at string 歸檔時間(歸檔後才有)
archived_by_user_id int 歸檔者(歸檔後才有)

files[](每檔):

欄位 型別 說明
file_drive_id / file_name string Drive 檔識別 / 名稱
is_na / is_deleted bool 標記不適用 / 移出證據池
matches[] array AI 候選:{ao_id(如 AC.L1-3.1.1[a]), confidence(0–1), reasoning}
placements[] array 確定放置:{ao_id, placement_drive_id(歸檔後才有), source(ai/manual), added_at?}

出處:evidence_classification_service.py::get_state(讀 Drive _state.json)

[PUT] /classification-run/{run_folder_id}/state

Request:同 GET 的 {metadata, files[]} 完整結構(前端整包送回)。BE diff old vs new placements:新增 → copy_file 進 per-AO 資料夾填 placement_drive_id;移除 → trash_file;蓋章 last_edited_*;覆寫 _state.json;_sync_run_state_to_db(idempotent)。Response data:{operations_applied, drive_copied, drive_trashed, errors[]}。出處:evidence_classification_service.py::put_state

[POST] /classification-run/{run_folder_id}/archive

無 body。對每個無 placement_drive_id 的 placement copy 進 per-AO 資料夾;設 archive_files=true、archived_at。Response data:{drive_copied, already_archived, errors[]}。出處:evidence_classification_service.py::archive_run

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/evidence-classification/EvidenceClassificationReview.vue 主檢視(2 欄 Splitter、分頁、篩選、存 / 歸檔、確認後跳下一份)
src/views/evidence-classification/reviewBucket.js 分頁歸屬規則(fileBucket)與「要你處理」排序(被攔下的排前)
.../components/ClassificationReviewHeader.vue 頁頭:分頁、進度、統計展開、門檻調整、儲存/捨棄、歸檔 slot
.../components/ClassificationFilterBar.vue 篩選列(僅「全部」分頁)
.../components/ClassificationFileList.vue 左檔案清單(虛擬捲動)
.../components/ClassificationFileDetail.vue 右詳情(三態)
.../components/PlacementTable.vue / AOPickerDialog.vue 已配對/AI 候選共用表(mode 切換)/ 加 AO
.../components/EvidenceFilePreviewDialog.vue Drive 檔預覽
src/service/EvidenceClassificationService.js API 包裝(getState / putState / archiveRun / 報表)
src/composables/useEvidenceClassification.js state 管理(load / add/remove placement / markNa / markReviewed / applyThreshold / save / hasUnsavedChanges)
src/config/router/index.js:859-862 route evidence-classification-review
src/config/locales/i18n/{zh-tw,en}/evidence-classification.json i18n(namespace lang.evidence_classification.*)

8. 後端檔案地圖(本頁核心鏈路)

鏈路 Route App Service 底層
讀 / 存 state api/evidence_classification/routes/evidence_classification_route.py::ClassificationRunStateRoute app/evidence_classification/service/evidence_classification_service.py::get_state / put_state(diff + Drive ops + DB 鏡像) EvidenceDriveOps(copy/trash/update_json)+ ClassificationRunDomainService.update_state
歸檔 同檔 ClassificationRunArchiveRoute archive_run EvidenceDriveOps
觸發分類(上游) 同檔(classify-evidence route) trigger_classify(_check manager)→ ClassifierContainerRunner(Docker)→ Drive + DB persist evidence_classification_runs repo

DDD 提醒:本模組 route → app service → domain service / repo(ClassificationRunDomainService)+ infra 的 EvidenceDriveOps(Drive 操作限縮在 infra)。error code 前綴 EC_(common/code/evidence_classification_error_code.py)。

9. DB

9.1 資料表總清單(本頁讀寫的全部表)

表 讀/寫 說明 欄位詳述
compliance.evidence_classification_runs 讀/寫(鏡像同步 state) 分類 run 記錄;真相在 Drive _state.json,本表 state/report_original JSONB 為鏡像 §9.3
(Drive _state.json / _report-original.json) 讀/寫 placement 編輯的真相來源(非 DB,見 _overview §2) —

本頁不直接寫 ground_truth(那是誤判報表 CANON 匯入);ground truth 表見 _overview §6 與 驗證報表。

9.3 核心表欄位(取自 DEV DB dump)

compliance.evidence_classification_runs — 證據分類 run 結果

欄位 型別 說明
run_folder_id varchar(128) Drive run folder id(自然鍵) = 頁面 URL 的 runFolderId
tenant_id / project_uid / ap_uid int / varchar 租戶 / 專案 / AP
framework_id varchar(64) 合規框架(v1 = cmmc-l1)
model / confidence_threshold varchar / numeric(4,2) 使用模型 / 信心門檻
status varchar(32) queued / processing / completed / failed
archive_files boolean 是否已複製 placement 檔進 per-AO 資料夾
input_file_count / classified_count int 輸入 / 已分類檔數
estimated_cost_usd numeric(10,4) 估算費用
state jsonb _state.json 鏡像(User 修正後)
report_original jsonb _report-original.json 鏡像(AI 首次輸出,immutable;報表對照基準)
container_log text 容器日誌
triggered_at / completed_at / last_edited_at / archived_at timestamptz 生命週期時間
triggered_by / last_edited_by / archived_by _user_id int 各動作使用者

10. 頁面邏輯與資料對應

載入時序:

頁面載入時序:onMounted → getState → snapshot 原始 placement(未存偵測)→ 自動選第一個未分類檔

關鍵欄位對應(畫面 ↔ API):

畫面元素 FE state API 欄位
分頁份數 bucketCounts files 依 fileBucket 分組
統計展開 ec.stats files 聚合(classified / unclassified / placements / coverage)
生效門檻 metadata.review_threshold ?? metadata.confidence_threshold 同左
待人審/原因 file.needs_review、review_reason(hidden_text 疑似藏字/injection 疑似注入指令/verbatim 原文外洩比對命中/其他) 沙箱或閘道寫入,前端唯讀
是否送過 AI file.ai_suggested true=AI 有看過、結果僅供參考;false 且 needs_review=沒送 AI,需人工配對
未分類原因 file.error quota_exhausted=額度用完;其他=閘道擋下或處理失敗
人工確認 file.reviewed_by(login_name)、reviewed_at;清單列顯示「已人工確認」 files[] 同名欄位,隨 PUT state 整包存(無獨立 endpoint)
AI 分數條 match.confidence matches[].confidence(tier 前端算)
已配對表來源欄 placement.source placements[].source(ai/manual;舊資料無此欄時有分數視為 AI)
AI 候選表 未放置的 matches ≥ 生效門檻(或「看全部」) matches[] \ placements[]
未存項數 pendingCount(配對 diff+每檔狀態變動) —

調整門檻:applyThreshold(n) 對每份檔(跳過已刪除、非證據、已確認)保留人工配對,AI 配對只留 matches 分數 ≥ n 者,並補上 ≥ n 但尚未配上的 match(source: 'ai');metadata.review_threshold = n。不呼叫後端,儲存時隨 state 一起寫。

儲存流程:前端整包 PUT state → BE diff → Drive copy/trash → 覆寫 _state.json → DB 鏡像;捨棄 = 重載。歸檔另走 POST archive。

錯誤對應:BE EC_ envelope → toast;常見 EC_403001(觸發非 manager)、EC_404003(_state.json 不存在)、EC_404008(run 未存 DB 無法產報表)、EC_500003(Drive 檔操作失敗)、EC_500004(state JSON 解析失敗)。

11. 背景行為與外部依賴

類型 內容
AI 分類(批次線) 背景工作 guidant-worker 撿單;每份檔先交檔案沙箱 guidant-sandbox 拆檔、掃藏字、算注入分數,再經 AI 閘道送外部 AI(遮蔽機敏資料、檢查額度、寫 ai_call_log,feature classification)。沙箱不連外網、不持有 AI 金鑰
AI 分類(Drive 線) 既有資料,只讀;_state.json + _report-original.json
Drive 覆核存檔 = Drive copy/trash + 覆寫 JSON(EvidenceDriveOps);歸檔複製 placement 檔進 per-AO 三層資料夾
Socket 本頁無 socket;覆核為前端記憶體操作、存時才寫
jedi-* 套件 Drive 操作 / classifier 容器(模組自有 infra);jedi-auth(JWT)
把握度門檻 批次流程第②步設定(預設 0.70、可調 0.50~1.00),本頁可另調 0.40~1.00;沙箱的注入分數門檻 0.8 是套件常數,不在畫面上
守門規則 主機規則目錄,現場可調,見 落地版維運 4.12
送出前額度預估 在批次流程第②步:預估超過剩餘額度 1.5 倍擋整批(GRC_412058),本頁不會見到

12. 邊界情況與已知坑

  1. 真相在 Drive _state.json 不是 DB:DB state 是鏡像;直接改 DB 會與 Drive 脫鉤(見 _overview §7 坑 2)
  2. 覆核權限 v1 未鎖:觸發鎖 manager,覆核 / 存 / 歸檔僅 JWT(§3)
  3. 觸發分類不在本頁:本頁「重跑分類」是 router.back();實際觸發 POST /project/{uid}/ap/{apUid}/classify-evidence 在上游專案 / AP 頁(單 project 單 AP、無並行,同 project 一次一 job)
  4. analyze-only 模式 placement_drive_id 為 null:未歸檔前 placement 只在 JSON、檔案未複製;歸檔後才落檔
  5. 儲存是整包 diff 不是增量:前端送完整 files 陣列,BE 自行 diff;多人同時覆核同一 run 會互蓋(無鎖)
  6. 限 CMMC L1 + Drive(v1):非 CMMC L1 框架 / 非 Drive 來源 v1 不支援(見 _overview §7 坑 5)
  7. 報表即時算、無確認狀態:驗證 / 誤判報表每次開重算(見 驗證報表 / 誤判報表)
  8. 預覽限檔型 / 大小:docx/xlsx/pptx/pdf/text/image、<50MB
  9. 兩個分數別搞混:頁頭的「自動配對門檻」會改變配對(算不算分類成功);「全部」分頁的「只顯示 AI 分數 ≥」只決定清單顯示哪些檔,不改任何配對
  10. 門檻下限 0.40:AI 分類時只回報 ≥ 0.4 的候選,調更低也配不出新東西;調門檻只重挑 AI 配的,人工配對與已確認檔不動
  11. review_threshold 不覆寫 confidence_threshold:驗證/誤判報表以 confidence_threshold 當「AI 原始判斷」基準線,覆寫會讓報表的 AI 準確率失真
  12. 確認不動待人審欄位:needs_review/review_reason 是安全檢查的判定,人工確認只加 reviewed_by/reviewed_at,事後仍查得到這份曾被攔下
  13. 「已攔截」涵蓋兩種來源:沒送 AI 的與 AI 結果僅供參考的都紅底標「已攔截」;要分辨看清單列那行原因與詳情下一步卡的待辦文字。
  14. 被閘道擋下的檔不算「已攔截」:它沒有 needs_review,落在橙點「沒有候選」;要知道是哪條規則擋的,到 AI 用量 呼叫明細找 feature=證據自動分類、狀態=被阻擋。

13. 開發與驗證

  • 跑起來:BE python main_socketio.py(port 8000,log 在 log/app.log);FE 在 compliance-manager-fe/ 起 Vite dev server。BE 改 service code 後必須重啟(無 hot reload)
  • 測試帳號:dev 環境專案 manager 帳號(密碼見 .env / 部署文件)
  • 導航路徑:登入 → 專案 / AP 觸發分類 → 分類 job 完成 → 進覆核頁(.../classify-evidence/run/{runFolderId})
  • 前置資料:租戶已連 Google Drive(CONNECTED)+ AP 已 init Drive 資料夾 + Evidences 有檔案 + 已跑過一個 completed 分類 run
  • E2E:compliance-manager-test/ repo(Cucumber + Playwright);以 證據分類 / classification 搜尋
  • 相關文件:FR-030(AI 證據分類,docs/features/FR-030-2605-auto-evidence-classification/)、FR-031(報表);下游報表見 驗證報表 與 誤判報表;DB / API 全量見 GAI-SD-02/03