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 一律写「远程服务器」。
1.9 KiB
1.9 KiB
十八、统一 KEY:管理员统一设置,用户只能使用管理员 KEY 和模型(2026-09-08 20:40)
决策(用户确认):① KEY 存放 = 复用 admin 密钥库(桌面/API 自助换 key 即全局生效);② 用户 dsh 界面自配暴露面先实测再定,本次不做 dsh patch。
改动(commit df5cc84,6 文件 +49/-14):
| 文件 | 改动 |
|---|---|
src/web/server.ts |
resolveApiKey 忽略入参 userId,改为 listPublicUsers().filter(role==='admin') 取 admin 的启用 key——所有用户 spawn 注入同一把管理员 key |
src/supervisor/spawner.ts |
Spawner 接口新增 restartAllMains() |
src/supervisor/orchestrator.ts |
LocalSpawner 实现:遍历内存 mains 逐个 restartMain(单个失败 console.error 不中断广播) |
src/supervisor/k8s-spawner.ts |
K8sSpawner 实现:遍历 db.listInstancesByRole('main') 逐个重启 |
src/web/routes/auth.ts |
/api/me/keys GET/POST/select/delete 由 requireAuth 改 requireAdmin(普通用户 403);POST/select 后 restartAllMains() 广播(key 是 spawn 时注入 env 的快照,不重启运行实例不刷新) |
web/desktop.html |
非 admin 隐藏"管理密钥"按钮;面板文案改"全局 API 密钥(所有用户共用,仅管理员可改)" |
验证(全链路实测):
- admin GET
/api/me/keys→ 200,deepseek-main 在列 ✅ - 注册 testuser(pending)→ admin approve(active)→ 登录 ✅
- 普通用户 GET/POST
/api/me/keys→ 403 forbidden ✅ - testuser launch DSH → 打开 200 SPA →
llm/listProvidersok:true deepseek-official ——证明普通用户无自配 key 也拿到 admin 全局 key ✅
遗留:用户 dsh 界面内自配 key/模型的能力面未实测(proxy 伪装 loopback 可能放行 dsh Settings)——第二道防线待 P1 实测后再定。testuser 账号保留作普通用户全链路验证种子。