docs(debt): ⑤′ 重建的实现约束 —— 静默丢 37 行的可达形态 + 订正 pi 两条理由

① ★★★ 陷阱1/3 成立且可达(我用真表名实测复现):
   重建若写成 DDL 里 4 条**无 BEGIN** 语句(migrate 逐条 Exec ⇒ 各自 auto-commit),
   DROP 后崩 ⇒ 次日启动 CREATE TABLE IF NOT EXISTS 建出空的新 PK 表、守卫见 PK 已新 ⇒ 跳过重建
   ⇒ 实测: agent_platform_sessions 行=0、_new 行=3 ⇒ **判据 (a)(b) 全绿而镜像为 0**
   ⇒ 判据必须加 (c) 断言无 <表>_new 残留(必需,非可选)

② ★★ pi 两条理由需订正(结论对、机制错):
   ① "SQL BEGIN 不生效" ⇒ 我实测 **BEGIN 生效**(BEGIN→DROP→ROLLBACK 表回来了;崩溃后亦完好)
      真因: 本仓 SQLite 走 SetMaxOpenConns(1)(db.go:91)⇒ 池里只有一条连接 ⇒ BEGIN 恰在同连接
      ⇒ 这是巧合不是保证(PG 分支就是 20)⇒ 用 BeginTx 对,但理由应写"正确性依赖 MaxOpenConns(1)"
   ② "实际文本无空格" ⇒ 本仓实际是 PRIMARY KEY (agent_name, platform_id) **有**空格
      失配真因是**它模式里 , 后少了空格** ⇒ 用 pragma 对,但理由应写"LIKE 依赖空白/换行/引号形态"

③ ✅ pi 自撤的"第二次 Migrate 会撞 PK"我也复核为真: 4 语句版天然幂等(run1/2/3 rc=0、行数不变)

④ ✅ 附带事实两条均成立: main.go 两次 Migrate ⇒ 重建必须幂等;
   全仓 REFERENCES agent_platform_sessions = 0 ⇒ 无需处理 FK

⑤ ④ 最终措辞: Go 层事务重建(BeginTx→新表→INSERT SELECT→DROP→RENAME→**同事务内重建索引**)
   ⇒ 与 DDL 批次前后无关 ⇒ 顺序依赖消失(收 pi 这点)
   判据: (a) 迁移路径断言 PK + (b) 断言索引存在 + (c) 断言无 <表>_new 残留

校验: go test ./internal/repo/ -run Debt -count=1 ⇒ ok
This commit is contained in:
2026-09-26 02:55:04 +08:00
parent d46509719f
commit 30079bf003

File diff suppressed because one or more lines are too long