build / build-and-scan (push) Waiting to run
文档库:目录改为编号制(01-规范/02-架构设计/03-数据库/04-调整方案/
05-交接单/06-ops/07-scripts/08-skills/09-archive),顶层散文件归入 01-规范/;
INDEX.md 与 docs-manifest.json 重刷(档案 146 篇);旧目录名引用全量对齐。
IM 线:src/im/**(SDK / hub / store / presence / ws / gateway-token)、
src/web/routes/im.ts、src/db/plugin-data/**、src/supervisor/plugin-assembly.ts
及对应 test/**。
插件线:poc/{im-agent-bridge,im-connection-gateway,im-conversation-tabs,
business-plugins-im,carbon-mcp-probe}、src/web/routes/{sessions,overlay-device}.ts、
src/net/relay/{device-grant,instance-credential}.ts。
仓库卫生:清出 40 个历史误入库 / 已改名文件(34 个交接单归档 + 6 个旧结构,
本地均有副本);dsh-server-docs/.gitignore 补 tmp/;交接单不入库(政策)。
145 lines
53 KiB
JSON
145 lines
53 KiB
JSON
{
|
||
"01": "登录直达 URL 自动带 launch token",
|
||
"02": "权限边界收紧 + DB 加固",
|
||
"03": "API KEY 收归管理员统一管控",
|
||
"04": "注册/审核/删除用户闭环",
|
||
"05": "插件化可行性 + PoC(**PoC-2 三项已复核**:①不做 ②已实现 ③作废)",
|
||
"06": "登录直达会话窗口 v1+v2",
|
||
"07": "升级红线(禁自动取最新版)与独立升级流程",
|
||
"08": "last-wins 单活跃会话 + idle-reap 常驻上限",
|
||
"09": "角色化 profile patch 裁剪 client 插件",
|
||
"10": "共享只读技能目录(bundledSkillDir)env 注入",
|
||
"11": "技能管理面 API + 页面(zip-only 两阶段替换)",
|
||
"12": "VoxEMW 全云 API 化调研 + M1 落地",
|
||
"13": "登录直达冷启动竞态 404 修复",
|
||
"14": "会话敏感信息暴露面审计 + nftables 出网护栏",
|
||
"15": "三页 401 守卫跳登录 + 核心插件开关收归 admin",
|
||
"16": "页面导航定稿 + 插件三层归属模型(folder_plugins 废弃)",
|
||
"17": "工作区选择器暴露面核查(P1/P2 边界判定)",
|
||
"18": "目录选择器收敛为仅见自有目录(v3 定稿实测,含 admin)",
|
||
"19": "方案与代码全面审查(代码 10 项 + 文档 8 项)",
|
||
"20": "崩溃自愈:指数退避 + 熔断 + 观测(含 live 实测)",
|
||
"21": "guest「卡顿」排查(根因=nginx proxy_buffering 已修)",
|
||
"22": "域名迁移到 alotbuy.com(含 4 个踩坑与回滚)",
|
||
"23": "实例内 AI 能力与权限限制核查(合成根补 /bin 修复)",
|
||
"24": "实例侧 401 自动恢复(freshAuthUrl 302 带新 token)",
|
||
"25": "实例崩溃循环修复 + not_running 兜底",
|
||
"26": "dsh 升级耦合点与回归清单(官方包零改动)",
|
||
"27": "MCN 工作台插件平台化评估(3 处 P0 必改)",
|
||
"28": "用户数据清理三件套(ws-cleanup / session-gc / purge-trash)",
|
||
"29": "官方白名单插件来源(awesome-dsh-plugin,仅预构建可导入)",
|
||
"30": "编排器孤儿实例清理(spawn 前清 stale scope)",
|
||
"31": "插件管理页双 Tab + 说明为主视觉",
|
||
"32": "mcntimo 会话取证与沙箱 P0 核查",
|
||
"33": "实例权限默认档位改为完全权限(env 开关)",
|
||
"34": "功能插件启用探活 + 逐插件隔离",
|
||
"35": "ws-cleanup 误删平台 bundle 包修复",
|
||
"36": "「功能插件」分区铺给普通用户 + 新用户自动铺",
|
||
"37a": "guest 会话取证与平台缺陷清单(P0-1 档位/P0-2 零技能)",
|
||
"37b": "功能插件分区 v0.2:官方 token + i18n + 交互升级",
|
||
"38a": "实例软件安装共享 / 网络与安全边界核查(S1-S3 缺口)",
|
||
"38b": "术语统一「业务插件」→「功能插件」",
|
||
"39": "实例可见面收窄(/etc 白名单)+ 封宿主访问(H5)",
|
||
"40": "共享技能层挂载修复(补 bwrap --ro-bind)",
|
||
"41": "技能上传安全加固(symlink/zip bomb)+ 用户技能启停",
|
||
"42": "实例共享 Python 运行时 + 会话取证复核(修 /etc/alternatives)",
|
||
"43": "root 污染用户工作区 → 属主自愈",
|
||
"44": "基础运行时版本冻结(PYTHONNOUSERSITE + USERBASE)",
|
||
"45": "存量会话「新开会话」提示(选提示不选迁移)",
|
||
"46": "实例共享工具 jq / ripgrep / ffmpeg",
|
||
"47": "admin「运行环境」管理页(含版本漂移告警)",
|
||
"49": "实例回收后首次访问的反馈与自愈(wake.html 过渡页)",
|
||
"50": "会话过期自愈注入脚本(**已被 04-51 在传输层取代**,保留兜底)",
|
||
"51": "实例侧 401 透明重放(含 SSE 自动重连)",
|
||
"52": "新用户实例无法启动(picker 三处连锁缺陷)",
|
||
"53": "文档质量审查与精简(含 37/38 编号冲突立项)",
|
||
"54": "文档信息架构优化(BRIEF 现状卡 + 机读清单)",
|
||
"55": "guest 最新会话取证与优化项(档位会话级播种)",
|
||
"56": "实例助手:我的文件 / 能力清单 / 档位提示 + 文件下载端点",
|
||
"57": "设置面板「用户管理」入口 + 全员安装",
|
||
"58": "实例内存优化与配额下调(512M→384M + 编译缓存)",
|
||
"59": "重连反馈:实例启动中的加载动画",
|
||
"60": "设置面板分区改名:功能插件 → 功能管理",
|
||
"61": "插件管理页:官方插件列表加高 + 页面底部留白 200px",
|
||
"62": "插件目录:缓存状态可见化 + 「重新拉取目录」按钮",
|
||
"64": "接入 AnySearch 搜索 provider(admin 侧已实施;**待端到端确认 → 铺普通用户**)",
|
||
"65": "功能插件启停与 web provider 配置联动(**已部署生效**:服务器 `lib/` 00:13 构建 → **00:15:23 重启即载入**,08:02 再载入;§7.3 第 3 条「anysearch 覆写脚本退役」已完成 = 加硬拦)",
|
||
"66": "业务插件 P0 误报 → admin 显式信任(fail-closed + 逐条回显 + 留痕)",
|
||
"67": "「功能管理」section 按 UI 规范重做 v0.2.4",
|
||
"68": "候选池启停的 root 属主污染根治(setpriv 降权 + 属主自愈 + 清存量)",
|
||
"69": "并发治理落地(文档库 commit 常态化 + 服务器侧操作锁 + 权限统一 + 代码库留路标)",
|
||
"70": "**anysearch 插件与 dsh 0.1.2-rc.1 不兼容 → 实例崩溃循环**(已止损;**待决:能力保留/下架**)",
|
||
"71": "**插件兼容性预检**:导入/上传即判定(判据 A semver 依赖范围 + 判据 B 运行时导出符号;已部署 `8d19e89`)",
|
||
"72": "**实例被回收/关闭后,回到页面自动唤醒并重建连接**(不再需要手动刷新;`b23e386`)",
|
||
"73": "**让锁真正拦得住人**:措辞修正(guard/交接单)+ **PreToolUse 强制钩子**(无锁拒写;⚠️ 待 `/hooks` 审核启用)",
|
||
"74": "**实例内存治理**:V8 老生代上限 **256→160 MiB**(走平台预留的 `DSH_INSTANCE_NODE_OPTIONS`,**零代码改动**)+ 采样脚本加**阈值告警**(85% × 连续 3 次 → WARN)+ cron 每小时→10 分钟。实测实例 `rss` **363.7→195.5 MiB**。**配额 384M 与宿主内存不动**",
|
||
"75": "**插件评估新增两维度**(接档案 71):**托管友好性** H1–H4(**向浏览器交付绝对 URL = 阻断**;硬编码 loopback / 自建监听 = 警告)+ **资源成本**(加载 `rss` 增量,>30 MiB 标注、>60 MiB 强提示)。附**改造规范 R-a~R-e**(入口唯一 / IPC 代替 TCP loopback / 不新增端口 / 重型依赖懒加载)。**只立标准,未改预检脚本**",
|
||
"76": "**dsh-univer-office 平台适配改造**(**档案 75 首个落地样本**):gateway 加 **unix socket** 传输(`UNIVER_DSH_GATEWAY_SOCKET`,**不设则完全保持原 TCP 行为**)+ **同源 Viewer 代理**(`/univer-api/viewer/**` 与 `/uf/**`,含 **WS upgrade 按文件懒注册**)。构建 rc=0 | 回归 `integration-smoke` 18 项 OK | **Linux socket 验证通过**(`GET /`→200 且 Univer 标记 true)。产物 `[email protected]`(41 MB)。**端到端验收待拍板(R8)**",
|
||
"77": "**回到页面自检 + 就地恢复(恢复过程可见化)**:判据从「进程在不在跑」改为「**页面能不能连上实例**」(新增实例侧探针 `GET /`,2.5 秒超时;`404/405` → 降级回旧判据,**绝不误报**)+ 新增**顶部轻提示条** `#__dshConnBar` 与**不自动消失**的覆盖层 + 恢复**就地**(跨域 `enter` 拿新 token 后原地跳回、**保留路径**,不再跳门户过渡页)。改 1 个源文件(`proxy.ts` 的注入脚本)。配置层全绿;**浏览器端实测 10/10 全绿**(2026-09-13)",
|
||
"78": "**崩溃熔断:冷却期 + 告警**(修档案 77 §八 遗留 1):熔断态改为**跨轮存活**(不再被 `resetCrashState()` 清空)+**指数冷却**(10 min × 2^(n-1),封顶 6 h),冷却期内 `launch()` 抛 `CrashBreakerOpenError` → HTTP **503 `instance_circuit_open`**(带 `retryAfterMs` / `opens`);熔断同时写 stderr + **`/var/log/dsh-crash-breaker.log`**,并在 `/api/dsh/status` 暴露 `breaker`。平台自身操作(插件启用/隔离)用 `force` 绕开。`npm test` **45 pass / 0 fail**;**已部署并验证**(2026-09-13 08:02;`/api/dsh/status` 新增 `breaker`)|**浮层视觉升级 + 现场故障热修**(08:15 视觉升级曾把注入脚本写崩 → 08:27 修复,并补齐「连接悄悄断掉」两条触发面:可见时 25 s 心跳 + EventSource/WebSocket 断流,均「连续两次失败才恢复」;新增 `07-scripts/verify-inject.cjs` 接入 `npm test`)",
|
||
"79": "**插件启停的两处平台缺陷**(2026-09-13 发现,**P0 未修**):① 隔离定位循环 `uninstall` **缺 `await`** → unhandled rejection **把整个 orchestrator 带崩**(07:43:58 实证,全体用户瞬断 + 实例被停)② `pnpm remove --ignore-workspace-root-check` 是**无效 flag**(仅 `add` 支持)→ 禁用路径必然失败 ⇒ 必然触发 ①;③ 连带:catch 未跑 ⇒ profile 停**半应用态**(实例每次启动即 OOM)。**修法已备**(1 行 await + 换 `-w` + 外层 `.catch`)|落地 = 改码 + build + **重启服务(R8)**",
|
||
"80": "**架构与功能优化评估(保留功能前提下的重构方向)+ 去平台痕迹**:**不推倒重来** —— 平台本体就是要保留的功能;**今天几次事故根因全是「层层补丁叠加」**(模板转义把注入脚本写崩 ×2、配额与插件集合脱钩致 OOM 137、缺有界恢复、自愈 5 代补丁)。9 项优化按事故排序:①注入脚本外置+构建期硬校验 ②`npm run verify` 统一校验 ③**实例配额跟随插件集合**(自适应内存)④**门户管理就地化 = 弹窗 iframe**(实测平台页无 `X-Frame-Options`;⚠️ 需先 R5 评估)⑤自愈收口成一份状态机 ⑥有界恢复 ⑦门户页面结构 ⑧可观测性统一 ⑨文档/代码同仓。**P0(去平台痕迹)已上线**;P1 四项建议合一次重启窗口",
|
||
"81": "① 定下**一套命名**:对外叫「**工作台**」、内部统一前缀 **`dshs`**(替换 `dshs`);",
|
||
"82": "① R2 的 **R5 权限影响评估**已在档案 81 §9.2 出齐并获批(扩大点=实例内出现可操作的管理入口 ⇒ **仅 admin 可见** + **只读** + 写操作回跳)。⚠️ **本档内部 16 份重复(190 个冗余块,85%)**,原文按 L5 冻结保留;`docs-dedupe.py` 已生成**去重视图**(89.1→59 KB,检索会提示)—— 根治需**拆分**,待立项",
|
||
"83": "① 查实:登录页用的是 `design.css` —— 一套**深色 OS-desktop 体系**,与 `06-工作台UI规范`(**强制基线**、冲突时以它为准)**全面冲突**;",
|
||
"84": "实例内存配额口径统一(消灭「388 MiB」误报)",
|
||
"85": "① 原先平台是「**统一 KEY**」——`resolveApiKey()` **显式忽略入参 userId**,不管谁 spawn 都注入 admin 那一把;② 本轮改为**两层**:**用户自己的 key 优先,没",
|
||
"86": "① 平台**所有**服务/文件 API 都是 `request.user.id` 语义(`desktop.ts` 头注释原文 \"one user can never address another user's file",
|
||
"87": "**平台自建「模型设置」**(官方「设置 → 模型」页在平台环境**必然报错** ⇒ 弃用它):① 官方「模型」分区对**全角色(含 admin)**隐藏 —— 判据是**浏览器页面**的 loopback 判定(真实域名恒 false),官方 README 原文 *\"Non-loopback pages get no durable settings\"*(与 `03-路线图` 决策 3 记的「proxy 伪装 Host ⇒ /api trust fence 放行」**不是同一层**,两者都成立);② 插件 **0.3.12** 新增「设置 → 模型设置」分区:**按官方页结构**(提供方行 + 新增先选厂家),**接官方 pi-ai 的 38 个厂家目录(国内 11 家:蚂蚁 / 通义千问 / 小米 / 月之暗面 / 智谱 / MiniMax)—— 目录厂家只需填 API 密钥**,端点/协议/模型由目录兜底;条目**各自开关、可同时启用** + 平台共享模型**也列入且可开关** + 模型在 dsh 对话框选;③ DB 迁移 **V6**(`credential_vault` 加 `route/base_url/api/models`、`users.shared_model_enabled`)并**重定义 `getEnabledCredentialKeyRef`**(原实现无 `ORDER BY`,互斥一删就会**任取一条**);④ 新落地层 `src/web/model-landing.ts`(spawn 时写实例 `.credentials.yaml` / `settings.yaml`,**只碰自己写过的**,托管清单 `/opt/dsh/state/model-landing/<userId>.json`)。**已上线 + 用户点名的验收四件事全绿**;顺带修掉两颗雷(角色补丁脚本整文件覆盖会抹掉 admin 另两个平台块、`verify-mem-model` 陈旧断言)",
|
||
"88": "**内置 dsh 安装路径按序探测(修 P1 静默失效)**:平台**三处**把内置 dsh 目录写死成 `/usr/local/lib/node_modules/@deepseek-ai/dsh` —— 而 `npm root -g` 落点**随发行版变**(发行版包管理器装的 Node 常见 `/usr/lib/node_modules`)⇒ 那种机器上:**厂家目录读成空**(模型设置只剩内置+自定义)、**插件兼容性预检安全网整体失效**(`platformPkgCount()`=0)、**目录选择器 import 即抛**;前两处**静默降级不报错**,所以在本机(`/usr/local` 恰好等于写死值)怎么也测不出来。修法 = 新增 `src/web/dsh-install.ts` 按序探测(env → **dsh 可执行文件解软链** → 常见全局根 → `npm root -g` → 历史默认值),三处调用点改走它(picker 跑在实例进程内 ⇒ 自带同思路一份);并**把降级改为可观测**(告警 + `/api/me/model-providers` 透出 `catalog{dir,readable,count}` + 插件 0.3.13 如实提示)。⚠️ **env 名两侧都要认**(源仓 `DSHS_DSH_BIN` / 导出侧 `DSH_USERS_PLATFORM_DSH_BIN`)。已在测试服 `test106`(`/usr/lib` = 原故障机)三种姿势验证 + 本服务器回归(223 / 39)。含**「为什么三轮都没发现」的根因复盘**与四条防再犯",
|
||
"89": "**对话内文件预览**:采纳官方推荐库现成插件 `@softspark/dsh-file-preview`(65 KB,包住官方 `openWorkspacePath` 接管\"点文件\"手势;兼容预检 ok、已启用、L5 待实测)| ④与⑤(82–88 待收口会话补登记)",
|
||
"90": "> 目标版本 = **`0.1.5-rc.1`**(npm `latest`;用户材料里插件 peer 也是 `^0.1.5-rc.1`,三方自洽)。",
|
||
"91": "**「模型设置」页复刻官方交互**:换行根因是 **4 列表格 auto 列宽** ⇒ 改官方**卡片行**(两侧 nowrap)+「新增」改**两步式**(两个虚线按钮 → 卡片主字段只剩「API 密钥」);顺修「由 admin 配置」「密钥可留空」两处错文案,补删除二次确认。插件 **0.3.15**,新增 `verify-models-dict` / `verify-models-render` 两个构建期校验",
|
||
"92": "**官方推荐插件列表按 dsh 版本过滤**:官方目录**不带** dsh 版本字段 ⇒ 平台侧逐包查 npm 声明与**平台真实版本**比;默认隐藏「仅兼容更旧版本」,「需更高版本」橙色标注。⚠️ 两处静默降级已钉住:`satisfies` **必须 includePrerelease**(否则把在跑的 univer/dshmarket 也藏掉)、伞包 `@deepseek-ai/dsh` **必须单独解析**(那 3 条 newer 全写在伞包上)。插件 **0.3.16**",
|
||
"93": "**兼容判定收口**:① 「单测长期红」真相 = **服务器源码落后于 git**(本机 48/0 全绿)⇒ 同步即修;② 伞包 `@deepseek-ai/dsh` 收口到 `dsh-install.platformPackageVersion()`,闸门与列表**共用版本表**;③ ⚠️ 收口带出的副作用必须一并修:闸门判据 A 默认语义会把「声明 `*`」判成不兼容(实测抽样 300 的 **prerelease-artifact 117 条 / 约 39% 假阳性**,含在跑的 `dshmarket`)⇒ 加 **prerelease 兜底**(容忍下能满足则只计数不阻断)。服务器 `ci.sh` 转绿",
|
||
"94": "**实例内存口径定案**(用户裁定 base 448 / max 1024):两侧常量(编排器 `instanceMemMb()` ↔ 插件客户端 `MEM_*`)收成一份事实 = **BASE 448 / MIN 448 / MAX 1024**(MIN 必须 ≥ BASE;MAX 1024 是编排器头部既有的宿主容量不变量,驳回草稿的 1536),mcn 成本表保持 128。实测 admin 384→576、guest 384→448;`verify-mem-model` 与 `npm run verify` 首次全绿。插件 0.3.17|commit 683c4cd",
|
||
"95": "**HTML 外壳缓存治理 —— 修「Failed to load plugins」根因 + 流程违规自审**:页面报 `client-modules: bundle script …&rev=… failed to load` 的真因 = **`rev`(内容哈希)变了 5 次**(当天连铺 4 次插件 + 3 次重启 `dshs`)+ **`GET /` 未下任何缓存头**(浏览器启发式缓存外壳)⇒ 旧外壳永远请求已不存在的 rev ⇒ 实例按契约 **404**,且**普通刷新命中缓存外壳、复现不消失**。修法 = 把 `no-cache` 从模块路径**扩到 HTML 外壳**(`proxy.ts` 1 处条件,实测 `GET /` 已 `no-cache`);`verify-inject.cjs` 加防回退断言。⚠️ **含 R8 违规自审**:中途 3 次重启平台 + 4 次铺插件**未先说明影响并取得确认**,且未攒批 ⇒ 直接成因;另阶段 0/1(未先加载本机已有技能、报障未先抓真实失败请求)与阶段 2/5(无方案确认、档案迟到)也各有硬伤,附「正确顺序」",
|
||
"96": "**实例内存与插件开关解耦 → 「基础 MIN、最多浮动到 MAX」**(用户两段原话:先「不要受插件开关影响,只受 min 和 max 值影响」,再「改成基础 min 最大可以浮动到 max」):平台侧 = cgroup **两个参数** `MemoryHigh=MIN(448)`(软限/基础)+ `MemoryMax=MAX(1024)`(硬限/上界);**不再读 profile 的 bundles**(删 `PLUGIN_MEM_MB`/`BASE_MEM_MB`);`/api/dsh/status` 的 `quota` 增加 `baseMb`;客户端显示「基础 → 最多」。实测两 scope 均 `High=448M/Max=1024M`。⚠️ 含**两处勘误**:我先把用户的\"约束\"写成\"固定配额=512(用户裁定)\"(512 是我擅自改的),又**凭记忆编过\"之前的实现一直是按用量浮动\"**——git 取证不成立(全历史无 `MemoryHigh`;今早 `1d72e8f` 是 `clamp(160+Σ插件, 384, 1024)`,更早是写死 384)。插件 0.3.19",
|
||
"97": "**`/plugins/` 合并脚本补 ETag + 304 短路**(承 96 之后查出的真缺陷,与当日故障无关):官方 `dsh-client-modules` 把全部客户端插件拼成**一条 11 MB 脚本**(`/plugins/??<模块列表>&rev=<revision>`);我们给它下发 `no-cache`(档案 95)而实例**既无 ETag 也无 Last-Modified** ⇒ 浏览器回源校验退化成**每次全量重下 11 MB**(经 Cloudflare 实测 **114.87 秒**,弱网直接\"页面加载不出来\")。修法:平台侧按 URL 派生 ETag(依据官方契约「已公告响应不可变;未知组合/revision 返回 404」⇒ 同 URL 必同内容),命中 `If-None-Match` **直接回 304、完全不回源**;只对 GET/HEAD + `/plugins/` 且含 `rev=` 生效。实测 **200/11,172,365B → 304/0B**。`verify-inject.cjs` 加防回退断言。⚠️ 判据沉淀:下次「页面加载不出来」先问**普通 vs 无痕**窗口",
|
||
"98": "**治本:陈旧 `dsh-auth-*` cookie 回写清理**:dsh 每次实例(重)启动都换 `dsh-auth-<随机>` 的 cookie 名,平台此前只在转发时丢弃旧的、**从不回写浏览器** ⇒ jar 只增不减 ⇒ `Cookie` 头涨到 ~15 KB(实测 12.8 KB 放行 / **19.1 KB 被 431**)就被 CF/nginx 直接 **431** 拒掉 ⇒ **请求到不了平台** ⇒ 11 MB 合并脚本取不到 ⇒ 官方报 `bundle script … failed to load`(界面 Failed to load plugins)。无痕正常 = 空 cookie 罐。修法:响应里对陈旧名字回写 `Set-Cookie: …; Max-Age=0`(**只在本次响应确实下发了 dsh-auth 时才动手**,绝不误删在用的)。⚠️ **救不了当下**(431 时请求进不来)⇒ 用户需先手动清一次。端到端实测:带 2 个假名 → 响应含 2 条 Max-Age=0",
|
||
"103": "**客户端安装 + 覆盖网络互联 · 可行性评估**(规划态 · 未实施):判定 ✅ 可行,且现有架构已给出约 80% 形状(`soft` 档实例=裸子进程 ⇒ 无需 root;Worker 拨出式反向隧道 ⇒ **节点本来就不需要公网 IP**);缺口 4 条(客户端运行时落点 · 节点身份 · **信任模型反转** · 分发与版本矩阵);形态三档已按用户口径收窄为**单机自用**(B 档);6 步落地、每步可单独回滚。⚠️ 真正硬阻塞点修正 = **平台调用层**(Windows 下裸名 `spawn` ENOENT / `.cmd` EINVAL),非 dsh 运行时",
|
||
"104": "**覆盖网络 · 全球架构复盘**(规划态 · 未实施):五层架构(控制面 / 会合 / 骨干·中继 / 数据面 / 观测)+ 12 条必须内建特性 + **10 类风暴类型学** + 流量组织五原则 + 流量预算表 + 7 步落地顺序。🔑 三句结论:控制面与数据面**彻底分离** · 失败不要变成重试(退避+抖动+判死) · 放大点必须前置治理。🟢 范围声明:**只做技术实现,跨境数据合规由使用者自负**(⛔ 不再作前置条件或上抛项)",
|
||
"105": "**覆盖网络 · 骨干层方案**(规划态 · 未实施):多中心骨干(≤10–20 成员、全互联;每节点只连 1–2 个骨干)+ 选择性加入。三条硬约束:**接入 / 成员 / 可见三分离** · **骨干资格只能控制面签发**(否则出现第二权威源、骨干沦为公网跳板) · **骨干不得被默认征用**(命中 R5)。⚠️ §7 唯一待拍板 = 骨干服务范围(A 只服务自己名下设备 / B 服务全网;**倾向 A→B 渐进**)",
|
||
"106": "**覆盖网络 · 百台规模推演 v2**(规划态 · 纯文字推演):⚠️ 含**前提级纠错**(v1 作废)—— 用户纠正「**单机用也要互联**」;错因 = **把「租户维度收窄」误当成「网络维度收窄」**。100 台异构画像:L1 10 / L2 30 / **L3 需中继 40–55** ⇒ **中继按 45% 设计、55% 留余量**(⛔ 不用同构假设的 15%);**必须补 443/TCP 兜底**(否则企业/校园网整类进不来);**L1 自动升格为中继候选**;仍不建全互联(4,950 vs 100)",
|
||
"107": "**覆盖网络 · 千台全场景推演**(规划态 · 纯文字推演):1000 台异构 × 11 场景 + **流量预算总表** + 瓶颈排序。🔥 **第一瓶颈 = presence**(1000 人大房 ≈ **16,700 次/秒**,是其消息扇出的 16 倍;普通房合计 8,200/s);💰 **最大成本杠杆 = 游戏服放 L1**(放家宽 ⇒ 中继 **600 Mbps 常驻**、峰值 1.2–2.0 Gbps;放公网 IP ⇒ **0**);游戏的真正门槛是 **jitter < 20 ms** 而非带宽;**agent 为本方案独有放大源**",
|
||
"108": "**覆盖网络 · 游戏专项(MMORPG 2D/2.5D · MUD · 传奇类)**(规划态 · 未实施):⚠️ 判定**由「不合适」修正为「最匹配」**(该类游戏天生服务端权威 + tick 驱动 + **AOI 九宫格** + 分区/分线;每玩家仅数 KB/s~数十 KB/s、几百 ms 无感)—— 原\"不合适\"只针对 3D 大世界强实时竞技。⭐ 核心简化:**玩家之间不需要互联 ⇒ 中继容量按「服数」算、不按「玩家数」算**。含 12 条设计细节 + 参考方案(Evennia/Skynet/Pomelo/Nakama…)+ 8 条反模式",
|
||
"109": "**覆盖网络 · 调研:游戏网络特征与单房间群聊上限**(规划态 · 全网调研稿,数值均标来源):游戏侧每玩家 **2–20 KB/s**、同步 5–20 Hz、**jitter > 20 ms 即 desync**;群聊侧 **Telegram 20 万 / WhatsApp 2,048 / Discord 单频道 100K+**;🔑 **上限不是「人数」而是「扇出预算」**,且 **presence(N²) 比消息更早爆**(1000 人房 ≈16,700/s)。**本方案实际上限 = min(扇出预算, presence 预算, agent 预算)**",
|
||
"110": "**覆盖网络 · 答疑(群聊+agent / 备份 / 迁移提速 / 传输保密)**(规划态 · 未实施):① 群聊=**应用层**的事(覆盖网络只给「可达」);**agent 四条硬约束**(⛔ 禁止 agent 直接触发 agent);② ✅ **备份主层用对象存储**,覆盖网络只当**搬运通道与第三副本**(P2P 副本无 SLA、可误删,不适合当存档);③ 迁移 7 条按收益排,**最大一招 = 只搬不可再生(46.3 MB vs 2.9 GiB ≈ 64×)**;④ 保密 = 三层加密 + 元数据保护,**最大缺口 = 身份(共享令牌 → 一机一钥)**",
|
||
"111": "**覆盖网络 · 补遗与参考方案**(规划态 · 未实施):互联游戏 ✅ 但**由游戏形态决定**(锁步/回合/异步最友好;FPS/MOBA 64+ ❌ 不合适,P2P 无法反作弊);补遗 **24 条**(身份与账户 / 寻址与名字 / 接入与可见性 / 自检与选路 / 流量与公平 / 移动端弱网 / 升级版本自愈 / 可观测)+ 10 个能力域的参考方案 + **反模式 12 条**。⭐ 最划算的架构复用:**群聊房间与游戏对局是同一个模型**(一次投资,群聊 + 游戏 + 协作 + 看板共用)",
|
||
"112": "**覆盖网络 · 九大瓶颈落地方案**(规划态 · 未实施):把 107 的九大瓶颈逐个给成**可执行做法 + 验收判据**(含 Slack / SCCM·BranchCache·Delivery Optimization 官方照抄点)。🎯 **只做三件 = presence 改造 + 游戏服放 L1 + 块级内容寻址分发**(覆盖最大三个瓶颈,且**都不需要改传输协议**)。🔑 分水岭:**必须做「块级」内容寻址,⛔ 别做「包级」**(包级 = 版本一发所有 peer 源失效 ⇒ 正是全量重拉风暴的成因)",
|
||
"113": "**覆盖网络 · 传输方案取舍(开放端口 vs 自研 relay)**(决策稿):逐条对比 5 种传输形态,定下**自研 relay + 回环监听 + 中继切流**路线;⛔ P4(SSH 版中继 / 32023)判**不做**",
|
||
"114": "**覆盖网络 · 应用场景推演完成度 & 方案待完善清单**(检查稿):逐场景打勾哪些已推演、哪些仍缺;作为后续补遗的取数底稿",
|
||
"115": "**覆盖网络 · 「插件 vs 改内核」架构判断**:结论 = **走插件层**(不改官方 dsh 内核,红线 R2);给出插件化边界与代价清单",
|
||
"116": "**覆盖网络方案 · 问题逐条推演与解决方案**:把散落疑问逐条编号推演并给解法,是 103–112 之前的**问题总账**",
|
||
"117": "**覆盖网络 · 参数表与观测口径(唯一一张)**:所有可调参数的**单一来源**(含「⛔ 不改」清单:`RELAY_FAILOVER_DEADLINE_MS` / `HB_SEC` / `COOLDOWN_MS=0` 禁用)+ 指纹口径(`sed '/^## §10 指纹/,$d'` 后再 md5)",
|
||
"118": "**会合 / 中继从 Manager 拆分 · 取证与改造方案**(**进行中**):S0–S4 分步 + 每步验收 / 回滚;起因 = 重启会收掉实例 scope 而无 reconciler",
|
||
"119": "**集群化改造方案 · Manager / Worker 模式**:D1–D5 已定(⏳ 仅 D6 未做)+ **数据分层判据**(归属/租约只 Manager 写 · 跟用户走放实例 home · 本机运维放 Worker 本地库)",
|
||
"120": "**跨节点迁移 & 节点自举 · 完整流程方案**:用户实例在节点间搬迁的完整流程与自举条件",
|
||
"121": "**项目代码 · 分层范式与迭代风险评估**:代码分层 P0 已立;给出各层边界与「层层补丁叠加」的返工风险",
|
||
"122": "**guest 迁移(w-47 → w-106)与共享重建方案**:存量 guest 落 106 的搬运步骤 + 共享面重建判据",
|
||
"123": "**方案规划方法 —— 从覆盖网络线提炼**:把本线的规划手法沉淀成**可复用方法论**(判据优先 / 单一来源 / 假绿识别)",
|
||
"124": "**文档无效信息审计报告**:对文档库做「无效信息」体检,输出应删/应改/应合并清单(**报告,未执行**)",
|
||
"125": "**会话接续机制 · 问题复盘与修复**:复盘「接续为何断链/为何空转」,产出修复项(**排期两条铁律** = ① 首个/唯一接续棒 = 收口 + **5~8 分钟**〔原记 2~5,2026-09-18 用户更正〕② **同一时刻只挂一个接续棒**;规则实体见技能 `dsh-auto-handoff-chain §3.1.1`)",
|
||
"126": "**会话接续规范:token 超限后如何无损继续**:接续六件套 prompt 骨架与登记门禁的规范文本",
|
||
"127": "**DSH 平台客户端化部署方案 —— 单机自用**:B 档(单机自用)形态下的客户端化部署路径;⚠️ 真正硬阻塞 = 平台调用层(Windows 裸名 `spawn` ENOENT)",
|
||
"128": "**DSH 桌面客户端开发方案 —— 基于官方 Electron 壳迭代**(待评审 · 只做规划不含代码):复用官方壳 vs 自建的取舍与分发/版本矩阵",
|
||
"129": "**日志采集 · 实时巡检 · 事后溯源(方案 C 实现)**:不装新日志服务(否 Amber / 否 Loki+Alloy),用 `07-scripts/dshlog.mjs` 把 47/106 journald 拉回本机按天归档 + 跨机时间线 + 8 条巡检规则;**服务器侧零安装零端口**;⚠️ 最大剩余缺口 = 实例 `dsh --profile` 的 stdout 不进 journald",
|
||
"133": "🔴 **序㊺ 实测判「D 本轮不实现」**(真实首屏包 **23 块 0 个低熵块**、60 份真实独立内容 **0 份低熵** ⇒ `D-1` 无对象可稀释、`D-2` 前提不成立)⇒ 剩 **C 域分离 + 判据重裁**(序㊻ · automation `aab9e357-8101-4011-b829-bf9f4a459bf7`)|**覆盖网络 · 低熵块治理方案 —— C 域分离 + D 非确定性**:块 id / 内容 id 的收敛哈希改 **per-network keyed hash**(切断跨 network 相关性,代价≈0)+ 低熵块非确定性(首选 **D-1「稀释域」**);⛔ **B(OPRF / SA-MLE)不立项**(降级为可选加强);🔴 **第一个动作 = 补测「低熵块种类数 / 体积 / 占首屏包比例」**(从未测过;且切分是**定长 1 MiB** ⇒ 首屏包内几乎无纯低熵块,待测必须含**子窗口腿**防假绿)|交付 = `05-交接单/覆盖网络-45-低熵块治理-测熵与实现.md`",
|
||
"134": "**注册页人机验证与邮箱验证码**(2026-09-19 落地 · 线上实测通过):注册 = 用户名 + 密码 + **邮箱验证码** + **Cloudflare Turnstile**(✅ **密钥已配、已启用**;服务端校 `success` + `action` + `hostname` **三项** —— 只校 `success` 时\"拿公开 sitekey 在自己站点替真人取合法 token 再打我们接口\"这条路是通的);DB **迁移 v10**(`users.email` + `email_codes` 事件表);邮件走**可插拔驱动**(`brevo` / `http` / `log`,换供应商只改 env),发件人 **`[email protected]`**(Brevo 域名已认证 + DKIM + SPF);防爆破 = 三层配额 + **递增冷却阶梯**(60→60→180→300→900→1800s)+ 试错 5 次作废 + 码只存哈希 + 单次使用;实测 Brevo **delivered**、冷却 429、错码 `attemptsLeft` 递减、正确码 201、重放被挡、无 token/假 token **403**|档案 `04-调整方案/134-注册页人机验证与邮箱验证码.md`",
|
||
"135": "**旧域 `alotbuy.com` 从项目移除**(2026-09-19 落地):代码 / 服务端 / 文档技能三层收敛为 `ai1net.com` 单域;旧域站点**降级为 301 过渡装置**(保留 ACME + `/dshs-relay` + `/dshs-overlay/bootstrap`,**30 天零流量**后退役);relay 候选 **5 → 3**(删掉两条“摘名不同、同落 47”的伪多样性);修 `wake.html` 转义点残留 + 演练脚本硬编码域造成的**假红**;参数表 2 键与 §10 指纹同步",
|
||
"136": "**控制面按两台中继取并集 —— 立项交接单**(2026-09-19 立项 · **未落地**):平台 web 层只取 47 中继 ⇒ 106 中继不被使用;根因链 7 行(取址路径 `src/web/server.ts` / `rendezvous.ts`)、**先红后绿**强制、候选 A/B 各带优缺点、验收 E1–E8 + 回滚",
|
||
"137": "**品牌标识改造 —— 去 DeepSeek 图形 → 平台自有标识**(2026-09-19 上线):**四页 + favicon 一并替换** —— `login` / `register` / `admin` 页头删 **DeepSeek 鲸鱼图标 +「DeepSeek」文字图形** 改平台标识(中文「**能力枢纽**」/英语及其他语言「**CapabilityNet**」,走 i18n 词条 `brand.name`,`en` 一条即覆盖其他语言回退);`portal` 顶栏换图标(页面名「管理门户」保留);**新建 `web/favicon.svg`**(平台自有 hub 图标,避开 DeepSeek 蓝);🔴 **会话页面左上角那处不动**(用户明示「先不替换」+它属官方 dsh client bundle,受 R2 约束);🔴 踩坑:**SVG 的 XML 注释不得含 ASCII 双连字符 `--`**(写 CSS 变量名即踩)⇒ 整份 SVG 解析失败、图标**静默不显示**,已加进 `verify-static.mjs` 并做反向自证;新增 `test/i18n-brand.test.mjs`|档案 `04-调整方案/137-品牌标识改造-去DeepSeek图形.md`",
|
||
"138": "**平台共享模型 —— 管理员逐用户授权(默认关闭)**(2026-09-19 上线):新增列 `users.shared_model_granted`(v11,**默认 0**),**生效 = `granted ∧ enabled`** —— 前者 admin 在**用户列表**里逐个开(新增「共享模型」列),后者仍是用户自己的偏好(保留);未授权时设置页**连\"平台共享模型\"那一块都不渲染**(插件 0.3.24);🔴 **顺带修掉一个既有真缺陷**:落地层原先用**本机 fs** 写用户 home,而用户卷在 worker 上 ⇒ **模型落地对\"实例不在本机\"的用户一直是静默空操作**(托管清单被清空、目标文件一字节没动;档案 87 的模型设置页对 guest 这类用户从未生效)⇒ 改为走 `UserFs` + worker agent 新增**白名单**端点 `/fs/home-read|write`;两腿实测(未授权撤销 / 授权恢复)|档案 `04-调整方案/138-平台共享模型-管理员逐用户授权.md`",
|
||
"139": "**品牌中文名:能力枢纽 → 能力网络**(2026-09-19 上线):其他语言仍 `CapabilityNet`(en 词条即回退);落点四处 = i18n 中文词条 / `admin.html` 顶栏 / **`favicon.svg` 的 `<title>`+`aria-label`**(最易漏)/ `design.css` 注释;品牌回归测试期望值同步,`verify-static` + SVG 真解析全绿;🔴 行尾按**目标目录既有风格**逐文件对齐(服务器 `admin.html`=CRLF 而本机=LF,直传会翻掉整个文件)|档案 `04-调整方案/139-品牌中文名改为能力网络.md`",
|
||
"140": "**涉密内容外置到配置目录**(2026-09-19 落地):把散落在代码里的**真实部署值**(域名 / IP / 主机号 / 内网路径 / Worker 令牌 / PG 口令)统一收进 `config/`,代码改为**引用配置**—— TS 走 `src/platform-paths.ts`、shell 走 `config/load.sh`、node 走 `config/index.cjs`;🔴 **真实值只放 `config/platform.env`**(`.gitignore` 排除、服务器侧 **600**),仓库内只留 `platform.env.example`;🔴 优先级 = **系统 env > `config/platform.env` > 代码内中性默认值**(代码默认一律中性 ⇒ ⛔ 别把生产值写回默认);🔴 `platform-dirs.conf` **必须保留 `DSH_PLATFORM_DIR=/opt/dsh`**(删掉它 `platformDir` 退化成 `<dataRoot>/platform` ⇒ state/backups/artifacts **静默搬家**);🔴 `DEFAULT_OVERLAY_SEED` / `DEFAULT_OVERLAY_BOOTSTRAP_SEEDS` **刻意留空**(种子只由 env 给,已固化为回归断言);`src/platform-paths.ts` **必须零副作用**(不 mkdir / 不写文件);注释里的真标识无法引用配置 ⇒ **一律中性化**(`<server-public-ip>` / `<base-domain>` / `<host-a>`);`web/wake.html` 注册域白名单改为**运行时从 `location.hostname` 推导**(换域名零改动);改造后**完整检查两遍**(第 2 遍抓到第 1 遍的漏项);零回归 = `tsc` 0 错 · `npm test` **373/375**(唯一失败 `lease` 属既有)· `/opt/dsh/{state,backups}` 未搬家 · `/var/lib/dshs/platform` 未误建;**下线核实轮**(09-19 15:3x)复扫补修 `07-scripts/find-ui-scan.py` 里残留的 `/var/lib/dshs` 字面量(改为由 `find-ui.mjs` 注入 `DSHS_USERS_DIR`,缺失即显式失败、⛔ 不静默回落)|档案 `04-调整方案/140-涉密内容外置到配置目录.md`",
|
||
"141": "实例子域冷启动窗口内代理裸断连接致 502(2026-09-19 修复)",
|
||
"142": "**IM 群组对话(需求基线与方案)**(2026-09-20 规划态):用户拍板 **B 方案**(人 + Agent 一次做齐);两条决定形态的语义 = **群聊消息作为 agent 上下文** · **agent 两种形态**(能力机器人占独立成员位 / 组员代理不占位、`auto_reply` 开关、@ 组员即触发)。取证 = `src/` 应用层零命中、无消息表;传输层已就绪 —— ⚠️ **按「平台侧 HTTP/WS + 账号体系就绪」读**,**relay / DIAL 不在 IM 依赖链上**。🔴 **2026-09-22 按两份架构定稿复核**:① relay / presence 复用口径更正(presence **通道**须由平台 IM hub 自建,网络层跨用户隔离是结构性的)② 三表库归属 = **控制面库 `dshs`** · 房主**锚定区** · **本期单区** ③ 迁移号 **v14**(现网最新 v13)④ **五单 A–E 已逐单对齐**(各单 §〇),⛔ 未登记执行棒 | 交接单 = `IM群组-{A,B,C,D,E}`。",
|
||
"143": "**MCN工作台入口失效 + 用户设置语言切换「没反应」**(2026-09-20 落地 · 真机浏览器实测通过):两条同源 —— **dsh 0.1.5-rc.1 改了插件依赖的老契约**:① 对话区槽位名 `conversation` → **`main.conversation`**,插件 `querySelector('[data-slot=\"conversation\"]')` 实测恒为 null ⇒ 工作台面板**根本不挂载**(点了没反应);改为双名自适应(含配套 CSS)。② `ctx.locale.getLocale()` 由「返回 id 字符串」变成「返回**快照对象** `{active,…}`」⇒ 取值恒为 `\"[object Object]\"` ⇒ 受控 select 匹配不上任何 option、只显示第一项 English(界面其实是中文)⇒ 选「中文」看着没反应;改为对象取 `.active`(兜底 `getSnapshot().active`)。同时把「MCN任务会话」入口**从左侧栏搬到工作台 header(图标按钮)**。产物:`dsh-plugin-mcn-suite` **0.3.11**(436 条目 / 1.90 MB / md5 `0b84b3bc…`)· `@dsh-local/portal-entry` **0.5.6**;顺手修掉构建链三处「一构建就负向回归」(计划任务被装回 / 死链「自动任务」菜单项 / 历史 tgz 被打进包)⇒ 新产物与线上旧产物 diff = **9 hunk / 51 行**,全部为本次改动。⚠️ guest(实例在 w-106)**未覆盖**|档案 `04-调整方案/143-MCN工作台入口失效与语言切换显示修复.md`",
|
||
"144": "**插件规模化投放与版本一致性(几百~上千用户)**(2026-09-20 方案 · **待拍板选档**):今天这条 bug 的真实瓶颈**不是耗时**(单用户 `pnpm add` 秒级 ⇒ 1000 用户串行 1 小时级、按 Worker 分组并行分钟级;\"停机\"实际= 每用户下次访问慢一次),而是 **① 编排脚本在本机枚举用户 ⇒ 迁到别的 Worker 的用户被静默跳过(guest 就是这么被漏的)② 无版本台账 ③ 每用户一份拷贝 + 无版本协商 ④ 契约失效零报错**(四条硬伤全有当天实证)。**推荐路线**:必装插件从「每用户安装」改成「**Worker 共享只读插件层 + 每用户只留开关**」(与 `bundled-skills` 同族,沙箱 scope 里**已有** `--ro-bind-try` 先例)⇒ 升级从 O(N) 次安装降到 **O(1) 份内容**。同时补**台账(PG)+ 按 Worker 分组编排 + 契约哨兵**。本轮已落地编排**基元** `07-scripts/install-plugin-for-user.cjs`(机器无关 / 幂等 / `--expect` 不符退 2 / 失败不静默),已用于 guest 补齐|档案 `04-调整方案/144-插件规模化投放与版本一致性.md`",
|
||
"145": "**覆盖网络·序47 单账号多设备多会话并存(S0–S4 前半 · 2026-09-20 落地)**:`POST /api/auth/login` **取消无条件驱逐**(原 `deleteUserSessions(user.id)` = last-wins,会把该账号其余设备当场顶下线)⇒ 改为**多会话并存 + 每用户上限 + 显式「登出全部」**。落地 = **迁移 v13**(`sessions.kind` 默认 `browser` / `overlay_devices.kind` 默认 `desktop` + `idx_sessions_user_created`;⛔ 不加 DB `CHECK`,值域由应用层白名单把关)+ S1(`client ∈ {browser,desktop}`,非法与 **`instance` 一律 400**,超上限按 `created_at` 最小者具名淘汰并落 `audit_log: session_evicted`,键 `DSHS_MAX_SESSIONS_PER_USER` 中性默认 **20**)+ S2/S3 新增 `GET /api/auth/sessions` · `POST /api/auth/sessions/revoke` · `POST /api/auth/logout-all` · `GET /api/overlay/my-devices`(对外标识只有 `sha256(token_hash)` 前 16 hex,⛔ 绝不回传 `token`/`token_hash`)+ S4 **抽出共用签发实现** `src/net/relay/device-grant.ts`(用户态端点改**薄路由**,⛔ 不留两处判据)。**真跑读数**(47):迁移后 `max(version)=13`、存量 3 条会话读回 `browser`、**迁移前落的 sid 仍 200**;E1 连登两次 ⇒ 两条 sid **各 200**(现状基线必为 401);E3 累计 26 次登录 ⇒ 会话数**恒 20**、最旧 401/最新 200、`session_evicted` 6 行;E4 按 `sid_public` 吊销 ⇒ 该条 401 另一条 200;E2 `revoked:19` ⇒ 全 401;回归 `/logout` 只删当前 401/200、admin 停用仍清全(会话 2→0);`npm test` **241 项 240 过 0 败** · `test/overlay-device.test.mjs` 33 过 0 败(S4 重构判据零变化)。**未做**:步 6–9(实例凭据平台侧签发/投递/续签、门户 UI)⇒ 已登记下一棒|档案 `04-调整方案/145-覆盖网络-47-会话并存与设备来源维度.md`;上游单 = `05-交接单/覆盖网络-47-单账号多设备会话并存.md`|⚠️ 档案 **08** 与技能 `dsh-change-workflow` 的 **R4** 旧理由(\"登录会踢人\")已同步作废",
|
||
"146": "**实例子域 503:中继 per-port 额度被「客户端断开不中止上游」泄漏占满**(2026-09-21 落地 · 已验收):guest 实例被报「一直重启 + 全站 503」,实测**实例健康、连续运行 20.8 h**(`curl 127.0.0.1:21000` 稳定 401 / 0.9 ms)⇒ **不是实例在重启**。真因 = **平台代理泄漏连接 ⇒ 占满中继的 per-port 并发门限 ⇒ 该实例端口永久 `refused: busy`**:① `proxyHttp` 在 `agent:false` 下每请求一条独立 TCP、靠「响应结束」释放,而 dsh 有大量**永不结束**的 SSE/长响应,**客户端断开(刷新/关页)时代码从不中止上游**(全文无 `request.raw.on('close')`)⇒ socket 永久 `ESTAB`;WS upgrade 隧道**只有 `'error'` 互销毁、没有 `'close'` 对称销毁** ⇒ 同样泄漏。② 中继 `DEFAULT_MAX_STREAMS_PER_PORT = 64` 是**纯计数门限、无空闲回收**(`idleTimeoutMs=45s` 只管会话)⇒ 打满即**永久**拒绝、无自愈;而**跨机(`via=relay`)才走这条链路** ⇒ 47 本机的 admin(`via=local`)不受影响,故**只有 guest 中招**。③「打不开 ⇒ 反复刷新 ⇒ 再泄漏」= **正反馈**(实测 45 min 不恢复,重启控制面才清空)。修复 = `src/supervisor/proxy.ts` **4 处**:新增 `liveUpstream` / `clientGone` + `request.raw.on('close')`(判据 `reply.raw.writableEnded`,**正常完成也会触发 `'close'`**);`upstream` / `upRes` 的 `error` 与 `upRes` 回调加 `clientGone` 短路(⛔ 否则断开后**每次凭空再开一条连接** = 正反馈来源);WS 补 `'close'` 对称收尾,两侧都 destroy。落地 = `npm run build` → `verify-inject.cjs` **全绿** → 与线上统一行尾后 diff **46 行全为本次改动**(无夹带)→ 备份 `/opt/dsh/backups/proxy.js.pre-guest503-20260921-062013` → md5 一致 → `restart dshs`。**验收**:中继 `21000 streams` **64 → 1**、47 拨号槽位连接 **64 → 1**(观察中一度 7、**25 s 后自动回落** ⟵ 连接**能回收了**)、`dialDenied` 184 **停增**、guest 通道 **401** + 同日真实流量 **120×200**、admin 实例 scope 未受影响。⚠️ **遗留未做**:中继「per-port 纯计数、无回收、打满即永久拒绝」仍在(属**覆盖网络线**资产,需独立立项)**另加中继侧兜底**(2026-09-21 · 用户选方案 1):`DEFAULT_MAX_STREAMS_PER_PORT` 原本是**纯计数、无回收、打满即永久拒绝** ⇒ 新增 `DEFAULT_STREAM_RECLAIM_MS=600000` / `DEFAULT_STREAM_RECLAIM_BATCH=8`(env 可覆盖)+ `MuxStream.openedAt` + `reclaimStale()`(**只在打满时**按\"最老优先\"回收存活超阈值的流;两条分配路径均在 `busy` 前调用)+ `/status.streamsReclaimed`(正常恒 0)。判据用**建立时刻**而非最后活动时刻 ⇒ 不改数据转发路径、避免误杀静默的 SSE/WS。单测 **36/36**;与线上统一行尾后 diff **10 hunk 全为本次改动**;md5 一致后 `restart dshs-relay`,`manager`+`w-106` 重连、`streamsReclaimed:0` 上线(旧码无此字段)。🔴 **relay 是独立部署 = `/opt/dsh-relay/lib/net/relay/`**(⛔ 非 `/opt/dshs/`),改完必须 `restart dshs-relay`(重启 `dshs` 不重载 relay)。⚠️ **106 relay 未同步**:其产物 `94.3KB/09-19` 落后于 47 改前的 `100.9KB/09-20`,直接覆盖会夹带序47 在途改动 ⇒ 留作遗留项|档案 `04-调整方案/146-实例子域503-中继per-port额度被连接泄漏占满.md`",
|
||
"147": "**多节点形态下的插件投放与数据面(把「插件规模化」放回整张网里)**(2026-09-21 方案 · 规划态 · 零改动):用户指出 144 §八 的「2~3 天」口径**默认了\"所有用户都在 47 本机\"** ⇒ 整张网摊开后还缺一条**今天完全不存在**的承重墙:**「控制面 → 某一台节点上的某一个用户」的投放通路**(`mine/apply` 的 `profileDir()/uidOf()/healOwnership()/runPnpmAs()` 全是本机路径与本机 uid ⇒ 用户不在本机即 ENOENT;跨机唯一那条腿 `userFs.writeHandoff` 因 `DSHS_ENABLE_PATCH` 默认 false(watchdog 不启动、`handoff.json` 无人消费)而**空转**)⇒ 对\"其他节点上的用户如何分发插件\"今天的答案是**没有通路**。同时把用户三问逐条答清:**① 组网**=覆盖网络线已做完机制层(`overlay-node-join.cjs` 一条命令接入 + `overlay-node-admit.cjs` 邀请/准入/派生白名单 + 一机一钥序③ + 443 兜底序④ + presence 序⑲ + 设备台账序47),缺的是**\"接进网\"与\"升格为 Worker(`bootstrap-worker.sh` + `dsh_hosts` 注册)\"两条路的衔接件**;**② 分工**=Manager/Worker/中继/设备四角色(119 §1.1)+ 三条铁律(归属只有 Manager 能写 · 跟用户走的在 home · **插件内容源只有控制面一个**);**③ 分发与数据库**=分发统一模型「内容源→每机一份只读缓存→每用户启用位」(服务器用户=不通 · Windows 客户端=同模型但**不得下发平台级密钥** · **移动端只能做壳 ⇒ 零分发动作**);**数据库不开放 PG**(控制面 PG 只绑回环且只有 Manager 能写)⇒ 真正缺口是**「实例/设备 → 控制面」的身份与数据 API = 0**(145 §一 已取证)建议与序47 步6–9 合批。**五条硬缺口 G1–G5 全带 `file:line`** + 推进顺序 S1–S6(S2 承重墙 = Manager 只发\"该装什么\"、**装配由该用户所在节点在 spawn 前完成**,复用 `/launch` 投递面,⛔ 不给节点开入站口)|档案 `04-调整方案/147-多节点形态下的插件投放与数据面.md`",
|
||
"148": "**多 Manager / 多区域联邦形态(把「一张网」改成「网的网」)**(2026-09-21 方案 · 规划态 · 零改动):用户指出 144/145/147 **共同默认了「一个控制面」**,实际形态是「**几百上千台骨干服务器,每台是各自区域的 Manager,背后都带自己的 Worker / 节点 / 设备**」⇒ 正确形状 = **控制面的联邦**。**四条硬缺口全带 `file:line`**:**G1** `deployMode` 词表只有 `local|k8s|cluster`(`src/config.ts:20`,`DEFAULT_DEPLOY_MODE=local` 于 `:409`,`toDeployMode` 于 `:572-577` 只认这三个字面量)且 `k8s` 档在 `src/web/server.ts:318-319` **直接抛错**(\"only the single-machine backend ships\")、`cluster` 档要求 `DSHS_CLUSTER_AGENT_URL=http://127.0.0.1:9000`(`:323-324`,**同机/同内网语义,不是跨区**)⇒ **联邦不是\"给 deployMode 加个值\"**,而是正交新维度;**G2** 节点注册表是**本机 JSON 文件**(`src/net/relay/registry.ts:40` `NODES_REGISTRY_VERSION = 1`;`device-grant.ts:94` 与 `routes/overlay-nodes.ts:53` 各自取 `join(dataRootDir(),'overlay','nodes.json')`;`07-scripts/overlay-node-admit.cjs:92` 同源)⇒ 百台 Manager = 百份互不知情的注册表,「网里有谁」天然分叉;**G3** `users` 表**无 `host_id`/`region`**(`schema.ts:112-123`,`username TEXT UNIQUE` 仅单库唯一),`userRoot()` 路径只含 `dataRoot`+`userId`(`src/fs/workspace.ts:25-27`),归属只在 `dsh_instances.host_id`(v11 于 `schema.ts:321`)⇒ **用户锚点是\"实例跑在哪台 host\"的推论而非字段**,联邦下登录路由/跨区迁移/全局重名三处立刻出问题;**G4(幸存资产)** `overlay_devices` 主键 = **`(network, host_id)`**(`schema.ts:487-502`/`:505-520`)⇒ **`network` 已是一等维度,\"区域 ≈ 一张网\"在数据模型上现成**,缺的是**区名由根分配**的规则。**三层权威**(根=区域名录+用户全球唯一名+联邦吊销|区域 Manager=本区归属/租约/资格|区内 Worker/节点=执行面与本机运维库)+ 把 105/107/119 的 **10 条结论**逐条标 存活/改写/降级(见档案 §四)。🔴 **唯一触碰红线处**:105 §3.2「骨策资格只能由控制面签发」须改写为「**本区 Manager 签发 + 根背书**」,已给 A/B/C 三案与优缺点并**未自决**(§七-1);§七-2 = 跨区可见性默认值(倾向默认互不可见)。推进 **F1–F7**(区域身份→区域名录→用户锚点→权威归属改写→跨区级联吊销→跨区可见性→**插件版本真源下沉到区域**),并点明 **F4 必须在 105 §五-2 之前拍板**(否则返工)。⚠️ 含**自我批评**:三档都默认单控制面**且未把该假设写出来**|档案 `04-调整方案/148-多Manager多区域联邦形态.md`",
|
||
"149": "**覆盖网络顶层架构全貌(去中心化形态 · 信任图与数据图分离)**(2026-09-21 方案 · 规划态 · 零改动):用户两次纠正范式 —— 先指出图「**不是网状结构还是树形的**」,再追问「**是不是 没有ROOT,或者多个ROOT(区块链共识机制发送签名),ROOT只给manager发,manager给接入放发送**」。核对 `src/net/relay/identity.ts` 后**三条结论都有代码证据**:① **「没有 ROOT」不成立**,但根已弱化到「只在签发那一刻存在」(不下发节点、不参与会话、不在数据路径上);② **「多个 ROOT」已支持** —— `identityEnvTrustedRoots()` 读 `DSHS_OVERLAY_ROOT_PUBKEYS`(`:492`,**复数逗号分隔**)、`loadTrustedSigners` 收 `roots: readonly string[]`(`:591`)、`verifySignerSet(doc,sig,opts.roots)`(`:610`),而 `verifySigned`(`:301-314`)是 **`for` 遍历受信密钥 + 命中即 `return 'ok'`** ⇒ **any-of-N(任一即可)而非 M-of-N(多数共识)**(⇒ 多根时**每把保管等级必须一致**,任一把沦陷 = 全网沦陷);③ **「ROOT 只给 manager 发」已满足** —— `SignerSet` 绑定 `network`(`:81`「签名者只在它被授权的网里有效」,跨网签发 ⇒ `network-mismatch`),`signNodeGrant` 跑在线签名者侧(`:395` 注释「现网 = 47」),节点**自己**判(`:420` 小节标题原文「本地校验的单一入口(**节点自己判**,D2)」)。**全貌 = 两张图分离**(148 把两张混讲 ⇒ 必然画成树,**这是本轮最有价值的修正**):**信任图**(离线根签签名者 → 签名者签节点,中心化**签发**、分布式**校验**)|**数据图**(节点直连打洞、relay 只转发密文,**❌ 无根 ❌ 无中心**;一台 relay 可同承载多网 `main.ts:140-141`;跨网结构性隔离 `dialers: Map<network,Set<hostId>>` 默认拒绝 `registry.ts:5`)。**否决「区块链共识」**:信任根是**用户自己的**,不存在需共识的对立方,引入只换运维复杂度;真正要补的是**防重放序号**。🔴 **两条新缺口**:**G1** `SignerSet`/`NodeGrant` **只有 `issuedAt` 无序号**(`signerSetPayload:136` 只用它参与签名;`parseSignerSet:236-241` 只查 ISO 合法性;`issuedAt` 唯一被读取处是 `:458` 的「签发时刻容差」;`version` 恒 = `IDENTITY_VERSION` = 1 `:57`)⇒ **旧名单重放验签会通过**(已撤签名者「复活」),**必须在 F2 区域名录之前修**(名录本身即待下发签名清单,会成为重放载体);**G6** **撤根无任何机制** —— `RevocationList` 只有 `hosts[]`+`nodeKeys[]`(`:107-111`)不涉根,`IdentityReason` 只有 `revoked-host`/`revoked-node-key`(`:127-128`),撤**签名者**尚有载体(`:103`「根签一份新的 SignerSet」)而**撤根只能逐台改 env 重下发**,且 any-of-N 下被撤那把留在任一节点 env 即仍有效;**⇒ G1 是 G6 的前置**(换新名单是唯一补救,而无序号使该补救本身不可靠),**两者须一起解决**。另修正 148 两句过强表述(「根=唯一权威」→「唯一**签发**权威,**校验**在节点本地」;「根只在登录时被碰一次」→「**只在签发签名者名单时被碰**,运行时含登录完全不在路径上」)。推进序修正为 **F1 → F1.5(G1+G6 序号)→ F2 → F3 → F4 → F5 → F6 → F7**。⚠️ 含**自我批评**:148 混讲两图 ⇒ 画成树;上轮断言「多根已支持」但**当时未查 `verifySigned` 实现**(本次补证据);**G6 为本次新发现**(148 与上轮均漏)。|档案 `04-调整方案/149-覆盖网络顶层架构全貌.md`"
|
||
}
|