Files
dsh_shenxian/dsh-server-docs/04-调整方案/19-方案与代码全面审查.md
T

66 lines
11 KiB
Markdown
Raw Normal View History

# 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 允许范围。