Files
dsh_ai1net_server/dsh-server-docs/04-调整方案/28-用户数据清理策略.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

79 lines
6.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.
# 28 · 用户数据清理策略(工作区 / 会话 / 回收站)
- 日期:2026-09-11
- 背景:用户提出「**AI 生成的代码和脚本等才是需要定期清理的重点**」,并明确「这些脚本基本都是根据某个对话任务产生,**没有复用价值**」;同时要求「会话记录达到某个大小阈值后,可清除 90 天前的记录」。
- 结论一句话:**已落地三件套**(`ws-cleanup` 工作区清理 / `session-gc` 会话回收 / `purge-trash` 回收站清空)+ **修掉一个平台自身 bug**(pnpm store/cache 污染用户工作区);全部走"**先 mv 到回收站、30 天后才真删**"。
## 一、先说结论:谁在吃盘
| 用户 | 清理前 ws | 其中"平台产物" | 真正用户内容 | sessions |
|---|---|---|---|---|
| admin | 18 MB / **2045 文件** | **17.6 MB**(pnpm store 16.1M + cache 1.5M + 6 个 tgz + poc/.poc-backup) | 92 KB | 708 KB |
| guest | 2.5 MB / 30 文件 | 2.0 MB(cache 1.8M + store 180K + 3 个 tgz) | 504 KB | 1.1 MB |
> **发现(平台 bug)**:安装脚本原用 `HOME=<用户 ws> pnpm add …` → pnpm 把 **store**(`$HOME/.local/share/pnpm/store`)与 **cache**(`$HOME/.cache/pnpm`)写进了**用户工作区**,再加我们复制进去的 `*.tgz`、`poc/`。这不是 AI 产物,是**平台自己制造的污染**,且掩盖了真正要治理的对象。
> **已修**:安装改为 `--store-dir <home>/.pnpm-store --cache-dir <home>/.pnpm-cache` + 直接用 `/opt/dsh/artifacts/` 的 tgz(不再复制进 ws)。
> **已清**:存量污染 `mv` 到 `<userRoot>/trash/2026-09-11-ws-pollution/`;效果 **admin 18M/2045 文件 → 12K/0 文件**、**guest 2.5M/30 → 480K/8**;并实测清理后真实 dsh 仍正常启动、插件正常加载。
## 二、清理策略:三档分类(判定依据只有"路径/文件名模式 + 年龄")
**前提说明**:**无法按"是不是 AI 生成的"判定**(没有可靠标记),所以规则只认**模式 + 年龄**,并强制分档:
| 档 | 对象 | 规则 | 动作 |
|---|---|---|---|
| **T1 平台产物/明确垃圾** | `ws/{.local,.cache,.poc-backup,poc,__pycache__,.pytest_cache,node_modules,.ipynb_checkpoints}`、`*.tgz/.tmp/.log/.bak/.part/.crdownload` | 白名单**精确匹配** | 达阈值即清(mv 到回收站) |
| **T2 一次性临时脚本** | `ws` **顶层**的 `*.py/.js/.mjs/.cjs/.sh/.ps1/.bat/.ts/.ipynb/.sql` | 且 **mtime 超过 90 天**(用户口径:无复用价值) | 达阈值即清 |
| **T3 其它一切** | 目录、文档、表格、图片、视频、数据、报告… | — | **永不自动删**,只统计与告警 |
**阈值(per-user,达到才动手)**:`ws` ≥ **2048 MB**;`sessions` ≥ **1024 MB**。
**保留期**:`ws`(T1/T2)**90 天**;**`sessions` 365 天**(用户 2026-09-11 定:**对话记忆要留长些**);**回收站 30 天**。
**豁免机制**:在 `ws/` 顶层放一个 `.keep` 文件 → **该用户跳过 T2**(一次性脚本不清理),T1 仍清。
## 三、落地组件
| 组件 | 作用 |
|---|---|
| `scripts/ws-cleanup.cjs` | 工作区画像(ws/T1/T2/资产 占比)+ 按阈值清理(`--apply`;默认 dry-run) |
| `scripts/session-gc.cjs` | 会话保留期回收:`sessions/<slug>/<session-id>/session.jsonl.zstd` 超 N 天且该用户 sessions 达阈值 → mv(含 dry-run) |
| `scripts/clean-ws-pollution.cjs` | 一次性:清平台自身污染(白名单同 T1 的前 4 项 + tgz) |
| `scripts/storage-report.cjs` | 每小时生成用量快照 `/var/run/dsh-storage-report.json`(每用户 ws/sessions/trash/总计 + 可清理候选 + 阈值状态) |
| `scripts/purge-trash.sh` | 清空 `<userRoot>/trash/` 下超 30 天的回收目录(**只有它会真删**) |
| 门户 **「存储用量」面板** | `admin.html` 新增一区块(表:工作区/会话/回收站/可清理项数),数据来自 **`GET /api/admin/storage`**(`requireAdmin`,直接读快照,不做实时 du) |
| `/etc/cron.d/dsh-maintenance` | 每小时 05 分 storage-report;每天 04:10 ws-cleanup(2048MB/90d)/ 04:20 session-gc(1024MB/**365d**)/ 04:40 purge-trash;日志 `/var/log/dsh-*.log` |
**安全设计**:所有清理动作都是 **`mv` 到 `<userRoot>/trash/<日期>-<任务>/`**(同盘秒级、可整目录移回恢复),**30 天后**才由 `purge-trash.sh` 真正删除。
## 四、为什么不"按 AI 产物"直接清
1. **不可判定**:AI 与用户都可能写脚本/文件,平台拿不到"这是 AI 生成的"标记;
2. **误删代价高**:`ws` 里同时有**用户资产**(guest 的 `MCN短视频创作/` 对标数据、报告);
3. **折中**:只清"**模式明确 + 超龄**"的东西(T1/T2),其余一律保留并只做用量告警 —— 宁可少清,不可误删。
## 五、风险与回滚
| 风险 | 缓解 |
|---|---|
| 误清 T2(用户其实想留的脚本) | 30 天回收期可整目录移回;且只清"ws 顶层 + 超 90 天" |
| 回收站膨胀 | `purge-trash.sh` 每日清 30 天以上 |
| 阈值调错 | 三个脚本都支持 `--threshold/--days`;cron 里可见当前值 |
| 会话删除影响 dsh | **结构已实测**:`sessions/` 无索引文件、按工作区分桶;只在超阈值时动,且走回收站;**并同步回收 `session_projcache/sessions/<session-id>.json`**(按 id 精确匹配,不会误删他人会话) |
| 误伤运行中实例 | 脚本只动 `ws/` 与超龄 `sessions/`,不动 profile/node_modules |
## 六、硬配额:评估结论 = **不做**(2026-09-11 定)
- 本机根文件系统实测为 **ext4**(`/dev/vda3`,`/ : ext4 rw,relatime`),**未启用 prjquota** → 无法直接使用 XFS project quota;
- 若强行上配额,需要"重挂载/重建文件系统或改用 loopback+XFS 镜像",**停机与数据风险都不可接受**;
- 当前用量仅 **24%**(8.6G/40G)、单用户最大 33MB → **无压力**;
- ⇒ 用"**软阈值 + 每小时用量快照 + 门户可视 + 每日自动清理**"替代硬配额;真到压力再评估(可选方案:loop 镜像挂到 `ws/`,成本中等)。
## 七、已完成(本轮"一次性优化到位")
1. ✅ **会话保留期加长**:90 → **365 天**(阈值 500 → 1024 MB);
2. ✅ **`.keep` 豁免**:`ws/.keep` 存在则跳过 T2;
3. ✅ **projcache 同步回收**:删会话时按 session-id 精确回收投影缓存;
4. ✅ **用量可见**:`storage-report.cjs`(每小时)+ 门户 admin.html「存储用量」面板(`GET /api/admin/storage`,实测未登录 401 即受 `requireAdmin` 保护);
5. ✅ **硬配额评估**:结论"不做"(ext4 无 prjquota,风险不对称)。
**剩余可选**(非必要):T2 更细的豁免(项目目录内 `scripts/`)、按用户差异化阈值、用量面板加"趋势/告警"。