Files
dsh_ai1net_server/dsh-server-docs/04-调整方案/35-ws-cleanup误删平台bundle包.md
T
admin 5ad755116e chore(docs): 文档库并入代码仓(R4 选 a)+ 索引/台账跟进
1) dsh-server-docs/ 从工作区(原 E:\...\aliyun-dsh-server\dsh-server-docs)**整体并入本仓**,
   保留目录名 ⇒ 仓库内 dsh-server-docs/... 的相对引用天然继续有效;旧目录(含其 .git)已归档到
   工作区 _中间产物_待清理/,未随本提交带入。
2) .gitattributes:新增 `dsh-server-docs/** -text` —— 原文档库是 `* -text` + autocrlf=false,
   必须保持纯 LF,否则会被本仓的 CRLF 规则翻掉。
3) 活引用里的绝对路径已全部改到新位置(docs 的 INDEX / README / scripts / skills + 用户级 skills
   + ~/.workbuddy/settings.json 的 hooks);历史档案(04-调整方案/、archive/)按「只增不改」未动。
   ⚠️ hooks 路径改动需「完全重启会话」才生效(配置是会话启动快照)。
4) 交接单/T08:新增 §16「生产整体切换执行记录」(形态 / 落地动作 / **4 个只有真上线才暴露的真 bug** /
   验收证据 / 回滚命令 / 残留项);台账 T08 行 → 已完成并归档;03-路线图 §二 登记 T08 收尾项。
5) 统一称谓:**「本机」只指跑 WorkBuddy 的开发机**,47 / 106 一律写「远程服务器」。
2026-09-15 18:47:13 +08:00

2.7 KiB
Raw Blame History

35 · ws-cleanup 误删平台 bundle 包(P0 回归修复)

  • 日期:2026-09-11
  • 触发:验证档案 34 时 apply 报「安装失败」,追查发现是与本改动无关的既有 P0
  • 状态:✅ 已修复(commit 70302e6)并 dry-run 验证

一、事故

scripts/ws-cleanup.cjs(档案 28 用户数据清理)的 T1 规则:

const T1_SUFFIX = ['.tgz', '.tmp', '.log', '.bak', '.part', '.crdownload']
...
const keepAll = existsSync(join(ws, '.keep'))
if (keepAll && t2.length > 0) { /* .keep 只豁免 T2 */ }

→ ws 顶层的 .tgz 被无条件删除,.keep 也豁免不了。

而平台三个自建 bundle 是以 file:<ws>/xxx.tgz 安装进 profile 的: @dsh-local/portal-entry / @dsh-local/business-plugins / @dsh-local/workspace-scoped-picker。

后果链:清理一跑 → tgz 消失 → profile 的 dependencies 指向不存在的文件 → 之后任何 pnpm 操作都 ENOENT 失败(用户侧「启用/禁用功能插件」正在此列)。

实测现状:admin 三个包全丢、guest 丢一个。之所以一直没被发现:node_modules 已经装好,实例照常运行,问题只在下一次 pnpm 操作时才爆发。

二、修复(不依赖硬编码文件名)

ws-cleanup.cjs 在扫描每个用户前,先读该用户所有 profile 的 file: 依赖,得到「被引用的 ws 文件名」集合 protectedNames → 循环里这些文件豁免 T1(体积计入「资产」而非「垃圾」)。

配套:把三个平台包重建到 /opt/dsh/artifacts/(portal-entry-0.4.3 / business-plugins-0.1.0 从 04-调整方案/poc/ 源码重新打包;workspace-scoped-picker-0.1.4 用现成产物),并幂等地放回各用户 ws(只在缺失时补,不覆盖用户文件)。

三、验证

node scripts/ws-cleanup.cjs(dry-run):

用户 修复前 T1 修复后 T1
admin 4 项(.local + 3 个 .tgz) 1 项(只剩 .local)
guest 2 项(.cache + 1 个 .tgz) 1 项(只剩 .cache)

三个 .tgz 全部转为「资产」;pnpm add 恢复正常(档案 34 的隔离实测得以继续跑完)。

四、教训

  1. T1「精确名或后缀」规则与「平台自己用 file: 引用的产物」天然冲突 —— 任何"按后缀删垃圾"的策略,都必须先排除"被其它组件引用的文件"。
  2. 这类 bug 的隐蔽性来自"延迟爆发":删掉的是安装源,运行时不报错,只在下次安装时炸。→ 清理类脚本的验证不能只看"实例还能跑"。
  3. 04-调整方案/poc/ 里的源码是唯一可重建平台 bundle 的副本(仓库里没有),/opt/dsh/artifacts/ 补上了这个缺口。