Files
Arcrun/system-dev/docs/5-records/2026-06-24-official-kbdb-cleanup-leo-misdelete.md
T
uncle6me-web 5d00e71275 chore: D22 落地——docs/SDD/wiki/CLAUDE.md 進 repo(Gitea private 預設全 push)
頂層 D22 決策(leo 2026-07-03 拍板):推什麼由開發環境歸屬決定,
Gitea private=除機敏值/build 產物/.github 外全 push。
解 T1.5 卡點:雲端工人 clone 拿得到 credential-store-migration.md,可就地改寫 SDD。
機敏掃描兩輪通過(新增 189 檔約 2.1MB,node_modules/dist/wasm 照舊排除)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 07:13:33 +08:00

145 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 官方 KBDB 誤寫清理 SOPissue #3 待辦 1
> **狀態**runbook 已備妥,**待官方運營方(leo)親自執行**。
> **為什麼不由 CC 直接跑**:對官方 prod D1 執行不可逆 `DELETE`,需官方憑證 + 人類明示確認
> (mindset §7「絕不代替人類做有風險的確認」;rule 06)。CC 只備妥可審、防誤刪的腳本,DELETE 由人按下。
> **來源**issue #3leo 2026-06-24 拍板,14-E 遷移善後)。根因 bug 已修(issue #2commit 9c4333d)。
---
## 背景
14-E 遷移期間(issue #2`KBDB_BASE_URL` fallback bug 修好**之前**),mira 的 `_kbdb_client.py`
**~11 萬筆 `owner_id='leo'`** 的資料誤寫進**官方 prod kbdb**`arcrun-kbdb`,非 leo21c self-hosted)。
- **歸屬**:官方 SaaS 庫的清理 = arcrun 官方運營方的事,不是 mira(用戶)。讓用戶拿官方憑證 DELETE 官方 prod 本身違反隔離。
- **重要性**:SaaS 尚未營運,這批誤寫資料不重要 → 可刪。但**官方 prod DELETE 不可逆 → 必須防誤刪**。
---
## 目標庫(精確座標)
| 項目 | 值 |
|------|-----|
| Worker / DB name | `arcrun-kbdb` |
| D1 database_id | `0c580910-e00b-4f8e-9c57-ac54ea52242f`(官方 prod,見 `kbdb/wrangler.toml:13` |
| 官方 CF account | `58309bb9…`(記憶 [[cf-account-official-vs-loadtest]] |
| 誤寫標記 | `entries.owner_id = 'leo'` |
⚠️ **帳號對齊**:執行前確認本機 wrangler 對的是**官方帳號**(不是 leo21c)。
`wrangler whoami` 應顯示官方 uncle6.me account。誤寫在官方庫,所以這次**就是要對官方帳號**操作
(與 self-hosted 部署相反,那邊要避開官方——見記憶 [[selfhosted-deploy-account-override-trap]])。
---
## 表關係(決定刪除範圍)
base 三表(`kbdb/migrations/0001_base.sql`):
- `entries`:主表,誤寫資料在這(`owner_id='leo'`)。
- `entry_values`slot-link`entry_id REFERENCES entries(id)`。若 leo 資料含 record(用 template 組的結構化資料),
其 slot 連結在這。**刪 entries 會留下孤兒 entry_values** → 要一併清。
- `templates``created_by` 可能是 `'leo'`。**先確認** leo 有沒有建 template(待辦 2 步驟會查),
template 較可能是共享/誤建,刪前單獨核實。
---
## SOP(逐步,每步有 gate,防誤刪)
> 全程用 `wrangler d1 execute arcrun-kbdb --remote --command "..."`。**`--remote` 不可漏**(漏了打本地空庫,假綠)。
### 步驟 0:帳號 + 庫核實(gate)
```bash
wrangler whoami # 確認 = 官方 uncle6.me account58309bb9
wrangler d1 info arcrun-kbdb # 確認 database_id = 0c580910...
```
### 步驟 1:備份(整庫導出,防誤刪的底氣)
```bash
wrangler d1 export arcrun-kbdb --remote --output backup-before-cleanup-2026-06-24.sql
ls -lh backup-before-cleanup-2026-06-24.sql # 確認檔案非空、大小合理
```
### 步驟 2:標記 / 核實刪除範圍(**最關鍵的 gate**)
```bash
# 2a. 誤寫總數(應 ~11 萬)
wrangler d1 execute arcrun-kbdb --remote --command \
"SELECT count(*) AS leo_entries FROM entries WHERE owner_id='leo';"
# 2b. 關鍵確認:owner_id='leo' 是否只有這批誤寫,有沒有別的 leo 真資料混入
# 看 entry_type 分布 + 時間範圍(誤寫應集中在 14-E 遷移那段時間)
wrangler d1 execute arcrun-kbdb --remote --command \
"SELECT entry_type, count(*) AS n, min(created_at) AS first_at, max(created_at) AS last_at \
FROM entries WHERE owner_id='leo' GROUP BY entry_type ORDER BY n DESC;"
# 2c. 孤兒 entry_values(會被 entries 刪除留下的)
wrangler d1 execute arcrun-kbdb --remote --command \
"SELECT count(*) AS leo_entry_values FROM entry_values \
WHERE entry_id IN (SELECT id FROM entries WHERE owner_id='leo');"
# 2d. leo 建的 template(單獨核實,勿盲刪——可能是共享/系統 template 誤標)
wrangler d1 execute arcrun-kbdb --remote --command \
"SELECT id, name, created_by FROM templates WHERE created_by='leo';"
```
**Gate 判定**(人類看數字決定):
- 2a count ≈ 11 萬、2b 時間集中在遷移期 → 範圍乾淨,可進步驟 3。
- 若 2b 出現非遷移期、或 entry_type 異常 → **停手**,逐筆核實,別整批刪。
- 2d 若有 template → 個別判斷是否該刪(template 通常想保留,除非確認是誤建)。
### 步驟 3:刪除(確認範圍乾淨後)
```bash
# 3a. 先刪孤兒 entry_values(外鍵指向即將被刪的 entries)
wrangler d1 execute arcrun-kbdb --remote --command \
"DELETE FROM entry_values WHERE entry_id IN (SELECT id FROM entries WHERE owner_id='leo');"
# 3b. 再刪 entries
wrangler d1 execute arcrun-kbdb --remote --command \
"DELETE FROM entries WHERE owner_id='leo';"
# 3c.(可選,僅當步驟 2d 確認某 template 是誤建才刪)
# wrangler d1 execute arcrun-kbdb --remote --command \
# "DELETE FROM templates WHERE created_by='leo' AND id='<確認過的 id>';"
```
### 步驟 4:驗證(刪後核實)
```bash
# 4a. leo 誤寫歸零
wrangler d1 execute arcrun-kbdb --remote --command \
"SELECT count(*) AS remaining_leo FROM entries WHERE owner_id='leo';" # 應 = 0
# 4b. 孤兒 entry_values 歸零
wrangler d1 execute arcrun-kbdb --remote --command \
"SELECT count(*) AS orphan_ev FROM entry_values \
WHERE entry_id NOT IN (SELECT id FROM entries);" # 應 = 0
# 4c. 官方庫其餘資料不受影響(總 entries 數應 = 刪除前總數 - 11 萬)
wrangler d1 execute arcrun-kbdb --remote --command \
"SELECT owner_id, count(*) AS n FROM entries GROUP BY owner_id ORDER BY n DESC;"
```
### 步驟 5:收尾
- 4a/4b/4c 符合預期 → 清理完成。
- 備份檔(`backup-before-cleanup-2026-06-24.sql`)可棄(SaaS 未營運,無長期保留必要)。
- 在 issue #3 comment 回報:刪除數量 + 驗證 count + 確認官方庫其餘不受影響。
---
## 為什麼這樣設計(防誤刪三道閘)
1. **備份先行**(步驟 1):DELETE 不可逆,先有 d1 export 的整庫快照當底氣。
2. **核實再刪**(步驟 2 gate):不盲信「~11 萬都是誤寫」,看 entry_type + 時間分布確認範圍乾淨,
排除別的 leo 真資料混入(issue #3 待辦 1 步驟 2 的「關鍵確認」)。
3. **驗證歸零**(步驟 4):刪後客觀證據(count=0 + 孤兒=0 + 其餘不受影響),不靠「跑完了」口頭宣布
(mindset §7 完成=客觀證據)。
## 待辦 2(願景)落點
`acr migrate` 一等公民雙向遷移已記頂層 `docs/1-vision/product-wishlist.md` C7 + 本 repo backlog,不急做。
詳見 issue #3 待辦 2。