FR-170 交接日誌(LOG)

append-only:每棒追加一個 block,既有 block 不改。發現舊 block 有誤,在新 block 的「推翻了什麼」寫明。現況看 FR-170-STATE.md。


§1

第 1 棒|2026-10-29|首腦:分析、四條裁決、開卡、無人值守重檢

角色:首腦(分析決策),決策者雷門。Fable 5.1。

commits(BE feature/FR-139,未 push)

  • 79eff2496 analysis、design、README、架構圖、cards.py/gen 腳本;開母卡 CM-3232+八張子卡 CM-3233~3240。
  • 5396eb110 architecture.html 從提案草圖改成定案版(四條裁決、檔案歸屬)。
  • 981e2f635 全案重檢:文件、建卡腳本、九張 Notion 卡對齊「等 166/166.1/169 收完才開」;首次 build FR-170 站與登記表。
  • 4f1f4b27c P0 改成無人值守可跑完:十張卡八批、套件單卡發 beta、系統身分改每請求裝;重寫九張 Notion 卡、新開 CM-3288/3289。

決策

  • 定位改判:Agent 當獨立產品,模組在外層在內;排除照抄主系統四層、排除換 Postgres、排除維持現狀靠 reviewer。
  • 四條裁決全採建議;命名 guidant-agent;DB 通用範圍定 Postgres+SQLite。
  • 等 FR-166/166.1/169 收完才開(當晚三案收完,立即派)。
  • 無人值守:開發卡發 beta、結案卡轉正式、決策者按結案批即確認套件清單;單卡要人裁的事停下回寫、狀態留 In progress。
  • jedi-remote-agent 1c1cdcd5(事件碼 6230~6236)不單獨發版,等 FR-167 結案卡帶。

推翻了什麼(本棒自己的前稿)

  • 1-2「啟動時裝一次系統身分」是錯的:jedi-common 身分是 ContextVar,Flask 每請求每執行緒各一份;改 before_request+背景入口裝飾器。且 0.0.31 的 DTO 沒有 is_system_context 欄位。
  • 1-1 要改主系統 pyproject.toml 一行:違反一卡一 repo,且主系統自己列了 psycopg,拔掉。
  • 2-1 守衛與 2-2 宿主殼同批:2-2 搬走 core/local_db,2-1 凍結清單立刻過期;改 2-2 先。2-3/2-4 都改 bootstrap.py,拆開。
  • 2-3 手測 sudo ifconfig down:跳密碼、demo 模式不起心跳;改測試模擬+SIGTERM 子行程。
  • 1-3 排練 docker exec guidant-agent:188 容器名是隨機 zen_sutherland,agent.db 是 WAL;改 docker ps 查名、.backup 抓。
  • 1-3 釘 jedi-file-upload 1.3.8:Nexus 現行 1.5.0,差異只選填掛點;改釘 1.5.0。

教訓

  • 重檢時每條假設都開檔核到底,花了一小時,決策者點名太慢。該先列「哪些沒驗會讓半夜停掉」只查那幾條,十五分鐘內回報,其餘寫進卡上「開工先確認」。
  • 完成宣告只 grep 三個詞被退:「整個重新檢視」要逐檔逐卡讀,含 Notion 實際內文。
  • 工作坊帳號 ccy(~/.claude)沒信任過 evidence-agent 主資料夾,bg session 開不起來(Workspace not trusted);信任看 git 主資料夾不看 worktree,決策者在主資料夾接受一次即解。之前 Agent 卡都用 ccy3 跑所以沒踩過。
  • Notion 大量 wipe+rewrite 會 429;notion_case.notion_request 遇 HTTP 錯誤是 sys.exit(1),包裝時要接 SystemExit 並 patch 模組全域。
  • 母卡批次行用 [:34] 硬截會把標題切成「jedi-fi」;改以分號切第一段。

環境實況(當時)

  • Agent HEAD d2fe93f;jedi-common 0.0.31/jedi-file-upload 0.0.22;1,655 測試綠。
  • Nexus 26 支套件版號全在;jedi-remote-agent 1.10.0b1(FR-167)已發。
  • 工作坊 28 已派批 1:CM-3233 In progress(23:38)、CM-3234 In progress(23:40,第三次開成)。

交給下一棒:首腦驗收,見 STATE §4。


§2

第 2 棒|2026-10-30 早|首腦:一夜結果盤點與交接

角色:同第 1 棒 session 續接,首腦。決策者要求「交接首腦工作」。

一夜結果(工作坊 28,無人值守)

  • 批 1(CM-3233、3234)與批 2(CM-3235、3236)四張全部做完,工作坊首腦 session 第 1 輪就驗過,狀態 驗收通過待確認。沒有一張停下來要人裁。
  • Nexus 上三個 beta 都在:jedi-common 1.3.7b1、jedi-password 0.1.0b1、jedi-iam 1.11.0b1。
  • 卡上「無人值守」改法生效:沒有 sudo、沒有等人確認發版、沒有 188 容器名寫死的問題。

卡住的地方(要決策者動手)

  • CM-3236 合回失敗:工作坊把未追蹤的 jedi-password/poetry.lock 當成「改到一半的檔」拒合。卡設計時沒想到工作坊的髒檔判定連 untracked 也算。
  • CM-3235 工作坊 log 沒有合回紀錄,ws-CM-3232 停在 3234 合回那一筆。批 3 依賴它。

工作坊首腦抓到的

  • jedi-iam 測試 4 支舊紅燈(1.10.0 就有),base 同樣紅,不是本案弄壞;建議批 7 前開小卡修。

教訓

  • 工作坊合回的髒檔判定含 untracked 檔。套件卡若會產生 poetry.lock(新套件第一次 poetry install),卡上要寫「lock 加進 .gitignore 或刪掉再回寫」,否則合不回。下次開套件新套件卡要補這句。
  • 卡上寫「首腦照這個驗」時,工作坊會自己開一個首腦 session 照卡驗;本 session 的角色退成抽查與裁示,不要重驗一遍。

commits:本棒只改 STATE/LOG。

交給下一棒:STATE §4。

§3

第 3 棒|2026-10-30 下午~傍晚|首腦:P0 合回主線、兩張補卡、Agent 資安規範、決策者裁暫停

角色:新 session 冷接首腦(決策者「照 §0 讀序與 §6 pre-flight 盤點完回報,等我發令」)。

做了什麼(時序)

  1. 盤點時查出 STATE 寫的「CM-3235 沒合回」其實是被 CM-3236 擋在合回隊列後面(工作坊依驗收時間逐張合、一張失敗整隊停);3236 的髒檔 poetry.lock 盤點當下已不在,按繼續派工就全過。決策者按下後 10:02 兩張同秒合回、批 3 開派。
  2. 工作坊 28 當天跑完 P0 十張+補卡 3290/3291/3292/3304/3305(共 15 張)。
  3. 決策者要求比兩版差異。用合併演練(暫存 worktree 把主線合進重構線、跑全量):無衝突、1781 綠/50 紅——45 紅是本機磁碟剩不到 1GB(主線同紅),5 紅是主線 FR-167 平行加的 core/update_sync.py、core/agent_tree_verify.py 違反 P0 守衛。決策者裁「先合、開卡修」。
  4. 合回:jedi 88ab3b05、Agent 8585e99(commit message 寫明 5 支守衛紅)。開 CM-3314(修守衛)、CM-3315(主系統改釘五支)掛母卡,開卡前查過 FR-170 全部子卡與 FR-167 Agent 側兩張無重複。
  5. CM-3314 小弟做到跨模組 import 停下問(卡上寫白名單只能變短,它沒自己加,正確);原 session failed 等不到回答,首腦回寫裁示到卡、按 resume 讓工作坊重派新小弟接著做。裁示:is_container 就地兩行;→ running_tasks、→ task_executor._get_stream 與 vulndb_sync/profile_sync 同形,進白名單、P1 上移 port 時一起刪。
  6. 兩張做完、工作坊首腦驗過、決策者按 Done。首腦抽查後發現只合到 ws-CM-3232 沒進主線,而 3315 小弟已把 BE 主資料夾 venv 裝成新版、pyproject 卻還是舊 pin;合回主線 Agent 9044d95、BE 36d6d5972,重啟本機 Agent。
  7. 順手修的 FE bug(決策者測到「下載沒反應」):FR-169 CM-3230 把主控台下載改走 useProtectedDownload 後,三處呼叫端 download: () => consoleApi.downloadFile(uid) 多包一層箭頭函式,密碼確認後拿到函式不是回應、靜默結束;Agent log 只見查開關的 /api/me 無下載請求是判斷依據。主線同壞,與重構無關。同 commit 把登入頁「AD」統一成「AD/LDAP」、範例換 EXAMPLE\amy.chen。FE bec490d5,已 push。
  8. 寫 Agent 自己的六支資安規則 .claude/rules/security/(按 Agent 威脅面改寫、不是 BE 複本,每條指向既有 canonical 函式)+覆蓋守衛;CLAUDE.md 加段;BE 總覽表與守衛加 Agent。Agent a6fdf7e、BE 7962f93ea。
  9. 給 FR-167 首腦的通知 prompt(Agent 結構已換、新規則、CM-3314 撞檔警告)已交決策者轉。
  10. 決策者問「後面還有多少」「現在能 work 嗎」「為什麼看起來還是舊架構」:答 P1~P3 規模與三選項、三層行為不變證據(42 條路由相同/1839 綠/本機實測)、P0 刻意不搬業務模組。決策者裁:先發版測 FR-167 線上更新,FR-170 暫停。

教訓

  • 工作坊「合回被拒」會卡住整個合回隊列,後面的卡看起來像「沒合回」其實是在排隊;盤點時先看隊列順序再判。
  • 決策者按 Done 的卡只代表合進工作坊線,不代表進主線;首腦抽查要多看一步 ws-<母卡> vs feature/FR-139。本棒就是這樣抓到 BE venv 與 pyproject 對不上。
  • 主 repo 的卡(Repo 欄空)小弟直接在主資料夾的 venv 裝套件,會影響決策者正在跑的 BE;開主 repo 的套件卡要在卡上寫「裝完提醒 BE 重啟」,本棒卡上有寫。
  • 比兩版差異用合併演練+全量測試+路由 diff,一次收齊;決策者點名前一天逐檔讀太慢。
  • 平行 FR 在主線加的新檔會撞新立的守衛,合回前要跑一次守衛預知紅燈數,不要等合完才發現。
  • 守衛新 paths 預留未來目錄(guidant_agent/<模組>/)時,覆蓋守衛要放行空命中,不然 P1 前一直紅。

commits:BE 7962f93ea、36d6d5972、本棒交接;Agent 8585e99、a6fdf7e、9044d95;jedi 88ab3b05;FE bec490d5(已 push)。其餘未 push。

交給下一棒:STATE §4。

§4

第 4 棒|2026-10-30 晚~10-31 下午|首腦:P1~P3 設計開卡、無人值守跑完、總驗收、合回主線

角色:同第 3 棒 session 續接,首腦。

時序

  1. 決策者裁「先設計 P1」→ AST 掃 49 支 core 檔的跨模組邊,identity/sync 真正要抽 port 的只有三種(audit()、LOCAL_ADMIN_SUB、對主系統 HTTP 通道),其餘搬到對的位置即消失。P1 五張卡四批(CM-3319~3323)。決策者「照建議、先不放行」。
  2. 母卡掛法反覆:先掛 CM-3232 → 擋了 P0 結案(結案要求子卡全 Done)→ 另開 CM-3324 → P2(CM-3325)/P3(CM-3331)各自母卡 → 決策者「合併到 P1 卡下面半夜跑完」→ 14 張全掛 CM-3324,兩張空母卡標 Done 作廢。
  3. 決策者「很多決策其實沒那麼重要,都可以往下跑」→ 掃 14 張卡裡會讓小弟停的句子,append「無人值守決策表」蓋過 P0 時期的「要人決定就停下、首腦早上裁」。
  4. 工作坊 29 從 10-30 19:48 跑到 10-31 10:55,批 12~22 十五張全部驗收通過(含工作坊首腦半夜依規則加開的 CM-3345),沒有一張停下等人。
  5. 總驗收(決策者「不要檢查的太繁瑣,以基本測試為主」):全量 1992 綠(補 venv 的 jedi-password 後)、路由 49=49、demo 起服務、真機基本功能;派 ddd-compliance-reviewer(opus)掃 310 檔 diff。兩條阻斷首腦自己修(8a807dc)、九項警告開 CM-3357 清理卡(兩條要裁的首腦預設:domain 准用純算法庫=改規則;單鎖類別=真收進 DI;決策者「照建議」)。CM-3357 做完驗過:九項全過、新守衛突變有牙齒、1997 綠。
  6. 決策者問 P4(心跳瘦身、改雙向直推、socket)→ 分析後裁「要改主系統,先暫緩等重構完成」。
  7. FR-167 側調整完 → 合回:先把主線(多 15 個 commit:P8-5/P9-4、1.4.6、工具升版、SeaweedFS 加密)合進 ws,三支文字衝突取 ws 版,update_notify 改由 sync.register() 掛、import 改新路徑,兩支測試 patch 目標改新路徑;全量 2014 綠。再合回 feature/FR-139(Agent 3ab1253、jedi fc67330e),本機 Agent 切回主資料夾。
  8. push 卡帳密(session 無 TTY)→ 設 glab auth git-credential 為 helper → 三 repo 推上 origin。
  9. 給 FR-167 首腦 prompt:主線已是新架構、FR-167 修正全在、出包前要在 188 真跑 Nuitka、188 不 pull 也可以停在 58793ac 出純 FR-167 包。

P4 分析(決策者問「等心跳太偷懶,能不能都改雙向」)

  • 現況兩條路不對等:Agent→主系統只有 60 秒心跳;主系統→Agent 有 8443 直推(mTLS+綁指紋 JWT)但只開 9 個端點,其餘全塞心跳回應。
  • 心跳回應 24 鍵分三類:指令類(pending/restart/update/取消,等 60 秒是純延遲,該改直推)、設定同步類(清冊、CIDR、profile、漏洞庫、操作者名單等,要的是最終一致,留心跳但改帶版本號有變才送)、對帳類(accepted/rejected/ack,不動)。真正要改的約 4 鍵、三張卡。
  • WebSocket 不做:落地版主系統與 Agent 同內網、8443 一定通;WebSocket 認證只在握手做一次、之後靠「連線還在」當信任,比每請求驗 JWT 差,要補每則訊息簽章/重認證/斷線重連;穿 proxy 常被切又要長出一套保活;BE 現有 SocketIO 8002 是給瀏覽器用的使用者身分,不能直接接機器。只在 SaaS 客戶不開 8443 時才有價值(design §3.x 第二期)。
  • 建議另開 FR(改對外契約,不是重構),順序在 FR-170 全部合回之後。

教訓

  • 母卡掛法要先看工作坊結案條件:子卡全 Done 才能結案,分期掛同一張就擋前一期;但決策者要「單一工作坊跑完」時又該合併。開卡前先問「要不要分工作坊」。
  • 「首腦早上裁」在無人值守下等於停工到天亮;要人裁的事列成表寫進卡,預設答案給好,真的要停的縮到三種。
  • Done ≠ 進主線;工作坊線與主線平行長時,合回前把主線先合進 ws 在工作樹上解,別在主資料夾解。
  • 卡工作區跑守衛會因 .worktrees 排除寫法假紅;驗收數字要在哪個樹跑清楚標。
  • pip 沒帶 Nexus index 裝不到 jedi 套件、poetry install 會挑另一顆 venv:驗收前先 pip show 確認 venv 裝了卡上新加的 pin。
  • 決策者兩度點名驗證方式:合併演練+全量+路由集合 diff+demo+真機基本功能,一輪做完;不逐檔讀、不設計複雜情境。

commits:BE 803a6e498(P3-5 spec)、本棒交接;Agent d7bc4e6、8a807dc、092efd4、3ab1253(合回);jedi fc67330e(合回)。三 repo 已推 origin。

交給下一棒:STATE §4。