From f87d0e92f49690253e7c89c5badc82a08eb5d21b Mon Sep 17 00:00:00 2001 From: uncle6me-web Date: Wed, 12 Aug 2026 21:10:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(migrations):=200005/0006=20=E5=BE=9E?= =?UTF-8?q?=E4=BE=86=E6=B2=92=E9=80=B2=E9=81=8E=E7=89=88=E6=8E=A7=E2=80=94?= =?UTF-8?q?=E2=80=94=E8=A2=AB=20`*.sql`=20=E8=A6=8F=E5=89=87=E5=90=83?= =?UTF-8?q?=E6=8E=89=EF=BC=8C=E6=AF=8F=E5=80=8B=E7=94=A8=E6=88=B6=E9=83=BD?= =?UTF-8?q?=E6=94=B6=E5=88=B0=E3=80=8C=E9=83=A8=E7=BD=B2=E7=89=A9=E7=BC=BA?= =?UTF-8?q?=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit leo 更新 leo21c 時撞到(他問「部分失敗?」): ✗ D1 migration: 部署物缺 kbdb/migrations/0005_credential_template.sql ✗ D1 migration: 部署物缺 kbdb/migrations/0006_drop_credentials_table.sql (四顆 worker cypher/registry/kbdb/mcp 全部 ✓,失敗的只有這兩個檔) 根因不是誰忘了推:.gitignore:53 的 `*.sql` 是為了擋 D1 匯出備份(整庫全量=機敏), 但它連 migration 一起吃掉。0001-0004 還在,只因為它們在該規則之前就 commit 了 (gitignore 不影響已追蹤檔案)⇒ 0005/0006 從產生那天起就不在任何 clone 裡。 ⇒ 這不是 leo 一台的事:更新指令從 Gitea 抓 main,那兩個檔不在那裡 ⇒ **任何人裝/更新都會收到同一組失敗**,包含全新安裝。 修法照 rules/05-deploy-convention.md「WASM 來源」段已有的慣例 (`.component-builds/**/component.wasm` 就是用否定規則放行的): !kbdb/migrations/*.sql 範圍實測(沒開太大): kbdb/migrations/0005、0006 → 放行 backup-2026.sql / kbdb/backup-x.sql / dump.sql / cypher-executor/export.sql → 仍被擋 進版控前確認過無機敏值:grep 命中的 token/secret/api_key 全是欄位名 (api_key、secret_ref)與註解;無 >=20 位英數的疑似真值。 殘項:leo21c 實查 templates 9 個、credential 不在其中 ⇒ 0005 從未套用, 那台仍停在 D38 之前(credentials 走 0002 的獨立表)。要補套需另跑一次更新。 Co-Authored-By: Claude Opus 5 --- .gitignore | 8 ++++ kbdb/migrations/0005_credential_template.sql | 25 ++++++++++ .../0006_drop_credentials_table.sql | 47 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 kbdb/migrations/0005_credential_template.sql create mode 100644 kbdb/migrations/0006_drop_credentials_table.sql diff --git a/.gitignore b/.gitignore index 290ebcf..bd2d7d4 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,14 @@ scripts/__pycache__/ # D1 備份/匯出(wrangler d1 export 產物,含整庫全量資料=機敏,絕不 commit) *.sql backup-*.sql +# 🔴 但 migration 不是備份,它是**要出貨的程式碼**(2026-08-12 實撞): +# 上面那條 `*.sql` 的用意是擋 D1 匯出(整庫全量資料=機敏),卻連 migration 一起吃掉。 +# 後果:0001-0004 因為在該規則之前就 commit 所以還在,**0005/0006 從此沒進過版控** +# ⇒ 更新指令從 Gitea 抓 main,那兩個檔根本不在那裡 ⇒ 每個用戶都會收到 +# 「✗ D1 migration: 部署物缺 kbdb/migrations/0005…」——**不是誰忘了推,是規則吃掉的**。 +# ⇒ 與 `.component-builds/**/component.wasm` 同慣例(見 rules/05-deploy-convention.md +# 「WASM 來源」段),用否定規則放行。備份檔仍由 `backup-*.sql` 與目錄位置擋住。 +!kbdb/migrations/*.sql # GitHub 公開 mirror 工作目錄(publish-github.sh 產物) .github-public/ diff --git a/kbdb/migrations/0005_credential_template.sql b/kbdb/migrations/0005_credential_template.sql new file mode 100644 index 0000000..e1a713e --- /dev/null +++ b/kbdb/migrations/0005_credential_template.sql @@ -0,0 +1,25 @@ +-- credential template seed(D38 圍牆修復,總管交辦,2026-08-07) +-- SDD:無專屬 SDD(D38 事故修復任務,見 system-dev/wiki/decisions-summary.md D38 段)。 +-- +-- D38 鐵律(leo 2026-06-14 立、2026-08-07 擴大):KBDB 三張表打天下,永遠不加新表; +-- 新資料類型一律用 template + entries,同 0003_library_map.sql / 0004_execution_log_template.sql +-- 的手法——對 templates 表 INSERT OR IGNORE 一列定義,不建新表、不動既有表的結構。 +-- +-- 這是「credential 目錄」的第二個家:原本 0002_credentials.sql 在 KBDB 裡多開了一張 +-- 獨立表(違規,見 kbdb-usage skill「反例」),本檔 + 0006_drop_credentials_table.sql +-- 把它改回三張表的形狀——一筆 credential=entries 表一列(entry_type='credential', +-- page_name=name 當冪等鍵,owner_id=api_key 做租戶隔離,其餘欄位打包進 metadata_json), +-- 儲存精神比照既有 recipe_stat / execution_log(template 只負責文件化,實際資料不走 +-- entry_values 全展開的多列 record)。 +-- +-- 密文本體不在這裡:值仍住在 CF Workers per-script Secrets(掛在 cypher worker 上,管理 +-- API 唯寫,D19「擁有目錄,不擁有內容物」不變)。這張 template 定義的 slots 全部是目錄 +-- 欄位,零密文——與舊 0002_credentials.sql 的欄位定義一字不變,只是換了個家。 +INSERT OR IGNORE INTO templates (id, name, description, slots_json, created_by) +VALUES ( + 'tpl-credential', + 'credential', + 'credential 目錄(D38 圍牆修復:改走 entries 表 entry_type=credential,取代舊 credentials 表;零密文,密文本體住 Workers per-script Secrets)', + '["name","service","sensitivity","secret_ref","last_used_at"]', + 'system' +); diff --git a/kbdb/migrations/0006_drop_credentials_table.sql b/kbdb/migrations/0006_drop_credentials_table.sql new file mode 100644 index 0000000..cb93bad --- /dev/null +++ b/kbdb/migrations/0006_drop_credentials_table.sql @@ -0,0 +1,47 @@ +-- 退役 credentials 表(D38 圍牆修復,總管交辦,2026-08-07) +-- SDD:無專屬 SDD(D38 事故修復任務,見 system-dev/wiki/decisions-summary.md D38 段)。 +-- +-- 這是本次唯一真的需要動表結構的一支 migration,理由(不是繞過鐵律,是鐵律要求的收尾): +-- D38 要求 KBDB 回到「只有三張核心表」的狀態。0002_credentials.sql 當初在 KBDB 裡多開了 +-- 一張獨立表,是已知違規(kbdb-usage skill 明文列為反例)。要把違規清乾淨,唯一辦法就是 +-- 真的把那張表拆掉——拆表本身不能只用 API 做(API 不提供「拆表」這種牆內維運操作, +-- 也不該提供),所以下面兩句 SQL 標 kbdb-sql-ok:這不是繞過圍牆去存取資料,是圍牆施工 +-- 本身(kbdb/migrations/ 就是牆內,本檔存在的唯一目的就是讓舊表退場)。 +-- +-- 冪等設計(deploy.ts 每次部署都會重跑這支檔案,沒有 migration 追蹤表): +-- 1. 先補一份空表存在保底——self-hosted 各實例套用進度不一,有些從沒跑過 0002(表從不 +-- 存在)、有些已經跑過本檔一次(表已被拆)。沒有這一步,下面的搬資料/退場語句會因表 +-- 不存在直接整支失敗(D1 對不存在的表沒有條件式跳過語法)。 +-- 2. 把舊表裡「entries 還沒有對應列」的 row 搬進 entries(entry_type='credential', +-- page_name=name 冪等鍵,owner_id=api_key,其餘欄位打包進 metadata_json,欄位對應 +-- 0005_credential_template.sql 定義的 slots)。NOT EXISTS 判斷防止重跑造成重複列。 +-- 3. 搬完資料後表就沒有存在的理由,最後一步讓它退場。下次部署若又被步驟 1 重新墊一份 +-- 空殼,也只是空表、立刻搬 0 筆、立刻退場,不影響任何人(真資料只會被搬一次,因為 +-- 步驟 2 的判斷是看 entries 裡有沒有,不是看這是不是第一次跑)。 +CREATE TABLE IF NOT EXISTS credentials ( -- kbdb-sql-ok: 表退場施工步驟①保底存在,非資料存取違規,理由見檔頭 + api_key TEXT NOT NULL, + name TEXT NOT NULL, + service TEXT, + sensitivity TEXT NOT NULL DEFAULT 'standard', + secret_ref TEXT NOT NULL, + created_at INTEGER NOT NULL, + last_used_at INTEGER, + PRIMARY KEY (api_key, name) +); + +INSERT INTO entries (id, entry_type, owner_id, page_name, metadata_json, created_at, updated_at) +SELECT + 'e_cred_' || lower(hex(randomblob(8))), + 'credential', + c.api_key, + c.name, + json_object('service', c.service, 'sensitivity', c.sensitivity, 'secret_ref', c.secret_ref, 'last_used_at', c.last_used_at), + c.created_at, + unixepoch() +FROM credentials c +WHERE NOT EXISTS ( + SELECT 1 FROM entries e + WHERE e.entry_type = 'credential' AND e.owner_id = c.api_key AND e.page_name = c.name +); + +DROP TABLE IF EXISTS credentials; -- kbdb-sql-ok: 表退場施工步驟③讓舊表退場,非資料存取違規,理由見檔頭