全檔掃描(ocr scan)

不需 Git diff 的整檔評審——審計陌生 codebase 或沒有有意義 diff 的目錄

是什麼

ocr scan 直接從工作樹讀取每個檔案的目前內容交給 LLM 評審,不需要 Git diff。適合:

基本用法

ocr scan                            # 掃描整個倉庫
ocr scan --path internal/agent      # 掃描單一目錄
ocr scan --path internal/agent,internal/llm/client.go
ocr scan --exclude '**/generated/*,*.pb.go'
ocr scan --preview                  # 看會掃哪些檔(不花 token)

參數

參數簡寫預設說明
--path <list>—整個倉庫逗號分隔的 repo 相對目錄或檔案
--exclude <patterns>——逗號分隔的 gitignore 風格排除模式;與 rule.json 的 excludes 合併
--preview-pfalse列舉並過濾但跳過 LLM

與 ocr review 一樣接受 --format json、--audience agent、--resume、--provider、--model、--max-tokens 等。

scan vs review

面向ocr reviewocr scan
輸入Git diff(三種模式)整個工作樹檔案
需要 Git 歷史是否
適用PR / commit 評審整檔審計、陌生 codebase
預覽--preview--preview
📖 教學解說:全檔掃描深入

scan vs review 的本質差異

ocr review 審的是「變更了什麼」(Git diff),ocr scan 審的是「檔案長什麼樣」(完整內容)。這不是功能差異——是使用場景差異:

  • 有 Git 歷史、要審 PR → review
  • 審計遺留程式碼、陌生 codebase → scan
  • 沒有有意義的 diff(首次導入)→ scan

--path 與 --exclude 的組合技巧

--path 接受逗號分隔的目錄或檔案,可以精確控制掃描範圍。配合 --exclude 排除生成碼:

ocr scan --path src/api,src/db --exclude '**/generated/*,*.pb.go'

這只掃描 API 和 DB 層,排除 protobuf 生成檔。

--preview 是你的安全網

跑 ocr scan --preview 可以不花 token 看到會掃描哪些檔案。這是第一次 scan 的必跑步驟——確保你不會掃到不該掃的(如含敏感資料的目錄)。

練習 / 驗收清單

  • 能區分 ocr scan 與 ocr review 的根本差異
  • 能使用 --path 與 --exclude 控制掃描範圍
  • 能用 --preview 確認掃描範圍
看完這頁你應該能說出:ocr scan 與 ocr review 的根本差異(diff vs 整檔)、--path 與 --exclude 的用法、以及何時該用 scan。

延伸閱讀:CLI 參考 · 評審規則

① 進階真實情境 Worked Example:上市前的最小安全審計

情境

你的產品明天要上線,但沒有正式的安全 team。你要用 OCR 做一次「最小可行安全審計」:掃描所有對外暴露的入口(API handlers、auth、上傳、SQL mapper),在預算內找到最該修的洞,產出一份可交差的報告。

Step 1 — 列出「對外暴露」的候選目錄

# 對外入口通常在: api / handler / controller / router
find src -type d \( -name api -o -name handler -o -name controller -o -name router \)

Step 2 — 用 --preview 確認範圍(先確認不掃到怪東西)

ocr scan --path src/api,src/auth,src/upload --preview

Step 3 — 掃描(拉高 token 給足上下文)

ocr scan --path src/api,src/auth,src/upload \
  --max-tokens 200000 --format json --audience agent > security-scan.json

Step 4 — 過濾出安全類評論

jq -r '.comments[] | select(.content | test("SQL|injection|auth|token|XSS|CSRF|traversal|SSRF"; "i"))' \
  security-scan.json

Step 5 — 分級交差

jq '.comments | length' security-scan.json   # 總數
# 依內容分 Critical/High/Medium,列成上市檢查清單

為什麼選這條審查路徑

安全審計不適合 ocr review——上線前「整個工作樹」的狀態才是重點,不是「最近改了什麼」。ocr scan --path 讓我們只審對外暴露面(auth/upload/API),token 預算花在刀口上。用 --preview 先確認範圍(避免掃到開發工具目錄)、用 --max-tokens 給足上下文(讓 Agent 有餘裕讀完整 handler 追蹤流程)——這是「有預算上限的審計」的正確姿勢。

預期產出

security-scan.json: 6 files, 14 comments
  過濾出 6 條安全相關:
    CRITICAL: auth/login.go — token 過期未驗證即可進入
    HIGH:     upload/store.go — 未驗證 user-supplied path
    MED:      api/v1/users.go — SQL 字串拼接風險
  → 上市前必須修: 2 條;建議: 1 條;其餘觀察

② 深入原理擴充:scan 的 token 預算是「逐檔」還是「整體」?

每檔獨立預算,整批共享 concurrency

ocr scan 對每個檔案獨立跑一個子 agent(跟 review 的 per-file 一樣),所以 --max-tokens 是「每檔」的 prompt 上限。整批掃描的總成本 ≈ 每檔上限 × 檔案數。這就是為什麼 --path 縮小範圍對成本影響巨大——掃 10 檔 vs 100 檔,token 差 10 倍。

「看起來審計通過但其實有隱患」的案例

# 你的 scan 只審了「source 目錄」:
ocr scan --path src --exclude '**/test/**'

# 但真正的 secret 藏在:  config/prod.yaml   ← 不在 src、也不在 Git 追蹤 (gitignore)
# scan 從工作樹讀檔 → config/prod.yaml 根本不在候選清單
# 審計報告「零 secrets」→ 但 prod.yaml 裡有 DB 密碼硬編碼

「掃不到 = 乾淨」是 scan 的最大盲點——它只掃它被指定掃的。隱患:範圍外的洞(config、.env、部署 manifest)完全不可見。防禦:審計前先「列全目錄」對照 Git 追蹤清單,確認沒有「該審但沒被掃」的檔;--preview 的輸出要跟 git ls-files 比對,找出「存在但被排除」的意外。

③ 診斷式疑難排解

症狀可能原因解決方案
scan 掃完零評論掃描範圍外有洞;或 --path 沒覆蓋到真正熱點對照 git ls-files 與 --preview;擴大範圍
某檔被截斷「審一半」該檔超過每檔 --max-tokens調高 --max-tokens 或縮小檔案(拆模組)
掃到 vendor / 生成碼拖慢沒設 --exclude加 --exclude '**/vendor/**,**/generated/**'
評論多到無法消化一次掃太多檔案分層掃:先核心目錄(auth/payment)再往外;用 jq 過濾分級
secrets 掃不到secrets 檔在 scan 範圍外(config/.env)把 config、部署 manifest 加進 --path;或另跑 gitleaks

④ 進階挑戰題

  1. 挑戰一:用 git ls-files + ocr scan --preview 設計一個「範圍差異檢查」:找出「存在於 repo 但 scan 沒掃到」的檔。
  2. 挑戰二:算一下成本:每檔平均 8,000 token、掃 50 檔,大概花多少 token?如果要壓到一半,你會用哪兩種手段?
  3. 挑戰三:判斷題——「scan 發現 0 條 SQL injection」等於「repo 沒有 SQL injection」嗎?提出一個能提高信心的補充檢查。