append-only;每棒追加一個 block,寫完不改
做了什麼
從決策者一句「本體跟 agent docker 都有改成 rootless 嗎」開始。查出 FR-180 只做到容器內非 root、引擎仍是 root,當時刻意不做 rootless。決策者改判要做。寫討論稿、design v1.0~v1.4、十張卡、Agent 主機手冊(Claude Docs)。工作坊跑完 A0~A8。之後首腦親手:分析正式發版各關卡、合回 ws-CM-3804、在 188 出測試包、協助決策者在 192 用真包首裝、把 16 個維運指令逐一驗過並修掉抓到的問題。
commits
BE(feature/FR-172,都已推):80ff36282 討論稿 → 49ee845c6 D4 → 8976dabd6 design v1.0+cards.py → 5363671c1 v1.1(D1 改 8443)→ 9c5f3091b v1.2(D8)→ da36b6d20 → cbe63588f 開卡 → 495d360e6 → bf9e8cdb6 v1.3(A0 實測後 D9~D11)→ ce2b1cf56 v1.4(A4~A6 合併)。
Agent(feature/FR-172,都已推):工作坊的 A1~A7(0d466da bcae205 e6d261d 9a9588f 88a19ac 0dbcd41 46b4703 87b712c bdb2ea5 cd9fbdf f73d523)、合回 62c23c3,之後首腦親手六個:
| commit | 修什麼 | 起因 |
|---|---|---|
710467e |
部署/演練/健康檢查三支腳本找對 Docker daemon | FR-193 漏掉 |
3ff9fa9 |
映像落地檢查在完整輸出裡找通過訊息,不只看最後 30 行 | FR-188 讓啟動輸出變長 |
9d6f577 |
包內容檢查不用「大輸出 | grep -q」(pipefail 下 141) | FR-193 讓清單變長 |
753e4e2 |
離線裝 Docker 不碰主機 systemd:不用 machinectl、包內不帶 systemd 一組、裝前驗相依 | 真包首裝第一步就失敗 |
cd54c60 |
沒填主系統時完成步驟不空等 90 秒 | 註冊改到主控台後沒收乾淨 |
b0efcba |
升級驗章改用 docker cp,不掛主機目錄 | rootless 下 daemon 進不了 root 700 目錄 |
未 commit:deploy/install.sh 的 uninstall 修正(見 STATE §1)。
決策
DOCKER_HOST 指到 guidant 的 daemon,不用 sudo -u guidant。後者讓 image_read_file、升級 docker load、--env-file 都 permission denied。/usr/local/lib/guidant-agent/install-lib,不以 root 去 source guidant 映像庫裡的腳本。ping_group_range。拿掉 NET_RAW 連 ping 都起不來。machinectl,改 sudo -u 加 XDG_RUNTIME_DIR 與 bus 位址。192 實測可行,重開機後不登入也會自己起來。build_all.sh --with-compose --internal-test,不走 GitLab 直接部署。後者會自動裝到 190/188/189,那三台系統層 Docker 上有主系統,新版安裝程式會拒絕。教訓
= 版號 的相依會壞。 連網機用 apt 驗不出來,apt 會連帶升級。離線路徑一定要離線驗。tail -N 或「大輸出 | grep -q」是定時炸彈。 輸出變長才壞,而且壞的時候產物是好的。cmd_uninstall 仍把載入綁在「讀得到映像名稱」上,wipe 之後整段還原沒執行卻印「移除完成」。wipe 之後容器應該還在(實際設計就是整個刪)。git stash 把別人未提交的檔一起收走。 當場用完整 hash apply、比對一致後才 drop,沒有遺失。檢查用的指令不要夾帶會改工作區的動作。.venv 建置中不可動,另開獨立環境時記得指定 Python 3.11,預設會拿到 3.13。推翻了什麼
dk() 用 sudo -u guidant、「compose 拿掉 NET_RAW」、uid 換算「起點 + N」(實際是起點 + N − 1)。machinectl shell 啟用 rootless、必備套件含 systemd-container。怎麼不重編譯重出包(188,/opt/guidant-ai-agent,先 git pull、pgrep -af 'nuitka|build_all' 確認沒人在建)
改動只在 scripts/、deploy/、test/ 時編譯產物不變(git diff --name-only <編譯時的 commit> HEAD 核對)。安裝程式會被簽章並進映像,所以從打包那步重跑:
B=/opt/guidant-ai-agent/.build
export FE_CONSOLE_DIST=$B/console/dist-console
scripts/build/build_agent_bundle.sh $B/dist/evidence-agent-1.7.4
scripts/build/smoke_agent_bundle.sh $B/bundle/guidant-agent-1.7.4.tar.gz
scripts/build/build_all.sh --compose-only --internal-test約 12 分鐘。fetch_docker_debs.sh 有改動時要先把 $B/docker-debs 移開,否則沿用舊快取。主控台前端要重建時:FE_REF=feature/FR-172 NPMRC_FILE=/home/jedi/.npmrc scripts/build/build_console_dist.sh $B/console。
正式發版各關卡(2026-11-10 實測)
套件弱點稽核通過;前端測試通過;映像弱點關卡通過(用更新後的判定程式,Agent 只擋 Critical,白名單 7 條命中、30 天內無到期);編譯、簽章、冒煙六項通過;全量測試 2555 過但環境是 Python 3.13。會擋的:版號仍是已發過的 1.7.4、版本說明未寫。
16 個維運指令在 192(rootless)的結果
正常:status logs fingerprint --help stop start restart reset-admin-password console-allow-cidr configure-storage。可執行但沒有主系統只驗到「失敗時不弄壞」:set-base-url re-enroll。upgrade 原本壞、已修(b0efcba)。console-login 壞、未修、非 rootless 造成(CM-3868)。wipe 正常。uninstall 在 wipe 之後不還原主機設定,修正未驗完。
交接文件寫完後把做到一半的 uninstall 修正收掉:Agent 3ea579d,已推。
第一次請決策者在 192 重跑 uninstall 時被 resolve_installed_paths 擋下(安裝目錄已被前一次刪掉,「看起來還沒安裝過」),沒走到修正。這暴露修正本身的漏洞:印「移除未完成,請再跑一次」但再跑會被拒。補 host_leftovers_exist,主機有殘留就放行只清殘留。第二次重跑後上機核對,帳號、rootless Docker、設定檔、升級單元、主機副本都清掉,系統層 Docker 恢復 enabled。
教訓:修「失敗時叫人重試」的訊息前,先確認重試那條路走得通。 以及確認題可以用答 no 的方式試跑到提示出現為止,不必真的刪,就能驗「有沒有走到那一段」。
本棒 Agent 親手 commit 共七個:710467e 3ff9fa9 9d6f577 753e4e2 cd54c60 b0efcba 3ea579d。