Files
dsh_shenxian/dsh-server-docs/04-调整方案/19-方案与代码全面审查.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

67 lines
11 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.
# 19 · 方案与代码全面审查(优化项 / 合并项 / 过期项)
- 日期:2026-09-10
- 触发:用户要求"全面检查现有方案和代码,看还有哪些值得优化,哪些文档需要合并或过时需更新"
- 方法:服务器代码通读(`src/` 全量 + 关键机制实测)+ 文档库 42 份一致性对账(md5/交叉引用/编号)+ git 卫生检查。**全程只读**,未改任何服务器文件。
- 结论一句话:**平台整体可用、架构清晰、红线守得住**;但存在 **3 个 P1(含 1 个会阻塞档案 18 落地)、5 个 P2、5 个 P3**,文档层有 **2 组完全重复文件 + 3 份滞后 + 1 处编号缺陷**。
> **TL;DR**|**结论**:全面审查(代码 10 项 + 文档 8 项):**3 个 P1**(含 1 个会阻塞档案 18 落地)与批次整改计划。
> **关键**:**本档是全库被引用最多的档案(24 次)** —— 动代码/文档前先看这里的批次表与决策点。
> **状态**:🔄 批次 1 因改走 bundle 路由消解;C3/C5 部分完成,C5 完整版已关闭
---
## 一、代码侧发现(10 项)
| # | 级别 | 发现 | 证据 | 建议 |
|---|---|---|---|---|
| **C1** | **P1** | **profile patch 存在"多 owner 冲突"**:`ensure-role-profile-patch.cjs` 采用**整文件写** + 见 MARK 即跳过 + **仅对非 admin 注入**;而档案 18 计划另建 `ensure-workspace-picker.cjs` → 两者必然互相跳过或覆盖 | 脚本 `MARK='# dshs role patch'`;`if (current.includes(MARK)) return skip`;DB 查询过滤非 admin | **合并为单一"平台段"owner**:把 picker 行并入同一脚本(建议改名 `ensure-platform-profile-patch.cjs`),统一管理"角色段(仅非 admin)+ 平台段(含 admin)";**档案 18 §4.2/4.3 需按此回写** |
| **C2** | **P1** | **档案 18 的"含 admin"要求与现有脚本能力不符**:admin 的 `cordis.patch.yml` 当前是 `[]`(脚本不覆盖 admin) | 实测 admin profile patch = `[]` | 平台段改为**无差别注入(含 admin)**,角色段维持仅非 admin;两段用不同 MARK 区分,便于独立回滚 |
| **C3** | **P1** | **自动化测试缺口**:`npm test` 只跑 4 个文件(db / k8s-spawner / leader / local-user-fs);11 个 `smoke-*.mjs` **未纳入 test**;其中 `smoke-plugins` / `smoke-watchdog` 对应的 `/api/plugins*` 路由已删 → **已失效** | `package.json` scripts;`src/web/routes/` 无 plugins.ts | ① 删/改失效 smoke;② 新增 `scripts/ci.sh`(typecheck + test + 关键 smoke);③ 为新模块补最小单测:**security-scan 规则**(正/反例)、**business-plugins 安装事务**、**picker 越界**(档案 18 P0-4 前置) |
| **C4** | ~~P2~~ **已订正** | ~~崩溃自修复实际未启用~~ → **2026-09-10 22:1x 订正:crash-repair 已实现**。`child.on('exit')` 里在 `spawnWatchdog()` 之外**已有 `scheduleRestart()`**(1 s 退避,`DEFAULT_RESTART_BACKOFF_MS=1000`)→ 崩溃后自动 `spawnInstance` 重启 main。watchdog 的独有能力仅剩「agent 级 handoff 命令执行」,而 `POST /api/dsh/restart {command}` **全站无前端调用**(grep 无 HTML 引用)→ handoff 事实上未使用。**真实缺口改为 3 项**:① `scheduleRestart` **无次数上限**(1 s 无限重试,坏 bundle 可致 spawn 风暴);② 崩溃无观测/告警(仅内存 `lastError`);③ handoff 语义悬空(写文件但无人读)。详见档案 20 | `orchestrator.ts:376-409`、`config.ts:130` | 按档案 20 方案 A:**自愈加固(上限/熔断/指数退避)+ 观测 + handoff 去留决策**;**不建议**为此启用 `enablePatch`(会让所有实例启动依赖 `dshs/runtime` 解析,而该包位于 700 的 `/opt`,实例 uid 读不到) |
| **C5** ✅部分(2026-09-11:`src/runtime.ts` 已删;`folder_plugins`/`enablePatch`/`renderPatch`/`patch?` 链路跨 10 文件 → 留专项) | **死代码 / 失效子系统**(订正后范围):`enablePatch` 分支、`renderPatch()`、`folder_plugins` 表与 repo 函数、`workspaces` 表、`src/runtime.ts`、`patches/` 目录、`/api/plugins/select` 已删但 repo 残留。**注**:自愈用的 `scheduleRestart` 是活代码,**不在**清理范围(见 C4 订正) | grep 全文命中;档案 16 已宣布 folder_plugins 废弃 | 统一清理(`git tag` 先存档);`dsh.ts:61` 分支删除后 `patch?` 参数链路(orchestrator/spawner/k8s-spawner)可一并简化。**若保留 handoff 能力则 `runtime.ts` 不能删**(见档案 20) |
| **C6** ✅完成(2026-09-11:P0/P1 分级 + 31 扩展名 + shebang/二进制/8MB;冒烟通过) | **安全扫描规则偏薄**:仅 7 条正则,仅扫文本扩展名,`>2MB` 跳过 | `src/web/security-scan.ts` | 对齐档案 17 §S/M 清单扩展:动态 `child_process.exec`、`vm`、出网域名统计与白名单、`process.env` 敏感键、长 base64 载荷、隐藏文件/`.git`;并输出**分级报告**(现在只有"命中即 400",无 P0/P1 分级与整改建议) |
| **C7** | P2 | **仓库根被备份文件污染**:9 个未跟踪 `bak-*`(约 400K,`bak-stage0/1/2`、`bak-401guard`、`bak-ui`、`bak-bwrap.ts`、`bak-stage3-proxy.ts`、`bak-ensure-role-patch.cjs`) | `git status --short` | 移入 `backups/`(加 `.gitignore`)或直接删除——**改动都在 git 历史里**,无需重复留档 |
| **C8** ✅完成(2026-09-11:02 附录 C.5 标注未验证子系统) | **上游 k8s/PG/leader 代码在本部署未使用、未验证**(`k8s-spawner.ts` 679 行、`pg.ts` 508 行、`leader.ts` 254 行、`reconcile.ts`、k8s `deploy/*.yaml`) | 本部署 `ISOLATION_MODE=account` + sqlite | 保留(上游能力),但在文档标注"本部署未验证",**升级 dshs 时重点回归** |
| **C9** ✅完成(2026-09-11:新增 `DEPLOY-本部署.md`) | **部署可复现性**:`lib/` 未跟踪(需 `npm run build`);仓库无"本部署说明"(服务器路径、env 键、patch 脚本族、bwrap/systemd-run 依赖、nft 规则) | `.gitignore` 忽略 `lib/`;`git ls-files lib/` = 0 | 在我们仓库加 `DEPLOY-本部署.md`(或 `docs/deploy-alotbuy.md`),列出构建/部署/回滚三步与依赖 |
| **C10** ✅完成(2026-09-11:两处 `docs/` 互指) | **两处 `docs/` 易混**:代码仓库内 `docs/`=上游 7 篇(blueprint/deployment/k8s…),文档仓库=本项目 42 份改造文档 | `git ls-files docs/` | 在两边 README 各加一行互指,避免后来人改错地方 |
**顺带确认(无问题项)**:仓库**无敏感文件入库**(无 `.env`/secret/key 被跟踪);工作树除 `bak-*` 外**干净**;`src/` **零 TODO/FIXME**(注释质量高,模块头有 `@module` 说明)。
---
## 二、文档侧发现(8 项)
| # | 级别 | 发现 | 证据 | 建议 |
|---|---|---|---|---|
| **D1** | **P1** | **`01-规划与架构.md` 滞后**:章节仍为一~五、九、十三;**未收录** 插件三层归属(16)、bwrap 沙箱隔离(16)、nftables 出网护栏与 uid 段(14)、单活跃会话/常驻上限(08)、技能共享层(10/11)、门户 SPA 化(16) | 章节清单 + 关键词 grep 全空 | 新增"**机制索引**"一节(一张表:机制 → 档案号 → 生效位置),或补第 14/16 章;**架构篇不应只停在 09-08** |
| **D2** | **P1** | **`02-运维手册.md` 缺新运维项**:nft egress 服务(启停/回滚)、bwrap 沙箱排障、功能插件上传与启用、技能管理面、picker、备份核查、patch 脚本族用法 | 章节为六~八、十二、十四、十五;关键词 grep 全空 | 逐项补排障/操作小节 + 附录 A 命令速查增补(`dsh-egress`、bwrap 进程核对、`--dump-config`) |
| **D3** | **P1** | **`03-路线图与待办.md` 未登记 14-18**;待办表残留已完成项 | grep 仅命中 档案 05/07/09/11/13 | 把 14/15/16/17/18 补进"已完成/进行中",清理已完成行(3 份草案入库 ✅、portal-entry 微调 ✅) |
| **D4** | P2 | **两组完全重复文件**:`README.md` ≡ `04-调整方案/README.md`(8.9 KB ×2);`05-登录直达…可行性.md` ≡ `04-调整方案/05-…md`(22 KB ×2) | md5 完全相同 | 单一来源 + 指针:建议保留根 `README.md` 与 `04/05` 放在 04 目录,另一处改为一行"见 ../x.md";**避免双份维护漏改** |
| **D5** | P2 | **`INDEX.md` 缺陷**:§六 列表编号重复(两个 `3.`);"当前下一号 = 17"已过期(应 **19**);§二 部分状态与实际不符 | 见文件 | 已在本轮修正编号与序号,状态列同步 |
| **D6** ✅完成(2026-09-11:档案 12 标注冻结) | **档案 12(VoxEMW 云化)长期悬置**:"云端链路待接线",自 09-10 起无进展 | 档案 12 §状态 + 03-路线图 | 决策:**继续**(需供应商账号)/**冻结**(标注"已暂停,待资源");建议先冻结,避免长期占待办位 |
| **D7** ✅完成(2026-09-11:档案 18 头部加主线互指,保持独立编号) | **档案 17+18 可合并**:17=核查、18=方案,同一条安全主线 | — | **档案 18 实施完成后**合并为《工作区文件系统可见面:核查 + 收敛 + 验证》一份,减少碎片 |
| **D8** ✅完成(2026-09-11:06 UI 规范加同步时间戳与回拷流程) | **`06-工作台UI规范.md` 双源**:权威源在 `mcn-work-shop/docs/`,本项目为回拷副本 | 文档头部说明 | 加"同步时间戳 + 回拷流程"一行,避免版本漂移 |
---
## 三、执行优先级(建议顺序)
| 批次 | 内容 | 说明 |
|---|---|---|
| **第 1 批(阻塞项)** | C1 + C2:统一 patch owner(含 admin)、**回写档案 18** | 档案 18 落地的前置;否则 PoC 阶段就会踩冲突 |
| **第 2 批(质量基线)** | C3:CI 脚本 + 失效 smoke 清理 + 3 个最小单测 | 直接提升后续所有改造的安全网 |
| **第 3 批(文档补齐)** | D1 + D2 + D3 + D5 | 让新人和未来的你"查得到、看得懂" |
| **第 4 批(清理与决策)** | C4/C5(crash-repair 决策 + 死代码)、C6(扫描扩展)、C7(bak 清理)、D4(去重) | 需你拍板 2 个决策点(见下) |
| **第 5 批(长期)** | C8/C9/C10、D6/D7/D8 | 低优先,随下次改造顺带 |
## 四、需你拍板的 2 个决策点
1. ~~**崩溃自修复(watchdog)要不要**~~ → **2026-09-10 22:1x 订正**:自愈**已在**(`scheduleRestart`),用户裁定的「需要」已满足;真实待办改为**加固**(上限/熔断/观测)与 **handoff 去留** —— 见 **档案 20**。附带订正:`ensure-role-profile-patch.cjs --restart` 注释「kill main 由 watchdog 拉起」**与实际不符**(watchdog 不启动,实例原地停住,需用户重新 enter 才会重新 launch)。
2. **文档去重口径**:`README.md` 与 `04-调整方案/README.md` 保留哪一份?`05-…可行性.md` 根副本是否删除?
## 五、红线遵守
- 本审查**全程只读**(`git status` / `grep` / `stat` / `--dump-config`),未改服务器任何文件。
- 建议项均不触碰 R1(不升级 dsh)与 R2(不改官方 dsh 主程序与缓存);C1 的合并脚本仅操作 profile 层 patch 文件。
- C4 若选 B,改的是编排器 env 与 profile bundles,仍在 R2 允许范围。