這份是 living 檔:每棒就地 Edit,只描述「此刻」。歷史脈絡看同資料夾的
FR-173-LOG.md。
| 項目 | 值 |
|---|---|
| 最後更新 | 2026-11-05 上午(CI 首腦第 4 棒:第一次正式發版完成——主系統 1.29.0、Agent 1.6.0 都由 Vault 正式章自動發布;190 主系統已從更新中心升到 1.29.0;Agent 直接部署跑通;三條路兩邊都驗過) |
| branch | feature/FR-172(五個 repo,與 171/172 共用;決策者 2026-11-02 裁) |
| 母案卡 | CM-3462;CM-3463~3467 Done、3468 D-1 暫緩;第二輪 CM-3481~3483、第三輪 CM-3485~3492、第四輪 CM-3494/3495 全部驗收通過待確認(等決策者 Done);3484 由 v2.0 取代 Done;url 見 handoff/notion-cards-*-made.json |
| 本棒角色 | FR-173 CI 首腦(接手者讀「🔴 此刻(2026-11-05 上午)」那段;文件首腦讀「📨 第五批」) |
| 接手前必讀 | 🔴 design-v2.0.md(完整設計,取代 v1.0 design.md)、本檔「設計 v2.0 已定案」段、vault-status.md、FR-167 release-runbook.md |
這節寫一次,之後各棒不動。
決策者 2026-11-01:「我看一定要我主本機去簽章,我想把這個 secret 放到 gitlab secret 讓他自己去簽有機會嗎?因為這應該是要自動化的。」「release note 以及最小相容版本應該可以放在 CI 前的欄位。」「主系統/agent 的 CI 要分開;前端也是。」「CI 應該是準備出版的最後一步了。」
目標:BE、Agent、FE 各一支活的 CI;蓋章從 Mac 搬到自架 Vault(鑰匙拿不出來、CI 用 GitLab 短效身分要簽名);建置期祕密進 Vault。排在 171/172 之後,開發不受影響。
冷接自檢(讀完能答再開工):①蓋章為什麼不放 GitLab 變數、也不用雲端 KMS?②1.29 用 Vault 簽,為什麼機器不能跳過 1.28.0?③6 張卡分 3 批,批 1 兩張開工前決策者要先做哪兩件事?④11-03 新增的 --internal-test/--skip-prod-key-check 略過 SBOM,跟 CI package 段的關係是什麼?
| 項目 | 狀態 |
|---|---|
| design.md | 11-03 修訂定案(D10~D13、時序圖 §2、決策者功課 §5、時程 §7 約 2 工作天),6 張卡 3 批 |
| Notion | 已開卡未派(handoff/gen_notion_cards.py 產;批 1 V-1、C-3/批 2 C-2、C-1/批 3 C-4、D-1),未建工作坊 |
| 前置案 | FR-171、172(含 172.1)、174 皆結案 Done;五個 repo 都在 feature/FR-172。190:主系統 1.28.3、Agent 1.5.5(測試章簽、已上站);189 POC 仍 1.27.x |
| Vault(192.168.50.172) | 已架:2.2.1、5 取 3、swap 關、稽核開、Transit ed25519 鑰 guidant-release(kid 05086455d42ca0d6,三個 false)、jedi 管理者帳號、root 已撤。全部細節見 vault-status.md |
| Vault 待補(決策者自己做) | 每日快照+異地備份、防火牆——決策者裁先開發,正式出版前一定要補 |
| Vault 公鑰 | 已隨 1.28.0 進 BE scripts/installer/release-keys/ 與 PROD_KIDS(FR-172 S-4);1.29 改用 Vault 簽時機器不能跳過 1.28.0 |
| Vault 待補(決策者做,卡開工前) | 只能簽章的開發帳號(V-1 前);GitLab OIDC 角色、建置期祕密進 KV、188 信任 CA(C-1/C-2 前);確認 docker runner(C-3 前) |
| 裁示 | 何時 | 誰 |
|---|---|---|
| 自架 HashiCorp Vault Community(不選 OpenBao:功能同、文件少;內部出版用 BSL 不受限;日後要換指令與 API 相同) | 2026-11-01 | 決策者 |
| 不選 GitLab Secrets Manager:公司是 GitLab 免費版,它要 Premium,且只存祕密不開放簽章 | 2026-11-01 | 決策者 |
| 不選雲端 KMS(不支援 Ed25519,要換演算法改三處驗章)、不把私鑰貼 GitLab 變數(反模式)、Cloudflare 無 KMS | 2026-11-01 | 決策者 |
| 專用 VM 192.168.50.172,apt 裝 systemd 服務,不用 docker;單節點 | 2026-11-01 | 決策者 |
管理者帳號名 jedi;只有決策者一人管;解封鑰匙 Apple「密碼」3 把+離線紙本 2 把 |
2026-11-01 | 決策者 |
| 快照、防火牆先不做,先開發 | 2026-11-01 | 決策者 |
| 本案排在 171/172 之後;1.28.0 不等本案、Mac 手簽先出,本案跟 1.29(2026-11-02 改裁);1.28.0 包內先附 Vault 公鑰(FR-172 S-4 做),1.29 才能換章 | 2026-11-01、11-02 | 決策者 |
| update-center、License Center 不進出版管線 | 2026-11-01 | 決策者 |
feature/FR-172(9c363ab)。部署 Worker 時決策者要:後台「印章」登記 05086455d42ca0d6 為 primary;Cloudflare Access 放行 GitLab 打 /admin/releases/*/publish。release-dev(只能簽測試章)、14.3 測試章公鑰只在 190、14.4 JWT、14.5 五筆 KV(逐欄與 188 比對一致)、ci-fe+fe-ci。feature/FR-172(eb63f95c)、已推;GitLab 實跑 pipeline 3022544900 通過:test 綠(78 檔 584 條)、vuln-scan 綠(Critical 0)、lint 黃(397 條既有錯誤,allow_failure)。實跑前補了兩處設定:FE 專案「CI/CD configuration file」原指 .gitlab-ci-terraform.yml(C-3 刪掉的舊檔)→ 決策者清空;188 未信任 Vault CA(runbook 第 11 段從沒做過)→ 決策者裝上。ci-release/ci-test 政策、release-ci/test-ci 角色(都綁 user_id=21126655);GitLab BE、Agent v* 受保護 tag(Maintainers)、FE job token 允許清單已含 Agent。C-3 驗完、V-1 改 Done 後工作坊派第二批。 4c. ✅ 188 上 BE、FE、Agent、jedi-python-package、update-center 五個 repo 都在 feature/FR-172(決策者要求,jedi 原在 feature/FR-139 快轉 40 個 commit);update-center 推上 GitLab 並 clone 到 /opt/update-center;FE C-3b 推上。C-1/C-2 共用 188 主機鎖 /home/jedi/.guidant-build.lock(resource_group 不跨專案)、蓋章工具在 188 用 node 容器跑 /opt/update-center 的 CLI。 4b. ✅ jedi 群組 runner:決策者在 commonservice3 註冊 188-guidantai-build-jedi(id 58355505,188 shell、tag guidantai-build)。首腦讀 gitlab-runner list 時遮罩失效,188 兩個 runner 的認證 token 印進對話紀錄 → 決策者 2026-11-03 14:47 UTC 在 188 跑 gitlab-runner reset-token --all-runners 重設,兩個 runner 讀回仍在線、token_obtained_at 已更新。/opt/guidant-ai-*/.env 的 License Center token、~/.fr167-r2.env、~/.npmrc、BE 專案 GitLab 變數裡的 R2 與 Bugsink;到 License Center 換新 token 放進 Vault(188 runner 以 jedi 跑,任何 job 都讀得到那些明文,含 FE 每次 push 的檢查)。⚠️ 這節是建議清單,不是執行授權。接手方讀完盤點完即停,等決策者發令。
🔴🔴 設計 v2.0 已定案(2026-11-04 下午,決策者裁;CI 首腦從這段開始讀)
決策者審系統說明時判定 v1.0 流程把「發給測試機」與「正式發給客戶」混在一起、正式發版要人介入五次,違背本案「自動化」目的。重新定案,完整設計在 design-v2.0.md(完整文件,不必對照 v1.0)。三條路,各一個入口、各自參數:
| 路 | 觸發 | 檢查 | 終點 |
|---|---|---|---|
| ① 正式發版 | 推受保護 v* tag |
測試+弱掃全跑;rehearse 勾才演練(主系統、Agent 都可選) |
自動發布給客戶,沒有手動 publish job |
| ② 直接部署 | 任一 branch,target 可複選 190/STG/POC |
不跑測試與弱掃、不簽出版章 | install.sh --upgrade(Agent:guidant-agent-compose upgrade)直接裝 |
| ③ 測試版發布 | 任一 branch | 不跑測試與弱掃;測試金鑰簽 | 登記成只有內部三台看得到的草稿,到該台更新中心按更新(取代決策者 Mac 的 publish2.sh) |
與下方舊段落衝突時以本段為準:
deploy_e2e.sh 與 deploy_agent_e2e.sh 解除只准 190。v1.0「測試金鑰只放 190」的前提不是決策者裁的,作廢。deploy-stg/deploy-poc(正式包尾端自動部署)與 environment 參數刪除;直接部署改走 ②。deploy_only 併入 ②(reuse_bundle)。release.yml/deploy.yml/test-release.yml)。卡片影響:批 4(CM-3481、3482、3483)不受影響,照常。CM-3484 由 v2.0 的 CI 改寫取代,決策者會在狀態頁按「這張不用做」。
✅ CI 首腦已拆卡(2026-11-04 下午):第三輪 8 張卡 CM-3485~3492、2 批(底表 handoff/cards_r3.py,產卡 gen_notion_cards_r3.py)。批 4 與 CM-3481/3482/3483 同批(共 8 張,全部不同檔):U-1 更新站規則/B-2 BE 腳本/A-2 Agent 部署腳本/A-3 Agent 登記腳本/F-1 FE 不刪映像;批 5:B-1 BE CI 三條路/A-1 Agent CI 三條路/U-2 後台離線檔連結。決策者拆卡前裁三件(寫在 cards_r3.py 檔頭):①正式發版一個動作=Run pipeline 選受保護 tag(不是推 tag 觸發);②Agent 演練樣本 db 放 188 .build/rehearse/agent-<舊版>.db,第一份決策者從 190 匯出;③離線檔連結沿用 presignDownload。§7.3 前置已寫進 U-1/B-1/A-1 卡。批 4 八張 2026-11-04 下午全部驗收通過(update-center 173+99 測試本機重跑綠;Agent 合回時 README 工具表撞檔,首腦兩邊保留解掉)。批 5 分流寫法定案 include 層+inputs 下拉(已 append CM-3490/3491),等決策者放行批 5。
文件:writing-technical-docs skill 已完成(.claude/skills/writing-technical-docs/);系統說明 出版管線總覽.md 尚未照 v2.0 重寫(文件首腦負責,等 CI 改完實跑後一起改)。
deploy_e2e/deploy_stg/deploy_poc(不用逗號字串),job 清單見 FR-167 release-runbook.md 步驟 2~4。📨 CI 首腦 → 文件首腦(2026-11-04 下午):拆卡時與 v2.0 文字有出入、或文件還沒寫到的事,更新 design-v2.0.md/出版管線總覽.md 時請一併對齊
v* tag」。實際做法是 在 GitLab Run pipeline 選那個受保護 tag(可填 rehearse/rehearse_base/fe_ref)。原因:推 tag 觸發的 pipeline 沒有參數畫面,三個參數只能用預設;且 FE 沒有同名 tag,fe_ref 預設「同名」會找不到。打 tag 本身交給 version-bump 流程。「人工只有一步」不變,只是那一步是 Run pipeline 選 tag。BE/Agent 的 workflow:rules 維持只收 web/api 觸發。.build/rehearse/agent-<舊版號>.db,第一份由決策者從 190 現行版匯出,之後每次 Agent 進版順手留一份。主系統演練吃的是 STG 唯讀 dump,Agent 沒有對應來源,這是補的規則。presignDownload(src/releases.ts:195,R2 預簽 15 分鐘網址,客戶主機下載安裝包就是走它),後台版本詳情多回一個 offline_download_url。不新增金鑰、不新增機制。文字可寫準成「後台取得 15 分鐘有效的預簽下載網址」。target 多選(v2.0 §4.9 表「可複選」):GitLab spec.inputs 沒有多選型別。B-1 卡讓小弟在「options 單選+逗號分隔字串」或「三個 boolean」擇一並回寫理由;文件寫 pipeline 參數表時等 B-1 合回看定案再寫。spec.inputs.pipeline 下拉(release/deploy/test-release,預設 deploy),include: 用 rules: 在主檔分流、一次只載一支路的子檔(common.yml 無條件;三支路各認自己的值且排程不載;vulndb.yml 只在排程);子檔內的 job 不寫「我是哪條路」的規則。受保護 tag 檢查留在 release.yml verify+Vault 角色。子檔放 .gitlab/ci/:common.yml(既有 .vault/.sync_repo/.in_repo/.collect)、release.yml、deploy.yml、test-release.yml、vulndb.yml。v2.0 §4.9 寫「依觸發方式與一個 PIPELINE 變數分流」——實作是 inputs 下拉不是手打變數;只提三支子檔,實際五支。build-be 第一次在 GitLab 上就通(Vault test-ci 登入、188 編譯鎖、Nuitka 813 秒、smoke 自動改走臨時庫、出映像)——總覽 §8「待實跑」那幾列可以更新成已驗;fe-pipeline 失敗真因是 trigger:branch 不吃 job rules:variables 設的變數(與 inherit.variables 無關),總覽 §排錯那列的「原因」要改。guidant-seaweedfs unhealthy 的根因(如果總覽有「出事怎麼辦」段要收):healthcheck 的 busybox wget 走 https 每 5 秒 fork 一個 ssl_client,PID 1 是 weed 不收屍,約 3 天撞滿容器 pids 上限後 docker exec 開不了行程、永遠 unhealthy,服務本身活著。修法 CM-3483 在主系統 compose 加 init: true+pids_limit(Agent compose 早有)。症狀判準:docker exec 回 procReady not received+dmesg fork rejected by pids controller。暫時清法 guidantai restart guidant-seaweedfs --force(不 --force 會被「設定比容器新」守門擋)。handoff/cards_r3.py(ren/why/accept 三欄);CM-3484 已由本輪取代。📨 第二批(2026-11-04 傍晚,批 5 合回+實跑後)
lint(allow_failure)被 strategy: mirror 鏡射上來,九個 job 全綠——排錯表可記一列「直接部署顯示 failed 但 job 全綠」。FE 映像實測「取本機」(D11 生效)。e963812e6):Run pipeline 多一個 input note(只對測試版發布有效,500 字內)。有填→當唯一一條版本說明;沒填→讀 release note 檔尾;都沒有→送空並警告,照常登記。正式發版不變(缺說明就擋)。v2.0 §4.9 參數表、圖 5 第「登記版本」步要補;R2 寫的是正式發版,不受影響。0b394862c):直接部署、測試版發布時,BE 映像多標 src-<最後改到程式的 commit>(排除 docs/.gitlab/.gitlab-ci.yml/test),188 本機有就跳過 Nuitka(省約 17 分)。正式發版不吃這個判斷、永遠重編。skip_be 仍保留、優先。§6.3/6.4 的時間估計可補一句。/admin/* 要過 Cloudflare Access(80163cb56/Agent be85eb5):決策者裁用 Service Token(不用 Bypass)。CI 請求多帶 CF-Access-Client-Id/Secret,存 Vault kv/ci/update-site 的 cf_access_client_id/cf_access_client_secret;Access 應用程式加一條「服務驗證」原則選 token guidant-ci。更新站程式收到 Authorization 時只認那個憑證、不看 Access 給的身分,所以程式不用改。v2.0 §6.6 角色表的 kv/ci/update-site 欄、§6.1 架構圖「登記版本、發布」那條線、§7.3 前置作業都要補這件;系統說明的機敏資訊表多一項(Service Token,有到期日要換)。version_already_published(1.28.3 是 11-03 Mac 測試章發布過的)。今天改用 1.28.4 跑通(BE f7fbfe495、FE 60a8a8cc)。X.Y.Z-beta.N(semver 寫法,不用 PEP 440 的 b1——更新站只認 semver),正式版就是 X.Y.Z,兩者永遠不撞。v2.0 §4.8「測試版發布只能用尚未正式發布的版號」要改寫成這個規則;卡合回前先別改文件,記一筆待改即可。/etc/machine-id 相同:190/188/189 主機指紋同一個 ff793254…a080,更新站內部主機清單登一筆即三台都認;但升級回報會互蓋。1.29 前要重生(見 §4)。系統說明「內部主機清單」那段要寫明現況與限制。05086455d42ca0d6 尚未登記,正式發版自動發布會被 kid_not_registered 擋。屬 §7.3「正式出 1.29.0 前」既有項,系統說明前置清單確認有列。📨 第三批(2026-11-04 晚,批 6 合回+直接部署改一次一台)
f3454d5e4/Agent 79090be):三個勾選框 deploy_e2e/stg/poc 換成單選 target(e2e/stg/poc,預設 e2e)。理由:一條 pipeline 動三台不好追蹤、紅了要猜是哪台。換下一台勾 reuse_bundle 不重建。v2.0 §1 表「190/STG/POC(可複選)」、§4.9 參數表、§8 驗收 #6、#16b 都要改成一次一台;runbook 已改。target=poc 時部署 job 是 manual,pipeline 跑到那步停下等人按 ▶ 才升級。說明文字已改白話。X.Y.Z-beta.N(CM-3494/3495 已合回):主系統與 Agent 測試版發布的第一步就擋不帶 -beta.N 的版號;正式發版帶 -beta 會擋。寫法只收 semver(1.29.0-beta.1),PEP 440 1.29.0b1 當格式錯。排序 beta.1 < beta.2 < … < 正式版,beta.10 > beta.9 數字比;主系統升級(upgrade_common.sh)、Agent 升級(upgrade_order.sh)、主系統判 Agent 包新舊(package_verifier.py,既有)、更新站(versions.ts)四處一致。v2.0 §4.8 改寫成這個規則(第 14 點的「待改」現在可以改了)。note 欄位(CM-3495),與主系統一致。b72f2b8、bec2019):① build_console_dist.sh 內 FE 弱掃摘要印在 stdout,污染了 FE_CONSOLE_DIST 路徑;② docker build --output type=local 把 dist-console 建成 700,包進映像後 uid 1000 讀不到,啟動防竄改檢查拒啟。1.5.5 以前主控台在 Mac 打包所以沒遇過。系統說明排錯表可收這兩條。📨 第四批(2026-11-04 夜,Agent 測試版發布跑通+主控台重套 bug)
agent/v1/1.5.6-beta.1/ 全過,更新站 D1 已核。系統說明「三條路驗到哪」更新:主系統 ②③ 已驗、Agent ③ 已驗(發布端),① 正式發版兩邊都還沒跑。????,建置斷言判失敗——deploy/Dockerfile.runtime 加 LANG=C.UTF-8、PYTHONIOENCODING=utf-8(Agent 502b6a2;客戶 docker 主機也可能沒 locale,所以修在映像);④ 蓋章 CLI 對 Agent 一律要求 --bundle 產離線檔,測試章也不例外——改成測試章不產、帶了就擋,正式章才要求(update-center 56aa2bf);⑤ Agent 上傳 R2 用 aws cli,188 只有 rclone——改同主系統用 rclone(Agent b1ebe7e)。系統說明排錯表可收這三條;②(dist-console 權限 700)與③ 的共通原因是「主控台前端改由 188 docker 打包、CI runner 沒有登入 shell 的環境」,可寫成一段。1f8878e86):core/plugins/_agent_console_update.py request_update 判同版重套時沒看更新站有沒有新版。主系統手上包=Agent 現行版、且同版重套開關開著(內部三台都開)時,一律走 reapply,「下載新版再推」那條永遠走不到。190 實踩兩次(audit action=reapply target_version=1.5.5)。修法:reapply 多加「更新站沒有相容又更新的版」。正式機開關關著不受影響。系統說明排錯表要收:症狀=主控台顯示「更新到 X」,按下去進度視窗標題卻是現行版號;判準=主系統 app.log 的 AGENT_UPDATE_ROLLOUT_CHANGED action=reapply。主系統更新中心 Agent 區的推送走另一條路(agent_rollout_service),沒有這個問題。-beta.N;Agent 已是 1.5.6-beta.1。RELEASE_NOTES.md 段落標題要與版號完全相同(## 1.5.6-beta.1),否則讀不到該段(測試版說明選填所以不會擋,但畫面會沒說明)。出版管線總覽.md 可以開始照 v2.0 重寫:主系統 ② 直接部署、③ 測試版發布與 Agent ③ 都已實跑,這三節可用實際紀錄寫作業程序與排錯;① 正式發版那節留空待實跑(要先進版 1.29.0、更新站印章表登記正式章——目前是空的)。📨 第五批(2026-11-05,第一次正式發版:主系統 1.29.0、Agent 1.6.0 都已發布)——文件首腦照這批改系統說明
v1.29.0=8c3d1d930)、Agent 1.6.0(Agent pipeline 3029934137,tag v1.6.0=2d936a2);更新站兩筆都 published、kid 05086455d42ca0d6(Vault 正式章)。Agent 離線檔第一次產生,與安裝包一起在 R2 agent/v1/1.6.0/。系統說明檔頭狀態、§2.3「待實際執行驗證」、§8.1「印章表目前是空的」都過期,要改。§8.1 標題「正式出 1.29.0 前必須完成」改成「正式出下一版前」,還沒做的幾項留著(Vault 快照與防火牆、三台 machine-id、189 POC 升 1.28.x 以上、STG/POC 測試公鑰與同版重套、188 明文憑證)。20261105-0254-efae),容器全 healthy、前門與 API 200。這是第一次用 Vault 正式章簽的包在客戶機驗章。[audit] ❌ 找不到 pip-audit | poetry sync --without dev 把 dev 群組(含 pip-audit、pip)刪了 | 拿掉 --without dev(BE 517b19ea2) | | FE 下游 test 584 條全過卻判紅,insertBefore of null | UpdateCenter.spec 沒 unmount,遺留的 3 秒輪詢在 188 忙時觸發;整檔跑超過 3 秒才會紅 | 測試清畫面前先 unmount(FE 8f9b55ff) | | package [vuln-gate] ❌ Critical … ruby 3.4.10 | CINC 自帶 Ruby,弱點資料 11-02 才收錄;測試版發布不掃映像,所以到正式版才看到;CINC 最新 7.3.4 仍帶 3.4.11 | 白名單(BE 8c3d1d930 be 列、2a23805cf agent 列;image 欄只收單一值,be/agent 各一列;Agent 的關卡讀 188 /opt/guidant-ai-be 的白名單,Agent 發版前 188 BE 工作樹要含那一列) | | package 掃描段無訊息退出、be-image.cdx.json 0 byte | 188 硬碟滿(剩 3.7G);syft 解映像沒空間 | 清 188 舊安裝包到 44G,只 retry package(不重編) | | register-publish 停在 git fetch -q --tags origin | 188 本機留著移動前的同名 tag(would clobber;另有 v1.16.0/v1.23.0/v1.24.1 三個舊 tag) | 188 fetch --tags --force 後 retry;CI 加 --force(BE 58feaeb19、Agent efc9409) | | Agent verify 守衛 5 條紅 | ① zap.py 模組層鎖(真違規,11-02 加的)② FR-166 守衛掃到 188 .build/bundle/stage/(8.1G 解開的舊包)③ config/version_bake.py 是產生檔 | 鎖收進 services();守衛排除 .build 與產生檔(Agent efc9409) | | Agent verify pip-audit 擋 37 條 | Agent 第三方套件落後主系統一大截(cryptography 45、PyJWT 2.13、flask-cors 5…);測試版發布不跑 verify,所以從沒在 CI 跑過 | 升到主系統已用的版本(Agent 199ab1c) | | Agent verify 用舊套件跑 pytest(會假綠) | 188 的 .venv 共用,verify 前沒人同步 | verify 先 poetry sync --with dev、宣告 pytest 為 dev 群組、verify 加 Vault 登入(Agent 8392172) |FE_VERIFY=1);直接部署、測試版發布的 FE 下游只建映像(BE 58feaeb19、FE 5e2c736c;決策者 11-04 裁,理由:push 頻率太高)。打 FE tag 因此不會再跟 BE 下游撞。2d936a2;原本只跑 FE 套件弱掃)。.venv(第 30 點最後一列)。glab api -X DELETE projects/<專案>/repository/tags/<tag>(git push --delete 被 GitLab 擋);刪除 API 可能回 400「Failed to remove tag」但實際已刪,先 git ls-remote --tags 查遠端再重打。只在更新站上還沒有這一版時才移 tag。/opt/guidant-ai-agent/.build/release-archive/1.6.0/(直接部署會在 .build/compose/ 產同名測試包蓋掉正式版)。feature/FR-172=2d936a2,target e2e,約 19 分:build 16、部署 3)。190 Agent 容器 guidant-ai-agent:1.6.0 healthy;啟動防竄改「完整性驗證通過(249 個檔案)」;mTLS 8443 起來;心跳打主系統 200;主系統 remote_agents 看到 agent_version=1.6.0、last_seen_at 11:19;主控台 8444 有回應。等於 Agent 1.6.0 的套件升級(cryptography 50、PyJWT 2.15、flask-cors 6、opentelemetry 1.45)在真機上跟主系統握手過。系統說明三條路驗證表 Agent ② 可標已驗。✅ 文件首腦已依第五批更新系統說明(2c4faea03)。Agent ② 直接部署在系統說明寫「實跑中」,結果補上後再更新。
📗 文件首腦交棒(2026-11-05 中午)——下一棒文件首腦從這段開始讀
本棒(文件首腦,2026-11-04~05)做完的:writing-technical-docs skill;設計 design-v2.0.md 定稿並收齊 CI 首腦第 1~27 點;系統說明 docs/system-design/release-pipeline/出版管線總覽.md 照 v2.0 重寫、再收第五批(ee94f1473、2c4faea03)。詳見 LOG「文件首腦」block。
下一棒兩件事,讀完盤點完先回報、等決策者發令再動手:
A. FR-173 文件收尾(小)
update_ticket,License Center 另簽,只含授權編號、指紋、主版號、kid,不含客戶名稱;D9),沒有票的舊主機才送授權檔原文。來源:BE app/product_update/service/update_site_client.py _identity、product_update_flow.py _host_identity;update-center src/licenses.ts 檔頭、src/routes/client.ts authenticate(驗章 → 比對指紋 → 查拒絕名單 license_denied;不看授權到期日)。兩處都改。B. 更新站系統說明(新,主工作)——決策者 11-05 要求
update-site-spec.md(Worker 規格與架構,410 行)、update-site-schema-spec.md(D1 資料表,329 行),兩份都停在 2026-11-01,沒有 FR-173 的改動;開頭還寫「轉交決策者在自己電腦簽好的清單」,已不是現況。update-center repo 只有 README.md(72 行,開發者筆記)與 cli/README.md(簽章 CLI)。docs/system-design/update-center/(比照 release-pipeline/:README.md front matter+主文件+diagrams/),照 writing-technical-docs 系統說明骨架,以 update-center repo feature/FR-172 現行程式碼為準重寫。FR-167 兩份原檔不動(FR 歷史),只在 FR-167 站 README 補一行指到新文件。update-center repo 的 README/cli README 留原地當開發者入口,主文件連過去。/v1/check、/v1/download-url、/v1/report、/healthz;後台 /admin/* 共 21 條路由,src/routes/admin.ts 的路由表):每支寫誰呼叫、身分(授權/身分票、Cloudflare Access、CI token、GitLab ID token、Access 服務憑證)、request/response 欄位、錯誤碼、主要流程畫循序圖;②資料表 schema(migrations/0001~0006.sql,10 個 CREATE TABLE,含 internal_hosts、product 欄、agent_version_reports):每張表欄位、鍵、誰寫誰讀;③專案架構(src/ 各檔責任、cli/ 簽章工具、public/admin.html 後台、wrangler.toml 綁定、部署方式、環境變數名稱——值不寫)。-beta.N、預簽下載)→ 資料表 → 組態與機敏資訊 → 已知限制 → 故障排除(錯誤碼對照)→ 重建。update-site-spec.md、update-site-schema-spec.md、update-center-api-spec.md(主系統端,只引用不重寫);FR-173 design-v2.0.md §4.3~4.8、§6;出版管線系統說明 §4.3、§4.4、§6.3。python3 scripts/deliverables/render_index.py --site-root docs/system-design/update-center docs/system-design/update-center。紀律:只改文件,不碰 update-center 程式、Worker 部署、D1、更新站後台;查 wrangler.toml、.env 只印有沒有、鍵名、長度,不印值;系統說明本文不寫 commit hash 與沿革;顯式 git add;push 前 fetch 確認 CI 首腦沒有新 commit;對決策者回報一律白話。
🔴 此刻(2026-11-05 上午)——CI 首腦第 4 棒
三條路驗到哪: | | 主系統 | Agent | |---|---|---| | ② 直接部署 | ✅ 3025779481、3026701936(190) | ✅ 3030035264(190,1.6.0 內容;心跳、mTLS、主系統看到在線) | | ③ 測試版發布 | ✅ 3026010775(1.28.4) | ✅ 3026549240(1.5.6-beta.1) | | ① 正式發版 | ✅ 1.29.0 已發布(3027235959) | ✅ 1.6.0 已發布(3029934137) | | 正式章簽的包在客戶機驗章升級 | ✅ 190 1.28.4 → 1.29.0 | ⏳ 走直接部署(不驗章);Agent 從更新中心升正式版留到下一版 | | 演練 rehearse | ❌ 沒跑過(188 沒 1.27.0 包;預設起點該改成 1.27.10) | ❌ 沒跑過(188 沒樣本 db) |
190:主系統 1.29.0(從更新中心以正式章升級);Agent 1.6.0(直接部署的內部測試包,同 commit 2d936a2)。188:BE 工作樹 feature/FR-172;剩約 19G。
GitLab 畫面標 failed 但 job 全綠:Cloudflare Pages webhook 把文件站建置狀態掛到 commit 上;成敗看 job 清單。之後可在 Cloudflare 停掉或加 branch 過濾(決策者決定)。
待辦(等決策者排):version-bump skill 改寫(已寫好未 commit,等 Agent 直接部署結果一起);第一步預檢(Vault、更新站、憑證、第三方安裝檔弱掃提早到第 1 分鐘);每日自動掃 188 最新映像(只報告);188 自動清舊安裝包;映像掃描改平行;188 docker 建置快取與舊映像標籤清理;FE v* 設受保護 tag;演練起點改 1.27.10;Agent 演練樣本 db。
✅ 2026-11-04 傍晚實跑結果(主系統):② 直接部署 190(3025779481)成功;③ 測試版發布 1.28.4(3026010775)登記草稿+上 R2 成功,190 從更新中心按更新 → 下載 3.3GB → 測試章驗章 → 八步升級 succeeded,190 現為 1.28.4、全部容器 healthy。更新站 instance_version_reports 的 current_version 已是 1.28.4,但 last_upgrade_* 仍是舊的(1.28.1→1.28.2),升級結果回報可能下次檢查才送——下次回來先核;三台同指紋讓這張表有多列互蓋,判讀不準(見 machine-id 那條)。Agent 三條路尚未實跑。下一步:放行批 6(CM-3494/3495 預發版號)→ Agent 直接部署與測試版發布實跑。
✅ CI 打更新站 /admin/* 被 Cloudflare Access 302(2026-11-04 撞到、當天解):決策者裁用 Service Token(不用 Bypass),Access 應用程式加「服務驗證」原則 guidant-ci,憑證存 Vault kv/ci/update-site;BE/Agent publish_draft.sh 帶 CF-Access-Client-* header。Service Token 有到期日(決策者建立時選的期限),到期 CI 會再 302,要在 Access 後台換新並更新 Vault 兩欄。
🔴 內部三台 /etc/machine-id 相同(2026-11-04 首腦登內部主機清單時發現):190/188/189 是同一範本複製的 VM,sha256(machine-id)=主機指紋三台都是 ff793254…a080。更新站、授權綁定、Agent 心跳的主機身分都用它,三台在更新站眼裡是同一台:內部主機清單登一筆即三台都認(這次反而方便),但 instance_version_reports 以 (license_id, fingerprint) 為鍵,三台升級回報會互蓋。決策者裁:先不動、跑完今天驗證;1.29 正式出版前另開卡重生三台 machine-id(systemd-machine-id-setup),要同時重簽三台授權(綁指紋)、更新站內部主機清單改成三筆,排在沒人用 STG/POC 的時段。
已裁(11-03):出包時就蓋章、GitLab job 身分發布(V-1 擴大到 Worker)、測試包模式+Vault 測試章 guidant-test;發版起點是 GitLab Run pipeline。
GitLab 免費版限制(已補進卡):secrets:、needs:project 都是付費版;改 id_tokens+script 內登入 Vault、CI_JOB_TOKEN 打 API 拿 artifact。trigger: 跨專案免費版可用,用 strategy: mirror。
runner 現況:188 shell runner(id 56998011,tag guidantai-build,群組級 auditmanager);docker runner 只有一台(id 37407054,tag docker,17.0.0,只註冊給 FE 專案,不在 188,主機待決策者確認)。jedi 套件在 commonservice3 群組,沒有可用 runner。
11-03 出包腳本變動(FR-172 收尾,已推 feature/FR-172;C-1/C-2 開工前要知道):
scripts/build/build_all.sh:帶 --skip-prod-key-check 時略過 ⓪a、⑦ 兩次 SBOM/弱點掃描(09308ef5d)。CI rehearse 段直接呼叫 build_bundle.sh、不經 build_all.sh,不受影響;package 段照舊全掃。scripts/build/build_bundle.sh:封包改 tar | pigz(沒裝退回 gzip,09308ef5d);釘版第三方 image 的 docker save 檔以 image ID 快取在 .build/image-cache/(9c1539491)。CI runner 每次乾淨工作區的話快取不生效,要生效得把 .build/image-cache/ 放在 runner 的持久目錄。scripts/build/build_all.sh/build_compose_bundle.sh:新增 --internal-test(略過 Step 3b 弱點關卡,70ec3d2);seaweedfs 匯出檔快取(cd3a1f9)。C-2「build_all.sh 加 CI 模式旗標」要與它併用,不要另開一個意思相同的旗標。--internal-test 15 分 52 秒(原 19 分 30 秒);主系統完整 build 51 分,其中 Nuitka 約 19 分、封包壓縮約 13 分、SBOM+弱點掃描約 9 分。Nuitka 在 188 本來就沒開 LTO,--lto=no 無效。測試期手動出版仍在用:Mac ~/Projects/Billows/Audit-Manager/.fr167-dev/publish/publish2.sh host|agent <版>(測試章簽、R2+D1,不入版控)。1.28.x 正式版不出,正式章/Vault 簽的第一版是 1.29(本案)。
🔴 Vault 沒快照:172 壞了這把章就沒了(Mac 備用章還在,但要出一版換 kid)。
188 /opt/jedi-python-package 原本的 git 網址內嵌一把 GitLab 個人 token(glpat-),2026-11-03 曾印進對話紀錄。已處理:188 改走部署金鑰 Build-188-STG(唯讀)、決策者已撤銷那把 token、本 session 與另一個 BE session 的對話紀錄檔已就地遮掉。
舊對話歸檔(BE repo docs/conversation-history/ 6 份、security-scan-consolidated 1 份,2026-04~05)與 FE 兩份對話紀錄裡另有 glpat- token(非這次那把),待決策者確認是否已撤銷。
Harbor 帳密 kv/ci/harbor 是共用的一組,能推 guidant-ai 專案底下任何映像、任何 tag。test-ci、classifier-ci 都不綁 ref(決策者按的任何 branch 都拿得到),所以決策者在別人推的 branch 上按測試包或觸發 jedi,那個 branch 的程式碼就能推(或蓋掉)Harbor 上任何映像。資安自動檢查 2026-11-04 提出(通用的最小權限建議,不是本專案 .claude/rules/security/ 或 SR 的要求)。決策者裁:先不處理,每個映像一個帳號太多。日後要補,優先只開 Harbor guidant-ai 專案的 tag 不可覆寫(一個設定,擋住既有版本被蓋掉;我們推的 tag 都帶 commit,不影響流程),不建 robot 帳號。
🔴 V-1 publishSignedDraft 寫入只核對 kid:檢查到寫入之間同 kid 換包會發布 190 沒裝過的包。修法:WHERE 加 sha256、signed_manifest。正式模式「發布」實跑前要修(CM-3463 卡尾)。
188 兩個 GitLab runner 的認證 token(glrt-)2026-11-03 曾印進對話紀錄,已重設(gitlab-runner reset-token --all-runners,舊 token 失效)。歸檔對話時仍把 glrt- 開頭字串遮掉。GitLab 網頁沒有重設 runner token 的按鈕,以後要換一律在 188 跑這行。
第一個 root token 曾貼進對話紀錄(已撤銷、失效);兩個 jedi token 也曾貼出(已撤銷)。歸檔這段對話時要把 hvs. 開頭的字串遮掉。
vault-ca.key 還在 172 /opt/vault/tls/,手冊建議複製到保管處後刪除,決策者未做。
只有一個管理員:Apple ID 單獨湊得滿 3 把解封鑰匙;有第二人時重分。
# 四個 repo 都在 feature/FR-172、本機=遠端
for r in compliance-manager-be compliance-manager-fe evidence-agent update-center; do git -C ~/Projects/Billows/Audit-Manager/$r fetch -q origin; echo "$r $(git -C ~/Projects/Billows/Audit-Manager/$r branch --show-current) ahead=$(git -C ~/Projects/Billows/Audit-Manager/$r log --oneline origin/feature/FR-172..HEAD | wc -l) behind=$(git -C ~/Projects/Billows/Audit-Manager/$r log --oneline HEAD..origin/feature/FR-172 | wc -l)"; done
# 跑到一半的 Agent 測試版發布
cd ~/Projects/Billows/Audit-Manager/evidence-agent && glab api "projects/auditmanager%2Fevidence-agent/pipelines/3026300590/jobs" | python3 -c 'import sys,json;[print(j["name"],j["status"]) for j in json.load(sys.stdin)]'
# 190 版本
ssh jedi@192.168.50.190 'sudo -n guidantai status | grep -m1 版本; docker inspect guidant-ai-agent --format "{{.Config.Image}}"'
# 更新站兩條線最新幾筆(唯讀)
cd ~/Projects/Billows/Audit-Manager/update-center && npx wrangler d1 execute guidant-update-center --remote --json --command "SELECT product,version,status,kid FROM product_releases ORDER BY created_at DESC LIMIT 6"https://192.168.50.172:8200(網頁 /ui,登入方式 Username);SSH jedi@192.168.50.172,sudo 要密碼。/etc/vault.d/vault-ca.pem。vault-setup-runbook.md、現況 vault-status.md。hvs. 字串)不進文件、不貼 Notion、不進 repo。vault status、或決策者已登入留下的 token 做唯讀 lookup)。