首腦交接:v1.20.0 出版後(2026-09-15)

前一個 arc(FR-089/090/091/093/094)已完整收尾,五張母卡全收、SUMMARY 落地。 本檔交接的是出版後的收尾殘項,不是未完成的 arc。 arc 全文見 docs/features/FR-089-2609-package-shape-unification/handoff/2026-09-15-arc-SUMMARY.md。

§0 接手讀序

  1. 本檔全部(不長)
  2. 2026-09-15-arc-SUMMARY.md §「已知 follow-up」與§「交付包注意」兩段
  3. 需要細節才開:FR-089-LOG.md 最後兩個 block(第十二任、第十三任)

冷接自檢(答得出來才開工)

  1. v1.20.0 已經出版了,為什麼還要重出一次包? (答:CM-1807 三支套件修正發版後,主專案 pin 跟著改,內容與原本打 tag 那顆不同。決策者裁「還沒給客戶,就用 1.20.0 不跳號」。)
  2. 為什麼主專案的 DI 改動一度是個隱患? (答:b70cc44a 在 DI 傳 identity= 給 SurveyFolderService,但 Nexus 上的 jedi-survey 1.1.1 建構子不收這參數——乾淨環境 poetry install 後啟動會 TypeError。本機看似正常只因 .venv 讀的是工作樹。發 1.1.2 + 改 pin 後解除。)
  3. 這個專案為什麼不能裸跑 poetry update? (答:不帶套件名會更新整棵相依樹,2026-09-15 順手升了 faker/google-api-python-client/pytest-html 等四支第三方套件——那些沒人驗過卻會進安裝包。一律 poetry update <指定套件>。)
  4. 套件在 poetry.lock 裡是 wheel 還是源碼樹?為什麼重要? (答:wheel。Nuitka 編譯吃 wheel 是 build 加速的前提,不可改成 path 形式。pyproject.toml 裡的 path override 全是註解狀態,開發期臨時打開後不可 commit。)

§1 當前狀態(2026-09-15 傍晚)

三 repo

repo branch HEAD 與遠端
BE main cc16f56d pin 三支套件 已推
jedi main 8bc5d27 三支套件進版 已推
FE main 6670c5f 版號對齊 1.20.0 已推

版號

  • 主專案 1.20.0(正式版)、FE 1.20.0
  • jedi 21 支:多數 1.1.0;1.1.1=task-platform/compliance-audit/system-core/issue;1.1.2=common/iam/file-upload/notification/flow-engine/log/remote-agent/survey;oscal-v2 走自身序列 2.4.0
  • 全數已推 Nexus

🔴 tag 狀態(接手第一件要處理的事)

遠端 BE/FE 都有 v1.20.0,但指向的是舊 commit(BE 34d48807),那時還沒有 CM-1807 的三支套件修正。

決策者已裁「刪掉再打一次就好」。等 190 手測通過後執行:

# BE
git tag -d v1.20.0 && git push origin :refs/tags/v1.20.0
git tag v1.20.0 && git push origin v1.20.0   # 推 tag 要決策者明示
# FE 同理

190 部署狀態(已完成)

1.20.0 正式版已裝上 190,六服務健康(guidant-api/socketio/fe 皆 1.20.0)。 升級腳本自動備份了資料庫:/srv/guidant-ai/backup/guidant_ai-pre-1.20.0b2-20260915-174612.sql.gz(3.9M)。

產物驗過(README 規則,從編譯後二進位 grep):get_menu_by_id 3 處、created_user_name 131 處、 GRC_403064 2 處、get_manu_by_uid 0 處(壞方法確實刪乾淨)。

🔴 190 的 MFA 目前是開著的(決策者測試時打開),而 MFA 有缺陷(見下), 該環境登出後會登不回去。要用 190 做其他驗證前,先把 MFA 關掉: 改資料庫 system_configs 的 MFA_REQUIRED,或請決策者在畫面上關。

Notion 卡

卡 狀態
五張母卡(1688/1682/1690/1752/1766) ✅ Done
六張實作子卡 ✅ Done
CM-1807 修正待驗證,等決策者在 190 驗過才收
資安掃描 25 張 修正待驗證(另一個 session 的 arc,不要碰)

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

裁示 何時
還沒給客戶,重出包用 1.20.0 不跳號,tag 刪掉重打 2026-09-15
除了本次修正的東西,其他外部套件都不要動 2026-09-15
角色矩陣不顯示「原廠保留」標籤與 hover 提示,只保留不可勾 2026-09-15
簡體中文錯誤訊息翻譯不補 2026-09-15
跳過自動回歸測試,以 190 實機手測為準 2026-09-15
188 舊交付包只留 tar.gz,刪掉解開的目錄 2026-09-15
資安掃描結果的修正不進 1.20.0,另開 arc 2026-09-13

§2.5 🔴 出版後發現的缺陷:MFA 開啟後登不進去(CM-1808)

決策者 2026-09-15 在 190 開啟 MFA(多因素驗證)後,登入第二關輸入驗證碼送出回 500。

根因已查明(不必重查):jedi-iam/jedi_iam/api/routes/otp_route.py:127 的 「發 token」那一段沒有包提權,而 FR-094 把租戶隔離改成 fail-closed 之後, 登入第二關還沒有身分 → 什麼都查不到 → 下游取 login_name 拿到 None 就炸。 同檔 117 行的「查人」那段有包提權(_lookup_user_before_login),所以是漏了一段不是整支沒做。

不是 1.20.0 這次改動造成的 —— beta.1/beta.2 就存在,只是當時沒開 MFA 沒人走到。 時間點指向 fc1cadb(FR-094.1c/CM-1788「引導型與機器端點接上顯式身分」),那一棒漏了發 token 這段。

修法要先判斷(卡上寫了兩案與首腦傾向,但沒實查過可行性,交接方自行決定): 擴大提權範圍(最小改動但拉大繞過隔離的範圍)vs 驗證成功後先設好身分再發 token(較乾淨)。

卡:CM-1808 https://app.notion.com/p/MFA-500-fail-closed-token-190-3dc346da4cd0814aaa87e1f4005b69bf

§3 下一步(每項都要決策者發令)

  1. 派 CM-1808(MFA 缺陷,建議 Opus medium——根因已查明但修法要設計判斷)
  2. 決策者在 190 手測八件(清單見 §4),通過後:
  3. 收 CM-1807(改 Done)
  4. 刪遠端舊 tag 重打 v1.20.0(見 §1)
  5. 上 STG(188)→ POC(189)——照 release note 第 7 節順序,POC 等同 production
  6. 待決策者裁:資安總表 12 項哪些要修/四支 audit-round 端點要不要退役

§4 190 手測清單(八件)

網址 https://192.168.50.190。先強制重新整理瀏覽器(Cmd+Shift+R)。

🔴 測之前先確認 MFA 是關的(見 §2.5),否則登出後會登不回去。

前五件是回歸確認(beta.2 已測過):

  1. 子租戶管理員 → 新增角色 → 勾「合規框架」→ 存檔應成功,那一列只有「檢視」勾得到、旁邊不該有任何標籤
  2. 最上層租戶管理員 → 同樣操作 → 四個動作全部勾得到、存得起來(改壞這邊比原本的 bug 更嚴重)
  3. 最上層管理員但「隸屬租戶」選子租戶 → 那三個動作應變成勾不到
  4. 停在專案詳細頁 → 切換租戶 → 應回到首頁不報錯;切語系數次後租戶下拉不該有重複項目
  5. 合規資源庫 → 新增 → 套用控制項 → 群組標題應為 Access Control (4),沒有 null

後三件是 CM-1807 新增: 6. 問卷資料夾清單 → 建立者欄位應顯示暱稱(例如「Billows Admin」)而非帳號 7. system-core 選單查詢:沒有對外端點,已由套件測試(241 passed)驗證 8. issue 查無成員:沒有對外端點,已做突變驗證(拿掉修法轉紅、還原轉綠)

§5 環境座標

項目 值
BE repo ~/Projects/Billows/Audit-Manager/compliance-manager-be,branch main
jedi monorepo ~/Projects/Jedicogy/module/jedi-python-package,branch main
FE repo ~/Projects/Billows/Audit-Manager/compliance-manager-fe,branch main
DEV DB localhost:5432 guidant_ai_dev,帳號 cmmgr,密碼查 .env
190 e2e 測試機 https://192.168.50.190,ssh jedi@192.168.50.190(有免密 sudo)
188 build 機 /opt/guidant-ai-be(BE)//opt/guidant-ai-fe(FE),更新走 git pull,禁 scp
Notion CLI python3 scripts/notion_case.py get/status/append/query;建卡 scripts/notion_create_case.py

§6 🔴 188 build 機的三個固定陷阱(每次都會撞)

① build_all.sh --all 直接跑會被 DB 斷言擋下。 預設連安裝版 stack 的 guidant-db——那是 STG,落後好幾支 migration。不要去套 migration(違反環境異動鐵律)。正確做法:

cd /opt/guidant-ai-be && PW=$(grep -m1 "^DB_PASSWORD" .env | cut -d= -f2-)
SMOKE_DB_TARGET=env DB_HOST=127.0.0.1 DB_PORT=25432 \
DB_NAME=guidant_ai_smoke_1200b1 DB_USER=cmmgr DB_PASSWORD=$PW \
scripts/build/build_all.sh --all

② FE image 標籤可能與 BE 版號對不上(beta 版才會,正式版兩邊同形不會)。 封包腳本按 BE 版號找三顆 image。build 過程那行「✔ 版號一致」是綠的也沒用——兩者比的不是同一個東西。撞到就 docker tag guidant-ai-fe:<人看版號> guidant-ai-fe:<Python版號>。

③ 磁碟會滿。 每出一版留約 3.3GB,build cache 不自動清。清法:docker builder prune -f(不要加 -a);.build/bundle/ 舊版只刪解開的目錄、保留 .tar.gz;刪 image 前先 docker ps——188 上跑著 STG stack。

④ 出包後必驗產物(README 規則):

strings .build/dist/<版號>/guidant-ai | grep <該版新增的獨特字串>

回 0 就是沒進去。本次驗的是 get_menu_by_id(3 處)、created_user_name(131 處)、GRC_403064(2 處)、get_manu_by_uid(0 處=壞方法確實刪乾淨)。

§7 行為規範提醒

  • poetry update 一律指定套件名,不要裸跑(見 §0 自檢第 3 題)
  • poetry.lock 裡套件是 wheel,不可改成 path 形式(Nuitka 加速的前提)
  • 不切 branch、不推 push(等決策者明示)、不碰 STG/POC
  • 驗收不採信 runner 自報:自己跑測試、開檔核對、必要時做突變驗證
  • 推翻 runner 時分清「方向」還是「範圍」——2026-09-15 CM-1807 第一項,runner 推翻了首腦卡片上的兩個選項且他是對的(那張表根本沒有 uid 欄位)
  • 文件與 Notion 不一致時兩邊都不可信,去查 git log --grep + 開檔
  • 回報一律白話文,術語首次出現要解釋
  • 派工 prompt 薄(卡號+URL+一句範圍+建議 model),細節進 Notion 卡

§8 交付包注意

🔴 目前的包缺正式環境(PROD)授權簽發公鑰——尚未建立(非故障,套件內只有 dev/stg/poc 三把),封包時以 --skip-prod-key-check 略過。因此不可交付客戶。

要出可交付的包需另行四步:授權中心端產正式簽發鑰 → 加進 jedi-license-runtime 的公鑰表 → 發版 → 重新 build。第一步不在開發端能做的範圍。