1需求背景
DeepSeek 于 2026 年 8 月 13 日开源了 agent 运行时 DeepSeek Harness(dsh),其核心主张是"一切皆插件":模型、工具、会话存储、沙箱、调度循环乃至 Web 界面全部以插件形式挂载在 Cordis 内核上,注册即可逆、热插拔、无需修改框架源码[1][2]。项目上线数日即获得超过 12 万 Star,围绕 dsh-plugin GitHub topic 已形成 5700+ 插件仓库的生态[3]。
dsh 的典型运行形态是一台主机上的个人服务:执行 npx @deepseek-ai/dsh web 后在浏览器打开 127.0.0.1:3080,选择工作区目录、配置模型 API Key 即可使用[4]。所有个人状态集中存放在 $DSH_HOME(默认 ~/.dsh)下:各 profile 的插件组合清单、settings.yaml 配置,以及写入 .credentials.yaml 的模型凭据(页面只能看到脱敏描述符)[12]。这是一套明确面向单人的设计——官方社区对"团队怎么共用 dsh"的答复是"共享 profile,不共享凭据",即仍然各起各的服务[12]。
但共用一台 dsh 的需求真实存在,而且没有一个现成方案能接住:
- 小团队与家庭:一台 NAS 或内网服务器跑一个 dsh,几个人都想用,只能共享同一个浏览器入口——工作区互相可见、会话历史混在一起,谁误删目录都会影响别人。
- 成本管控:模型 API Key 填一次全员可用,任何成员都能进设置页改模型、看 Key 描述符,用量也无法按人分账。
- 权限分级:管理员希望控制"谁能用哪些插件、哪些模型",而 dsh 的插件与模型配置都是 profile 级全局的,没有按用户的开关。
生态调研(见第 2 章)确认:现有插件覆盖了提供商登录、账号池、插件市场、用量统计等方向,但没有一款插件做"多用户"——登录墙、按用户隔离的工作区与插件、模型配置权限分级、按用户用量统计这四件事都是空白(生态外仅有一个独立网关形态的多用户方案,非插件[14])。本插件即为此空白而生。
2生态调研与功能综合
2.1调研范围
调研覆盖三层数据源:dsh 官方仓库与文档(P0)、GitHub dsh-plugin topic 与 awesome 清单(P1)、插件目录站 dsh-plugins.top 于 2026-08-17 的快照(收录 307 款精选插件、10 个分类、共 23772 Star,全量生态 1000+ 收录)[3][5]。筛选标准:与"多用户、登录鉴权、隔离、账号与凭据管理、插件管理"直接相关的插件,逐个阅读其 README 提取功能与设计模式。
2.2相关插件盘点
| 类别 | 代表插件 | 核心功能 | 对本插件的借鉴 |
|---|---|---|---|
| 提供商登录鉴权 | dsh-AuthInOne[6] | 9 家 Provider 的 OAuth / 设备流登录(OpenAI Codex、Kimi、xAI、Anthropic 等)、API Key 与自定义 OpenAI 兼容提供商管理、默认模型切换、token/成本统计 | 登录事务模型(start / redacted status / cancel / refresh / logout);凭证只存 Host 侧、浏览器仅获脱敏状态;自包含安装器 + 同端口替换重启;卸载自动还原官方组件 |
| 账号池 | dockyard-dsh[7] | macOS 原生账号池:扫描导入本机已有登录态,manual / sticky-session / round-robin / failover 调度策略,实时模型目录与额度窗口 | 多凭据统一持有、按策略分发的思路;但它是"多人共用多个提供商账号",不是"多用户各用各的环境" |
| 多用户网关先例 | dsh-server-deployment[14](曾用名 dsh-multi-user-gateway) | DSH Web 的多用户网关:在 dsh 之外部署一层网关做多人接入 | 证明"多人共用一台 dsh"需求真实存在;但它是外部网关形态,本插件以无侵入插件形态在 dsh 内部实现,安装与还原体验完全不同 |
| 插件管理 | dsh-web-plugin-manager[8]、dsh-plugin-hub、dsh-market | Web UI 内查看、实时启停、安装卸载、更新检测、健康检查(依赖 / 冲突 / 兼容性分析)、环境管理、内置插件市场 | 插件级控制面板的交互范式;健康检查中的依赖冲突分析可用于"给子用户分配插件"时的依赖提示 |
| 配置安全 | dsh-undo-plugin[9] | 配置与插件代码变更撤销、脱敏快照、一键安全模式、DSH 无法启动时仍可用的离线 CLI/GUI | 变更前快照 + 一键回滚机制,直接用于本插件"启用 / 卸载"的可逆性保障 |
| 用量统计 | dsh-usage-stats[10]、dsh-cost-meter | token 热力图、按模型分解、账户余额、会话费用与预算显示 | 多租户天然要求按用户统计与配额——将"按模型"维度扩展出"按用户"维度(列入 FR-7) |
| Agent 团队 | dsh-agent-teams[11] | 给子 Agent 增加队长 / 成员 / 任务依赖 / 活动面板 | 负样本:命名与定位上须与"用户团队"明确切割,避免被误认为同类插件 |
| harness 级登录先例 | deepseek-helmsman[13] | pi harness 的 fork,DeepSeek-only 终端 agent,/login 输入 API Key,凭据存本地 auth.json |
证明"登录态"可以放进 harness 层;但它是 fork 且仍是单用户,本插件以无侵入插件形态实现同等能力 |
2.3空白点分析
把上述插件的能力放到"多租户"的四个核心诉求下检视,结论是全部落空:
| 多租户诉求 | 现有最接近的方案 | 差距 |
|---|---|---|
| 登录墙与用户身份 | dsh-AuthInOne(提供商 OAuth 登录) | 登录对象是"模型提供商账号",不是"使用 dsh 的人";无本地用户体系 |
| 工作区 / 会话按人隔离 | 无(dsh 工作区为目录级全局列表) | 所有访客看到同一个工作区与会话列表 |
| 插件按人可见 | dsh-web-plugin-manager(启停管理) | 启停是 profile 级全局开关,影响所有人,无按用户过滤 |
| 模型配置权限分级 | 无(设置页对所有人开放) | 任何访客可增删提供商、更换默认模型、看到 Key 脱敏信息 |
3产品定位与命名
一句话定位:dsh-multi-user 把一台个人 dsh 变成一台多人可用的 dsh——登录才可进入,每人有自己的工作区、会话与插件,模型与凭据只有主管理员能动。
命名分析
生态内的检索路径决定了命名策略:用户在 GitHub 搜 dsh-plugin topic、在目录站按关键词(Web、Agent、工具、安全……)浏览[5],插件名的功能词直接决定被发现的概率。现有命名规律是 dsh-<功能词>(dsh-web-ui、dsh-cost-meter、dsh-notification)。候选评估如下:
| 候选名 | 优点 | 风险 | 结论 |
|---|---|---|---|
| dsh-multi-user | 最直白,任何背景的人一眼可懂;dsh- 前缀锚定生态检索,multi-user 是覆盖面最广的功能词;已核验 GitHub 无同名仓库(2026-08-17),仅存在名称不同的相近方案[14] | "multi-user" 裸词在 GitHub 噪声大,但配合 dsh- 前缀与 topics 后检索精度可控 | 推荐 |
| dsh-multiuser | 合成词写法,含义相同,撞名概率更低 | 可读性略逊于带连字符写法 | 备选 |
| dsh-tenancy | 行业术语 tenancy(租户制),偏 B2B 语境,独特性高 | 对非企业背景用户不直观 | 备选 |
| dsh-multi-tenant | 术语准确 | 名称已被其他仓库占用(用户反馈,2026-08-17) | 放弃 |
| dsh-team / dsh-team-space | 好记 | 与 dsh-agent-teams(子 Agent 团队)[11]强烈撞名,会被误认 | 放弃 |
配套的仓库呈现(让 GitHub 首屏即可读懂):
- 仓库描述:Turn one DeepSeek Harness (dsh) into a multi-user platform: password / email-code / WeChat-QR / SMS login, per-user workspace & plugin isolation, admin-only model config. 把一台 dsh 变成多用户平台。
- Topics:
dsh-plugin、deepseek-harness、dsh、multi-tenant、multi-user、authentication、workspace-isolation - README 首屏对照表:单人用 dsh vs 装 dsh-multi-user 之后,一行看懂差异。
4角色与总体架构
4.1角色与术语
| 术语 | 定义 |
|---|---|
| 主管理员(Owner) | 启用插件时绑定的第一个用户,是原 dsh 个人配置的继承者。全插件周期内唯一可配置模型与凭据、管理子用户、管理插件安装的角色。 |
| 子用户(Member) | 由主管理员创建的普通用户,登录后进入自己的隔离环境:只见自己的工作区、会话与被授权的插件。 |
| 租户环境 | 一个用户名下的工作区集合、会话存储、插件可见集与个性化设置的总和。 |
| 未启用态 | 插件安装但未开启的状态,此状态下 dsh 行为与未安装时完全一致。 |
4.2权限矩阵
| 能力 | 主管理员 | 子用户 |
|---|---|---|
| 配置模型提供商与 API Key | 可 | 不可(只读可见可用模型清单) |
| 选择会话内使用的模型 | 可(全部) | 可(限管理员开放的模型集合) |
| 安装 / 卸载插件 | 可 | 不可 |
| 启用插件 | 可(全部) | 可(仅被授权的插件) |
| 工作区 | 全部 + 目录授权管理 | 仅自己被授权的目录 |
| 会话与历史记录 | 全部 | 仅自己的 |
| 子用户管理(创建 / 停用 / 插件授权) | 可 | 不可 |
| 登录方式与认证接口配置 | 可 | 不可 |
| 查看用量统计 | 全部用户 | 仅自己 |
4.3总体架构
5功能需求详述
本章按六个功能模块展开,每个模块附可交互原型。原型用于确认交互逻辑,不代表最终视觉稿。优先级标注:P0 = 首个可用版本必须交付;P1 = 紧随其后的第一批增强。
FR-1插件生命周期与无侵入设计 P0
卸载插件将自动停用多用户功能并恢复原 dsh 个人配置(工作区、模型、会话回到启用前的全局默认视角);各子用户的租户数据默认保留在插件数据目录,可在卸载时勾选"同时彻底清除用户数据"。
业务逻辑
安装(dsh plugin --profile web add …)完成后,插件处于未启用态:不注册登录路由、不替换任何官方组件,dsh 的启动配置树与安装前一致(可用 dsh web --dump-config 验证)。用户在设置页看到"多用户"卡片,卡片上明确提示启用前置条件——必须先设置主管理员:填写用户名、初始密码并选择一种初始登录方式。主管理员保存后,"启用"按钮方可点击;在此之前按钮置灰并附原因文案,避免出现"启用了却没有管理员能进去"的死锁。
点击启用后,插件做三件事:对当前 $DSH_HOME 的个人配置(模型提供商、默认工作区、既有会话归属)做一次快照并把它们绑定给主管理员;写入启用状态;触发页面自动刷新。刷新完成后,登录墙生效——此后任何未携带有效会话的访问都会被重定向到登录页,主管理员用刚才设置的账号登录后,看到的正是启用前自己的环境(模型、会话、工作区原样继承),实现了"单人无缝过渡为多人的管理员"。
停用是可逆操作:登录墙撤下、回到单用户视角(即主管理员视角成为全局默认),所有租户数据保留,再次启用无需重设。卸载则遵循还原承诺:插件通过官方 CLI 卸载时自动执行还原流程——若从未启用过,dsh 不受任何影响;若启用过,则把主管理员的环境恢复为全局默认配置,等同于回到安装前。子用户数据默认保留(目录可手动清理),卸载对话框中提供"同时彻底清除用户数据"选项。
状态转换
| 当前状态 | 允许操作 | 下一状态 | 触发条件 |
|---|---|---|---|
| 已安装 · 未启用 | 设置 / 修改主管理员 | 已安装 · 未启用(管理员已设置) | 保存管理员表单且校验通过 |
| 未启用(管理员已设置) | 启用 | 已启用 | 点击启用 → 快照 → 自动刷新 |
| 已启用 | 停用 | 未启用(管理员与数据保留) | 管理员确认停用 |
| 任意状态 | 卸载 | 还原为原 dsh 个人配置 | 执行插件卸载(未启用过则无任何影响) |
FR-2多方式登录 P0
业务逻辑
启用后,登录页成为 dsh Web 的唯一入口:任何未携带有效会话的页面访问(包括刷新、直达 URL、API 调用)一律重定向到 /login。页面上呈现的登录方式集合由管理员在 FR-3 中配置的启用项决定——只开账号密码就只显示一个页签,全部开启则显示四个,登录方式对用户是"被动可选集",不能自行增减。
四种方式的交互流程:账号密码为用户名 + 密码直接提交校验;邮箱与短信验证码均为"输入账号标识 → 获取验证码(按钮进入 60 秒倒计时防重发)→ 输入验证码提交";微信扫码展示二维码占位并轮询状态,依次经过待扫码 → 已扫码待确认 → 确认登录三态,二维码有效期 2 分钟,过期可手动刷新。任一方式登录成功后建立会话(HttpOnly Cookie,有效期可配,默认 7 天),根据账号解析出的用户身份进入对应租户环境;主管理员账号登录则进入管理员视角。
边界与异常
- 验证码有效期默认 5 分钟;同一账号 1 分钟内最多请求 1 次,超限提示而非静默丢弃。
- 连续失败 5 次锁定 10 分钟(阈值可配),锁定期间所有方式均拒绝,防止撞库。
- 微信扫码轮询失败或认证接口超时(默认 5 秒)时,页签内显示可重试错误,不整页崩溃。
- 被停用的子用户登录时提示"账号已停用",不泄露具体原因细节。
FR-3认证方式可配置:接口与参数 P0
业务逻辑
本模块回答"每种登录方式调什么接口、带什么参数"。设计为双模式:内置模式开箱即用,插件自带本地用户库,账号密码本地校验,验证码由插件配置的发送通道(SMTP 参数 / 短信服务商 API)发出,适合没有任何账号体系的个人与小团队;外部接口模式面向已有账号体系的部署者(公司统一认证、自建用户服务),每种登录方式的每个动作都映射到一个可配置的 HTTP 接口,插件按字段映射组装请求、解析响应。
每种方式的配置项由"动作 → 接口 → 参数"三元组构成。账号密码只需一个校验接口(URL、方法、用户名/密码字段名、成功判定表达式、用户标识取值路径);邮箱与短信各需"发送 + 校验"两个接口并共享字段映射;微信扫码需 AppID / AppSecret(走官方开放平台),或在有自建微信网关时覆盖二维码获取与轮询两个接口。所有接口配置含超时(默认 5 秒)与失败重试次数(默认 0 次)。保存时插件对配置做连通性校验("测试连接"发送探测请求),通过后方可保存并即时生效,无需重启。
字段规则
| 字段 | 类型 | 必填 | 约束 | 默认 |
|---|---|---|---|---|
| 方式启用开关 | 布尔 | 是 | 至少启用一种方式,否则保存被拒 | 账号密码开,其余关 |
| 模式 | 枚举 | 是 | 内置 / 外部接口 | 内置 |
| 接口 URL | 文本 | 外部模式必填 | 合法 http(s) URL | 空 |
| 请求方法 | 枚举 | 外部模式必填 | GET / POST | POST |
| 字段映射 | 键值对 | 外部模式必填 | 键为插件标准参数名,值为目标接口字段名 | 预填常用名 |
| 成功判定表达式 | 文本 | 外部模式必填 | 对响应 JSON 的取值/比较表达式 | data.ok == true |
| 超时 | 数字 | 否 | 1–30 秒 | 5 |
FR-4工作区与会话隔离 P0
业务逻辑
隔离的落点是 dsh 的两个全局列表:工作区列表与会话历史。启用后,这两份列表按登录身份过滤——每个租户环境持有独立的工作区授权集合与会话存储命名空间,用户 A 的工作区目录、会话记录、附件与运行轨迹对用户 B 完全不可见,反之亦然。主管理员额外持有全部工作区的可见性与目录授权管理权。
工作区采用授权制而非自由浏览制:新用户默认没有任何工作区,主管理员在用户管理页为其授权一个或多个主机目录(或在该用户租户目录下新建空工作区),用户登录后只能在授权集合内选择与切换。会话内文件操作沿用 dsh 原生沙箱(workspace-write 限制在当前工作区内[2]),插件不改变沙箱行为,只在入口层收敛"哪些目录可以成为工作区"。会话数据按用户命名空间分目录存储,登录后 dsh 原生的会话恢复、历史列表、轨迹回放功能照常工作,只是数据源被限定为本命名空间。
边界与例外
- 两个用户被授权同一目录时,插件给出显著提示(共享目录会互相看到对方会话产物文件),由管理员决策是否保留。
- 用户被移除授权时,其进行中的会话立即终止;历史会话保留在本人命名空间内,仅列表不可再进入该工作区。
- 子用户的租户数据目录(工作区文件、会话)不因停用账号而删除,卸载插件时的数据处置遵循 FR-1。
FR-5插件可见性与子用户默认插件 P0
新建子用户
业务逻辑
插件的安装与可见是两件事:安装由主管理员全局操作(沿用 dsh 官方 CLI 或插件市场),安装后的插件进入"可分配池";可见性按用户授予——每个子用户持有一个被授权插件集合,dsh 界面的插件列表、插件设置页、会话内插件能力均按该集合过滤,未授权插件对该用户等于不存在。主管理员默认可见全部已安装插件。
新建子用户时指定默认开放插件是本模块的核心交互:创建表单中列出可分配池,管理员勾选该用户初始可用的插件;勾选存在依赖的插件时(例:视觉类插件依赖模型工具插件),界面自动带出依赖提示并可一键连选依赖项——依赖关系数据来自插件清单,校验思路对齐 dsh-web-plugin-manager 的依赖 / 冲突分析[8]。存量用户的插件授权可随时增删,调整即时生效(用户下次加载页面即更新,进行中的会话不受影响直到其结束)。
子用户不能安装、卸载或更新插件,也不能看到"未分配给自己"的插件条目;插件市场类页面(若管理员安装了市场插件)对子用户同样按授权过滤展示与操作。全局插件启停(影响所有人的操作)仅管理员面板可见。
FR-6模型配置权限 P0
业务逻辑
模型提供商、API Key、OAuth 登录、Base URL 与模型映射这些配置的写权限收敛到主管理员一人:设置 → 模型页对子用户渲染为只读视图。管理员可进一步指定"对全员开放的模型集合"(按提供商或按具体模型粒度),子用户在该集合内选择自己的默认模型与会话内模型(dsh 原生的会话级模型选择器保留,但选项被限定在开放集合内);集合外的提供商在子用户视角显示"未对你开放"或不显示,两种展示策略由管理员设置决定。
凭据可见性遵循"只紧不松"原则:dsh 原生设计中页面本就只能拿到 Key 的脱敏描述符、真实凭据存于 Host 侧 .credentials.yaml[12];本插件进一步把脱敏描述符也从子用户界面移除。子用户的任何请求由 Host 按管理员配置的提供商路由,全程不接触凭据材料。管理员在用户维度可设置"默认模型",新建用户时沿用,用户可自行覆盖(若管理员未锁定)。
FR-7综合增强能力(吸收现有插件功能)P1
以下能力不是多租户的必要条件,但都是调研中已被验证的高价值功能,在多租户语境下价值放大,规划为首个可用版本之后的第二批交付:
| 能力 | 借鉴来源 | 多租户下的增量价值 |
|---|---|---|
| 按用户用量统计与成本分账 | dsh-usage-stats[10] / dsh-cost-meter | 把 token 热力图、费用统计从"按模型"扩展出"按用户"维度:管理员看全员,用户看自己;共享一个 API Key 的成本第一次可以算清归属 |
| 用户配额与限速 | (生态空白,配额语义源自多租户刚需) | 按用户设日 / 月 token 或请求次数上限,超额提醒或限流,防止个别用户吃光共享额度 |
| 插件依赖与冲突检查 | dsh-web-plugin-manager[8] | 在给子用户分配插件时即时校验依赖完整性与版本冲突,分配面板内置健康检查 |
| 配置快照与一键回滚 | dsh-undo-plugin[9] | 每次启用 / 停用 / 升级前自动快照多租户配置,出问题一键回到上一个已知良好状态 |
| 操作审计日志 | (多租户合规刚需) | 记录登录、授权变更、插件分配、模型配置修改的操作者与时间,供管理员回溯"谁改了什么" |
6安全与数据边界
- 口令存储:内置模式的密码必须以不可逆哈希(加盐)存储,任何界面、日志、导出物中不得出现明文密码或验证码。
- 会话安全:登录会话使用 HttpOnly Cookie,有效期与续期策略可配;登出即失效;启用登录墙后所有 API 端点同样要求有效会话。
- 凭据边界不放松:模型 API Key、OAuth 令牌仅存 Host 侧 dsh 凭据体系,与 dsh 原生行为一致[12];本插件不复制、不导出、不向浏览器下发凭据材料,子用户界面连脱敏描述符也不展示。
- 外部认证接口:仅接受管理员配置的固定 URL;请求超时与失败有明确上限;认证接口返回体中除用户标识外的字段一律丢弃,不进入插件存储。
- 租户数据归属:插件只管理路由与可见性,不复制用户工作区文件;租户数据集中存于插件数据目录下按用户隔离的命名空间(目录布局与文件载体见第 7 章),卸载时的处置选项见 FR-1。
- 最小替换原则:替换官方设置组件时只挂载必要的组合点,卸载时还原官方组件——对齐 AuthInOne 已验证的边界做法[6]。
7数据存储设计
存储设计遵循三条约束:零外部依赖(不引入 MySQL / Redis 等外部服务,NAS 与家用服务器开箱可用)、自包含可备份(一个数据目录打包即完整备份)、命名空间映射而非复制(会话历史等大体积数据仍存 dsh 原生存储,插件只维护映射)。首个可用版本以带原子写入的 JSON 文件为载体;P1 起引入嵌入式 SQLite(单文件,仍无服务依赖)承载用量与审计的聚合查询。
7.1目录布局
所有插件数据集中落在 $DSH_HOME 下的插件数据目录,与 dsh 原生文件(profiles、settings.yaml、.credentials.yaml)物理分离,互不污染:
7.2数据分类与职责
| 数据类别 | 载体 | 写入方 | 生命周期 |
|---|---|---|---|
| 插件配置 | settings.json | 仅 Host 进程(管理员操作) | 停用保留;卸载时随数据目录按 FR-1 处置 |
| 用户账户与口令哈希 | users.json | 仅 Host 进程(管理员操作) | 删除用户后条目匿名化保留(供审计追溯),不留口令哈希 |
| 登录会话 | sessions.json | Host(认证适配器) | 登出或过期即删除;停用时全量失效 |
| 授权与偏好 | grants.json / preferences.json | Host(管理员授权;用户改自己的偏好) | 停用保留;卸载时随租户目录处置 |
| 会话历史与附件 | dsh 原生会话存储 + 命名空间映射 | dsh 原生机制 | 不复制、不迁移;卸载后原生数据完整可读 |
| 用量流水 | usage.jsonl(P1 起 SQLite 聚合) | Host 代理层自动追加 | 明细默认保留 180 天(可配);聚合视图可由流水重建 |
| 审计日志 | audit.jsonl | Host 自动追加 | 默认保留 365 天(可配),按大小轮转 |
| 模型凭据 | dsh 原生 .credentials.yaml | 仅主管理员经原生体系 | 不落本插件——与插件数据目录完全隔离,卸载不受影响 |
7.3存储原则
- 原子写入:所有 JSON 文件写入一律走临时文件 + rename,进程崩溃不产生半写文件;多写并发由 Host 单点串行化,插件数据不出现多写者。
- 文件权限:数据目录与文件按最小权限收紧(Unix 下 0700 / 0600,Windows 下等价 ACL),确保同机其他系统用户不可读;口令哈希采用 argon2id / bcrypt(加盐,见第 6 章)。
- 命名空间映射:每个用户的 dsh 会话历史存于原生会话存储中独立的命名空间(
tenants/<uid>/sessions维护映射表),插件不复制、不改写原生文件——这是"未启用态 / 卸载后行为与原版一致"承诺的基础。 - 追加不可改:
usage.jsonl与audit.jsonl为 append-only 流水,作为分账与审计可信度的基底;聚合报表只是衍生视图,可随时从流水重建。 - 自包含备份:打包
plugins-data/dsh-multi-user/即得完整备份,恢复即解压;配合snapshots/可回到任一启用 / 升级前的状态。README 提供备份与迁移命令示例。 - 无外联:数据目录内的一切文件仅由本插件读写,不向任何外部地址发送;与第 6 章的凭据与认证边界一致。
8兼容与性能约束
- 版本声明:dsh 处于 developer preview 快速演进期,每个发布版必须声明验证过的 dsh 版本 / commit(对齐 AuthInOne 的 exact-compat 声明与"未知宿主即拒绝安装"策略[6]),不兼容版本给出明确错误而非静默运行。
- 还原性验证:卸载后
dsh web --dump-config输出与安装前一致;未启用态的页面加载行为与未安装时无可感知差异。 - 性能预算:登录墙对已登录用户的常规页面加载增加开销不超过 200ms;认证接口调用默认 5 秒超时;用户切换、插件可见性过滤在服务端完成,不向客户端下发全量列表再过滤。
- 界面语言:UI 文案中英双语(社区插件惯例),README 同步双语。
- 安装方式:一条命令安装到 web profile(
dsh plugin --profile web add …),不要求二次端口、手动改 profile YAML 或内核补丁。