Files
dsh_shenxian/dsh-server-docs/README.md
T
admin 04776af4b1 docs: 工作区根项目文档批量入仓(04-调整方案 113–128 / 交接单 T09–T21 / ops / archive)
起因:用户 2026-09-17 明确「所有文档都要同步,都放在开发仓库 docs 对应文件夹下」。
判据:工作区根 *.md 中在仓库(git ls-files --quotepath=false)搜不到的那些。

入仓 33 份(一律复制,工作区根原件保留不动,避免引用断链):
- 04-调整方案/113–128(16 份 · 原子占号后落盘):覆盖网络 传输方案取舍 / 应用场景与待完善清单 /
  插件化vs改内核 / 问题逐条推演 / 参数表与观测口径;会合中继拆分取证与改造方案;
  集群化改造方案 Manager-Worker;跨节点迁移与节点自举;项目代码分层范式与迭代风险评估;
  搬运与共享重建方案 guest w47→w106;方案规划方法提炼;文档无效信息审计报告;
  会话接续机制复盘与修复;会话接续规范;dsh 客户端化部署方案;dsh 桌面客户端开发方案
- 交接单/archive/交接单-已完成/T09–T21(13 份 · 覆盖网络线已完成单归档)
- ops/(2 份运行态指针:接续入口 / 接续包 · 覆盖网络线)
- archive/(2 份临时与内部简报)

已排除(无需重复入仓):覆盖网络线 10 份方案正文已入档案 103–112(文件名不同)。

登记:INDEX.md §二 新增 04-113–128 共 16 行 + §四 追加 T09–T21 说明 + 机器摘要行刷新
(⛔ 未跑 docs-index-stats.py --write:该脚本会按 \r\n 归一化全文件行尾,故改为字节级单行替换);
README.md 追加 1 条入仓指针;docs-manifest.json 复跑 scripts/docs-manifest.py 刷新。

验收:工作区根 47 份 .md —— 同名已入仓 8 / 本次内容一致 29 / 已知改名映射 10 / 未入仓 0;
git status 待提交清单只含本次新增与登记 3 件(未涉 src/ 与 relay 代码面)。
2026-09-17 18:24:19 +08:00

103 lines
19 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.
# dsh 多租户平台 — 改造方案文档库
> 服务器:47.77.182.89(Alibaba Cloud Linux al8)| 平台:dshs + dsh 0.1.2-rc.1(account 硬隔离)
> 域名:**`alotbuy.com`**(门户)/**`<用户名>.alotbuy.com`**(用户实例)| 旧域 `dsh.alotbuy.com` 已 **301**(档案 22)
> 服务:systemd `dshs`(127.0.0.1:3080)| 现行状态与部署细节见 **`DEPLOY-本部署.md`**
> ⚠️ **两处 `docs/` 勿混**(档案 19 §C10):
> - **本仓库**(`dsh-server-docs`)= **本项目改造文档**(档案 01-53、`ops/`、`scripts/`、`archive/`、`skills/`);
> - **代码仓库**(`/opt/dshs/docs/`)= **上游 dshs 自带 7 篇**(blueprint / deployment / k8s-deploy …),**不要往里写我们的改造记录**。
> 构建/部署/回滚与依赖清单一律看根目录 **`DEPLOY-本部署.md`**。
## 阅读约定(先读这 7 条,避免歧义)
0. **首读 `BRIEF.md`**(现状卡):30 秒拿到"现在是什么样、该读哪篇";需要筛档时用 `python3 scripts/docs-manifest.py`(产出机读 `docs-manifest.json`)。
1. **两套编号互不相同**:根级 `01/02/03/06` 是**长期文档**(架构、运维、路线图、UI 规范);`04-调整方案/NN-` 是**一次性改造成档案**。说"档案 NN"时**默认指后者**。
2. **单一来源**:**清单与状态 = `INDEX.md` §二**;**待办与优先级 = `03-路线图与待办.md`**;**部署/构建/回滚 = `DEPLOY-本部署.md`**。其余文件提到这些内容时**只做指针,不复制**(历史上 README/INDEX 各存一份清单,已漂移 —— 见档案 53)。
3. **术语以档案 38b 为准**:统一称「**功能插件**」(早期档案写"业务插件"= 同一事物;历史档案保留原文,不回改)。
4. **域名以 `alotbuy.com` 为准**:2026-09-11 迁移(档案 22)。早期档案里的 `dsh.alotbuy.com` 属当时事实,**保留原文**;现行入口一律 `alotbuy.com`。
5. **AI 默认不读**:`archive/`(历史全文)、`scripts/` `ops/`(工具与配置)、`*.bak*`、`04-调整方案/poc/`(源码)—— 需要时再按需打开。
6. **档案头部格式**:`- 日期:` + `- 状态:`(✅已完成 / 🔄进行中 / ⏸暂缓 / ❌关闭)+ `- 触发:`;正文用「需求 → 改动点 → 验证」三段。
## 模块一览
| 文件 | 内容 | 用途 |
|------|------|------|
| **`BRIEF.md`** | **现状卡(AI / 人首读)**:现行事实(入口/服务/运行时/隔离/可见面/清理阈值/定时/证书/红线)+ 当前待办 top5 + 高频问题→档案映射 + **4 步读取顺序** | **先看这份**:30 秒对齐现状,再决定读哪篇 |
| `01-规划与架构.md` | 背景/现状盘点、总体架构、目录布局、dsh 分层机制、归属矩阵、安全边界(一~五、九章)、架构切换实施记录(十三章) | 理解平台怎么搭的、为什么这样隔离 |
| `DEPLOY-本部署.md` | 本部署说明:拓扑/目录/env 键/依赖版本/脚本族/构建部署回滚三步/红线 | **重建或交接先看这份** |
| `02-运维手册.md` | 迁移执行步骤、备份/恢复语义、多用户过渡方案、域名接入、面板反代站点、uid 排障、命令速查(六~八、十二、十四、十五章 + 附录) | **日常操作对照查**:重启/备份/看 token/改 key 流程 |
| `03-路线图与待办.md` | 待验证项结论(Open Questions 已实测)、路线图(已完成/待办)、历史决策记录 | 追踪未完成事项与优先级 |
| **`06-工作台UI规范.md`** | **前端 UI 强制基线**:设计 Token(色/字/圆角/阴影/间距)、布局框架与滚动规则、页面路由、组件规范(按钮/输入/表格/Tab/卡片/徽章/弹窗/Toast/空状态/分页/评分/图标)、关键交互约定、9 条已知坑与规避 | **开发/改任何前端页面前必读并遵循**(门户页 desktop/admin/skills/plugins + 工作台页);权威源 `mcn-work-shop/docs/工作台UI规范.md` |
| `skills/dsh-change-workflow/` | 平台改造工作流 skill(**v2.9.2**):需求识别→调研→规划→开发→验证→归档六阶段 + 红线机制 R1-R11 + 档案模板 + **多任务并行调度协议**(按冲突域定并行度)+ **「三把锁」落地机制**(全局执行锁 / 单级占用锁 / 服务器侧操作锁) | 执行平台功能改造时对照本流程。**同步方向:工作副本在本机 `.workbuddy/skills/`(技能必须本地加载),本目录为服务器归档副本 —— 改动后单向推进来(本机 → 此处),勿反向覆盖** |
| `skills/dsh-env-bootstrap/` | 环境引导 / 迁移 skill(**v1.0.4**):把工作区 `CODEBUDDY.md` 的**关键章节**做成技能内**快照**,并给出 `--check`(校验关键规则齐备,默认只报)/ `--inject`(标记块内替换,首次需 `--init`)/ `--env-check`(路径与 hooks 命令自检)/ `--snapshot`(由权威重生成快照) | 换电脑、换工作区路径、新环境初始化时用。**设计红线:权威方向单向(CODEBUDDY.md 为权威,快照为副本),避免造第二真相源** |
| `skills/dsh-decision-method/` | **改造决策方法论** skill(**v2.8.0**):决策素材库(用户有效决策 U1-U28 / AI 有效决策 A1-A25 / 反例 X1-X14,已拆到 `references/`)+ **如何确认最优解**(判定矩阵 + 拍板前十问 + 验收口径 L1-L5)+ **技术选型判据轴 §4.6**(⛔ 热度 ≠ 安全/性能;先立轴再排序;必查默认值 + CVE 历史)+ 决策流程十步 + 交互 UI 改造专项清单 + 决策语言对照表 | **先定案再执行**:本技能管「怎么想、怎么定」,`dsh-change-workflow` 管「怎么落地」。素材源 = 本库 68 份改造档案的真实决策痕迹。**同步方向同上(本机 → 此处,勿反向覆盖)** |
| `skills/dsh-feature-first/` | **功能优先协作协议** skill(**v1.7.0**):复盘证实「技术类 40% + 报障类 24% 吃掉用户注意力」→ 用户的输入收窄为**功能卡 4 问**;AI 自主决策的 **9 类白名单(永不问)**;只上抛**功能语义分叉与红线门禁**;上抛语言转换表;报障闭环前置五条;交付回执格式(功能性语言优先 + 技术附录折叠);**§5.3 五条铁律 / §5.4 九条硬约束:待确认项 = 回复最后一节、逐条编号、候选竖排成段(不横排)且必须写「优点 / 缺点」** | **改协作方式时对照本协议**:把"事前请示"改成"**默认自主 + 事后可推翻**" |
| `skills/dsh-auto-handoff-chain/` | **多棒自动接力编排法** skill(**v1.3.2**):把跨多个上下文窗口的长任务拆成「规划棒 ↔ 执行棒」交替的**一次性自动化链条**,每棒做完自动开新会话接下一棒(零人工点击)。核心 = 六件套 prompt 骨架(状态单点 → 唯一执行依据指针 → 全局锁 → 单一动作 → 成本纪律 → 收尾四件套)+ **登记门禁**(要拍板的先等拍板再登记)+ 五条实测防护(断链 / 双开 / once 不转完成态 / 跨过拍板点 / 下一棒定太晚)+ 复跑脚本 `scripts/chain_report.py` | **跑跨会话长任务时用**:与 `dsh-change-workflow`(单次改造落地)、`dsh-decision-method`(单次取舍)分工互补;唯一执行依据 = 工作区 `接续入口_<线名>_<日期>.md`。**同步方向同上(本机 → 此处,勿反向覆盖)** |
| `交接单/` | **规划会话 → 执行会话的任务单**(目标 / 只读前置 / 范围 / 决策点 / 步骤 / 验收 / 回滚 / 回报格式)+ 交接约定 | **要执行某个任务时才读**;单子完成后移入 `archive/交接单-已完成/` |
| `04-调整方案/` | 每个功能改造一份档案:需求 → 改动文件 → commit → 验证结果 | **核对用**:某功能当时怎么改的 |
| `archive/` | `dsh-improvement-plan-20260909-full.md`:拆分前的 19 章完整时间线归档 | 保留历史全文,防拆分遗漏 |
`04-调整方案/` 档案清单:
| 档案 | 对应章节 | commit |
|------|---------|--------|
| `01-launch-token自动携带.md` | 十六 | 29c8907 |
| `02-安全加固-权限边界与DB.md` | 十七 | —(chmod 操作) |
| `03-统一KEY管理员管控.md` | 十八 | df5cc84 |
| `04-删除用户功能.md` | 十九 | 4943c8c |
| `06-登录直达会话窗口.md` | —(方案 A 第一步落地,v1+v2) | 6f63108 + e39628a |
| `07-红线-禁止dsh自动获取最新版本.md` | —(红线+升级流程) | 生效 |
| `08-实例常驻上限与单活跃会话.md` | —(回收+last-wins 落地) | 928dde1 + 6336c53 |
| `09-普通用户隐藏模型设置-角色化profile-patch.md` | —(cordis patch disable 裁剪 client 插件,`ensure-role-profile-patch.cjs`) | —(工具脚本,2026-09-09 落地) |
| `10-共享技能只读部署-bundledSkillDir.md` | —(调研分析 + 实施:编排器 env 注入 + 共享只读目录,dsh 全员可见只读技能层) | —(已实施 2026-09-09;管理面见 11) |
| `11-技能管理面-shared+mine-API与页面.md` | —(管理面:编排器新增 `/api/skills/{shared,mine}` + `/skills.html`;**v2 = zip-only 两阶段替换**:上传检测→同名提示确认→apply 全量替换) | —(已实施 2026-09-09,v2 同日) |
| `12-VoxEMW全云API化接入dsh-调研与M1落地.md` | —(外部产品插件化调研 + 云 API 方案:VoxEMW 魔镜 → dsh-plugin-voxemw-cloud) | —(本地插件 v0.1.0 已实现,2026-09-10;云端链路待接线验证) |
| `13-登录直达冷启动竞态404修复.md` | —(登录直达冷启动竞态:enter 等 launch token 到位再返回 URL) | fa718d2 |
| `14-实例会话敏感信息暴露面审计与加固.md` | —(读取→留存→外传链路审计;uid 段收敛 [100000,199999] + nftables 出网护栏封元数据端点/观测外联) | —(已上线 2026-09-10,`dsh-egress.service` enabled+active) |
| `15-会话失效401未跳登录页修复与guest可见面复核.md` | —(三页注入 401 守卫跳 `/login.html`;核心插件开关收归 admin;guest 可见面复核) | —(已上线 2026-09-10) |
| `16-页面导航定稿-技能插件管理面三决策落地.md` | —(已封板:skills.html 两 tab 管公共面 + 插件三层归属模型 + folder_plugins 已废弃;分阶段实施) | 🔄 实施中 |
| `17-工作区选择器暴露面核查.md` | —(会话内「添加工作区」为何能看到 `/`:bwrap 合成根还原 + 实测可读/可写/跨租户边界;判定 P1 写边界随会话 cwd、P2 picker 无根白名单与 /etc/passwd 泄露;收敛项 H1-H4) | 核查完成,收敛待确认 |
| `18-目录选择器收敛为仅见自有目录.md` | —(**已定稿**:自建 host 插件子类化 `DirectoryPicker` seam,根固定 `<userRoot>/ws`,含 admin;改走 **bundle 路由**不动用户 patch;**PoC 26/26 通过**;P0-1/P0-3 待装包重启) | 已定稿,待装包重启 |
| `19-方案与代码全面审查.md` | —(代码 10 项 + 文档 8 项体检:patch 多 owner 冲突 / 含 admin 注入缺口 / 测试缺口 / 01-02-03 滞后 / 2 组重复文件;含优先级批次与决策点) | 审查完成,整改待启动 |
| `20-崩溃自愈现状核实与加固方案.md` | —(订正档案19 §C4:自愈**已在**(`scheduleRestart` 1s 退避);真缺口=重试无上限/无观测/handoff 悬空;方案 A 加固+观测+handoff 决策,**不建议**启用 enablePatch) | 方案A(熔断+观测)+ handoff 停写 **已实施**;待 live 实测 |
| `21-guest会话卡顿排查.md` | —(服务端全链路取证:TTFT 1.0–3.5s、实例 TTFB 2ms、nginx 全 <5s、0 崩溃;体感来自客户端侧 + 两个干扰项:生产启用 HMR 每 65s 连 /plugins/events、无关域名流量误入编排器) | 排查完成,待拍板 A1/A2 |
| `22-服务域名迁移到alotbuy.com.md` | —(走 CF 代理切换服务域名:门户 alotbuy.com + 用户 `<用户名>.alotbuy.com`;签通配证书、CF 真实 IP 还原、旧域名 301 含用户名映射;含 4 个踩坑与回滚) | ✅ 已上线 |
| `23-实例内AI能力与权限限制核查.md` | —(guest 报的 9 条环境限制逐条判定:**1 条 P1 真 bug**——合成根缺 /bin /sbin /lib 致 dsh 沙箱探针失败 → bash 工具被整体拒绝,已修复待重启;3 条可优化(ffmpeg/python/rg/jq/浏览器);4 条设计使然;1 条与平台无关) | 修复已编译,待重启生效 |
| `24-实例侧401自动恢复.md` | —(实例重启后旧标签页 token 失效 → dsh 报 `dsh web authentication required` 死端页;代理补上「实例侧 401 + 浏览器导航 → 302 带最新 token 原地恢复」;与档案 23 沙箱修复同批重启上线) | ✅ 已上线 |
| `25-实例崩溃循环修复与not_running兜底.md` | —(**自造事故修复**:插件包内 patch 与 profile 层重复 insert 同一 loader id → `duplicate loader entry id` → 实例崩溃循环(被档案 20 熔断拦住)→ 用户看到裸 `{"error":"not_running"}`。修:包内改空补丁单点插入 + 浏览器导航永不吐 JSON + 并发进场等待在飞实例 token) | ✅ 已修复上线 |
| `26-dsh升级耦合点与回归清单.md` | —(回答"是否影响官方包/升级会不会覆盖":**官方包零改动**(实测无痕迹/无新 mtime);升级不覆盖我们的改动,但有 **6 类契约耦合点**需回归:profile 引用的官方 client 行 id、自建插件继承的 seam 基类、client bundle 契约、bwrap 合成根、proxy 401/not_running 假设等) | 清单建立 |
| `27-MCN工作台插件平台化评估.md` | —(MCN 工作台插件能否作为功能插件投放/多用户/存储/自带 DB 风险/技能整合 vs 外置:**可行但 3 处 P0 必改**(DSH_HOME 路径、技能路径硬编码 13 处、agent preset 随包投放);技能结论=**外置**) | 评估完成,改造待启动 |
| `28-用户数据清理策略.md` | —(ws 三档清理(T1 平台产物 / T2 超 90 天顶层脚本 / T3 永不删)+ 会话阈值回收 + 回收站 30 天 + cron;含平台自身污染 bug 的发现与修复) | ✅ 已上线 |
- **单一来源约定(2026-09-11 订正,档案 53)**:档案**清单与状态**的单一来源是 **`INDEX.md` §二**;本文件的档案表**仅作拆分前(01–26)的历史对照,不再新增行**。`04-调整方案/README.md` 为指针式说明。(此前本文件与 INDEX 各维护一份全量清单 → 已实际漂移,故订正。)
## 红线(硬性,全部档案同遵守)
1. **禁止启动 dsh 时自动获取最新版本**;dsh 版本升级必须先走独立"升级测试→评估→修复"流程再整体更新(详见档案 07)。
2. **不改官方 dsh 主程序与缓存**(/usr/local/lib/node_modules/@deepseek-ai/dsh 及依赖);扩展只走 profile 层官方插件机制(档案 05)。
3. 服务器 docs 只读归档(root 600);技能同步类红线见各技能 MEMORY 约定。
4. **禁止未经确认的批量 / 全仓写入**(2026-09-12 新增,见 R7):不得对仓库或生产目录做**全库遍历改写、通配符重写、批量 `chmod`/`chown`、批量换行符转换、`cp -r` 整目录覆盖**;**任何可能影响 >10 个文件的操作用前必须先出受影响清单并取得确认**。执行过程中发现的**额外问题一律"先报告、后动手"**,不得顺手改 —— **本机镜像不是沙箱**,本机批量改动会经 scp 传导到生产。
5. **中断在线用户的生产变更须先确认**(2026-09-12 新增,见 R8):重启 `dshs`、drain 实例 scope、批量铺插件、改 `MemoryMax`/实例 env 等,都会让在线用户掉线;执行前必须先说明「**影响谁、断多久**」并取得确认,能避开用户活跃时段就避开。
`04-调整方案/poc/`:PoC 插件源码档案(`portal-entry/` = `@dsh-local/portal-entry` v0.4.3,含 package.json / cordis.patch.yml / lib/{index,client}.js;版本演进:v0.1.0→v0.1.1 行级 `inject:[tools]`(host 面)、v0.2.0 client 面 `exports["./client"]` + `dsh.client.platform=web`、v0.3.0 bundle 内 `exports.inject=["slots"]`、v0.3.1 package.json `dsh.client.inject=["@deepseek-ai/dsh-client-ui-sidebar"]`、v0.3.2 list-slot register `id`+callback 形式、v0.4.0 footer.action 废弃改 `settings.section`(id:"platform",与通用设置/模型/插件/Agent预设 同槽)、v0.4.1 删 `exports.default`(loader ESM interop 取函数 → 无 inject → settings.section 注册失败,浏览器实测根因,**红线 3**)+ `label` 函数形式、**v0.4.2 尝试 var() fallback 失败**(深色主题下 `--dsw-alias-label-primary`/`--dsw-alias-button-elevated-fill` 都已定义 `#f9fafb`,fallback 永不生效,文字/背景同浅色不可见)、**v0.4.3 hardcode 修复**(文本 `#f9fafb`、按钮边框 `#43464d`、打开管理台 `#4f6ef7` 蓝底白字、退出登录 `#ff4d4f` 红字透明底;浏览器验收白字蓝底清晰可见——但**部署后首次仍见旧 bundle**,根因=实例 pid 147068 16:32 启动 vs tgz 16:40 部署**未重启**,dsh client bundle 在实例启动时打包缓存;重启走编排器 `POST /api/dsh/restart`(主域 Host+admin sid),新实例 port 37817→45543,bundle rev `259e7a43027c→936d9012841a`);服务器同步副本在 `/opt/dsh/docs/04-调整方案/poc/`)。
## 使用约定
- **新增改造**:按主题写进对应文件;功能类改造在 `04-调整方案/` 新建档案(编号递增,**复跑取号勿写死**:`ls 04-调整方案/ | sort -n | tail -1`;**63 为空号,勿补占**),模板 = 需求 → 改动点表 → 验证结果。
- **规范/基线类**(跨页面长期生效)→ 根级编号文档(`06-工作台UI规范.md`),**不入 `04-调整方案/`**。
- **工作区根批量入仓(2026-09-17)**:工作区根尚未入仓的项目文档已一次性归位 —— 16 份方案 / 评估 / 复盘 / 规范类 → `04-调整方案/113–128`;13 份交接单 → `交接单/archive/交接单-已完成/T09–T21`;运行态指针(`接续入口_*` / `接续包_*`)→ `ops/`;临时与内部简报 → `archive/`。**档案清单仍以 `INDEX.md` §二 为单一来源**(本文件的 01–26 表按上条约定不新增行)。
- **前端页面改动**:先读 `06-工作台UI规范.md` 再动手;视觉判断辅以 `.workbuddy/skills/impeccable`(Operate 模式)与 `taste-skill`(反 AI 味),**冲突时以 `06` 的实测 Token 为准**。
- **排障**:追加进 `02-运维手册.md` 排障小节。
- **自查**:归档/改动文档后跑一次 `python3 scripts/docs-audit.py`(歧义/悬空引用)与 `scripts/docs-manifest.py`(刷新机读清单)(编号冲突 / 标题号不符 / 悬空引用 / 重复 / 体量)——**编号冲突与悬空引用会让它退出码非 0**。
- **保留原章节编号**(如"十六、"):方便与 archive 完整版对查。
- **同步**:本机 `D:\github\dsh_shenxian\dsh-server-docs\` ↔ 服务器 `/opt/dsh/docs/` 整目录镜像,改完即 scp(服务器侧档案 `chmod 600` 保持 root-only,README 保持 644)。
- **对账**:`bash scripts/docs-sync-check.sh`(工作区 `scripts/`,2026-09-10 落地)一条命令输出「一致 / 内容不一致 / 仅本地待推送 / 仅服务器待拉取」,退出码 0=全绿;加 `--push` 一键推送本机变更(档案 600 / README 644 自动设权)。
- **定位**:先查 `INDEX.md` 的场景速查表(编号规则见「阅读约定」第 1 条)。
## 目录内其他文件(服务器侧)
- `nginx-dsh.alotbuy.com.conf.bak-20260908` / `.manual-20260908`:面板注册前的手写反代配置备份。
- `dshs.db.bak-20260908-uidfix`:uid 错配修复前的数据库备份(正式备份见 `/opt/dsh/backups/`)。