FR-063 Nuitka 落地版打包 — LOG(append-only,每棒追加一 block)


§1

Block 1 — 2026-08-14 首腦 session(設計棒)

角色:分析決策首腦(協調者)。實作零行,文件產出外包。

產出軌跡(時序)

  1. 三路探脈(動態 import/__file__ 路徑/外部依賴)→ 盤點 15 項風險(🔴2/🟠4/🟡5/🟣4)
  2. 討論稿(discussion.md/html)產出 → user 審 → D1–D11 逐項定案(D7–D10 由原 Q1–Q4 待確認項升格)
  3. design.md 定稿 → commit b053c765(未 push)
  4. 開卡:三母案 CM-1187(FR-063)/CM-1188(FR-064 防竄改)/CM-1189(FR-065 Installer)+ FR-063 子卡樹 14 張 CM-1190~1203 一次建齊(Case No 連號)
  5. 第 1 波派工 prompt 產出(.1a/.1b/.1f 三棒平行),等 user 發令

關鍵決策脈絡(供回顧)

  • Nuitka 取代 .pyc 方案:Python 3.11 反編譯工具鏈已斷(uncompyle6/decompyle3 停在 3.8 前後),純 .pyc 其實已有基礎保護力,但 user 拍板要最高保護等級 → Nuitka standalone,對齊 Go binary 陣營交付形態。
  • 夜間實測炸 dependency-injector(2026-08-13 STG 機實測:冷 build 1h27m/產物 808MB/pymupdf 單檔 34 分):import 期 SystemError: dynamic module 'dependency_injector.providers' not initialized properly from def——官方 wheel 走 Limited API(abi3)強制 PEP 489 多相初始化,與 Nuitka 靜態嵌入不相容 → D2 私房 wheel rebuild 納入管線前置步驟(版本感知快取+sdist 留檔)。
  • D9 統一入口是 user 提議:原方案兩支入口各自編譯(build ×2、產物 ×2),user 反把兩次 build 變一次——單 binary RUN_MODE 切 api/socketio 兩模式,三支舊入口全退役,順帶解 scheduler 雙跑+socketio 進程瘦身。
  • D11 config 三層重整源自 user 主動提問(binary 化後「改 config=重編譯交付」,設定放錯層代價放大)→ 六套環境 class 塌一套/Secret 拆 JSON 包裝+config_loader 集中驗證(向後相容舊 .env)/營運參數遷 DB system_config,加開子任務 .1g(CM-1200)。
  • 盤查大發現(列 follow-up memory)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 驗炸點。


§2

Block 2 — 2026-08-14 晚 首腦 session(第二任,第 1 波驗收)

角色:接手首腦(分析決策/協調)。本棒動作:.1a / .1f 驗收。

驗收結果(皆親手實跑,不信 runner 自報)

  • .1a CM-1194(commit 18ef3142)✅ 通過:
    • gen_di_modules_static.py 實跑產 138 模組、--check
    • 兩軌等價:CM_DI_MODULES_MODE=static/dynamic 取清單 list equal
    • 突變測試:親手在靜態清單插 app.fake.module_xyz--check exit 1 並指名多餘項
    • 缺檔 fail-fast:移走靜態清單 → static 模式 RuntimeError(非靜默退回動態掃)
    • code 抽查:--check 走 AST parse 不 import(避開 import 快取),設計正確
  • .1f CM-1199(jedi repo commit 57e8a41)✅ 通過:
    • env override:設 LIBREOFFICE_CMD=/fake/path/soffice → resolve 回傳該值
    • fallback:清 env → 回 PATH 的 soffice
    • grep 兩 adapter 確認舊 LibreOffice.app/platform 硬編已清零,共用 helper
    • path override(pyproject.toml M)確認為開發態,未 commit,符合 jedi-* 規範

教訓/備忘:無新教訓;runner 自報與實況一致(含突變測試都有做)。

下一步:.1b(CM-1195)進行中等回寫;.1b 過驗後派第 2 波 .1g(CM-1200)。卡收 Done 等 user 令。


§3

Block 3 — 2026-08-14 晚 首腦 session 續(.1b 驗收、白話化、.1g 派工與事故復原)

本棒動作:.1b 驗收 → Notion 15 卡白話化 → 派 .1g → .1g 事故裁決與交接檔復原。

.1b CM-1195 驗收 ✅ 通過(commit 78937428):

  • 四讀取點親測解析:TRANSLATIONS_DIR isdir、SSP docx 範本 exists、load_canon('cmmc-l1') 63 條、build_catalog('cmmc-l1') 6 domains
  • resources/download/ 5 支範本檔實在;GLOBAL_DOWNLOAD_DIR 絕對路徑
  • 範本下載端點 401 非 404(route 註冊活;完整下載留 user 手測——login 有 Cloudflare captcha 擋 curl)
  • 核心測試 26 passed;test/ 9 個 ai_dashboard collection error 查證為既存(前一 commit 就缺模組)
  • 備忘:version_route.py:17 __file__ 讀 pyproject.toml 打包後 fallback 'unknown'——歸 .1e version bake,派 .1e 時寫進 prompt

Notion 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 已由其驗證為既存)→ 回寫卡等驗收。


§4

Block 4 — 2026-08-14 夜 首腦 session 續(.1g 驗收)

.1g CM-1200 驗收 ✅ 通過(commit 5acedd9b):

  • 驗收③ 親驗:隔離 env 跑 validate_required_env() → ConfigError 一次列全 5 缺項(含新舊兩種填法提示)
  • 驗收④ 親驗(DEV DB 突變):UPDATE LOGIN_MAX_LOCK_COUNT 3→9 → init_db(uri) 後讀到 9;DELETE 該列 → 回內建預設 3;re-seed migration 冪等還原 7 列
  • 六套環境 class 已刪(grep class Development/Staging/Production = 0);SQLALCHEMY_/APISPEC_/TOKEN_TTL/WEBSITE_URL 已清
  • schema_migrations 有登記 2026-08-14-fr063-1g-runtime-config-seed.sql
  • HEAD 起服務 200、log 印 Config loaded (ENV label=DEVELOP_PREMISE, DEBUG=True)
  • 既有測試抽跑 16 passed;tests/ 整合套件全紅為既存(runner 用改版前程式碼驗證同紅)

驗收方法備忘runtime_config reader 走 db.SessionLocal,裸 script 未 init 引擎時 fail-open 回預設(設計如此)——獨立驗證要先 init_db(uri)create_app() 二次呼叫會炸 dependency-injector NonCopyableArgumentError(既存行為,服務路徑不受影響)。

Runner 留下的注意事項(首腦查證)

  1. MANUAL_FILENAME(login_route.py:127 手冊下載端點讀取)config 從未定義——既存問題,該端點一直是壞的;不在 .1g 清單,留待裁決是否開卡
  2. STG/POC CORS 目前全放行(既存,因 ENV 一直填 DEVELOP)——上版時補實際站台網址,已列 config-migration-mapping.md
  3. JWT 效期改 DB 後需重啟才生效(框架啟動期讀 app.config),登入政策/MFA 即時生效——已寫進對照表
  4. tests/ 測試 DB 缺 schema 全紅、6 支 module_frame collection error——皆既存,另行處理

下一步:第 3 波 .1c+.1d 併一棒待派;四張卡收 Done 等 user 令。


§5

Block 5 — 2026-08-14 夜 首腦 session 續(.1c+.1d 驗收、.env 整理、CM-1204 開卡)

.1c+.1d CM-1196/CM-1197 驗收 ✅ 通過(commit b40a5710):

  • 新入口 main.py+新平鋪 .env 起服務:version 200、DI 138、menu 401(@inject 活)
  • socketio 模式:8002 /healthz 200(mode=socketio)、/api/1.0/version 404(REST 未載)
  • scheduler:init_scheduler 獨立驗證 4 jobs 掛齊(drive_sync_worker 5s/webhook_channel_renewer 6h/framework_parse_job_cleanup 1am/license_expiry_state_machine 2am);socketio 模式 log 印 disabled
  • grep 舊入口引用:僅剩註解與歷史文件,程式/腳本/Dockerfile 全改
  • 備忘:main.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 遷平鋪格式+全檔分區註解(備份 .env.bak-20260814-pre1g
  • 逐 key 審計 49 項(主專案+jedi 全樹):清 6 死項——REDIS_DB(程式硬寫 0)、通知四項(SEND_NOTIFY_MODULES/TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID/DISCORD_WEBHOOK_URL,通知已全走 DB NOTIFY_CONFIG)、DRIVE_WEBHOOK_PUBLIC_BASE_URL(config 有定義零讀者,Phase 3 未實作)
  • 差點誤殺後留下的:SCHEDULE_REPORT_DIR(api 層在讀)、ENABLE_MULTI_TENANT/AUTH_CHANGE_SECRET_COOLING_HOURS/TURNSTILE_SECRET_KEY(jedi 套件在讀)——審 env 死活必須連 jedi 套件一起 grep
  • .env.sample 同步:清通知四項+修 TURNSTILE 格式錯誤(範本裸值→JSON,jedi-captcha json.loads 它)

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 變更一併收。


§6

Block 6 — 2026-08-14 深夜 首腦 session 續(.1e 驗收=FR-063.1 子需求收口)

.1e CM-1198 驗收 ✅ 通過(commits aa760c50 + 8a83fa98):

  • version 端點親打:回 {version: 1.14.0, commit: 5766...} 兩欄位
  • bake 突變親演:gen → 改 9.9.9-ARBITER → 讀到突變值(真讀檔非快取)→ 刪 bake → fallback pyproject 1.14.0
  • fail-fast 突變親演:REGISTERED_APPS 塞假模組 → RuntimeError [FATAL] 指名模組
  • 意外收穫查證:resource 模組確為死項(api/ 無此目錄、FE api.js 無呼叫)——fail-fast 上線即抓到 19 次靜默 warning 的陳年漏拔
  • 收口 gate 八項 runner 自報全過,抽驗①②③⑥⑧一致;⑧ PyCharm 真實 debug 體驗留 user 本人驗
  • test_api_version_route 2 passed

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 已刪除退役。


§7

Block 7 — 2026-08-14 深夜 首腦 session 續(FR-063.1 收 Done)

user 本機複測通過(登入/範本下載/SSP 匯出/i18n/雙模式),下令收卡:

  • 七工作卡 CM-1194/1195/1196/1197/1198/1199/1200 → Done
  • 子需求卡 CM-1190 → Done+收口註記(commits 清單/gate 結果/新啟動指令)
  • 母案 CM-1187 續留(全案結案才收)

下一階段 = 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 機,只是沒法實跑)。


§8

Block 8 — 2026-08-14 深夜 首腦 session 續(.2a+.2b 驗收=D2 炸點排除)

.2a+.2b CM-1201/CM-1202 驗收 ✅ 通過(commit d510ed79):

  • 🔴 D2 炸點親驗排除:build 機親跑兩份探針產物——官方 wheel 版炸 SystemError: dynamic module 'dependency_injector.containers' not initialized properly from def(重現 8/13);私房 cp311 wheel 版 RESULT=PASS。全案最底層風險解除,且走候選①(setup.py 預設重編)即成功
  • rebuild script 快取親測 0.047 秒命中;abi3 守門突變測試 runner 已做
  • abi3 觀察名單 3 套件:cryptography/gevent/nacl(4 個 .so),.2c 整包編譯見真章
  • build 機環境全項達標(Nuitka 4.1.3/ccache 46% hit/二次編譯 55s→8.9s)

兩阻塞事項處置(user 當場裁示):

  • /opt/guidant_ai 權限:user 給 sudo,首腦 chown jedi:jedi+清 8/13 舊產物 4.8GB(磁碟回 198G)
  • Nexus 憑證:user 本人在 build 機設 pip extra-index-url(憑證處置不經 Claude,紀律正確);首腦驗證 pip download jedi-common 成功拉到

runner 誠實澄清:pyproject path override 只在 Mac working tree 未 commit,build 機 checkout 是 pin 版——派工單預想的處置不需要。

下一步:.2c Nuitka build script(整包編譯)——jedi-* 19 支可裝了、工作區權限已解,無阻塞可派。


§9

Block 9 — 2026-08-15 01:03 首腦夜間檢查(user 授權自主驗收):.2c 通過

.2c CM-1203 驗收 ✅ 通過(commit 8a697d85)——夜間第 1 檢查點即完成回寫,直接進驗收:

  • 產物親驗(build 機實跑,非抄自報)
    • /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 載入)在真產物內首次驗證通過
    • 驗完 pkill 清進程,無殘留
  • runner 自報數據:首編 56m42s(勝 8/13 的 1h27m)、二次 18m36s(快取證實)、六項健檢全過(含 gunicorn 雙 worker)、防呆突變測試有做
  • 兩個真問題 runner 已修:①gunicorn 動態載入模組 Nuitka 追不到→顯式 include+升級為健檢項(開發環境看不出、只有正式承載會死的陰險型)②編譯參數誤收 metadata 目錄
  • 觀察名單三套件(cryptography/gevent/nacl)整包編譯未觸發——不需重編,繼續觀察
  • 待 .3 的遺留:七項全套探針(PDF 中文/上傳/socketio 實際收發)、production Dockerfile

FR-063.2 三卡全數過驗(.2a/.2b/.2c),收 Done 等 user 令。下一波 .3(CM-1192 production image)→ .4(CM-1193),全案剩最後兩棒。


§10

Block 10 — 2026-08-15 上午 首腦 session 續(發版收官、.4 回歸裁決、.2d 開卡)

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 完成後派)。


§11

Block 11 — 2026-08-15 下午 首腦 session 續(.2d 驗收+.4 產物層驗證)

.2d CM-1205 驗收 ✅ 核心通過(commits 381acf76f449f939 共 5 筆):

  • 親打 STG 成品(user 授權起於 188):8000 version 200+commit 36708b35 身分正確、menu 401、8002 healthz 200、REST 隔離 404
  • 產物抽驗:業務碼 .py=0、jedi 目錄 0(全編入 binary)、排除套件抽樣 5/5 在位
  • 成果數字:冷編 56m42s→穩態 12m11s(省 78%);三個靜默複製 bug 全修+三道自動把關(完整性斷言/功能探針 9 項/dry-run 預檢)
  • .4 產物層同場驗證:runner 確認兩 namespace(notification/fill-survey)在編譯成品內註冊成功——.4 的修正在產物層活著
  • runner 名言收錄:「拿最慢的迴圈去測最快能測的東西」——驗證順序金字塔已寫進腳本檔頭

首腦自踩事故(記錄):驗收時在 188 跑 --dry-run,但 188 停在 36708b35f449f939 的 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 複測令。


§12

Block 12 — 2026-08-15 下午 第二任首腦交棒(中繼 handoff)

交棒時刻的狀態:.1 七卡+.2 四卡(.2a/b/c/d)全 Done(user 皆複測過);.4(CM-1193)修正待驗證——產物層 namespace 驗證已過,user 實測中發現新的 socket bug,正在另開卡(等 .4 runner 回報,新卡號待補);.3(CM-1192)未派。

給下一任首腦的待辦(依序)

  1. 等 .4 runner 回報+user 的新 socket bug 卡——驗收 .4 時注意:產物層 namespace 註冊已驗過(STG 上 36708b35 成品),欠 client 級收發探針(scripts/build/socketio_probe.py 是現成工具);新 bug 卡按 user 指示處理(可能併 .4 修或獨立棒)
  2. .3(CM-1192 production image)派工——包含:Dockerfile(非 root uid/entrypoint chdir+chown/apt 清單/fc-match 斷言)、七項探針全套(design §5.6)、nginx 範例避開 http2(LOG Block 10 的發現)、volume 佈局(design §5.5);產物用最終修正後的那顆
  3. .3/.4 全收後:母案 CM-1187 收 Done 等令、全套收尾(SUMMARY 由 LOG 濃縮/spec/手冊/analysis——.2d「公開套件不需編譯保護」的推理已答應 user 寫 analysis)

組織記憶(這兩天最值錢的教訓,皆已實證)

  • 「服務有回應≠你要的版本在跑」——commit bake 的版本端點是唯一身分證(runner 撞 root 舊進程、首腦撞舊版 script 誤觸真編譯,同日兩例)
  • 靜默失效是本案主敵:三個複製 bug 全部「回報成功但成品是壞的」;防線=把人工清點做進腳本斷言+功能級探針(不只 import 級)
  • 驗證順序金字塔:bash -n 0.01s → dry-run 0.3s → 小探針 10s → 全量 19m,先快後慢
  • Nuitka 常數表連坐:模組集合一變全量重編;排除清單越大連坐圈越小(12m11s 的由來)
  • env 管理三坑同日爆:sample 歷史欠帳 18 支/188 設定在 .bashrc 隱形/LICENSE_ACTIVATION 隱式預設剛好能動——單一真相來源+顯式化是解

在途物:STG 188 上兩服務(8000/8002,36708b35 成品)供 user 驗證中,驗完由 user 決定去留;.env.bak-20260814-pre1g 留在 repo 根(user 自留);jedi repo 與 BE 均已 push 齊。


§13

Block 13 — 2026-08-15 傍晚 首腦 session 續(.4 驗收=eventlet 命題閉環)

.4 CM-1193 驗收 ✅ 通過(commits 78debb6c/e8104ef6):

  • 首腦親跑產物 socketio 探針(STG 8002,36708b35 成品):4/4 PASS——兩 namespace connect、join 回應、多人 join 走到 @inject service(DI 注入實證)
  • runner 全套驗證:產物雙模式(8002 healthz 200/REST 404/scheduler 0;8000 REST 200/socket.io 404/scheduler 4)、突變測試(關 namespace 註冊→探針 0/2)、既有測試 37 passed
  • eventlet × Nuitka 命題閉環:編譯產物下 monkey_patch + socketio.run 正常,D1 保底方案(換 gevent)不需啟用——本卡最初存在的目的達成
  • Flask-SocketIO 5.3.6→5.6.1 升版根治(user 裁示,取代 manage_session workaround);app_factory 留「不可退版至 5.3.6 以下」警語+症狀特徵
  • user 實測:加入/離開通知、在線頭像正常;自動存檔問題確認為既存獨立 bug(2026-07-07 起)→ CM-1206(socket 路徑無 auth context,patch_task_survey_answer AttributeError)——先前被「連不上」蓋住現形,不擋 .4
  • 排程雙跑老問題實錄確認解除(api 1 份 scheduler、socketio 0 份)

全案盤點至此:.1 七卡+.2 四卡+兩母卡(CM-1190/1191)Done;.4 修正待驗證(等 user 收卡令);剩 .3(CM-1192 production image)未派+母案 CM-1187。CM-1206 獨立 bug 待排程(不掛 FR-063)。nginx http2 待裁示。


§14

Block 14 — 2026-08-15 傍晚 更正(推翻了什麼)

🔴 更正: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 假設)疊在一起,修好前者後就該回頭重測後者再下結論。


§15

Block 15 — 2026-08-15 晚 第二任首腦最終交棒(兩棒派出、.4 收 Done)

收卡:.4(CM-1193)+.2a/b/c(CM-1201/1202/1203)+CM-1191 全收 Done——FR-063 主線 11 工作卡+兩子需求卡全數完結

兩棒同時派出(平行,零檔案重疊)

  • CM-1206(socket 共編存檔修復,app 層+可能跨 FE):修法方向已定=connect 驗 JWT 建 auth context、FR-048 守門不降級、錯誤不再靜默(handler emit 錯誤事件+log);驗收五項含突變測試
  • .3 CM-1192(production image,docker 層):Dockerfile.production(非 root uid1000/entrypoint/apt+fc-match 斷言/volume §5.5)+七項探針 §5.6;先用 36708b35 產物跑通、合流時重打

更正沿革注意(接手必知):nginx http2 誤診已在 Block 14 作廢——.3 的派工 prompt 發出時仍含「避開 http2」字樣(發出在更正之前),驗收 .3 時若 runner 照做了要把該部分退回:nginx 不需任何 http2 特殊處置。

交棒交割:STATE 已定稿(當前狀態/待辦地圖四項+場外/遺留待辦);交接 prompt 已交 user(讀 STATE→LOG→盤點→停)。本任首腦 context 滿載退場,接手者從驗收兩棒開始。


§16

Block 16 — 2026-08-15 晚 第三任首腦(合流執行+全案收口)

角色:接手首腦。本棒與前兩任不同:user 直接令首腦本體執行合流(原 runner session 已失能),故本 block 含執行紀錄。

驗收

  • CM-1206 ✅(commit 6de7ffd8+FE 967e67b):code 抽查(fail-closed 全路徑、UserContextDTO 組裝抽單一實作與 HTTP 等價、DI fixed_modules 有補)+DI --check 綠+guard 測試 6 passed+本機 8002 活體負向探針拒連 PASS
  • .3 CM-1192 ✅(commits 29c4013fcc7714d2 共 3 筆):Dockerfile/entrypoint 實讀(glibc 對齊理由、chown-then-setpriv 設計、fc-match 斷言)+188 image 內實跑 fc-match 解析 NotoSansCJK、業務 .py=0、uid1000;http2 檢查:全部產出 grep 零命中,runner 未踩已作廢誤診

合流執行(皆 188)

  • 插曲:前 session 遺留一份 build 與新起的互撞 → linker crash(undefined reference to module_code_anthropic$_exceptions,判定為共用 nuitka-out 汙染非 code 問題)→ 全清重跑單 build 一次過
  • rebuild 產物 bake cc7714d2摘要報告範本本輪由腳本自動收(上輪手動 cp 欠帳閉環,斷言 OK)
  • build_image(0dcabc8d)→ push Harbor guidant-ai/guidant-ai-be:1.14.0latest(digest bba0449d…);Harbor API 端複驗在位。探針最終輪依 user 指示跳過
  • 發現修正:188 gitlab SSH 金鑰實測可用(runner「無金鑰」為誤判);user 同日立 memory「部署機程式碼一律走 git pull、禁 rsync」

收尾補強: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

  • 依賴關係:FR-064(binary/image 側)與 DB 初始化(資料側)零依賴可平行;兩者皆為 FR-065 前置

教訓

  • 起遠端長任務前先 pgrep 查同類進程——兩份 build 互撞的 crash 症狀(linker undefined reference)像 code 問題,實為 artifact 汙染
  • runner 的「環境不可行」結論(無金鑰)也要親驗——一條 ssh -T git@gitlab.com 就能戳破,誤信就多養一條 rsync 歧路
  • 覆蓋率統計是便宜的守門:--statistics 一行參數,首輪即抓到潛伏死條目

下一步(給接手者):FR-064 期間首腦待命;CM-1207 盤點棒回報後驗收(重點:待裁決清單品質、有無越界寫入);FR-063 文件收尾等 user 令。


§17

Block 17 — 2026-08-15 晚 文件收尾完結(第三任首腦,user 下令後執行)

user 令「收尾直接派 subagent」。兩支平行:

  • SUMMARYhandoff/2026-08-15-FR-063-SUMMARY.md,commit 0e7368a0):八段式,由 LOG 16 blocks 濃縮;抽查過——commits 清單/交付物座標正確,http2 僅以「誤診更正」教訓形式出現(無「避開」指示)
  • analysis 兩篇(commit feccea4e):2026-08-15-nuitka-public-package-exclusion.md(公開套件不需編譯保護推理,含反悔條件)+2026-08-15-nuitka-build-verification-pyramid.md(常數表連坐+驗證金字塔+靜默失效防線);抽查過——皆含選項/取捨/反悔條件四段,數字與 LOG 一致
  • memory:新增 feedback「起遠端 build 前先 pgrep 查同類進程」;MEMORY.md 瘦身至 140 行內(含 FR-063 收案座標、BE 入口 main.py 修正)

範圍裁定:spec/使用手冊不觸發——FR-063 是 build/打包基建,無終端使用者操作變更(啟動方式屬部署文件範疇,已在 deployment-env.md)。

FR-063 至此全案含文件完結。剩餘:本機 4 筆 docs commits 待 user push;CM-1207 盤點棒等 user 派。