FR-122 交接現況(STATE)

✓ ARC 已收口 — 2026-09-30。1.22.0 出貨三環境(188 STG/189 POC/190),母卡 CM-2293 Done。 收口文件:2026-09-30-arc-SUMMARY.md(規模/行為差異/決策/驗收/follow-ups)。 本檔停止更新,以下為收口當刻狀態;後續待辦座標在 memory followup_fr122_leftovers。

這份是 living 檔:每棒就地 Edit,只描述「此刻」。歷史脈絡看同資料夾的 FR-122-LOG.md。 本 arc 走協調者級:接手者是「驗收派工中心首腦」,不自己寫 code,只派工、驗收、裁決。

項目 值
最後更新 2026-09-30 深夜(收口棒:決策者下令收尾,CM-2363/CM-2293 Done,arc 結束)
branch 三 repo 已合 main 並 push(BE f6e3d8a7a、FE 55d8422、jedi dd4a5b14);本機 BE 在 main。決策者 09-30 授權首腦本 arc 內可 git push origin main(memory feedback_fr122_push_delegated,CM-2293 收口即失效)
母案卡 CM-2293 https://app.notion.com/p/FR-122-AI-AI-6-21-3e9346da4cd081f28e5fe25703685f5c
本棒對應卡 首腦,無子任務
已完成(Done) 三階段全部子卡 Done(第一階段 CM-2294~2337、第二階段 CM-2351/2352/2354/2360、第三階段 CM-2339~2350/2353、文件與收尾 CM-2338/2355~2359/2361/2362);子需求母卡 CM-2294~2299 Done
回寫待首腦驗 無
進行中 無。出貨包 188 .build/bundle/guidant-ai-1.22.0.tar.gz(sha 0f788947…,內部測試包缺 PROD 鑰);三環境皆在此包(BE 62a864e62)。§7.1-9 未驗、收尾接受
未派 無;follow-ups 見 SUMMARY §9
Notion 回寫規範 docs/claude/notion-issue-tracker.md
接手前必讀 §0 讀序

🧭 原始需求 / WHY

這節寫一次,之後各棒不動。

決策者原話(2026-09-28):「AI 小助手會去呼叫 AI API,目前完全沒有過濾內容。我要怎麼防範使用者亂使用,造成他可以去攻擊我們的系統,或是他可以做哪些資安的攻擊行為操作,我要怎麼阻擋。這是一個很嚴重的問題。」後續擴大:「參考 OWASP 和 EU AI Act」、「還有 AI 動態儀表板、證據自動分類也用到 AI」、「先從資安面防禦來解決,再來解決燒錢問題」、「證據會不會有機敏資料外洩」、「要能被稽核的紀錄:人事時地物、user 原始發什麼、我們調整成什麼、送出、回應什麼、花了多少 token、用什麼服務」、「有機制可以暫停功能,直到加值後才再開放」、「做成共用的 AI 資安模組、預留 DDD+六邊形、不被舊設計綁死」、「有輪子我們就不要再做輪子」。

要解決什麼:三支 AI 功能(小幫手 jedi-ai-bot、儀表板 jedi-ai-dashboard、證據分類 jedi-evidence-classification)各自直接打外部 AI,無守門、無稽核、無配額;分類容器同時握金鑰+出網+解析不可信檔案。實查出 16 項資安問題(🔴4/🟠6/🟡4/🟢2),對照 OWASP LLM Top 10 2025、EU AI Act 第 50 條(2026-08-02 生效)。

目標模型:三個角色——

  • ai-gateway(library,套件 jedi-ai-gateway):所有打 AI 的唯一出口,七步管線:入口守門(Presidio 遮機敏+Prompt Guard 2 判注入+自寫離題/格式)→ 提示強化(Segment 三段 instruction/data/untrusted)→ 金鑰(包現有 resolver)→ 供應商(LiteLLM)→ 出口守門(pydantic+Presidio 再掃+去原文)→ 稽核 ai_call_log(LiteLLM callback 給計量)→ 配額(第三階段)。
  • ai-sandbox(容器,由 guidant-classifier 改造):只拆檔+掃藏字,無網路無金鑰無 DB,POST /v1/extract。
  • worker(BE 同 image RUN_MODE=worker):長工作的家,background_jobs 表撿單,分類第一個搬進去。

執行時容器 api + worker + sandbox。輪子全是 pip 套件(LiteLLM MIT/Presidio MIT/Prompt Guard 2 Llama 授權標「Built with Llama」/onnxruntime),Langfuse 只架 DEV。

本棒在大圖的位置:第 1 棒=首腦,已完成討論稿→design.md→28 張卡→派出棒 1、2。接手首腦負責:驗收棒 1、2 → 派棒 3(小幫手,依賴棒 2)→ 派棒 4(儀表板,依賴棒 2,可與 3 平行)→ 派棒 5(沙箱+分類,依賴 1+2)→ 派棒 6(前端,依賴 3、4、5)→ 第一階段整體驗收 → 等決策者裁上 STG。

§0 接手讀序

0.1 🔒 先懂需求 gate(全讀)

  1. 本檔 🧭 WHY 節
  2. docs/features/FR-122-2609-ai-gateway-and-sandbox/design.md:分工概述(30 秒版)、決策定案表(D1~D11+成本三題)、拆分表——全讀;詳細設計節驗收時再翻對應段
  3. python3 scripts/notion_case.py get CM-2293(母卡)

0.2 現況與待辦

  1. 本檔 §1、§3
  2. FR-122-LOG.md 最後 2 個 block

0.3 需要細節才開

  • discussion.md §4.5 採用的開源元件、§4.6 市面對照(給 PM 講時用)
  • 三支功能現況實查座標:~/Projects/Jedicogy/module/jedi-python-package/jedi-ai-bot/jedi_ai_bot/app/service/ai_bot_service.py、jedi-ai-dashboard/jedi_ai_dashboard/app/service/ai_dashboard_app_service.py、jedi-evidence-classification/docker/container_entrypoint.py、core/plugins/ai_bot.py/evidence_classification.py

0.4 ✅ 冷接自檢(答不出來回去讀 0.1)

  1. 為什麼「守門」要做成 gateway library 而不是各功能自己接?(答:三支各自打→三份守門會漂移;功能只認 complete(),守門在管線內自動發生)
  2. 為什麼分類容器要改成純沙箱?(答:解析不可信檔案的箱子不該握金鑰+出網;守門只能一份)
  3. 為什麼 Bifrost 不採?(答:開源版無 guardrail 與可查稽核,皆企業版且 guardrail 轉接雲端;落地版不成立)
  4. ai_call_log 原文存不存?(答:D5——預設遮罩後+原文 hash,租戶可開完整保留 N 天)

§1 當前狀態(2026-09-29 上午,首腦盤點已驗證)

git(皆未 push)

  • BE feature/ai-guard,自 abc33954b 後:57ffa3738 6a35e2cf3 d5d20f135 742e69892(棒 1)、6a7a37f1d 29e2ea908(CM-2321)、bd2da4d69 41c3acefc 97da10a1e(棒 2)、2d367c4bd(CM-2322)、6028d3f42 701770fdc(棒 3)、f8dfb4530(棒 4)、28a24e61e(棒 5 前段交接)、7cfc36085(CM-2320)、d1bde3f3c feae9bd3f 352874d9d ff606e27d d7e54bf1b 5af285baa(棒 5+CM-2327)、0dea28a49 a83fe372d(首腦 STATE)、f763b37f0(CM-2328)、9cbf9113b 63473ddb3 c8d2232dd(決策者自己:紀錄頁匯出 xlsx、儀表板兩步合一、申報狀態顯示名)、ce49c234e(CM-2331)、1804a778d(CM-2335)、d594768cd~e3ee3efaa 七支 docs(CM-2334 討論稿+CM-2336/2337 SPEC)
  • jedi feature/ai-guard,自 18b52e50 後:486c1d9e(CM-2303)、76dde3f9 fc2777b1 5eb892ca(棒 2)、2ac98195(CM-2322)、6dfe496a 3f7aeb43 c4602bb7(棒 3)、8f85e3b6 89422153(棒 4)、bd281942 ff680b73 b9207dbd(CM-2324~2326)、d1109b9e 23e35a14 bcbc77d1(CM-2314~2315)、709e7404(決策者自己:分佈卡樣式)、d8eeb1e2(CM-2329)、0d10ca4e(CM-2330)、9bc618b0 43e70120(CM-2332)、95b9e199(CM-2333)
  • FE feature/ai-guard,自 50bda00 後:a385017(CM-2310 相容)、4db5b98(CM-2320)、279554e(CM-2318)、479fd3c(CM-2323)、494d58e(CM-2319)、7c53710(CM-2328)、46dbb6a 531823a(決策者自己)、3e6d401(CM-2329)、efc3e58(CM-2332)、cf721a6(CM-2335)、9ce16d3 2a07b4a(CM-2336/2337)
  • BE 工作區:pyproject.toml/poetry.lock 的 path dependency 改動(jedi-evidence-classification、jedi-ai-gateway、jedi-ai-bot、jedi-ai-dashboard 四支)刻意不 commit,arc 收尾還原 pin 一起 commit;不要 add、不要 checkout 還原。jedi 工作區只剩 jedi-evidence-classification/docker/requirements.txt 未 commit(+430 行,來源不明,兩棒都沒人認領),runner 勿夾帶;收尾前要決策者裁留或丟

DB/環境

  • DEV 已套 2026-09-28-fr122-background-jobs.sql、2026-09-28-fr122-ai-call-log.sql、2026-09-29-fr122-ai-call-log-page.sql(seed:ai-call-log.read 能力點授 9 角色+選單)——三支出貨基線待重產(屬決策者裁示);守衛 test_module_boundaries.py::test_host_capabilities_are_seeded 因此紅、重產後轉綠。STG/POC 未動
  • 本機 api/worker PID 會被各棒換掉,一律 lsof -iTCP:8000 查當下,別信這裡
  • DEV 本機起法:API python main.py;分類要 另起 worker RUN_MODE=worker python main.py(沒 worker 單子停在 queued 不會跑);沙箱不用起,SANDBOX_MODE 留空走 inprocess,但 .env 要有 AI_GATEWAY_PROMPT_GUARD_MODEL_DIR 否則沙箱不算注入分數
  • 決策者桌面 ~/Desktop/fr122-classify-test/ 有四份分類測試檔(正常政策/白字+極小字+零寬 PDF/明文注入/PEM),CM-2333 驗收用
  • 模型檔 .build/models/prompt-guard-2/model.onnx 513MB(另有 model.fp32.onnx 1.1GB 是比對用,不入 image,可刪)
  • HF_TOKEN 在決策者本機 ~/.zshrc,188 尚未放

棒 5 裁示(決策者):jedi-common 從閘道核心相依移到 [gateway] extra(jedi d1109b9e);socketio 推分類進度不做、記 followup(memory followup_classify_progress_socketio_push_not_done.md);installer 未在乾淨 VM 實跑,留到上 STG 前在 188 用 install.sh --upgrade 實跑

§2 已定裁示(不要重新討論)

何時 裁示
09-28 優先序:資安(第一階段)→ 補強(第二)→ 成本(第三)
09-28 D1 gateway 與沙箱 client 同一支套件;D2 沙箱改造進第一階段;D3 疑似注入才切 PDF 視覺;D4 規則 YAML;D5 稽核預設 hash 租戶可開完整保留;D6 worker 第一階段只搬分類;D7 開發機沙箱行程內模式
09-28 D8 Prompt Guard 2(非 DeBERTa);D9 LiteLLM library(非 proxy);D10 ONNX Runtime(非 PyTorch);D11 Langfuse 只 DEV
09-28 成本三題:點數計量、原廠鑰=試用額度、硬上限只擋 AI 呼叫
09-29 成本改美金制推翻點數:每租戶+每人美金額度(金額+日/月週期)任一超就擋;每分鐘次數搬進閘道統一管;設定獨立「AI 額度」頁(自有能力點 ai-quota.read/update);預設租戶 5 USD/日、每人 1 USD/日、20 次/分;額度直接 SUM ai_call_log(不建 Redis 計數器)、日曆日伺服器時區;分類送出前預估超剩餘 1.5 倍整批擋;license limits 只預留不做(客戶可自帶鑰,SaaS 再做);用量頁與呼叫紀錄合併兩分頁。全文 design §3.2/§5.18
09-28 #16 離題攔截補進棒 3
09-28 通則:討論任何 FR 前必查開源輪子(memory feedback_fr_design_must_survey_open_source_first)
09-28 本 arc branch feature/ai-guard
09-29 第二階段只做 .8+.9;.7/.10/.11 劃掉不做。第三階段成本討論另棒平行進行

§3 下一步

✓ arc 已收口。下列為收口當刻的殘留清單,已全數搬進 SUMMARY §9 與 memory followup_fr122_leftovers,此節不再維護。

1.22.0 已出包並在 190 全新安裝驗過(CM-2363 卡末 runner 回報 #3 有全文)。出包鏈這棒修了 12 支 commit(BE 11+jedi 3,皆 push main),根因與修法見 LOG 本棒 block。

  1. 合 main+push 出包 已完成;CM-2363 等決策者驗收收 Done
  2. 190:FE 對齊 已與 STG 同包;license 要重新匯入(備份在 190 ~/backups/pre-1.22.0-reinstall/license_raw.txt,machine-id 未變、綁 STG 鑰 04b1e65f,應可直接用);Agent stack /srv/guidant-ai-agent 要重新 enroll。setup-token sudo guidantai setup-token 取
  3. 188 STG install.sh --upgrade 已完成(21:31,先停 api 再升;備份 backup/guidant_ai-pre-1.21.0-20260930-213121.sql.gz)。剩 design §7.1 9 手測(分類中 restart guidant-api 不中斷)→ 收 CM-2293。189 POC 等放行 POC 已升(23:00,備份 backup/guidant_ai-pre-1.21.0-20260930-225529.sql.gz)
  4. e2e 補測(test repo,另開卡)——不擋
  5. spec-site 快照肥大另案討論(1.23.0 切版前必解)
  6. 出包 SOP 結構性問題另案:smoke 預設連 STG stack 與「出包前不准套 STG」矛盾,本棒用「從 STG 唯讀 dump → 25432 臨時庫 guidant_ai_smoke_1220 補套 → cm_app 連」繞過,應寫進 scripts/build/README.md;PROD 簽章鑰仍缺(客戶交付前必補)
  7. 清理(等裁):188 .build/bundle/guidant-ai-1.22.0.tar.gz.BAD-compose-socketio-inprocess、25432 guidant_ai_smoke_1220、.build/bundle/ 20GB 舊包

待決策者裁的產品面問題(未裁,不擋收尾):

  • 「標記」級(0.8~0.95 照送打旗)要不要改成先問使用者/當放行/當阻擋
  • 紀錄頁原文保留開關(D5 租戶層)要不要提前做
  • 儀表板遮罩後拒答仍花 token:可在 gateway_rules.yaml 加 format 規則直接 block
  • 小幫手前端未接注入警告(後端有回 needs_review,只儀表板顯示)——FE 小卡
  • 平台預設租戶額度要不要改每月 20 USD(決策者 09-30 提過、裁先不動)

§4 待辦與風險

  • 第 3 棒揪出的五個缺口(CM-2330~2333)全部修完驗過收 Done
  • 已知不修:主專案 middleware 印整個 request body,儀表板 prompt 含身分證仍在 log/app.log 找得到(決策者 2026-09-03 裁記錄不修,memory followup_be_logs_request_body_plaintext_credentials)
  • 推測,待 verify:design.md 撰寫者自補的數值(回覆抄原文門檻 40 字、session_id ^[A-Za-z0-9_-]{8,64}$、worker 心跳 30s/租約 300s/重試 3、分類並行 3、沙箱並行 2、CALL_LOG_RETENTION 每日 03:00 清)——決策者未逐一裁,runner 照做,驗收時若不合理再調
  • 出貨基線已重產(CM-2355,2026-09-29 晚,決策者放行):188 基線庫套進 FR-122 五支、三個產生檔重產(BE e1e79dd5d 1382fa225)、守衛 test_host_capabilities_are_seeded 綠。備份 ~/backup/guidant_ai_baseline_20260929_2320_before_CM-2355.dump。「FR-114 十餘支未進」是虛驚(seed 類或已 converged)。stamp gate (c) 段套件攤平在本機因 path dependency 紅,出 image 用正式 pin 時重驗
  • jedi 套件 pin:棒 2 開發期主專案 pyproject.toml 走 path dependency 不 commit;arc 收尾前要還原 pin(發版等決策者明示)
  • Prompt Guard 2 模型檔:不入 git,ONNX 轉檔腳本在 scripts/build/;實測只量化詞彙表版 513MB(.build/models/prompt-guard-2/model.onnx)。188 尚未放 HF_TOKEN,上 STG 出 image 前要放
  • 記憶體比 design 大:閘道常駐實測 1.5GB(design 寫 400MB);靠 gunicorn preload_app 共用一份(實測 4 worker 從各 530MB 降到 42~268MB)+installer worker 上限 8→4。落地版規格建議改最低 16GB/建議 24GB(尚未改進規格文件)
  • 兩 repo 平行 commit:棒 2 同時動套件 repo 與 BE repo,驗收要對兩邊 git log
  • 三環境:只動 DEV;STG/POC 等第一階段整體驗收後決策者放行

§5 Pre-flight(必跑,唯讀)

cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git branch --show-current            # 必須是 feature/ai-guard,不對停下問
git status --short                   # 預期只有 poetry.lock/pyproject.toml 未 commit(path dependency,正常)
git log --oneline -8

cd ~/Projects/Jedicogy/module/jedi-python-package/jedi-ai-gateway && git branch --show-current && git status --short && cd -
cd ~/Projects/Jedicogy/module/jedi-python-package/jedi-evidence-classification && git branch --show-current && git status --short && cd -

for c in CM-2298 CM-2313 CM-2314 CM-2315 CM-2316 CM-2317; do
  python3 scripts/notion_case.py get $c --props-only | grep -E '^狀態|^任務名稱'; done

# 沙箱要改的四支檔還是不是原封不動(照這份 STATE 寫的行數比對,行數若已變表示有人動過)
wc -l ~/Projects/Jedicogy/module/jedi-python-package/jedi-evidence-classification/docker/{container_entrypoint,classifier_service,llm_clients,prompt_guard}.py

psql -h localhost -U cmmgr -d guidant_ai_dev -Atc "select table_name from information_schema.tables where table_name in ('ai_call_log','background_jobs')"   # 密碼查 .env DB_SECRET

§6 環境座標

  • DEV DB:本機 localhost:5432 guidant_ai_dev,帳號 cmmgr,密碼查 .env(DB_SECRET)
  • 現行分類容器(將改造成 sandbox):POC 189 /srv/guidant-ai 的 guidant-classifier(image evidence-classifier:1.4.1);BE guidant-api 已裝 LibreOffice
  • 金鑰解析器:app/system_config/service/ai_provider_key_resolver.py;DB 內金鑰為 Fernet 密文(AI_PROVIDER_ENCRYPTION_KEY,三環境容器內皆有)
  • jedi 套件源碼:~/Projects/Jedicogy/module/jedi-python-package/
  • Notion CLI:scripts/notion_case.py get|status|append;建卡 scripts/notion_create_case.py;token 查 .env NOTION_API_TOKEN

§7 行為規範提醒(本 arc 相關)

  • 首腦只派工/驗收/裁決,不自己寫 code;派工=Notion 卡已存在(28 張都在);subagent 必帶 model 參數
  • 判定 branch 一律當下 git branch --show-current,不信 session 開頭快照(本棒教訓,見 LOG)
  • 只動 DEV;migration 走 sql-migration skill;jedi 套件走 path dependency 不 commit path、絕不發版推 Nexus
  • 各 repo 分開 commit、顯式 git add、不 push(決策者本人)
  • 驗收要實打端點/開檔核對,不信 runner 自報(DI 簽章漂移是靜默的)
  • 長工作收工發 terminal-notifier

§8 不在本期 scope

  • 第二階段(租戶出境開關、供應商揭露頁、殘留驗證、啟動檢查、供應鏈鎖定、license 補登 resource_type、SSP/框架匯入接沙箱)
  • 第三階段(點數配額)(已結案,見 §3 第 1 點)
  • 其他長工作搬 worker(框架 PDF、SSP 匯入、同步)
  • STG/POC 部署
  • Langfuse 架設(DEV 用,runner 想用可自架,不是卡)

§9 給 fresh session 的短 prompt

給「驗收派工中心首腦」角色接手(若決策者要換回協調者模式)

你是 FR-122(AI 閘道與檔案沙箱)的驗收派工中心首腦,只派工、驗收、裁決,不自己寫 code。
請讀 docs/features/FR-122-2609-ai-gateway-and-sandbox/handoff/FR-122-STATE.md 全文,照 §0 讀序讀完 design.md 指定節與母卡 CM-2293,答 §0.4 自檢四題,跑 §5 pre-flight(唯讀)。
讀取與盤點完成後不做任何事——不派工、不跑測試、不改檔——回報①自檢答案②現況盤點(含 CM-2338 狀態、jedi 工作區未 commit 檔)③待辦已就緒,等我下指令才開始作業。
第一階段程式已全數收卡;本棒主題是 §3 第 1 點「成本討論」(第三階段),走 big-feature-workflow 出討論稿,先從換算表怎麼定談起。

給「執行者續棒」接手(2026-09-30 23:00 中繼,延續出包/部署收口)

你接手 FR-122(AI 閘道與檔案沙箱)1.22.0 出貨收口,角色是「執行者」:自己動手在 188/190 操作,不派卡、不開 subagent。
先讀 docs/features/FR-122-2609-ai-gateway-and-sandbox/handoff/FR-122-STATE.md 全文(重點:檔頭表、§3)+ FR-122-LOG.md 最後一個 block(「第 6 棒 — 執行者」含兩段「續」)+ Notion 卡 CM-2363 全文(python3 scripts/notion_case.py get CM-2363,runner 回報 #3~#5 是本棒紀錄)。
現況:1.22.0 出貨包在 188 /opt/guidant-ai-be/.build/bundle/guidant-ai-1.22.0.tar.gz(sha 0f788947…,--skip-prod-key-check 內部測試包);STG(188)與 190 都已用它 install.sh --upgrade --force 對齊,BE commit 62a864e62、8 服務全綠。三 repo main 已 push(BE e305b049c、FE 3826339、jedi 017d12cb)。
唯讀 pre-flight:本機三 repo git status 乾淨且等 origin/main;188/190 `docker ps` 五個 guidant 容器 1.22.0 健康;`curl -sk https://<host>/api/1.0/version` 回 62a864e62。盤點完停下回報,等決策者發令。
待決策者裁/發令的事(STATE §3):①手測「AI 服務設定先存 A 家再只填 B 家儲存,A 要保留」與 design §7.1-9「分類中 restart guidant-api 不中斷」,過了收 CM-2363→CM-2293;②190 license 重匯(備份在 190 ~/backups/pre-1.22.0-reinstall/license_raw.txt)與 Agent 重 enroll;③~~189 POC 升級~~ 已完成;④188:25432 臨時庫 guidant_ai_smoke_1220 留或刪;⑤README 補「smoke 用臨時庫」SOP、PROD 簽章鑰交客戶前必補、190 沙箱 image 若要重建注意 deb.debian.org 慢。
紀律:三環境已同包,再動 189 仍要決策者當次放行;升級前先 compose stop guidant-api guidant-socketio;push 本 arc 已授權;收尾類(母卡 Done/SPEC/memory)等令。