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 一律写「远程服务器」。
47 lines
2.7 KiB
Markdown
47 lines
2.7 KiB
Markdown
# 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/` 补上了这个缺口。
|