角色:分析決策首腦(協調者)。實作零行,文件產出外包。
產出軌跡(時序):
__file__ 路徑/外部依賴)→ 盤點 15 項風險(🔴2/🟠4/🟡5/🟣4)b053c765(未 push)關鍵決策脈絡(供回顧):
SystemError: dynamic module 'dependency_injector.providers' not initialized properly from def——官方 wheel 走 Limited API(abi3)強制 PEP 489 多相初始化,與 Nuitka 靜態嵌入不相容 → D2 私房 wheel rebuild 納入管線前置步驟(版本感知快取+sdist 留檔)。RUN_MODE 切 api/socketio 兩模式,三支舊入口全退役,順帶解 scheduler 雙跑+socketio 進程瘦身。SQLALCHEMY_* 四支 ×7 份全無消費者(未裝 flask_sqlalchemy、app_factory 自組 URI)——讀寫分離從未實際生效(DB_READ_HOST 設了沒人用);Swagger 從未啟用(docs.init_app 被註解,APISPEC_* 是死項)。兩者皆不進本案,Swagger 補齊列 follow-up。教訓/備忘:
.env.bak(user 自留備份)差點被 git add 掃進——不在 .gitignore(現行規則只有 .env);當場攔下,.gitignore 補 .env.* 留給 .1g 一併做。ENV 環境變數降級為純顯示標籤時不退變數本身——避免破壞現有部署腳本(三環境 .env / systemd / compose 都還在傳它)。產出物:discussion.md/html、design.md/html(含 D1–D11 決策表、§5 詳細設計、§6 拆分表)、commit b053c765、Notion 3 母案 + 14 子卡、第 1 波派工 prompt ×3、本 STATE/LOG 雙檔。
下一步(給下一任首腦):依 STATE「派工順序表」發令——第 1 波 .1a/.1b/.1f 三棒平行;build 機一到位插隊 .2b 驗炸點。
角色:接手首腦(分析決策/協調)。本棒動作:.1a / .1f 驗收。
驗收結果(皆親手實跑,不信 runner 自報):
18ef3142)✅ 通過:
gen_di_modules_static.py 實跑產 138 模組、--check 綠CM_DI_MODULES_MODE=static/dynamic 取清單 list equalapp.fake.module_xyz → --check exit 1 並指名多餘項--check 走 AST parse 不 import(避開 import 快取),設計正確57e8a41)✅ 通過:
LIBREOFFICE_CMD=/fake/path/soffice → resolve 回傳該值sofficeLibreOffice.app/platform 硬編已清零,共用 helperM)確認為開發態,未 commit,符合 jedi-* 規範教訓/備忘:無新教訓;runner 自報與實況一致(含突變測試都有做)。
下一步:.1b(CM-1195)進行中等回寫;.1b 過驗後派第 2 波 .1g(CM-1200)。卡收 Done 等 user 令。
本棒動作:.1b 驗收 → Notion 15 卡白話化 → 派 .1g → .1g 事故裁決與交接檔復原。
.1b CM-1195 驗收 ✅ 通過(commit 78937428):
load_canon('cmmc-l1') 63 條、build_catalog('cmmc-l1') 6 domainsresources/download/ 5 支範本檔實在;GLOBAL_DOWNLOAD_DIR 絕對路徑version_route.py:17 __file__ 讀 pyproject.toml 打包後 fallback 'unknown'——歸 .1e version bake,派 .1e 時寫進 promptNotion 15 卡白話化:subagent 全數重寫(PM 受眾+文末「技術細節(工程用)」段,事實零流失),抽查 CM-1194 確認。
🔴 .1g 事故(checkout-index 誤抹):.1g runner 用 stash 驗「測試 error 是否既存」,pop 後改動進 index、工作樹回 HEAD,再跑 git checkout-index -f -a 把 index 沒有的檔案(STATE/LOG 的未 commit 更新、pyproject path override)覆寫回 HEAD 版。runner 自己的 .1g 改動無損。復原:STATE/LOG 由首腦逐字還原(皆本棒親筆,context 有原文);pyproject override 由首腦改回。教訓:runner 派工 prompt 應明令「驗既存問題用 git stash 後恢復只准 stash pop,禁 checkout-index / checkout -- / restore 整樹操作」;交接檔未 commit 就跨棒是風險放大器——首腦寫完 STATE/LOG 應盡快 commit。
下一步:.1g runner 續跑驗收⑤(module_frame 6 支 collection error 已由其驗證為既存)→ 回寫卡等驗收。
.1g CM-1200 驗收 ✅ 通過(commit 5acedd9b):
validate_required_env() → ConfigError 一次列全 5 缺項(含新舊兩種填法提示)init_db(uri) 後讀到 9;DELETE 該列 → 回內建預設 3;re-seed migration 冪等還原 7 列2026-08-14-fr063-1g-runtime-config-seed.sqlConfig loaded (ENV label=DEVELOP_PREMISE, DEBUG=True)驗收方法備忘:runtime_config reader 走 db.SessionLocal,裸 script 未 init 引擎時 fail-open 回預設(設計如此)——獨立驗證要先 init_db(uri);create_app() 二次呼叫會炸 dependency-injector NonCopyableArgumentError(既存行為,服務路徑不受影響)。
Runner 留下的注意事項(首腦查證):
MANUAL_FILENAME(login_route.py:127 手冊下載端點讀取)config 從未定義——既存問題,該端點一直是壞的;不在 .1g 清單,留待裁決是否開卡下一步:第 3 波 .1c+.1d 併一棒待派;四張卡收 Done 等 user 令。
.1c+.1d CM-1196/CM-1197 驗收 ✅ 通過(commit b40a5710):
main.py+新平鋪 .env 起服務:version 200、DI 138、menu 401(@inject 活)/healthz 200(mode=socketio)、/api/1.0/version 404(REST 未載)init_scheduler 獨立驗證 4 jobs 掛齊(drive_sync_worker 5s/webhook_channel_renewer 6h/framework_parse_job_cleanup 1am/license_expiry_state_machine 2am);socketio 模式 log 印 disabledmain.py 與舊入口一樣不自帶 load_dotenv(PyCharm/dotenv wrapper 慣例),CLI 起服務用 wrapper:python3 -c "from dotenv import load_dotenv; load_dotenv(); import runpy; runpy.run_path('main.py', run_name='__main__')".env 整理(user 直接交辦首腦做,非 runner):
.env.bak-20260814-pre1g)CM-1204 開卡(subagent):MANUAL_FILENAME 手冊下載端點——查證升級為「死碼端點」(route 從未註冊、FE 無呼叫、config 無定義、檔案不存在三缺一殼);獨立 bugfix 不掛 FR-063。另 config-migration-mapping.md §6 補 STG/POC 上版 13 項 checklist(commit cb830d09)。
下一步:.1e(CM-1198)+.1 收口 gate——派工 prompt 要帶:version bake 接點含 version_route.py:17、config.py:200 死定義清除、.env.sample working tree 變更一併收。
.1e CM-1198 驗收 ✅ 通過(commits aa760c50 + 8a83fa98):
{version: 1.14.0, commit: 5766...} 兩欄位resource 模組確為死項(api/ 無此目錄、FE api.js 無呼叫)——fail-fast 上線即抓到 19 次靜默 warning 的陳年漏拔FR-063.1「程式整理」子需求 7 卡全數過驗(a/b/c/d/e/f/g)。剩:.2 build 線(等 build 機)→ .3 → .4。
啟動方式變更(user 已確認知悉):python main.py=API 服務(8000,日常唯一指令);RUN_MODE=socketio python main.py=通知服務(8002)。main_app.py/main_socketio.py 已刪除退役。
user 本機複測通過(登入/範本下載/SSP 匯出/i18n/雙模式),下令收卡:
下一階段 = FR-063.2 Build 管線:.2a(build 機環境建置)→ .2b(wheel rebuild,到機最優先驗 dependency-injector 炸點)→ .2c(Nuitka build script)。卡點=user 的 24core/32GB build 機;.2c script 撰寫依 design §5.4 可先行(不需 build 機,只是沒法實跑)。
.2a+.2b CM-1201/CM-1202 驗收 ✅ 通過(commit d510ed79):
SystemError: dynamic module 'dependency_injector.containers' not initialized properly from def(重現 8/13);私房 cp311 wheel 版 RESULT=PASS。全案最底層風險解除,且走候選①(setup.py 預設重編)即成功兩阻塞事項處置(user 當場裁示):
/opt/guidant_ai 權限:user 給 sudo,首腦 chown jedi:jedi+清 8/13 舊產物 4.8GB(磁碟回 198G)pip download jedi-common 成功拉到runner 誠實澄清:pyproject path override 只在 Mac working tree 未 commit,build 機 checkout 是 pin 版——派工單預想的處置不需要。
下一步:.2c Nuitka build script(整包編譯)——jedi-* 19 支可裝了、工作區權限已解,無阻塞可派。
.2c CM-1203 驗收 ✅ 通過(commit 8a697d85)——夜間第 1 檢查點即完成回寫,直接進驗收:
/opt/guidant_ai/.build/dist/guidant-ai-1.14.0/(832MB):.py 檔數 0(保護未破)、.mo ×2、SSP docx 範本在位、resources/download 5 支在位./guidant-ai binary → /api/1.0/version 回 {version: 1.14.0, commit: 8a83fa98...}(與 bake 一致)、/users/menu 401(DI wire 活)——.1 全部機制(DI 靜態清單/resource_path/version bake/binary 旁 .env 載入)在真產物內首次驗證通過FR-063.2 三卡全數過驗(.2a/.2b/.2c),收 Done 等 user 令。下一波 .3(CM-1192 production image)→ .4(CM-1193),全案剩最後兩棒。
jedi 發版收官:file-upload 0.0.21+captcha 0.0.14 推 Nexus、pin 還原、BE/jedi 雙 repo user 親推齊(BE 至 02146e9d)。poetry.lock 自此入版控(歷史誤排除移除;當日實測教訓:build 機因 lock 不同步 poetry 拒跑,scp 急救後拍板正規化)。TURNSTILE 平鋪化(captcha 三段式解析)+ENV 四值新慣例(DEV/STG/POC/PRD,本機與 sample 已改)同日落地。
.4 發現真回歸(runner 調查):.1c 模式裁剪把 socketio namespace 註冊(藏在 create_module() 內)一起裁掉——兩模式都沒有可用 namespace,即時功能整組失效。首腦裁決選項 2:namespace 註冊抽離至集中清單 config/socketio_namespaces.py(比照 REGISTERED_APPS),app_factory 於 init_app+DI wiring 後統一註冊。首腦全 repo 掃定 namespace 封閉集合=2 個(notification/fill-survey)。派工 prompt 已出(含端到端 client 探針要求——本回歸正是 healthz 級探針測不到的層,驗收探針深度教訓)。獨立發現:nginx http2 擋 WebSocket(環境異動待裁示;.3 範例設定需避開)。順序改為 .4 → .2d → .3(.3 包最終修正後 binary)。
.2d 開卡 CM-1205(編譯加速):首腦研究+user 拍板「公開套件不需編譯保護」——pymupdf(31 分地板)等公開大套件 --nofollow 排除原樣附帶、測試依賴(pytest 系 4 支誤放正式清單)搬 dev group。預估冷 build 砍半。jedi-*+業務碼照舊全編譯。
在飛:user 的熱 rebuild 計時(監看中)、.4 runner、(.2d 待 .4 完成後派)。
.2d CM-1205 驗收 ✅ 核心通過(commits 381acf76→f449f939 共 5 筆):
36708b35 身分正確、menu 401、8002 healthz 200、REST 隔離 404首腦自踩事故(記錄):驗收時在 188 跑 --dry-run,但 188 停在 36708b35(f449f939 的 dry-run 功能未 push),舊版無參數解析、--dry-run 被無視直接進真編譯——誤觸兩輪、已 pkill 清除,STG 驗證服務無波及。教訓:跑新功能前先驗目標機的 code 版本(與 runner 的「服務有回應≠你要的版本在跑」同型——它 09:58 也撞過 root 舊進程佔 8002)。 runner 留的環境警示:188 .env 今早被異動時漏了一支 Drive 金鑰導致成品一度起不來(已補)——其他環境同批異動需檢查。
待收尾:188 push 齊後親跑一次真 dry-run+腳本端到端輪(runner 的「需讓腳本完整跑一次」);.4 尚欠 client 級 socketio 收發探針;兩卡收 Done 等 user 複測令。
交棒時刻的狀態:.1 七卡+.2 四卡(.2a/b/c/d)全 Done(user 皆複測過);.4(CM-1193)修正待驗證——產物層 namespace 驗證已過,user 實測中發現新的 socket bug,正在另開卡(等 .4 runner 回報,新卡號待補);.3(CM-1192)未派。
給下一任首腦的待辦(依序):
組織記憶(這兩天最值錢的教訓,皆已實證):
在途物:STG 188 上兩服務(8000/8002,36708b35 成品)供 user 驗證中,驗完由 user 決定去留;.env.bak-20260814-pre1g 留在 repo 根(user 自留);jedi repo 與 BE 均已 push 齊。
.4 CM-1193 驗收 ✅ 通過(commits 78debb6c/e8104ef6):
全案盤點至此:.1 七卡+.2 四卡+兩母卡(CM-1190/1191)Done;.4 修正待驗證(等 user 收卡令);剩 .3(CM-1192 production image)未派+母案 CM-1187。CM-1206 獨立 bug 待排程(不掛 FR-063)。nginx http2 待裁示。
🔴 更正:nginx http2 不是問題,不需要任何處置——user 裁定並實證。先前 .4 runner(Block 10/13 引用)記「http2 擋 WebSocket、修法拿掉 http2 或升 nginx」是誤診:當時 400 的真因是 socket endpoint 沒建置好(namespace 未註冊,即 .1c 回歸本身),不是 HTTP/2 協定問題。user 已把 http2 開回、實測 h2 200 正常。後續一律不再把「避開 http2」寫進 .3 nginx 範例或任何文件;Block 10/11/13 中相關句子視為作廢。教訓:runner 的「獨立問題發現」也要驗證因果——當時兩個問題(namespace 缺席+http2 假設)疊在一起,修好前者後就該回頭重測後者再下結論。
收卡:.4(CM-1193)+.2a/b/c(CM-1201/1202/1203)+CM-1191 全收 Done——FR-063 主線 11 工作卡+兩子需求卡全數完結。
兩棒同時派出(平行,零檔案重疊):
更正沿革注意(接手必知):nginx http2 誤診已在 Block 14 作廢——.3 的派工 prompt 發出時仍含「避開 http2」字樣(發出在更正之前),驗收 .3 時若 runner 照做了要把該部分退回:nginx 不需任何 http2 特殊處置。
交棒交割:STATE 已定稿(當前狀態/待辦地圖四項+場外/遺留待辦);交接 prompt 已交 user(讀 STATE→LOG→盤點→停)。本任首腦 context 滿載退場,接手者從驗收兩棒開始。
角色:接手首腦。本棒與前兩任不同:user 直接令首腦本體執行合流(原 runner session 已失能),故本 block 含執行紀錄。
驗收:
6de7ffd8+FE 967e67b):code 抽查(fail-closed 全路徑、UserContextDTO 組裝抽單一實作與 HTTP 等價、DI fixed_modules 有補)+DI --check 綠+guard 測試 6 passed+本機 8002 活體負向探針拒連 PASS29c4013f→cc7714d2 共 3 筆):Dockerfile/entrypoint 實讀(glibc 對齊理由、chown-then-setpriv 設計、fc-match 斷言)+188 image 內實跑 fc-match 解析 NotoSansCJK、業務 .py=0、uid1000;http2 檢查:全部產出 grep 零命中,runner 未踩已作廢誤診合流執行(皆 188):
undefined reference to module_code_anthropic$_exceptions,判定為共用 nuitka-out 汙染非 code 問題)→ 全清重跑單 build 一次過cc7714d2;摘要報告範本本輪由腳本自動收(上輪手動 cp 欠帳閉環,斷言 OK)0dcabc8d)→ push Harbor guidant-ai/guidant-ai-be:1.14.0+latest(digest bba0449d…);Harbor API 端複驗在位。探針最終輪依 user 指示跳過收尾補強:build script i18n 加 --statistics+註明 .mo 現場重編語意(f921ed39;查證 Step 2 本就重編、「忘 compile」本就進不了產物,原提案的 staleness 檢查不需要);--statistics 首輪即抓到 zh_Hant_TW 65/66 → 查證為死條目 non_existent_key(jedi-system-config 測試 fixture 被 extract 誤收)清除,兩 locale 回 100%(2834cf4c)。188 工作樹清乾淨(proxy.csr/key=8/13 nginx 實驗遺留 → 搬 ~/certs/;messages.pot 還原)。
收卡:CM-1192/CM-1206 user 複測後親收 Done;母案 CM-1187 收 Done(末段 append 全案收口摘要)——FR-063 全案完結。
新戰線決策(user 拍板):①FE image+產品 compose 不提早做,劃入 FR-065(compose 形狀由 installer 決定;FE 靜態產物無保護議題)②DB 初始化基線獨立開卡 CM-1207(FR-065.0:帳號/schema 基線/GRANT 逐表/seed 三分類/初始 admin,一卡五事互相咬合)③順序=FR-064(user 親做)→ CM-1207 實作 → FR-065;盤點棒唯讀可先行,prompt 已交 user
教訓:
pgrep 查同類進程——兩份 build 互撞的 crash 症狀(linker undefined reference)像 code 問題,實為 artifact 汙染ssh -T git@gitlab.com 就能戳破,誤信就多養一條 rsync 歧路下一步(給接手者):FR-064 期間首腦待命;CM-1207 盤點棒回報後驗收(重點:待裁決清單品質、有無越界寫入);FR-063 文件收尾等 user 令。
user 令「收尾直接派 subagent」。兩支平行:
handoff/2026-08-15-FR-063-SUMMARY.md,commit 0e7368a0):八段式,由 LOG 16 blocks 濃縮;抽查過——commits 清單/交付物座標正確,http2 僅以「誤診更正」教訓形式出現(無「避開」指示)feccea4e):2026-08-15-nuitka-public-package-exclusion.md(公開套件不需編譯保護推理,含反悔條件)+2026-08-15-nuitka-build-verification-pyramid.md(常數表連坐+驗證金字塔+靜默失效防線);抽查過——皆含選項/取捨/反悔條件四段,數字與 LOG 一致範圍裁定:spec/使用手冊不觸發——FR-063 是 build/打包基建,無終端使用者操作變更(啟動方式屬部署文件範疇,已在 deployment-env.md)。
FR-063 至此全案含文件完結。剩餘:本機 4 筆 docs commits 待 user push;CM-1207 盤點棒等 user 派。