只追加、不改寫既有 block。 每棒一個 block:commits/決策/教訓/推翻了什麼。
卡:CM-1756(驗收棒,不改檔) commits:無(純驗收,未改任何檔;本檔為新增) 前置:.1a CM-1753、.1b CM-1754、.1c CM-1755 均已 Done
.venv/lib/python3.11/site-packages/jedi_asset/migrations/002-asset-rls-grants.sql enum RENAME VALUE 段落在 120-146 行,之後(147-159 行)只有 GRANT 語句,沒有任何 INSERT/UPDATE 用到新值。核無問題,不需拆 003。
DEV(localhost:5432 / guidant_ai_dev)套前 \dT+ 兩型別已全小寫 (operational, under-development, disposition, under-major-modification, other / low, moderate, high)——CM-1678 手套過。schema_migrations 內 packages/% 為 23 筆,確認 jedi_asset/002 尚未登記(符合 .1c 的刻意排除)。
跑 MIGRATE_SQL_DIR=$(pwd)/scripts/sql MIGRATE_DB_NAME=guidant_ai_dev MIGRATE_DB_USER=cmmgr MIGRATE_APPLY=0 bash scripts/init/migrate.sh:
[migrate] 目標:cmmgr@localhost:5432/資料庫 guidant_ai_dev
[migrate] 模式:dry-run(不寫入)
[migrate] 已套 189 支(主線+套件合計)
[migrate][error] 資料庫缺少 __init_baseline_* 標記——這個庫不是由 scripts/init/ 建立的。
升級只能套在 installer 建出來的資料庫上;請確認 MIGRATE_DB_NAME 是否正確。
根因:DEV 是主線 align_migrations.sh 管理的舊制庫,schema_migrations 裡的 哨兵是 __baseline_pre_2026-05-28__,不是 migrate.sh 要求的 __init_baseline_v*__ (那是 installer 建庫才會有的 marker,見 99-stamp.sql)。migrate.sh 的這道檢查 (scripts/init/migrate.sh:92-95)是刻意設計成「只認 installer 建的庫」,本意是擋 「拿錯庫套」,但也連帶把「舊制 DEV 想借用 migrate.sh 的第二輪套件差集邏輯」這條路堵死。
而主線 align_migrations.sh(DEV 現行套用工具)完全沒有套件 migration 的第二輪邏輯 (grep -n "packages\|PKG" scripts/align_migrations.sh 零命中)——它只認 scripts/sql/manifest.tsv,不知道 scripts/sql/packages/manifest.tsv 的存在。
結論:目前沒有一條路徑能讓 DEV 這種舊制庫套用 packages/jedi_asset/002:
migrate.sh 有邏輯但拒絕非 installer 建的庫align_migrations.sh 認 DEV 但沒有套件差集邏輯這是 design 沒講透的缺口(design.md §5.1⑦(a) 只討論了「新裝 vs 升級」的 enum 終態 不一致,沒討論「舊制既有庫(DEV/STG/POC/客戶既有安裝)根本套不到套件 migration」 這個更前面的問題)。已回寫本卡,未自行修改任何腳本。
guidant_ai_fresh_cm1756)—— 驗證了設計已預見的不一致用 scripts/init/init.sh 對本機 cmmgr(本身即 superuser)建一顆全新庫:
INIT_DB_HOST=localhost INIT_DB_PORT=5432 INIT_DB_NAME=guidant_ai_fresh_cm1756 \
INIT_SUPERUSER=cmmgr INIT_SUPERUSER_PASSWORD=<.env DB_PASSWORD> \
INIT_CMMGR_PASSWORD=<同上> INIT_CMAPP_PASSWORD=<同上> \
bash scripts/init/init.sh
結果:✅ init 完成:資料庫 guidant_ai_fresh_cm1756 已就緒(167 表/106 policy/ 缺權限表 0/缺 USAGE sequence 0)。
init 後立即查兩型別(未跑 migrate):
system_status_enum: OPERATIONAL, UNDER_DEVELOPMENT, DISPOSITION, under-major-modification, other
security_sensitivity_level_enum: LOW, MODERATE, HIGH
大寫混雜(02-schema.sql 建的原始定義,符合預期——02-schema.sql 尚未跟著 CM-1678 的 enum 修正走)。schema_migrations 內 packages/% 已是 24 筆(含 jedi_asset/002),因為 99-stamp.sql 在 .1c 時已把 24 支套件檔全部登記為 「converged into __init_baseline_v1.19.0__」——新裝庫從一出生就被標記「002 已收斂 進基線」,但基線 schema(02-schema.sql)實際上還是舊的大小寫混雜值。
跟著跑 migrate.sh dry-run 驗證這個「假裝已套」的狀態確實會讓 migrate 判定零待套:
[migrate] 已套 177 支(主線+套件合計)
主線待套 0 支(無,主線已與本版對齊)
套件待套 0 支(無,套件已與本版對齊)
✅ 無待套項目,資料庫結構已是最新
驗證了 design.md §5.1⑦(a) 的預警是真的:新裝路徑的 enum 終態=大寫混雜(永遠 不會被 002 修正,因為 99-stamp 已把它標記為「基線已收斂」,migrate 差集看不到它); 升級路徑(真正走過 002 的庫)的 enum 終態=小寫。兩條路徑的終態不一致,且新裝 路徑目前沒有任何機制會讓它變成小寫(02-schema.sql 本身沒改、99-stamp 又把 002 標記成已收斂)。
臨時庫已 DROP DATABASE guidant_ai_fresh_cm1756 清除。
Q1(②的前提缺口,新發現,design 未討論):DEV/STG/POC/既有客戶庫是舊制 align_migrations.sh 管的庫,沒有 __init_baseline_v*__ marker,migrate.sh 拒絕 它們。這些庫要怎麼真的套上 packages/jedi_asset/002? 選項可能是: (A) 放寬 migrate.sh 的 marker 檢查,改認舊制 __baseline_pre_* 也算合法目標; (B) 幫舊制庫補一個 __init_baseline_v*__ marker(等於承認它已收斂到某版基線); (C) DEV 另外直接用 psql --single-transaction 手套 002(繞過 migrate.sh,僅限 內部環境,正式客戶升級仍需 migrate.sh 能動); (D) 其他。
Q2(③卡上已預見的選項,design §5.1⑦(a) 沒講透):新裝路徑的 002 天生被 99-stamp 標記為已收斂、不會真的套,enum 終態停在大寫混雜,與升級路徑(小寫)不 一致。選項: (A) gen_stamp_sql.sh 補登清單排除 jedi_asset/002(讓新裝也走一次真套用, 需求是它必須是冪等且不依賴其他已收斂的表結構——已核對過,002 只有 FK/NOT NULL/enum RENAME/GRANT,都可對剛建好的 02-schema.sql 冪等執行); (B) 修 02-schema.sql 基線把兩個 enum 定義直接改小寫並重生(動基線,違反 D3「不手改 02/04/05,只能靠 regenerate」精神,且 02-schema.sql 是從基線庫 dump 出來的,要先把基線庫本身的 enum 也改小寫); (C) 接受不一致,記錄為已知缺口。
runner 判斷:Q1 是更急迫的問題——它代表現有機制目前完全無法讓任何真實既有庫 (含未來客戶的既有安裝)吃到 002 這類套件 migration,不只是「enum 終態不一致」的 美觀問題,而是「升級鏈本身對舊制庫失靈」。Q2 則是 Q1 解掉後才會實際發生的次要不一致。
| 項目 | DEV(升級路徑) | 臨時庫(新裝路徑,未跑 migrate) |
|---|---|---|
system_status_enum |
小寫(CM-1678 已手套過) | 大寫混雜(02-schema.sql 原始值) |
security_sensitivity_level_enum |
小寫 | 大寫混雜 |
packages/% 筆數 |
23(不含 002) | 24(含 002,但只是登記非實套) |
migrate.sh dry-run |
拒絕(缺 __init_baseline_v*__) |
主線 0/套件 0(誤判已對齊) |
① 「.1c 已補登 23/獨留 002 給 .1d 驗收」的假設,卡在更前面一關——DEV 根本不是 migrate.sh 認得的目標庫。design 只想到「002 該不該被新裝路徑收斂」,沒想到 「migrate.sh 本身的守門條件排除了 DEV 這種舊制庫」。開卡前對「這條路走不走得通」 的假設要親手跑一次 dry-run 驗證,不能只看 manifest 差集算出來的數字。
② 新裝路徑的「packages/% = 24」不能只看筆數,要對照 enum 實際值——筆數對的 上不代表真的套了,99-stamp 的「收斂進基線」登記本身就是一種「假裝已套」,卡上明確 提醒了這點(「這裡要想清楚」),驗證時確實要交叉看兩個指標。
首腦唯讀複驗兩個發現屬實,並修正 Q1 的範圍判斷:runner 原判斷「DEV/STG/POC/ 既有客戶都是同一種舊制庫」不對——實查 STG(188 stack)與 POC(189 stack)哨兵都是 __init_baseline_v1.14.0__,是 installer 建的庫,migrate.sh 對它們是通的。舊制 庫只有 DEV 與 188 基線庫兩個,客戶端沒有這個問題。Q1 因此不是「升級鏈對舊制庫 失靈」的系統性問題,只是「DEV 這顆內部庫怎麼套」——答案就是 DEV 一貫的 SOP: psql --single-transaction 手套、補登 schema_migrations。migrate.sh 的 marker 守門是對的,不放寬。
Q2 屬實且需修:新裝庫被 stamp 標「002 已收斂」但 02-schema.sql 基線仍大寫,標記 是假的。首腦建議正規解法是「migration 先套基線庫、再重產 02」(對 188 基線庫套 002 並登記 → 重產 02-schema.sql → enum 變小寫 → 99-stamp 的「已收斂」才是真的), 不採 (A) 排除 002 讓新裝再套一次(純 init 路徑沒有 migrate 步驟,仍會留大寫)、 不採 (B) 手改 02(違反 D3)。動基線庫屬出貨基線寫入,決策者裁示先不做(見下)。
決策者裁定(2026-09-14):一律只在本機,不套 188。
localhost:5432)用 psql --single-transaction -v ON_ERROR_STOP=1 手套 jedi-asset 002,補登一列進 schema_migrations。migrate.sh marker 守門 不放寬。卡:CM-1756(續做,接續第 4 棒) commits:無邏輯檔案改動(純 DB 操作+本 LOG 追記)
Step 1:DEV 真套 002
套前狀態確認(與第 4 棒一致,無漂移):enum 皆小寫、packages/%=23(不含 002)。
PGPASSWORD=*** psql -h localhost -p 5432 -U cmmgr -d guidant_ai_dev \
--single-transaction -v ON_ERROR_STOP=1 \
-f scripts/sql/packages/jedi_asset/002-asset-rls-grants.sql
輸出:DO ×15/ALTER TABLE ×3,無錯誤(enum RENAME 因舊 label 已不存在,判斷式 跳過,符合冪等預期——DEV 早被 CM-1678 手套過,這次是把「登記」補齊,不是第一次 真的改變 enum 值)。
補登:
INSERT INTO public.schema_migrations(filename, note)
VALUES ('packages/jedi_asset/002-asset-rls-grants.sql',
'applied by CM-1756 (FR-093.1d) manual apply per 決策者裁定 2026-09-14')
ON CONFLICT (filename) DO NOTHING;→ INSERT 0 1。套後 packages/%=24,含 002 且 note 正確。套後 \dT+ 仍 小寫(未變,符合預期)。
Step 2:188 基線庫——未連線、未操作,符合裁定。
Step 3:本機臨時庫二次驗證新裝路徑
用 scripts/init/init.sh 建 guidant_ai_fresh_cm1756_v2(腳本與檔案自第 4 棒起 未變動),init 成功(167 表/106 policy/缺權限 0)。
system_status_enum: OPERATIONAL, UNDER_DEVELOPMENT, DISPOSITION, under-major-modification, other
security_sensitivity_level_enum: LOW, MODERATE, HIGH
packages/% 筆數: 24
大寫混雜,與第 4 棒結果一致——確認 Q2 缺口仍在(DEV 手套不影響新裝路徑,兩者 互不干擾,符合預期:DEV 是既有庫走升級 SOP,新裝路徑走 02-schema.sql,兩條線 在基線庫未套 002 前天然分岔)。臨時庫已 DROP DATABASE 清除。
本卡狀態:Q1 已完全解決(DEV 已真套+補登,packages/%=24 且非假登記)。 Q2 是已知缺口,待日後排定時間對 188 基線庫套 002+重產 02-schema.sql(出貨前 待辦,非本卡範圍)。回寫 Notion 卡→改「修正待驗證」。