FR-184 交接紀錄(LOG)

append-only。每棒收工追加一個 block,寫完不改。現況看 FR-184-STATE.md。


§1

第 1 棒|首腦|2026-11-07~11-08

做了什麼

  • 需求探脈:compose 十服務、installer、FR-065 §4.8 K8s 預留、FR-173 直接部署、saas 模式影響面、189/190 實測記憶體
  • 費用實查(不是記憶值):Google 定價頁前端渲染,用 test repo 的 Playwright 無視窗切台灣區抓;AWS 抓定價頁背後官方 JSON;DO/Hetzner 官方頁。GCP 台灣 16 GB 約 144/月、8 GB 約 82;K8s 正統約 290、高可用約 770
  • 討論稿 → 設計 v1.0 → cards.py 驗批 → 開卡 CM-3643~3651(八張六批);新 repo guidant-ai-infra 骨架並登記進工作坊
  • 引導決策者完成:GCP 專案、帳單、API、state bucket、Cloudflare 權杖、Brevo、Turnstile 小工具、Origin 憑證、Secret Manager 12 個、SSL 嚴格規則
  • T2 親手 apply:24 資源、VM 35.194.213.124,真機驗開機腳本與防火牆,寫 runbook
  • 架構圖(mingrammer diagrams,GCP 官方圖示),補上客戶地端 Agent 區塊

commits:BE db989fcc3~811a9ba44;infra 7ec4f3a~08c67b6(含小弟 T1 93e0287)。11-08 決策者授權後兩 repo 都已 push(infra 新建遠端分支)。BE 這次 push 夾帶另一 session 的 01fb1289e+b0cc9b321(CM-3653 加開關又撤回,淨效果零),推前已核對

決策(理由在 design §3)

  • VM 不 K8s;8 GB;host 模式;Turnstile 必開;密碼自帶;序號裝完才貼;SSL 只對單一主機名嚴格

教訓

  • 費用要實查:首輪憑記憶報價錯四處(DO 沒有 4 核 16 GB Basic、Hetzner 新加坡缺貨且 4 核只到 8 GB、AWS 台北比東京便宜而非貴、GCP 台灣比美國貴 14%)。決策者原話「你要確認啊,不然幹嘛請你評估」
  • Model 欄留空擋不住工作坊:T2 被派給小弟、等人回答 3 分鐘後工作坊整個暫停。已記 memory,首腦親手的卡要開成「暫緩」
  • 第一個 GCP 帳單帳戶被 Google 風控關閉:重建帳單帳戶與專案才過。apply 前先看 billingEnabled
  • Cloudflare 免費方案「設定規則」在下拉選單的「Configuration Rules」,左側選單的「設定」是另一個功能;欄位要選「主機名稱」不是「完整 URI」,否則規則永遠比對不到
  • pbpaste 搭指令時不要用 Cmd+V 貼指令,剪貼簿會被指令文字蓋掉

推翻了什麼

  • 討論稿 D2「Turnstile 先關」→ 決策者推翻,改必開(加 F1/T4)
  • 討論稿 D3 建議 16 GB → 決策者裁 8 GB
  • 首腦一度要決策者預先放 License 序號 → 決策者指出沒機器碼不能開通,更正為裝完才貼
  • 設計 §5.2「從快照還原 License 不用重開」→ T1 小弟實查不成立(machine-id 在系統碟、vTPM 換機解不開),列 O1 待解

交出時:1.30.0 包 11-08 10:57 已在 188 出好,T3 前置齊了,未開始裝。


§2

第 2 棒|首腦|2026-11-08

做了什麼

  • 冷接盤點:pre-flight 全綠(GCP、Secret 12 個、VM 空機、網址 521、188 有 1.30.0 包、Terraform 無漂移)
  • 決策者問「雲端版也走線上更新嗎」→ 盤點更新中心與直接部署兩條路,建議主路改線上更新(待裁,記 STATE §4)
  • 追 Turnstile 時發現原 F1/T4 做法有兩個洞:升級會把 FE 蓋回關閉版,且前門 CSP 根本會擋 Turnstile 的 script 與 iframe
  • 決策者裁「有填 key 就開」並要首腦直接改:BE a108ab505、FE f95a85b8,已 push
  • F1 CM-3650、T4 CM-3651 卡上寫取消理由;T3、V1、母卡補說明;design、README、STATE 更新

決策

  • Turnstile:兩把都填真 key 才開(Cloudflare 測試 key 視同沒填),TURNSTILE_ENABLED=false 可強制關;後端驗 token、/setup/status、前門 CSP 三處同一判定(common/util/turnstile_state.py)
  • key 放 compose .env(GUIDANT_TURNSTILE_SITE_KEY/_SECRET_KEY),不放 guidant.env:前門要 site key 決定 CSP,compose 只能從 .env 插值,且不能把整份 guidant.env 掛給前門
  • 沿用既有未登入端點 /setup/status 帶 Turnstile 狀態,不另開 API(登入頁本來就會打)
  • 升級健康檢查:Turnstile 開著時接受 CAPTCHA_400001,只在 /setup/status 說開著時才放寬
  • 舊機器 guidant.env 的 TURNSTILE_ENABLED=false 升級時不自動刪:客戶可能有意強制關,沒填 key 本來就是關
  • admin 後台設定之後另做

教訓

  • 「要另出一顆 image」的方案先檢查前門擋不擋:F1/T4 開卡時只查了 FE build 與 BE 開關,沒看 nginx CSP,方案本身就開不起來
  • build 時寫死的開關搭配會被升級覆蓋的產物,等於每次升級都要人補一步:同一包靠執行期設定切換才是對的形狀
  • 首腦這棒自己動手改主產品,是決策者當次明示(「你直接改」),不是常態

推翻了什麼

  • design v1.0「程式零改動」→ 主產品改了 Turnstile 開關
  • design D2「F1 出 build:CLOUD、T4 換雲端 FE image、每次升級後重跑」→ 取消,改有填 key 就開
  • design §5.2「先寫 /srv/guidant-ai/.env 再跑 install.sh」→ 走不通(install.sh:933 看到 guidant.env 或 certs/server.key 就停),改 install.conf;這點第 1 棒 STATE §3 已發現,本棒同步進 design

交出時:BE、FE 已 push。188 上 10:57 的 1.30.0 包不含 Turnstile 改動,T3 要等重出包。

  • 同棒追加:決策者裁「升級走線上更新,出包我自己跑」。design D8 改為平常走更新中心、只收正式發版,P1 直接部署定位救火用;§5.3、§8 第 7 項、兩張架構圖標籤同步。P1 CM-3647、母卡補說明。雲端版機器指紋不登記內部主機清單、不加 PRODUCT_UPDATE_ALLOW_SAME_VERSION,寫進 STATE T3 步驟 8
  • 同棒追加(13:20~14:05):T3 系統裝好。決策者重出 1.30.0(13:09)→ 開包核過含 Turnstile 改動 → 188 直接 scp 到 VM → Mac 組 install.conf → --check-only → 安裝。踩三個坑:①Ubuntu 24.04 要先 apt 裝 tpm2-tools(--check-only 不擋、正式才擋,記 §4 另開卡)②vulndb 檔 600,容器 uid 1000 讀不到,第⑥-3 步失敗;根因 188 的 zstd 1.4.8 從 stdin 寫檔一律 600,457f2964a 修出包腳本;VM 上 chmod 644 後 GUIDANT_REUSE_EXISTING_INSTALL=1 重跑通過 ③手跑出包沒帶 DEFAULT_UPDATE_SITE_URL,guidantai config edit 補 UPDATE_SITE_URL。另:決策者 Secret Manager 的 db-admin 與 db-app 原本同一組,首腦指出後決策者換了 db-app。裝完換 Origin 憑證、外驗 200/Turnstile enabled/CSP 放行/直打 IP 擋;installer 自產九組回寫 Secret Manager;VM 家目錄安裝包刪除(先查過無容器與單元參照)
  • 教訓:手跑出包與 CI 出包有差異(DEFAULT_UPDATE_SITE_URL 只有 CI 帶),用手跑的包裝正式環境要對照 CI 變數補;讀含祕密的安裝輸出時過濾要以「一行裡的長十六進位」為準,不要只過濾標籤(設定碼單獨一行,本棒漏過濾印進對話,一次性、已用途內,影響小)
  • 同棒追加(14:05~15:30):T3 完成——決策者跑設定精靈(Billows tenant 3、另建 Jedicogy tenant 4)、License 開通、Brevo 填好測試信寄出成功(/mail/test 200)。首腦另做:①出包權限根因查到底——包內 19 檔 600,只有 vulndb 掛給容器讀會壞,9086e8ad8 改接既有 dist_perms.sh 整包正規化+斷言(188 實包+guidant-ai-be:1.30.0 端對端驗:600 讀不到、644 讀得到),已 push;決策者要出 1.30.1 帶上 ②預算告警 Terraform(infra 724e9c0),第一次 USD 回 400——帳單帳戶是 TWD,改 6,500 TWD 成功 ③查清楚雲端連更新站不需 Zero Trust token(Access 只守 /admin/*,/v1/* 靠 LC 簽的身分票+指紋驗章);更新站 /v1/* 沒有限流,建議 Cloudflare 加一條(未做) ④郵件與儲存設定的多租戶行為(寫進 STATE §4)
  • 教訓:STATE 裡「等某張卡出新版」這類依賴要開工前實查——本棒照 STATE 說「Agent 接雲端要等 CM-3654」,被決策者問才去查,修正早已含在 Agent 1.7.0 並發佈;跨 session 的依賴狀態會過期,回報前 git branch --contains/git tag --contains 一下
  • 決策:雲端版 Billows(安裝精靈建的總部)留給自家用,外部試用客戶另開租戶——host 模式下總部管理員能改全站寄信/LDAP;根治在 saas FR
  • 同棒追加(15:30~16:00):決策者要求「安裝後手動處理」能進自動化的都做、併 1.30.1 出。主產品 b3b21a950:--check-only 與正式安裝共用「出貨包 tpm2-tools 適不適用這台」判斷(只修誠實度,不改成自動連網 apt——installer 只裝本地檔);infra 8194fb0:開機腳本預裝 tpm2-tools、時區走 metadata。Origin 憑證刻意不進開機腳本(VM 服務帳號不該讀私鑰;升級會保留),寫進 runbook。手動處理清單 10 項,剩重建 VM 時的憑證與 188 known_hosts
  • 同棒追加(16:00~17:20):1.30.1 經更新中心線上更新成功(發版 session 發、決策者按更新,首腦監看八步;健康檢查在 Turnstile 開著時通過)。決策者覺得慢,實測拆解:VM 內 API 80~130 ms、外部 0.65~1.3 秒,差額是 Cloudflare 分到 SJC 繞路;升級後記憶體用 6.2/7.75 GB(三個後端各載一份 AI 守門模型約 1.5 GB)、CPU pressure 28%。決策者裁升 e2-standard-4(infra 5fe59da):先 guidantai stop 再 apply,重開後手動 guidantai start;VM 內降到 17~24 ms、CPU pressure 4%、可用記憶體 9.4 GB。Cloudflare 靜態檔快取:雜湊檔已在快取、固定檔名的主題檔有 4 小時舊版風險,決策者裁先不動、看客戶反應
  • 教訓:升級中與平常的資源數字差很多——首腦先依決策者在升級中截的 htop(後端全停、851 MB)說「記憶體完全沒壓力」,服務起來後實際 6.2 GB,當場更正。判規格要在服務穩定後量

第 2 棒 commits 總表(交出時補)

  • BE(本棒):a108ab505 Turnstile 有填 key 就開、457f2964a+9086e8ad8 出包整包權限正規化、b3b21a950 installer tpm2-tools 判斷一致;文件 b8365df40、0a6cd990c、3fa60590c、b250ffca0、33272a8e6、79049c878、7c2c531c7
  • BE(發版 session,1.30.1):0134d23f5 進版、f2066a58c 正式發版帶預設更新站網址、2aeb13257 弱點白名單
  • FE:f95a85b8 登入頁問後端決定 Turnstile+前門 CSP;d9b1221d 版號 1.30.1(發版 session)
  • infra:724e9c0 預算告警、8194fb0 開機腳本補時區與 tpm2-tools、5fe59da 升 e2-standard-4、7caae4a Terraform 導讀

推翻了什麼(第 2 棒)

  • design D2「F1 出 build:CLOUD、T4 換雲端 FE image」→ 取消,主產品改有填 key 就開
  • design D8「升級走 CI 直接部署」→ 平常走更新中心,P1 改救火用
  • design D3/T1「e2-standard-2 8 GB」→ 決策者 11-08 裁升 e2-standard-4(三個後端行程各載 AI 守門模型,8 GB 平常就用到 80%)
  • 首腦說「CI 正式發版會帶 DEFAULT_UPDATE_SITE_URL」→ 實際 CI 變數名與出包腳本讀的名字沒對上,發版 session 在 1.30.1 才修(f2066a58c);雲端 VM 的 UPDATE_SITE_URL 是首腦手動補的、1.30.1 升級後保留
  • STATE「Agent 接雲端要等 CM-3654」→ 早已含在 Agent 1.7.0

交出時:雲端版 1.30.1、e2-standard-4,決策者先給客戶試用。下一棒 Q&A:決策者要看懂 Terraform 回答 PM,導讀在 infra docs/terraform-walkthrough.md。之後 P1 → O1 → V1。