Files
dsh_shenxian/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

47 lines
2.7 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.
# 35 · ws-cleanup 误删平台 bundle 包(P0 回归修复)
- 日期:2026-09-11
- 触发:验证档案 34 时 `apply` 报「安装失败」,追查发现是**与本改动无关的既有 P0**
- 状态:**✅ 已修复(commit `70302e6`)并 dry-run 验证**
## 一、事故
`scripts/ws-cleanup.cjs`(档案 28 用户数据清理)的 T1 规则:
```js
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/` 补上了这个缺口。