feat(overlay): 内容块级寻址 + 实例逐步拉起 + 骨干选路 + 组密钥加密(序24–㉛ 累积同步)
代码
- 内容分发块级寻址:新增 src/net/relay/content/{chunker,store,runtime,source,peer,crypto}.ts
- 组密钥(C 档)确定性加密:AES-256-GCM,块 id β′ = sha256(密文) 前 32 hex;双 epoch 过渡窗口
- 实例生命周期:三处 teardown() 不再杀实例(local/remote/leased-spawner);启动认领 + TCP 探活判孤儿
- 骨干选路:jitter 选路 + endpoint-target;relay client/server/wire/identity/directory/rendezvous/switcher 调整
- 工作台 src/web/server.ts、src/worker/relay-tunnel.ts 装配与候选链观测
脚本与测试
- scripts/overlay-{probe,keyring,jitter}.cjs 更新
- 探针新增 OBS-21(每连接候选数)/ OBS-22(teardown 静态守卫 + 认领面)/ OBS-23(组密钥加密)
- 新增 test/{orchestrator-teardown,orchestrator-rehydrate,overlay-content,overlay-jitter}.test.mjs;relay 两例更新
文档
- 新增交接单:覆盖网络-序24-内容分发块级寻址 / 序25-实例逐步拉起 / 序26-骨干稳定选路与加密
- INDEX.md、交接单/README.md、skills/dsh-auto-handoff-chain/SKILL.md 同步
验收(零回归,2026-09-18 08:0x 复核)
- npm test 201 tests / 200 pass / 0 fail / 1 skipped
- overlay-failover-drill --scene all --table 12 PASS / 0 SKIP / 0 FAIL
- overlay-probe --table 23 PASS / 0 SKIP / 0 FAIL (rc=0)
This commit is contained in:
1 parent
04776af4b1
commit
09ce76f3af
38 files changed
+9133
-211
No files matched your search
+135
-135
@@ -1,59 +1,59 @@
|
||||
# dsh 平台文档导航(INDEX)␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
> **首读 `BRIEF.md`(现状卡)**:30 秒对齐现行事实;本文件只管"定位篇目 + 状态"。␍␍␍␍␍
|
||||
> **双端模型**:本机 `D:\github\dsh_shenxian\dsh-server-docs\`(**工作树**,git 仓库 `dsh_shenxian_doc`)↔ 服务器 `/opt/dsh/docs`(**部署镜像**,root 600,**无 .git**,靠 scp)。␍␍␍␍␍
|
||||
> **对账**:`bash scripts/docs-sync-check.sh`(退出码 0 = 全绿)。␍␍␍␍␍
|
||||
> **最后核对**:2026-09-12 — **篇数与规模不在此写死**:本库由多会话并行改动,绝对值数十分钟即失效(同日实测 83 → 85 → 87,3 次作废);**一律以 `python3 scripts/docs-manifest.py` 复跑结果为准**。代码 HEAD 看服务器:`git -C /opt/dshs log -1`(最后核对值 `ebe8075`)。域名 `alotbuy.com`(旧域 `dsh.alotbuy.com` 已 301)。␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
---␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
## 一、按场景快速定位␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
| 我要做什么 | 先读 |␍␍␍␍␍
|
||||
|---|---|␍␍␍␍␍
|
||||
| **访问入口(当前域名)** | 门户 `https://alotbuy.com`;用户实例 `https://<用户名>.alotbuy.com` | `04-22`(迁移+回滚) |␍␍␍␍␍
|
||||
| **重建 / 交接部署** | **`DEPLOY-本部署.md`**(拓扑·目录·env·依赖·脚本族·构建/部署/回滚) | 档案 19 §C9 |␍␍␍␍␍
|
||||
| 理解架构 / 多租户隔离 | `01-规划与架构.md`(一~五、九、十三) | `archive/` 全文 |␍␍␍␍␍
|
||||
| 日常运维(重启/备份/token/KEY/排障) | `02-运维手册.md` | `03-路线图与待办.md` |␍␍␍␍␍
|
||||
| **做一次平台改造(完整流程)** | **`skills/dsh-change-workflow/SKILL.md`**:六阶段 + **红线 R1-R11** + 档案模板 + 并行调度协议 |␍␍␍␍␍
|
||||
| **开源导出 / 发新版本** | **`skills/dsh-opensource-release/SKILL.md`**:五条硬规则 R-O1–R-O5(源仓库只读 / 探针 0 命中 / 去插件 / 不带文档与 skill / 分层授权)+ 脱敏映射表 + **迭代 SOP** + 验证六件套;产物在本机 `_开源导出_20260913/` |␍␍␍␍␍
|
||||
| **排查业务插件故障(没 UI / 装不上 / 改了没生效)** | **`skills/dsh-plugin-diagnose/SKILL.md`**:三层归属 + 三把尺子(inject 差集 / glibc 直测 / 产物插探针)|␍␍␍
|
||||
# dsh 平台文档导航(INDEX)
|
||||
|
||||
> **首读 `BRIEF.md`(现状卡)**:30 秒对齐现行事实;本文件只管"定位篇目 + 状态"。
|
||||
> **双端模型**:本机 `D:\github\dsh_shenxian\dsh-server-docs\`(**工作树**,git 仓库 `dsh_shenxian_doc`)↔ 服务器 `/opt/dsh/docs`(**部署镜像**,root 600,**无 .git**,靠 scp)。
|
||||
> **对账**:`bash scripts/docs-sync-check.sh`(退出码 0 = 全绿)。
|
||||
> **最后核对**:2026-09-12 — **篇数与规模不在此写死**:本库由多会话并行改动,绝对值数十分钟即失效(同日实测 83 → 85 → 87,3 次作废);**一律以 `python3 scripts/docs-manifest.py` 复跑结果为准**。代码 HEAD 看服务器:`git -C /opt/dshs log -1`(最后核对值 `ebe8075`)。域名 `alotbuy.com`(旧域 `dsh.alotbuy.com` 已 301)。
|
||||
|
||||
---
|
||||
|
||||
## 一、按场景快速定位
|
||||
|
||||
| 我要做什么 | 先读 |
|
||||
|---|---|
|
||||
| **访问入口(当前域名)** | 门户 `https://alotbuy.com`;用户实例 `https://<用户名>.alotbuy.com` | `04-22`(迁移+回滚) |
|
||||
| **重建 / 交接部署** | **`DEPLOY-本部署.md`**(拓扑·目录·env·依赖·脚本族·构建/部署/回滚) | 档案 19 §C9 |
|
||||
| 理解架构 / 多租户隔离 | `01-规划与架构.md`(一~五、九、十三) | `archive/` 全文 |
|
||||
| 日常运维(重启/备份/token/KEY/排障) | `02-运维手册.md` | `03-路线图与待办.md` |
|
||||
| **做一次平台改造(完整流程)** | **`skills/dsh-change-workflow/SKILL.md`**:六阶段 + **红线 R1-R11** + 档案模板 + 并行调度协议 |
|
||||
| **开源导出 / 发新版本** | **`skills/dsh-opensource-release/SKILL.md`**:五条硬规则 R-O1–R-O5(源仓库只读 / 探针 0 命中 / 去插件 / 不带文档与 skill / 分层授权)+ 脱敏映射表 + **迭代 SOP** + 验证六件套;产物在本机 `_开源导出_20260913/` |
|
||||
| **排查业务插件故障(没 UI / 装不上 / 改了没生效)** | **`skills/dsh-plugin-diagnose/SKILL.md`**:三层归属 + 三把尺子(inject 差集 / glibc 直测 / 产物插探针)|
|
||||
| **换电脑 / 改了工作区路径,规则会不会丢** | **`skills/dsh-env-bootstrap/SKILL.md`**:常驻规则快照 + `--check` 校验 / `--inject` 注入 / `--env-check` 环境自检(默认只报不改)|
|
||||
| **跑跨会话长任务(自动接力)** | **`skills/dsh-auto-handoff-chain/SKILL.md`**:六件套 prompt 骨架 + 登记门禁 + 五条实测防护 + 复跑脚本 `scripts/chain_report.py` |
|
||||
| 看还有什么没做完 | `03-路线图与待办.md` §二 | **`交接单/README.md` §一**(已规划待执行) |␍␍␍␍␍
|
||||
| **改前端页面(强制基线)** | **`06-工作台UI规范.md`** |␍␍␍␍␍
|
||||
| **改实例 UI 分区(设置面板)** | **`07-实例UI分区登记表.md`**(哪个包提供 / 源码在哪 / 能不能改)+ `06-工作台UI规范.md` |␍␍␍␍␍
|
||||
| 红线与硬约束 | `README.md` §红线(含 **R7 禁批量全仓写入**、**R8 中断用户须先知会**)| `04-07` |␍␍␍␍␍
|
||||
| **插件兼容性预检(导入/上传即判定)** | **`04-71`**(判据 + PoC + 三层防线)|**`交接单/T05`**(执行单)|`scripts/plugin-compat-check.mjs`(可在服务器直接跑) |␍␍␍␍␍
|
||||
| **实例崩溃循环 / 插件不兼容** | `04-70`(anysearch 与 dsh-llm `assertNever` 不兼容;判据「重启后错误是否变化」)|`04-20`(自愈熔断)|`04-25`(崩溃循环前例)|`02 §C.4` |␍␍␍␍␍
|
||||
| **锁机制(防并行冲突)** | **`04-73`(强制钩子)|`04-69`(三把锁建立)**|`交接单/README.md` §一·§三·§六|`scripts/{handoff-guard.sh,op-lock.sh,lock-guard-hook.py}` |␍␍␍␍␍
|
||||
| **多会话并行 / 冲突治理** | **`04-69`**(两级文档锁 + 服务器侧操作锁 + commit 常态化)|`交接单/README.md`(占用锁 / 写者归属 / §六 服务器侧锁)|`scripts/handoff-guard.sh`、`scripts/op-lock.sh` |␍␍␍␍␍
|
||||
| 插件管理面 | `04-16`(三层归属)| `04-31`(门户双 Tab)| `04-57`/`04-60`(设置面板分区) |␍␍␍␍␍
|
||||
| **搜索 provider / 联网搜索** | `04-64`(接入 AnySearch)|`04-65`(启停与 web provider 联动)|`04-66`(P0 误报与 admin 显式信任) |␍␍␍␍␍
|
||||
| **「能力管理」section UI** | `04-67`(按 UI 规范重做)|`04-36`/`04-38b`(分区铺开 / 术语统一)|`04-68`(启停属主污染根治)|**`04-100`(「我的技能」分组 · 09-15)**|**`04-101`(改名「能力管理」+ tab 分页 + 卡片三行 + DeepSeek 改名 · 09-15)** |␍␍␍␍␍
|
||||
| 安全 / 暴露面 | `04-14`(出网护栏)|`04-39`(可见面收窄·封 loopback)|`04-41`(上传加固) |␍␍␍␍␍
|
||||
| 技能共享层 / 管理面 | `04-10`(bundledSkillDir)|`04-11`(API+页面)|`04-40`(挂载修复) |␍␍␍␍␍
|
||||
| 会话/登录跳转 · 断连恢复 | `04-13`(冷启动 404)|`04-24`(实例侧 401)|`04-49`(回收后反馈)|`04-51`(401 透明重放)|**`04-72`(回收/关闭后回到页面自动唤醒)** |␍␍␍␍␍
|
||||
| 实例易用性 | `04-45`(老会话档位提示)|`04-56`(实例助手)|`04-59`(启动动画) |␍␍␍␍␍
|
||||
| 实例资源 / 配额 | `04-58`(内存口径 + 配额 384M)|`04-38a`(边界:无磁盘配额) |␍␍␍␍␍
|
||||
| VoxEMW | `04-12`(摘要)| `archive/工作区草案/` 两份全文 |␍␍␍␍␍
|
||||
| 历史全量时间线 | `archive/dsh-improvement-plan-20260909-full.md` |␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
---␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
## 二、全量清单␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
> **状态摘要**(**机器生成,勿手改**):档案 **115** 份(`04-*`),另含根级编号 5 条(01/02/03/06/07),另有非编号行 14 条(README / INDEX / 技能 / poc 等)—— ✅ 16 | 🔄 5 | 🔍 1 | 📋 22 | 未标记 76。复跑 `python3 scripts/docs-index-stats.py` 取数,`--write` 就地刷新本行。
|
||||
> **分层与机读明细**(路径 / 日期 / 字符数 / 被引次数 / tier,可 `jq` 先筛后读):**`docs-manifest.json`**;复跑 `scripts/docs-manifest.py` 即刷新。␍␍␍␍␍
|
||||
> 图例:✅已落地 | 🔄维护中 | 🧪PoC | 📝待开发 | 🔍核查完成 | 📋评估 | 🟡保留兜底 | 🗄归档|🔧修复|🔴|🚧|❓␍
|
||||
␍␍␍␍␍
|
||||
| 号 | 状态 | 一句话 |␍␍␍␍␍
|
||||
|---|---|---|␍␍␍␍␍
|
||||
| README | 🔄 | 文档库总说明、模块一览、红线、使用约定(**档案清单唯一来源**)|␍␍␍␍␍
|
||||
| INDEX | 🔄 | 本文件:场景速查 + 状态总览 |␍␍␍␍␍
|
||||
| 01 | ✅ | 背景/架构/目录布局/dsh 分层/归属矩阵/安全边界 |␍␍␍␍␍
|
||||
| 02 | ✅ | 迁移、备份恢复、域名接入、uid 排障、命令速查(**正文为历史,现行以附录 C 为准**)|␍␍␍␍␍
|
||||
| 03 | 🔄 | OQ 结论、已完成清单、进行中/待办、历史决策 |␍␍␍␍␍
|
||||
| **跑跨会话长任务(自动接力)** | **`skills/dsh-auto-handoff-chain/SKILL.md`**:六件套 prompt 骨架 + 登记门禁 + 六条实测防护 + **排期两条铁律**(首个/唯一接续棒 = 收口 + 5~8 分钟 · 同一时刻只挂一个接续棒) + 复跑脚本 `scripts/chain_report.py` |
|
||||
| 看还有什么没做完 | `03-路线图与待办.md` §二 | **`交接单/README.md` §一**(已规划待执行) |
|
||||
| **改前端页面(强制基线)** | **`06-工作台UI规范.md`** |
|
||||
| **改实例 UI 分区(设置面板)** | **`07-实例UI分区登记表.md`**(哪个包提供 / 源码在哪 / 能不能改)+ `06-工作台UI规范.md` |
|
||||
| 红线与硬约束 | `README.md` §红线(含 **R7 禁批量全仓写入**、**R8 中断用户须先知会**)| `04-07` |
|
||||
| **插件兼容性预检(导入/上传即判定)** | **`04-71`**(判据 + PoC + 三层防线)|**`交接单/T05`**(执行单)|`scripts/plugin-compat-check.mjs`(可在服务器直接跑) |
|
||||
| **实例崩溃循环 / 插件不兼容** | `04-70`(anysearch 与 dsh-llm `assertNever` 不兼容;判据「重启后错误是否变化」)|`04-20`(自愈熔断)|`04-25`(崩溃循环前例)|`02 §C.4` |
|
||||
| **锁机制(防并行冲突)** | **`04-73`(强制钩子)|`04-69`(三把锁建立)**|`交接单/README.md` §一·§三·§六|`scripts/{handoff-guard.sh,op-lock.sh,lock-guard-hook.py}` |
|
||||
| **多会话并行 / 冲突治理** | **`04-69`**(两级文档锁 + 服务器侧操作锁 + commit 常态化)|`交接单/README.md`(占用锁 / 写者归属 / §六 服务器侧锁)|`scripts/handoff-guard.sh`、`scripts/op-lock.sh` |
|
||||
| 插件管理面 | `04-16`(三层归属)| `04-31`(门户双 Tab)| `04-57`/`04-60`(设置面板分区) |
|
||||
| **搜索 provider / 联网搜索** | `04-64`(接入 AnySearch)|`04-65`(启停与 web provider 联动)|`04-66`(P0 误报与 admin 显式信任) |
|
||||
| **「能力管理」section UI** | `04-67`(按 UI 规范重做)|`04-36`/`04-38b`(分区铺开 / 术语统一)|`04-68`(启停属主污染根治)|**`04-100`(「我的技能」分组 · 09-15)**|**`04-101`(改名「能力管理」+ tab 分页 + 卡片三行 + DeepSeek 改名 · 09-15)** |
|
||||
| 安全 / 暴露面 | `04-14`(出网护栏)|`04-39`(可见面收窄·封 loopback)|`04-41`(上传加固) |
|
||||
| 技能共享层 / 管理面 | `04-10`(bundledSkillDir)|`04-11`(API+页面)|`04-40`(挂载修复) |
|
||||
| 会话/登录跳转 · 断连恢复 | `04-13`(冷启动 404)|`04-24`(实例侧 401)|`04-49`(回收后反馈)|`04-51`(401 透明重放)|**`04-72`(回收/关闭后回到页面自动唤醒)** |
|
||||
| 实例易用性 | `04-45`(老会话档位提示)|`04-56`(实例助手)|`04-59`(启动动画) |
|
||||
| 实例资源 / 配额 | `04-58`(内存口径 + 配额 384M)|`04-38a`(边界:无磁盘配额) |
|
||||
| VoxEMW | `04-12`(摘要)| `archive/工作区草案/` 两份全文 |
|
||||
| 历史全量时间线 | `archive/dsh-improvement-plan-20260909-full.md` |
|
||||
|
||||
---
|
||||
|
||||
## 二、全量清单
|
||||
|
||||
> **状态摘要**(**机器生成,勿手改**):档案 **115** 份(`04-*`),另含根级编号 5 条(01/02/03/06/07),另有非编号行 14 条(README / INDEX / 技能 / poc 等)—— ✅ 16 | 🔄 5 | 🔍 1 | 📋 22 | 未标记 76。复跑 `python3 scripts/docs-index-stats.py` 取数,`--write` 就地刷新本行。
|
||||
> **分层与机读明细**(路径 / 日期 / 字符数 / 被引次数 / tier,可 `jq` 先筛后读):**`docs-manifest.json`**;复跑 `scripts/docs-manifest.py` 即刷新。
|
||||
> 图例:✅已落地 | 🔄维护中 | 🧪PoC | 📝待开发 | 🔍核查完成 | 📋评估 | 🟡保留兜底 | 🗄归档|🔧修复|🔴|🚧|❓
|
||||
|
||||
| 号 | 状态 | 一句话 |
|
||||
|---|---|---|
|
||||
| README | 🔄 | 文档库总说明、模块一览、红线、使用约定(**档案清单唯一来源**)|
|
||||
| INDEX | 🔄 | 本文件:场景速查 + 状态总览 |
|
||||
| 01 | ✅ | 背景/架构/目录布局/dsh 分层/归属矩阵/安全边界 |
|
||||
| 02 | ✅ | 迁移、备份恢复、域名接入、uid 排障、命令速查(**正文为历史,现行以附录 C 为准**)|
|
||||
| 03 | 🔄 | OQ 结论、已完成清单、进行中/待办、历史决策 |
|
||||
| 04-01 | ✅ | 登录直达 URL 自动带 launch token |
|
||||
| 04-02 | ✅ | 权限边界收紧 + DB 加固 |
|
||||
| 04-03 | ✅ | API KEY 收归管理员统一管控 |
|
||||
@@ -103,7 +103,7 @@
|
||||
| 04-45 | ✅ | 存量会话「新开会话」提示(选提示不选迁移) |
|
||||
| 04-46 | ✅ | 实例共享工具 jq / ripgrep / ffmpeg |
|
||||
| 04-47 | ✅ | admin「运行环境」管理页(含版本漂移告警) |
|
||||
| — | ⚠️ | **编号 48 未使用**(跳号;不影响检索,勿补占)|␍␍␍␍␍
|
||||
| — | ⚠️ | **编号 48 未使用**(跳号;不影响检索,勿补占)|
|
||||
| 04-49 | ✅ 已落地 | 实例回收后首次访问的反馈与自愈(wake.html 过渡页) |
|
||||
| 04-50 | ❓ | 会话过期自愈注入脚本(**已被 04-51 在传输层取代**,保留兜底) |
|
||||
| 04-51 | 已落地并实测验证 | 实例侧 401 透明重放(含 SSE 自动重连) |
|
||||
@@ -118,7 +118,7 @@
|
||||
| 04-60 | ✅ 已实施并验证(服务器已生 | 设置面板分区改名:功能插件 → 功能管理 |
|
||||
| 04-61 | ✅ 已实施并验证(服务器已生 | 插件管理页:官方插件列表加高 + 页面底部留白 200px |
|
||||
| 04-62 | ✅ 已实施并验证(服务器已生 | 插件目录:缓存状态可见化 + 「重新拉取目录」按钮 |
|
||||
| — | ⚠️ | **编号 63 未使用**(跳号;该号只出现在当日工作日志的「事故 63」里,**无档案**,勿补占)|␍␍␍␍␍
|
||||
| — | ⚠️ | **编号 63 未使用**(跳号;该号只出现在当日工作日志的「事故 63」里,**无档案**,勿补占)|
|
||||
| 04-64 | admin 侧已实施 | 接入 AnySearch 搜索 provider(admin 侧已实施;**待端到端确认 → 铺普通用户**) |
|
||||
| 04-65 | ✅ 已部署并生效(服务器 ` | 功能插件启停与 web provider 配置联动(**已部署生效**:服务器 `lib/` 00:13 构建 → **00:15:23 重启即载入**,08:02 再载入;§7.3 第 3 条「anysearch 覆写 |
|
||||
| 04-66 | ✅ 已实现、已验证、已部署 | 业务插件 P0 误报 → admin 显式信任(fail-closed + 逐条回显 + 留痕) |
|
||||
@@ -144,20 +144,20 @@
|
||||
| 04-86 | ✅ 已上线并端到端验证(后端 | ① 平台**所有**服务/文件 API 都是 `request.user.id` 语义(`desktop.ts` 头注释原文 "one user can never address another user's file |
|
||||
| 04-87 | ✅ 已上线并端到端验证(后端 | **平台自建「模型设置」**(官方「设置 → 模型」页在平台环境**必然报错** ⇒ 弃用它):① 官方「模型」分区对**全角色(含 admin)**隐藏 —— 判据是**浏览器页面**的 loopback 判定(真实域 |
|
||||
| 04-88 | ✅ 已修复并验证(源仓 `c | **内置 dsh 安装路径按序探测(修 P1 静默失效)**:平台**三处**把内置 dsh 目录写死成 `/usr/local/lib/node_modules/@deepseek-ai/dsh` —— 而 `npm |
|
||||
| — | 🔍 | **档案 82–86 尚未登记进本表**(本轮发现;属别人 lane 故未代加):82 R2 管理面就地化|83 登录注册页对齐|84 内存配额口径统一|85 模型密钥开放给用户自配|86 admin 跨用户实例管理 + 两处改名。**待收口会话补** |␍␍␍␍␍
|
||||
| — | 🧪 | `04-调整方案/poc/portal-entry/`:portal-entry 插件源码(v0.5.1)|␍␍␍␍␍
|
||||
| 06 | 🔄 | **前端 UI 强制基线**:Token/布局/组件/交互/9 条已知坑 |␍␍␍␍␍
|
||||
| 07 | ✅ | **实例 UI 分区登记表**:settings.section 的 id/order/label → 提供者 → 源码 → 可改性 + 定位套路(含"中文文案要同时搜 UTF-8 与 \uXXXX") |␍␍␍␍␍
|
||||
| — | 🔍 | **档案 82–86 尚未登记进本表**(本轮发现;属别人 lane 故未代加):82 R2 管理面就地化|83 登录注册页对齐|84 内存配额口径统一|85 模型密钥开放给用户自配|86 admin 跨用户实例管理 + 两处改名。**待收口会话补** |
|
||||
| — | 🧪 | `04-调整方案/poc/portal-entry/`:portal-entry 插件源码(v0.5.1)|
|
||||
| 06 | 🔄 | **前端 UI 强制基线**:Token/布局/组件/交互/9 条已知坑 |
|
||||
| 07 | ✅ | **实例 UI 分区登记表**:settings.section 的 id/order/label → 提供者 → 源码 → 可改性 + 定位套路(含"中文文案要同时搜 UTF-8 与 \uXXXX") |
|
||||
| 04-89 | 🔄 进行中(L2 机制级已验 | **对话内文件预览**:采纳官方推荐库现成插件 `@softspark/dsh-file-preview`(65 KB,包住官方 `openWorkspacePath` 接管"点文件"手势;兼容预检 ok、已启用、L5 |
|
||||
| 04-103 | 📋 | **客户端安装 + 覆盖网络互联 · 可行性评估**(规划态 · 未实施):判定 ✅ 可行,且现有架构已给出约 80% 形状(`soft` 档实例=裸子进程 ⇒ 无需 root;Worker 拨出式反向隧道 ⇒ **节点本来就不需要公网 IP**);缺口 4 条(客户端运行时落点 · 节点身份 · **信任模型反转** · 分发与版本矩阵);形态三档已按用户口径收窄为**单机自用**(B 档);6 步落地、每步可单独回滚。⚠️ 真正硬阻塞点修正 = **平台调用层**(Windows 下裸名 `spawn` ENOENT / `.cmd` EINVAL),非 dsh 运行时 |
|
||||
| 04-104 | 📋 | **覆盖网络 · 全球架构复盘**(规划态 · 未实施):五层架构(控制面 / 会合 / 骨干·中继 / 数据面 / 观测)+ 12 条必须内建特性 + **10 类风暴类型学** + 流量组织五原则 + 流量预算表 + 7 步落地顺序。🔑 三句结论:控制面与数据面**彻底分离** · 失败不要变成重试(退避+抖动+判死) · 放大点必须前置治理。🟢 范围声明:**只做技术实现,跨境数据合规由使用者自负**(⛔ 不再作前置条件或上抛项) |
|
||||
| 04-105 | 📋 | **覆盖网络 · 骨干层方案**(规划态 · 未实施):多中心骨干(≤10–20 成员、全互联;每节点只连 1–2 个骨干)+ 选择性加入。三条硬约束:**接入 / 成员 / 可见三分离** · **骨干资格只能控制面签发**(否则出现第二权威源、骨干沦为公网跳板) · **骨干不得被默认征用**(命中 R5)。⚠️ §7 唯一待拍板 = 骨干服务范围(A 只服务自己名下设备 / B 服务全网;**倾向 A→B 渐进**) |
|
||||
| 04-106 | 📋 | **覆盖网络 · 百台规模推演 v2**(规划态 · 纯文字推演):⚠️ 含**前提级纠错**(v1 作废)—— 用户纠正「**单机用也要互联**」;错因 = **把「租户维度收窄」误当成「网络维度收窄」**。100 台异构画像:L1 10 / L2 30 / **L3 需中继 40–55** ⇒ **中继按 45% 设计、55% 留余量**(⛔ 不用同构假设的 15%);**必须补 443/TCP 兜底**(否则企业/校园网整类进不来);**L1 自动升格为中继候选**;仍不建全互联(4,950 vs 100) |
|
||||
| 04-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 为本方案独有放大源** |
|
||||
| 04-108 | 📋 | **覆盖网络 · 游戏专项(MMORPG 2D/2.5D · MUD · 传奇类)**(规划态 · 未实施):⚠️ 判定**由「不合适」修正为「最匹配」**(该类游戏天生服务端权威 + tick 驱动 + **AOI 九宫格** + 分区/分线;每玩家仅数 KB/s~数十 KB/s、几百 ms 无感)—— 原"不合适"只针对 3D 大世界强实时竞技。⭐ 核心简化:**玩家之间不需要互联 ⇒ 中继容量按「服数」算、不按「玩家数」算**。含 12 条设计细节 + 参考方案(Evennia/Skynet/Pomelo/Nakama…)+ 8 条反模式 |
|
||||
| 04-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 预算)** |
|
||||
| 04-110 | 📋 | **覆盖网络 · 答疑(群聊+agent / 备份 / 迁移提速 / 传输保密)**(规划态 · 未实施):① 群聊=**应用层**的事(覆盖网络只给「可达」);**agent 四条硬约束**(⛔ 禁止 agent 直接触发 agent);② ✅ **备份主层用对象存储**,覆盖网络只当**搬运通道与第三副本**(P2P 副本无 SLA、可误删,不适合当存档);③ 迁移 7 条按收益排,**最大一招 = 只搬不可再生(46.3 MB vs 2.9 GiB ≈ 64×)**;④ 保密 = 三层加密 + 元数据保护,**最大缺口 = 身份(共享令牌 → 一机一钥)** |
|
||||
| 04-111 | 📋 | **覆盖网络 · 补遗与参考方案**(规划态 · 未实施):互联游戏 ✅ 但**由游戏形态决定**(锁步/回合/异步最友好;FPS/MOBA 64+ ❌ 不合适,P2P 无法反作弊);补遗 **24 条**(身份与账户 / 寻址与名字 / 接入与可见性 / 自检与选路 / 流量与公平 / 移动端弱网 / 升级版本自愈 / 可观测)+ 10 个能力域的参考方案 + **反模式 12 条**。⭐ 最划算的架构复用:**群聊房间与游戏对局是同一个模型**(一次投资,群聊 + 游戏 + 协作 + 看板共用) |
|
||||
| 04-103 | 📋 | **客户端安装 + 覆盖网络互联 · 可行性评估**(规划态 · 未实施):判定 ✅ 可行,且现有架构已给出约 80% 形状(`soft` 档实例=裸子进程 ⇒ 无需 root;Worker 拨出式反向隧道 ⇒ **节点本来就不需要公网 IP**);缺口 4 条(客户端运行时落点 · 节点身份 · **信任模型反转** · 分发与版本矩阵);形态三档已按用户口径收窄为**单机自用**(B 档);6 步落地、每步可单独回滚。⚠️ 真正硬阻塞点修正 = **平台调用层**(Windows 下裸名 `spawn` ENOENT / `.cmd` EINVAL),非 dsh 运行时 |
|
||||
| 04-104 | 📋 | **覆盖网络 · 全球架构复盘**(规划态 · 未实施):五层架构(控制面 / 会合 / 骨干·中继 / 数据面 / 观测)+ 12 条必须内建特性 + **10 类风暴类型学** + 流量组织五原则 + 流量预算表 + 7 步落地顺序。🔑 三句结论:控制面与数据面**彻底分离** · 失败不要变成重试(退避+抖动+判死) · 放大点必须前置治理。🟢 范围声明:**只做技术实现,跨境数据合规由使用者自负**(⛔ 不再作前置条件或上抛项) |
|
||||
| 04-105 | 📋 | **覆盖网络 · 骨干层方案**(规划态 · 未实施):多中心骨干(≤10–20 成员、全互联;每节点只连 1–2 个骨干)+ 选择性加入。三条硬约束:**接入 / 成员 / 可见三分离** · **骨干资格只能控制面签发**(否则出现第二权威源、骨干沦为公网跳板) · **骨干不得被默认征用**(命中 R5)。⚠️ §7 唯一待拍板 = 骨干服务范围(A 只服务自己名下设备 / B 服务全网;**倾向 A→B 渐进**) |
|
||||
| 04-106 | 📋 | **覆盖网络 · 百台规模推演 v2**(规划态 · 纯文字推演):⚠️ 含**前提级纠错**(v1 作废)—— 用户纠正「**单机用也要互联**」;错因 = **把「租户维度收窄」误当成「网络维度收窄」**。100 台异构画像:L1 10 / L2 30 / **L3 需中继 40–55** ⇒ **中继按 45% 设计、55% 留余量**(⛔ 不用同构假设的 15%);**必须补 443/TCP 兜底**(否则企业/校园网整类进不来);**L1 自动升格为中继候选**;仍不建全互联(4,950 vs 100) |
|
||||
| 04-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 为本方案独有放大源** |
|
||||
| 04-108 | 📋 | **覆盖网络 · 游戏专项(MMORPG 2D/2.5D · MUD · 传奇类)**(规划态 · 未实施):⚠️ 判定**由「不合适」修正为「最匹配」**(该类游戏天生服务端权威 + tick 驱动 + **AOI 九宫格** + 分区/分线;每玩家仅数 KB/s~数十 KB/s、几百 ms 无感)—— 原"不合适"只针对 3D 大世界强实时竞技。⭐ 核心简化:**玩家之间不需要互联 ⇒ 中继容量按「服数」算、不按「玩家数」算**。含 12 条设计细节 + 参考方案(Evennia/Skynet/Pomelo/Nakama…)+ 8 条反模式 |
|
||||
| 04-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 预算)** |
|
||||
| 04-110 | 📋 | **覆盖网络 · 答疑(群聊+agent / 备份 / 迁移提速 / 传输保密)**(规划态 · 未实施):① 群聊=**应用层**的事(覆盖网络只给「可达」);**agent 四条硬约束**(⛔ 禁止 agent 直接触发 agent);② ✅ **备份主层用对象存储**,覆盖网络只当**搬运通道与第三副本**(P2P 副本无 SLA、可误删,不适合当存档);③ 迁移 7 条按收益排,**最大一招 = 只搬不可再生(46.3 MB vs 2.9 GiB ≈ 64×)**;④ 保密 = 三层加密 + 元数据保护,**最大缺口 = 身份(共享令牌 → 一机一钥)** |
|
||||
| 04-111 | 📋 | **覆盖网络 · 补遗与参考方案**(规划态 · 未实施):互联游戏 ✅ 但**由游戏形态决定**(锁步/回合/异步最友好;FPS/MOBA 64+ ❌ 不合适,P2P 无法反作弊);补遗 **24 条**(身份与账户 / 寻址与名字 / 接入与可见性 / 自检与选路 / 流量与公平 / 移动端弱网 / 升级版本自愈 / 可观测)+ 10 个能力域的参考方案 + **反模式 12 条**。⭐ 最划算的架构复用:**群聊房间与游戏对局是同一个模型**(一次投资,群聊 + 游戏 + 协作 + 看板共用) |
|
||||
| 04-112 | 📋 | **覆盖网络 · 九大瓶颈落地方案**(规划态 · 未实施):把 107 的九大瓶颈逐个给成**可执行做法 + 验收判据**(含 Slack / SCCM·BranchCache·Delivery Optimization 官方照抄点)。🎯 **只做三件 = presence 改造 + 游戏服放 L1 + 块级内容寻址分发**(覆盖最大三个瓶颈,且**都不需要改传输协议**)。🔑 分水岭:**必须做「块级」内容寻址,⛔ 别做「包级」**(包级 = 版本一发所有 peer 源失效 ⇒ 正是全量重拉风暴的成因) |
|
||||
| 04-113 | 📋 | **覆盖网络 · 传输方案取舍(开放端口 vs 自研 relay)**(决策稿):逐条对比 5 种传输形态,定下**自研 relay + 回环监听 + 中继切流**路线;⛔ P4(SSH 版中继 / 32023)判**不做** |
|
||||
| 04-114 | 📋 | **覆盖网络 · 应用场景推演完成度 & 方案待完善清单**(检查稿):逐场景打勾哪些已推演、哪些仍缺;作为后续补遗的取数底稿 |
|
||||
@@ -171,75 +171,75 @@
|
||||
| 04-122 | 📋 | **guest 迁移(w-47 → w-106)与共享重建方案**:存量 guest 落 106 的搬运步骤 + 共享面重建判据 |
|
||||
| 04-123 | 📋 | **方案规划方法 —— 从覆盖网络线提炼**:把本线的规划手法沉淀成**可复用方法论**(判据优先 / 单一来源 / 假绿识别) |
|
||||
| 04-124 | 🔍 | **文档无效信息审计报告**:对文档库做「无效信息」体检,输出应删/应改/应合并清单(**报告,未执行**) |
|
||||
| 04-125 | 📋 | **会话接续机制 · 问题复盘与修复**:复盘「接续为何断链/为何空转」,产出修复项(间隔纪律 = 收口 + 2~5 分钟) |
|
||||
| 04-125 | 📋 | **会话接续机制 · 问题复盘与修复**:复盘「接续为何断链/为何空转」,产出修复项(**排期两条铁律** = ① 首个/唯一接续棒 = 收口 + **5~8 分钟**〔原记 2~5,2026-09-18 用户更正〕② **同一时刻只挂一个接续棒**;规则实体见技能 `dsh-auto-handoff-chain §3.1.1`) |
|
||||
| 04-126 | 🔄 | **会话接续规范:token 超限后如何无损继续**:接续六件套 prompt 骨架与登记门禁的规范文本 |
|
||||
| 04-127 | 📋 | **DSH 平台客户端化部署方案 —— 单机自用**:B 档(单机自用)形态下的客户端化部署路径;⚠️ 真正硬阻塞 = 平台调用层(Windows 裸名 `spawn` ENOENT) |
|
||||
| 04-128 | 📋 | **DSH 桌面客户端开发方案 —— 基于官方 Electron 壳迭代**(待评审 · 只做规划不含代码):复用官方壳 vs 自建的取舍与分发/版本矩阵 |
|
||||
| — | 🗄 | `archive/dsh-improvement-plan-20260909-full.md`:拆分前 19 章 |␍␍␍␍␍
|
||||
| — | ✅ | `skills/dsh-change-workflow/SKILL.md`:六阶段 + **红线 R1-R11**(工作副本在本机 `.workbuddy/skills/`)|␍␍␍␍␍
|
||||
| — | ✅ | `skills/dsh-decision-method/SKILL.md`:**改造决策方法论**(用户有效决策 U1-U12 / AI 有效决策 A1-A13 / 反例 X1-X8 + 确认最优解十问 + 交互 UI 专项清单)(工作副本在本机 `.workbuddy/skills/`)|␍␍␍␍␍
|
||||
| — | ✅ | `skills/dsh-feature-first/SKILL.md`:**功能优先协作协议**(用户只提功能卡 4 问 · AI 自主决策 9 类白名单 · 只上抛功能语义分叉与红线门禁 · 报障闭环前置 · 交付回执格式)(工作副本在本机 `.workbuddy/skills/`)|␍␍␍␍␍
|
||||
| — | ✅ | `skills/dsh-opensource-release/SKILL.md`:**开源导出与版本迭代**(五条硬规则 R-O1–R-O5 · 脱敏映射表唯一口径 · 分层授权与其 MIT 法律前提 · 迭代发布 SOP · 验证六件套 · 8 条实测坑)(工作副本在本机 `.workbuddy/skills/`)|␍␍␍
|
||||
| — | ✅ | `skills/dsh-plugin-diagnose/SKILL.md`:**业务插件故障诊断**(三层归属 host / client / 网关·原生绑定 · 三把尺子 inject 差集 / glibc 直测 / 产物插探针 · 8 条实测坑)(工作副本在本机 `.workbuddy/skills/`)|␍␍␍␍␍
|
||||
| — | 🗄 | `archive/dsh-improvement-plan-20260909-full.md`:拆分前 19 章 |
|
||||
| — | ✅ | `skills/dsh-change-workflow/SKILL.md`:六阶段 + **红线 R1-R11**(工作副本在本机 `.workbuddy/skills/`)|
|
||||
| — | ✅ | `skills/dsh-decision-method/SKILL.md`:**改造决策方法论**(用户有效决策 U1-U12 / AI 有效决策 A1-A13 / 反例 X1-X8 + 确认最优解十问 + 交互 UI 专项清单)(工作副本在本机 `.workbuddy/skills/`)|
|
||||
| — | ✅ | `skills/dsh-feature-first/SKILL.md`:**功能优先协作协议**(用户只提功能卡 4 问 · AI 自主决策 9 类白名单 · 只上抛功能语义分叉与红线门禁 · 报障闭环前置 · 交付回执格式)(工作副本在本机 `.workbuddy/skills/`)|
|
||||
| — | ✅ | `skills/dsh-opensource-release/SKILL.md`:**开源导出与版本迭代**(五条硬规则 R-O1–R-O5 · 脱敏映射表唯一口径 · 分层授权与其 MIT 法律前提 · 迭代发布 SOP · 验证六件套 · 8 条实测坑)(工作副本在本机 `.workbuddy/skills/`)|
|
||||
| — | ✅ | `skills/dsh-plugin-diagnose/SKILL.md`:**业务插件故障诊断**(三层归属 host / client / 网关·原生绑定 · 三把尺子 inject 差集 / glibc 直测 / 产物插探针 · 8 条实测坑)(工作副本在本机 `.workbuddy/skills/`)|
|
||||
| — | ✅ | `skills/dsh-env-bootstrap/SKILL.md`:**环境引导 / 迁移**(常驻规则快照 `references/常驻规则-快照.md` + `scripts/resident-rules.py` 的 `--check / --inject / --env-check / --snapshot`;**权威方向单向**:CODEBUDDY.md 为权威、快照为副本)(工作副本在本机 `.workbuddy/skills/`)|
|
||||
| — | ✅ | `skills/dsh-auto-handoff-chain/SKILL.md`:**多棒自动接力编排法**(规划棒 ↔ 执行棒交替 · 一次性 automation 链条 · 六件套 prompt 骨架 · 登记门禁 · 五条实测防护 · 断链 / 双开 / once 不转完成态 等 · `scripts/chain_report.py` 复跑)(工作副本在本机 `.workbuddy/skills/`)|
|
||||
␍␍␍␍␍
|
||||
> **待办与优先级不在本文件维护**(单一来源):**未规划**的见 `03-路线图与待办.md` §二;**已规划待执行**的见 `交接单/README.md` §一。␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
---␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
## 三、变化与更新状态:怎么追␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
| 手段 | 怎么做 |␍␍␍␍␍
|
||||
|---|---|␍␍␍␍␍
|
||||
| **双端对账** | `bash scripts/docs-sync-check.sh`(一致/不一致/仅本地/仅服务器 + 退出码 0=全绿)|␍␍␍␍␍
|
||||
| **机读清单** | `python3 scripts/docs-manifest.py` → `docs-manifest.json`(状态/日期/tier/引用数)|␍␍␍␍␍
|
||||
| **质量审计** | `python3 scripts/docs-audit.py`(9 类判定;编号冲突与悬空引用会返回非 0)|␍␍␍␍␍
|
||||
| **代码侧变更** | `git -C /opt/dshs log --oneline`(平台代码是 git 仓库,比文档更细)|␍␍␍␍␍
|
||||
| **文档侧变更** | 本目录是 git 仓库:`git log --oneline`;服务器镜像无 .git,靠 scp 单向推送 |␍␍␍␍␍
|
||||
| 时间线溯源 | `03-路线图 §已完成` + 各档案 commit 列 + `archive/` 全文 |␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
---␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
## 四、归档与工作区残留␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
| 文件 | 位置 | 状态 |␍␍␍␍␍
|
||||
|---|---|---|␍␍␍␍␍
|
||||
| **已完成的交接单**(规划/执行分离的单子)| `archive/交接单-已完成/` | **T02**(文档库收尾:37/38 编号消歧 + INDEX 瘦身 28,809→7,468)|**T03**(7 插件整合投放:`dsh-plugin-mcn-suite` 上传候选池 + **guest 启用成功**,实例重启探活通过)|**T04**(并发治理:commit 常态化 + 服务器侧操作锁 `/opt/dsh/state/.op-lock` + 权限 700/600 + 代码库 `ebe8075`→`06e63ac`)|**T05**(插件兼容性预检:`04-71` 落地 + 档案 66 源码回填)— 均 2026-09-12 完成|**T06**(平台自建「模型设置」:`04-87` 落地 + 插件 0.3.11 铺发 + 迁移 V6 + 官方模型分区全角色隐藏;验收四件事全绿,顺手修角色补丁整文件覆盖与陈旧断言两颗雷)— 2026-09-13 完成|**T07**(内置 dsh 安装路径按序探测:`04-88` 落地;**三处**写死路径(第 3 处是提出方漏的)改为按序探测 + 降级留痕;测试服 `test106` 三种姿势验证通过)— 2026-09-14 完成 |␍␍␍␍␍|**T09–T21**(2026-09-17 从工作区根批量入仓:覆盖网络线 13 份交接单 —— 含「落地执行 / 网抽象与地址规划 R6 / relay R2-R4 / 443 兜底 / 中继失败切流 / 切流冷却语义 / presence 在线态 / 一机一钥与信任根 / 参数表与观测 / 检测时延与 deadline / 最小形态真机批次 / 观测口径与在册缺陷 / 在册收尾」;⚠️ 均为**已完成单的归档副本**,若其中仍有未完成项需在 `交接单/` 另开新单)
|
||||
| 三份工作区草案(插件管理面 / VoxEMW×2)| `archive/工作区草案/` | 已归档防丢;插件草案 v5 被档案 16 取代 |␍␍␍␍␍
|
||||
| `scripts/docs-{sync-check.sh,audit.py,manifest.py}` | 本库 `scripts/` | 随库分发,**在用** |␍␍␍␍␍
|
||||
| `.workbuddy/memory/YYYY-MM-DD.md` | 工作区 `.workbuddy/` | 过程日志,不入库 |␍␍␍␍␍
|
||||
| `*.bak*` | 各处 | 已纳入 `.gitignore`;**服务器侧勿生成结尾带点号的备份名**(Windows 落不了地)|␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
---␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
## 五、仓库与同步拓扑␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
| 资产 | 路径 | 仓库 / 状态 |␍␍␍␍␍
|
||||
|---|---|---|␍␍␍␍␍
|
||||
| **平台代码** | 服务器 `/opt/dshs`(git,上游 fork,**浅克隆**)| `git@work.alotbuy.com:maogeigei/dsh_shenxian.git` — `master @ ebe8075` ✅ 已推送 |␍␍␍␍␍
|
||||
| **改造文档** | 本机 `dsh-server-docs/`(**本目录即工作树**)↔ 服务器 `/opt/dsh/docs`(镜像,root 600)| `git@work.alotbuy.com:maogeigei/dsh_shenxian_doc.git` — `main @ 43e4ae9` ✅ 已推送 |␍␍␍␍␍
|
||||
| 上游基线 | `上游骨架仓库(已按要求不再具名)`(123 提交,HEAD `04bc832`)| 本机 remote 名 `upstream` |␍␍␍␍␍
|
||||
| 本机代码副本 | `D:\github\dsh_shenxian` | 上述代码仓库的 clone |␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
**约定**␍␍␍␍␍
|
||||
1. **推送只能从本机执行**:服务器无 Gitea 凭据 → 服务器改码后 `git bundle`(区间)→ 本机 fetch/merge → push。␍␍␍␍␍
|
||||
2. **同步链路(文档)**:编辑本目录 → `docs-sync-check.sh` 对账 → scp 到 `/opt/dsh/docs`(`chmod 600`,README 保持 644)→ 复跑脚本确认全绿。␍␍␍␍␍
|
||||
3. **权限**:服务器 docs 树 root 600(README 644);`/opt/dsh` 为 `drwx------ root`(用户 uid 读不到,需先暂存到用户 home 再安装)。␍␍␍␍␍
|
||||
4. **行尾**:本机 git 的 system 级 `core.autocrlf=true` 会把工作树写成 CRLF,而仓库 blob 是 **LF** → **scp 单文件前看 `file` 输出**;脚本类必须 LF(否则 shebang 带 `\r` 执行失败)。␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
---␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
## 六、新增文档的落位规则(约定)␍␍␍␍␍
|
||||
␍␍␍␍␍
|
||||
1. **功能类改造** → `04-调整方案/` 新建档案,**编号递增**(**复跑取号,勿写死**:`ls 04-调整方案/ | sort -n | tail -1`;**63 为空号,勿补占**);模板:目标 → 改动 → 验证 → 红线遵守 → 回滚。␍␍␍␍␍
|
||||
2. **规范 / 基线类**(跨页面长期生效)→ 根级编号文档(`01`~`06`),不入 `04-调整方案/`;入库时登记 §一 场景表 + §二 清单。␍␍␍␍␍
|
||||
3. **排障记录** → 追加 `02-运维手册.md` 排障小节。␍␍␍␍␍
|
||||
4. **状态 / 待办变化** → 更新 `03-路线图与待办.md` 与本文件 §二。␍␍␍␍␍
|
||||
5. **保留原章节编号**,便于与 `archive/` 完整版对查。␍␍␍␍␍
|
||||
6. **同步**:见 §五.2(对账 → scp → chmod → 复跑)。␍␍␍␍␍
|
||||
7. **UI 规范优先**:涉及前端改动**先读 `06-工作台UI规范.md`**;沉淀了新"为什么"要回写源侧并回拷 `06`。␍␍␍␍␍
|
||||
8. **规划/执行分离的任务单** → `交接单/`(约定见其 `README.md`):规划会话产出单子,执行会话按单开工(**不读规划会话上下文**);完成后 `git mv` 入 `archive/交接单-已完成/` 并在 §四 加行。␍␍␍␍␍
|
||||
| — | ✅ | `skills/dsh-auto-handoff-chain/SKILL.md`:**多棒自动接力编排法**(规划棒 ↔ 执行棒交替 · 一次性 automation 链条 · 六件套 prompt 骨架 · 登记门禁 · **排期两条铁律 §3.1.1**〔首个/唯一接续棒 = 收口 + 5~8 分钟 · 同一时刻只挂一个接续棒〕· 六条实测防护 · 断链 / 双开 / once 不转完成态 / 预登记队列 等 · `scripts/chain_report.py` 复跑)(工作副本在本机 `.workbuddy/skills/`)|
|
||||
|
||||
> **待办与优先级不在本文件维护**(单一来源):**未规划**的见 `03-路线图与待办.md` §二;**已规划待执行**的见 `交接单/README.md` §一。
|
||||
|
||||
---
|
||||
|
||||
## 三、变化与更新状态:怎么追
|
||||
|
||||
| 手段 | 怎么做 |
|
||||
|---|---|
|
||||
| **双端对账** | `bash scripts/docs-sync-check.sh`(一致/不一致/仅本地/仅服务器 + 退出码 0=全绿)|
|
||||
| **机读清单** | `python3 scripts/docs-manifest.py` → `docs-manifest.json`(状态/日期/tier/引用数)|
|
||||
| **质量审计** | `python3 scripts/docs-audit.py`(9 类判定;编号冲突与悬空引用会返回非 0)|
|
||||
| **代码侧变更** | `git -C /opt/dshs log --oneline`(平台代码是 git 仓库,比文档更细)|
|
||||
| **文档侧变更** | 本目录是 git 仓库:`git log --oneline`;服务器镜像无 .git,靠 scp 单向推送 |
|
||||
| 时间线溯源 | `03-路线图 §已完成` + 各档案 commit 列 + `archive/` 全文 |
|
||||
|
||||
---
|
||||
|
||||
## 四、归档与工作区残留
|
||||
|
||||
| 文件 | 位置 | 状态 |
|
||||
|---|---|---|
|
||||
| **已完成的交接单**(规划/执行分离的单子)| `archive/交接单-已完成/` | **T02**(文档库收尾:37/38 编号消歧 + INDEX 瘦身 28,809→7,468)|**T03**(7 插件整合投放:`dsh-plugin-mcn-suite` 上传候选池 + **guest 启用成功**,实例重启探活通过)|**T04**(并发治理:commit 常态化 + 服务器侧操作锁 `/opt/dsh/state/.op-lock` + 权限 700/600 + 代码库 `ebe8075`→`06e63ac`)|**T05**(插件兼容性预检:`04-71` 落地 + 档案 66 源码回填)— 均 2026-09-12 完成|**T06**(平台自建「模型设置」:`04-87` 落地 + 插件 0.3.11 铺发 + 迁移 V6 + 官方模型分区全角色隐藏;验收四件事全绿,顺手修角色补丁整文件覆盖与陈旧断言两颗雷)— 2026-09-13 完成|**T07**(内置 dsh 安装路径按序探测:`04-88` 落地;**三处**写死路径(第 3 处是提出方漏的)改为按序探测 + 降级留痕;测试服 `test106` 三种姿势验证通过)— 2026-09-14 完成 |␍␍␍␍␍|**T09–T21**(2026-09-17 从工作区根批量入仓:覆盖网络线 13 份交接单 —— 含「落地执行 / 网抽象与地址规划 R6 / relay R2-R4 / 443 兜底 / 中继失败切流 / 切流冷却语义 / presence 在线态 / 一机一钥与信任根 / 参数表与观测 / 检测时延与 deadline / 最小形态真机批次 / 观测口径与在册缺陷 / 在册收尾」;⚠️ 均为**已完成单的归档副本**,若其中仍有未完成项需在 `交接单/` 另开新单)
|
||||
| 三份工作区草案(插件管理面 / VoxEMW×2)| `archive/工作区草案/` | 已归档防丢;插件草案 v5 被档案 16 取代 |
|
||||
| `scripts/docs-{sync-check.sh,audit.py,manifest.py}` | 本库 `scripts/` | 随库分发,**在用** |
|
||||
| `.workbuddy/memory/YYYY-MM-DD.md` | 工作区 `.workbuddy/` | 过程日志,不入库 |
|
||||
| `*.bak*` | 各处 | 已纳入 `.gitignore`;**服务器侧勿生成结尾带点号的备份名**(Windows 落不了地)|
|
||||
|
||||
---
|
||||
|
||||
## 五、仓库与同步拓扑
|
||||
|
||||
| 资产 | 路径 | 仓库 / 状态 |
|
||||
|---|---|---|
|
||||
| **平台代码** | 服务器 `/opt/dshs`(git,上游 fork,**浅克隆**)| `git@work.alotbuy.com:maogeigei/dsh_shenxian.git` — `master @ ebe8075` ✅ 已推送 |
|
||||
| **改造文档** | 本机 `dsh-server-docs/`(**本目录即工作树**)↔ 服务器 `/opt/dsh/docs`(镜像,root 600)| `git@work.alotbuy.com:maogeigei/dsh_shenxian_doc.git` — `main @ 43e4ae9` ✅ 已推送 |
|
||||
| 上游基线 | `上游骨架仓库(已按要求不再具名)`(123 提交,HEAD `04bc832`)| 本机 remote 名 `upstream` |
|
||||
| 本机代码副本 | `D:\github\dsh_shenxian` | 上述代码仓库的 clone |
|
||||
|
||||
**约定**
|
||||
1. **推送只能从本机执行**:服务器无 Gitea 凭据 → 服务器改码后 `git bundle`(区间)→ 本机 fetch/merge → push。
|
||||
2. **同步链路(文档)**:编辑本目录 → `docs-sync-check.sh` 对账 → scp 到 `/opt/dsh/docs`(`chmod 600`,README 保持 644)→ 复跑脚本确认全绿。
|
||||
3. **权限**:服务器 docs 树 root 600(README 644);`/opt/dsh` 为 `drwx------ root`(用户 uid 读不到,需先暂存到用户 home 再安装)。
|
||||
4. **行尾**:本机 git 的 system 级 `core.autocrlf=true` 会把工作树写成 CRLF,而仓库 blob 是 **LF** → **scp 单文件前看 `file` 输出**;脚本类必须 LF(否则 shebang 带 `\r` 执行失败)。
|
||||
|
||||
---
|
||||
|
||||
## 六、新增文档的落位规则(约定)
|
||||
|
||||
1. **功能类改造** → `04-调整方案/` 新建档案,**编号递增**(**复跑取号,勿写死**:`ls 04-调整方案/ | sort -n | tail -1`;**63 为空号,勿补占**);模板:目标 → 改动 → 验证 → 红线遵守 → 回滚。
|
||||
2. **规范 / 基线类**(跨页面长期生效)→ 根级编号文档(`01`~`06`),不入 `04-调整方案/`;入库时登记 §一 场景表 + §二 清单。
|
||||
3. **排障记录** → 追加 `02-运维手册.md` 排障小节。
|
||||
4. **状态 / 待办变化** → 更新 `03-路线图与待办.md` 与本文件 §二。
|
||||
5. **保留原章节编号**,便于与 `archive/` 完整版对查。
|
||||
6. **同步**:见 §五.2(对账 → scp → chmod → 复跑)。
|
||||
7. **UI 规范优先**:涉及前端改动**先读 `06-工作台UI规范.md`**;沉淀了新"为什么"要回写源侧并回拷 `06`。
|
||||
8. **规划/执行分离的任务单** → `交接单/`(约定见其 `README.md`):规划会话产出单子,执行会话按单开工(**不读规划会话上下文**);完成后 `git mv` 入 `archive/交接单-已完成/` 并在 §四 加行。
|
||||
|
||||
| 04-90 | 🔄 进行中(阶段 1 通过 | > 目标版本 = **`0.1.5-rc.1`**(npm `latest`;用户材料里插件 peer 也是 `^0.1.5-rc.1`,三方自洽)。 |
|
||||
| 04-91 | ✅ 已上线(`busines | **「模型设置」页复刻官方交互**:换行根因是 **4 列表格 auto 列宽** ⇒ 改官方**卡片行**(两侧 nowrap)+「新增」改**两步式**(两个虚线按钮 → 卡片主字段只剩「API 密钥」);顺修「由 |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: dsh-auto-handoff-chain
|
||||
description: 长任务「多棒自动接力」编排法 —— 把一个跨越多个上下文窗口的大任务,拆成「规划棒 ↔ 执行棒」交替的一次性自动化链条,每棒做完自动开新会话接下一棒,**全程零人工点击**。当用户说「自动新建会话接续处理」「接力跑下去」「多步骤任务自动推进」「跑完一棒自动接下一棒」「无人值守推进」,或一个任务预计要跨 ≥3 个会话 / 超过一个上下文窗口时触发。核心 = 六件套 prompt 骨架(状态单点 → 唯一执行依据指针 → 全局锁 → 单一动作 → 成本纪律 → 收尾四件套)+ **登记门禁(★要拍板的,等拍了再登记 —— 用户 2026-09-17 明令,当天已有实测事故 §3.3.1)** + 五条实测防护(断链 / 双开 / once 不转完成态 / 跨过拍板点 / **下一棒定太晚**,间隔纪律见 §3.1.1)+ 实测成本基线 + 复跑脚本 `scripts/chain_report.py`。⛔ 两条关键判据:**prompt 里绝不抄任务细节**(细节只有一个漂移源 = 入口文件的「本轮动作」块);**先判「是不是要拍板」,未命中才轮到「候选排不排得出优劣」—— 顺序颠倒就会自我扩权**。
|
||||
version: 1.3.2
|
||||
updated_at: 2026-09-17
|
||||
description: 长任务「多棒自动接力」编排法 —— 把一个跨越多个上下文窗口的大任务,拆成「规划棒 ↔ 执行棒」交替的一次性自动化链条,每棒做完自动开新会话接下一棒,**全程零人工点击**。当用户说「自动新建会话接续处理」「接力跑下去」「多步骤任务自动推进」「跑完一棒自动接下一棒」「无人值守推进」,或一个任务预计要跨 ≥3 个会话 / 超过一个上下文窗口时触发。核心 = 六件套 prompt 骨架(状态单点 → 唯一执行依据指针 → 全局锁 → 单一动作 → 成本纪律 → 收尾四件套)+ **登记门禁(★要拍板的,等拍了再登记 —— 用户 2026-09-17 明令,当天已有实测事故 §3.3.1)** + 六条实测防护(断链 / 双开 / once 不转完成态 / 跨过拍板点 / **下一棒定太晚** / **预登记多个接续棒**,排期纪律见 §3.1.1)+ 实测成本基线 + 复跑脚本 `scripts/chain_report.py`。⛔ **排期两条铁律(§3.1.1,用户 2026-09-18 明令)**:首个(唯一)接续棒 = 收口 + **5~8 分钟**;**同一时刻只挂一个接续棒**,下一棒由当棒收官时再排。⛔ 两条关键判据:**prompt 里绝不抄任务细节**(细节只有一个漂移源 = 入口文件的「本轮动作」块);**先判「是不是要拍板」,未命中才轮到「候选排不排得出优劣」—— 顺序颠倒就会自我扩权**。
|
||||
version: 1.4.0
|
||||
updated_at: 2026-09-18
|
||||
created_from: 覆盖网络线 19 个会话(2026-09-16 ~ 09-17)的实测复盘 —— 09-17 链条连续 8 棒零断链,规划棒成本降至旧形态的 1/8–1/12
|
||||
agent_created: true
|
||||
---
|
||||
@@ -74,7 +74,7 @@ agent_created: true
|
||||
|
||||
纪律:技术实现项**自决不上抛**;只有「没有客观优劣」的取舍才列候选,且每个候选必须写「优点 / 缺点」、**候选竖排成段**(不横排);判据必须可被第三方复现。
|
||||
|
||||
收尾(缺一即算未完成):① 释放锁 `--release-exec`;② **先过登记门禁(见 §3.3)**——只有「下一棒可自决」才登记,**`scheduledAt` = 此刻 + 2~5 分钟(见 §3.1.1,⛔ 不许留长等待窗口)**;用**陈述句**告知「已登记自动接续、约 2~5 分钟后自动开新会话、接续点 = X」;③ 把入口 §2「🎯 本轮动作」推进到再下一棒;④ 写工作区日志。
|
||||
收尾(缺一即算未完成):① 释放锁 `--release-exec`;② **先过登记门禁(见 §3.3)**——只有「下一棒可自决」才登记,**`scheduledAt` = 此刻 + 5~8 分钟(见 §3.1.1 铁律①,⛔ 不许留长等待窗口)**,且**同一时刻只挂一个接续棒**(§3.1.1 铁律②:⛔ 不预登记队列,后续项写进入口 §2 的「⏭️ 本线下一项」由下一棒自己排);用**陈述句**告知「已登记自动接续、约 5~8 分钟后自动开新会话、接续点 = X」;③ 把入口 §2「🎯 本轮动作」推进到再下一棒;④ 写工作区日志。
|
||||
```
|
||||
|
||||
### 2.1 三条骨架为什么长这样(都有实测出处)
|
||||
@@ -100,18 +100,19 @@ agent_created: true
|
||||
## 3. 收尾四件套(缺一即算未完成)
|
||||
|
||||
> 这四件里**第 ② 件是唯一会"断链"的地方**,也是钩子**做不到**的地方(钩子不能创建会话、不能创建自动化)。
|
||||
> 🔴 第 ② 件的两条硬约束(详见 §3.1.1):**只排"下一棒"这一棒**(⛔ 不预登记队列)+ **`scheduledAt` = 收口 + 5~8 分钟**。
|
||||
|
||||
| # | 动作 | 判据 |
|
||||
|---|---|---|
|
||||
| ① | 释放锁 `--release-exec` | 跑一次信息模式确认已释放 |
|
||||
| ② | **先过 §3.3 登记门禁** → 登记下一棒的一次性 automation(**`scheduledAt` = 此刻 + 2~5 分钟**,见 §3.1.1)+ **在给用户的回复里用陈述句告知** | 门禁不过 ⇒ **不登记,改为告知"链条已暂停待拍板"**;陈述句三要素:约 2~5 分钟后自动开新会话 / **不用你操作** / 接续点 = X |
|
||||
| ② | **先过 §3.3 登记门禁** → 登记下一棒的一次性 automation(**`scheduledAt` = 此刻 + 5~8 分钟**,见 §3.1.1 铁律①;**同一时刻只挂一个**,铁律②)+ **在给用户的回复里用陈述句告知** | 门禁不过 ⇒ **不登记,改为告知"链条已暂停待拍板"**;陈述句三要素:约 5~8 分钟后自动开新会话 / **不用你操作** / 接续点 = X |
|
||||
| ③ | 把入口文件 §2「🎯 本轮动作」**推进到再下一棒** | 入口 = 下一棒的**第一信息源**;不推进 ⇒ 下一棒照旧口径做,做重工 |
|
||||
| ④ | 写工作区日志(当日 `memory/YYYY-MM-DD.md` 追加自己的小节) | 只追加自己的小节,⛔ 不重写别人的段落 |
|
||||
|
||||
### 3.1 收尾陈述句模板(实测原文,照抄)
|
||||
|
||||
```text
|
||||
已登记自动接续:一次性 automation `<id>`,约 5 分钟后(08:37)自动开新会话,不用你操作;
|
||||
已登记自动接续:一次性 automation `<id>`,约 5~8 分钟后(08:37)自动开新会话,不用你操作;
|
||||
接续点 = 序 ④「443/TCP 兜底」的规划棒(出 `交接单_443兜底_20260917.md`,只出单、不改服务器)。
|
||||
|
||||
收口:锁 抢 ✓ → 释放 ✓(08:32)|未 commit / 未 push|入口 §0/§2 已刷到「③ 已完成 → 下一棒 ④」|产出物已交付。
|
||||
@@ -119,12 +120,30 @@ agent_created: true
|
||||
|
||||
**⛔ 只登记不告知 = 缺陷**:新建会话是**用户可感知的状态变更**。实测:`408636f2` 登记了自动化却一字未提,用户两小时后自己发现才追问。
|
||||
|
||||
#### 3.1.1 🔴 间隔纪律:`scheduledAt` = 收口时刻 **+ 2~5 分钟**(2026-09-17 用户追问后定)
|
||||
#### 3.1.1 🔴 排期两条铁律:**首个(也是唯一的)接续棒** = 收口 + **5~8 分钟**;⛔ **同一时刻只挂一个**(2026-09-18 用户明令定稿)
|
||||
|
||||
- **实测反例**:序⑦ 执行棒 12:2x 收口,把下一棒定在 **12:50**(留 ~25 min)⇒ 用户 12:26 直接追问「**为什么要等20多分钟才执行接续会话**」。当时的自我理由是「给用户留一个在本会话追改的窗口」+「让旧锁自然陈旧」——**两条都站不住**:锁在收尾 ① 里**已经释放**(不存在"等锁陈旧"),而"追改窗口"等价于**主动制造 20 分钟空转**。
|
||||
- **判据**:收口那一刻,链条上**没有任何"要等的对象"** ⇒ **等待时间越短越好**(2~5 min 只用于避开调度器的最小提前量与文件落盘竞态)。
|
||||
- **唯一允许拉长的情形**:下一棒**明确要等一个外部窗口**(对方服务重启完 / 另一条棒在跑 / 用户拍板)⇒ 可以拉长,但**必须在陈述句里写明在等什么**。
|
||||
- ⛔ **不许把"给用户留追改窗口"当理由** —— 用户要的是**尽快推进**,追改可以在任何一轮直接打断。
|
||||
> 用户 2026-09-18 原话:「**首个接续任务 5-8分钟**」+「**最好不要建立多个接续任务,一个会话结束时在排下一个**」
|
||||
|
||||
- **铁律①(间隔)**:`scheduledAt` = **收口时刻 + 5~8 分钟**。⚠️ 这 5~8 分钟是「**从本会话收口,到那"唯一一个"接续棒开跑**」的间隔 —— ⛔ **不是"棒与棒之间的间隔"**,后者根本不存在(由铁律②,任何时刻只该有一个待跑接续棒)。
|
||||
- **铁律②(唯一)**:**同一时刻只挂一个接续棒**,下一棒**只能由"正在收官的那一棒"自己排**。⛔ **禁止预登记队列 / 堆叠**("我先把后面两棒都排上" = 违规)。
|
||||
- **后续项不会丢**:把它写进入口文件 §2 的 **「⏭️ 本线下一项(⛔ 本棒不预登记)」** 行(含要点 / 根因 / 验收基线),**由当前那一棒收官时照此立棒**。
|
||||
|
||||
**边界(哪一头都不能越)**
|
||||
|
||||
| 方向 | 判据 |
|
||||
|---|---|
|
||||
| 下限为何是 5(不是 2) | 避开调度器最小提前量与文件落盘竞态 |
|
||||
| 上限 8 何时可越 | ⛔ 只有「**要等一个外部窗口**」才允许拉长(对方服务重启完 / 另一条棒在跑 / 用户拍板),且**必须在陈述句里写明在等什么** |
|
||||
| ⛔ 不许的两条理由 | 「**给用户留追改窗口**」(追改可在任何一轮直接打断 ⇒ 等价于主动空转)· 「**怕它跑不完**」(**排期按实测基线算,不按猜不确定性算**:规划棒实测只需 **6–13 分钟**,序⑦/⑨/⑪/⑯/⑱/㉔) |
|
||||
|
||||
**实测事故 2026-09-18(一棒之内两处都犯过 ⇒ 本节因此重写)**
|
||||
|
||||
| # | 我做了什么 | 用户原话 | 性质 |
|
||||
|---|---|---|---|
|
||||
| ① | ㉘ 规划棒排到 **收口 + ~2 h**,又给 ㉙ 留 **1.5 h 余量** | 「为什么时间要定在3:00」→「㉘ 规划棒 = 01:30 **也还有1个多小时呢**」 | 违反铁律①:长空转 + **用"猜不确定性"代替实测基线** |
|
||||
| ② | 用户说「**5-8分钟即可**」后,我把它读成 **"棒与棒之间的间隔"**(㉘→㉙ = 8 分钟),于是**同时挂了 ㉘ + ㉙ 两个接续棒** | 「我说的是**首个**接续任务 5-8分钟,**最好不要建立多个接续任务,一个会话结束时在排下一个**」 | 违反铁律②:预登记队列。**根因 = 改规则时只在旧句子上换了个数字,没有回到本节核对规则的完整定义** |
|
||||
|
||||
⇒ **判据**:任何一次"排期调整"都要**回到本节逐条对照两条铁律**;⛔ 不许只换数字就交差 —— 数字与"口径落在哪个对象上"会一起漂移。
|
||||
|
||||
#### 3.1.2 🔴 下一棒的 **automation id 只能来自工具返回值**(2026-09-17 实测踩坑)
|
||||
|
||||
@@ -174,7 +193,7 @@ agent_created: true
|
||||
|
||||
---
|
||||
|
||||
## 4. 五条实测防护(都是真踩过的)
|
||||
## 4. 六条实测防护(都是真踩过的)
|
||||
|
||||
| # | 现象 | 后果 | 处置 |
|
||||
|---|---|---|---|
|
||||
@@ -182,7 +201,8 @@ agent_created: true
|
||||
| ② | **双开 / 重复登记** | 同一份活被跑两遍,白烧一轮 | 见 §3.2(登记前先看有没有在跑的) |
|
||||
| ③ | **once 型 automation 跑完不自动转完成态** | 列表里堆积"已过期但 ACTIVE"的一次性任务;调度器补跑窗口 **12 小时** ⇒ 理论上可能被扫到、**多开一个会话** | 实测 09-17:列表里躺着 4 条过期仍 ACTIVE 的 once 型任务。处置:**保持原样**(不动既有配置)或**设为暂停**;⛔ 不要用 shell 去改库 |
|
||||
| ④ | **自动跨过"需要拍板"的点** | 拍板未定就跑,**要等用户自己发现**(已有实测事故 §3.3.1) | **要拍板的,等拍了再登记**(§3.3 门禁) |
|
||||
| ⑤ | **下一棒 `scheduledAt` 拉太长**(实测 ~25 min) | 链条白白空转,**用户当场追问** | 实测:序⑦执行棒 12:2x 收口、下一棒排 12:50 ⇒ 用户 12:26 追问「**为什么要等20多分钟才执行接续会话**」。⇒ 修法 = §3.1.1:**= 收口时刻 + 2~5 分钟** |
|
||||
| ⑤ | **下一棒 `scheduledAt` 拉太长**(实测 ~25 min,甚至 ~2 h) | 链条白白空转,**用户当场追问** | 实测:序⑦执行棒 12:2x 收口、下一棒排 12:50 ⇒ 用户 12:26 追问「**为什么要等20多分钟才执行接续会话**」;09-18 又排过「收口 + ~2 h」。⇒ 修法 = §3.1.1 铁律①:**= 收口时刻 + 5~8 分钟**,且**按实测基线算**(规划棒 6–13 分钟) |
|
||||
| ⑥ | **预登记多个接续棒**(队列堆叠) | 链条上挂着 ≥2 个待跑棒 ⇒ 抢锁空转;后续项要么白烧要么被撤,**用户当场纠正** | 实测 09-18:㉗ 棒同时挂了 ㉘+㉙ 两条 ⇒ 用户原话「**最好不要建立多个接续任务,一个会话结束时在排下一个**」。⇒ 修法 = §3.1.1 铁律②:**同一时刻只挂一个**;后续项写进入口 §2 的「⏭️ 本线下一项(⛔ 本棒不预登记)」,由当棒收官时立棒 |
|
||||
|
||||
---
|
||||
|
||||
@@ -231,7 +251,7 @@ agent_created: true
|
||||
1. **建入口文件** `接续入口_<线名>_<日期>.md`,把状态、定序、`§2「🎯 本轮动作」块` 写进去
|
||||
2. **让 `state.py` 能读到它**(状态脚本的 `[入口]` 段只展开入口 §2 ⇒ 钉在 §2 顶部才有用)
|
||||
3. **定序**:把整条线切成「规划棒①→执行棒①→规划棒②→…」,并**写进入口 §0**
|
||||
4. **起第一棒**:`automation_update` 建一次性 automation(`+2~15 分钟`),prompt 照 §2 骨架填
|
||||
5. **每棒收尾走完 §3 四件套**(其中第 ② 件**前置 §3.3 登记门禁**)—— 推进 §2 + 登记下一棒
|
||||
4. **起第一棒**:`automation_update` 建一次性 automation(`+5~8 分钟`,见 §3.1.1 铁律①),prompt 照 §2 骨架填
|
||||
5. **每棒收尾走完 §3 四件套**(其中第 ② 件**前置 §3.3 登记门禁**)—— 推进 §2 + 登记下一棒;🔴 **同一时刻只挂一个接续棒**:本棒只排"下一棒"一棒,后续项写进入口 §2 的「⏭️ 本线下一项」行,⛔ 不预登记队列
|
||||
6. **收口**:链条跑完时,最后一棒不登记下一棒,改为**明确告知用户"链条已完结"**
|
||||
7. **遇到拍板点**:停在「待你拍板」节(候选竖排 + 优缺点 + 我的倾向),**并明确告知链条已暂停**;等用户拍板后再由当时会话登记下一棒
|
||||
@@ -22,6 +22,9 @@
|
||||
| `T06-模型设置页-多厂家条目可开关.md` | ✅ **已完成并归档**(2026-09-13 23:5x,`craft-session-T06`) | `—`(已释放) | 平台自建「设置 → **模型设置**」:条目**各自开关、可同时启用** + 官方「模型」分区对全角色隐藏 + spawn 时把「已启用条目」落地到实例 `.credentials.yaml` / `settings.yaml` | **代码** `src/db/*`、`src/web/{model-landing.ts,server.ts,routes/auth.ts}`、`ensure-role-profile-patch.cjs`、`poc/business-plugins`(**0.3.11**) + `systemctl restart dshs` + `ensure-biz-plugins --all --restart`;**文档** `README`/`INDEX`/`03-路线图` | ✅ 无阻塞(口径用户已定);证据与判据见 **`04-87`**;⚠️ 本轮**顺手修掉两颗雷**:角色补丁脚本的整文件覆盖会抹掉 admin 另两个平台块、`verify-mem-model` 的陈旧断言 |
|
||||
| `T07-内置dsh安装路径探测.md` | ✅ **已完成并归档**(2026-09-14 05:0x,`craft-session-installpath` + `craft-session-tailclear`) | `—`(已释放) | 修 **P1 静默失效**:三处把内置 dsh 安装目录写死 ⇒ 在 `npm root -g` = `/usr/lib/node_modules` 的发行版上,厂家目录读空 / 兼容性预检安全网失效 / 目录选择器 import 抛错 | **代码** 新增 `src/web/dsh-install.ts` + 三处调用点(含 `poc/workspace-scoped-picker`)+ 插件 `business-plugins` **0.3.13** / `workspace-scoped-picker` **0.1.5** + build/restart/铺发;**文档** `04-88` + `README` 补 3 个 env | ✅ 无阻塞;**由开源导出会话提出**(它抢不到锁按 R9 停手),源仓独立复核后经用户「确认修改」落地。⚠️ 复核时**发现提出方漏了第 3 处**、且其 env 名是导出侧的 ⇒ 均已纠正 |
|
||||
| `T08-集群化落地-兼容单例模式.md` | ✅ **已完成并归档**(2026-09-15 18:0x,`exec-cluster-1a`) | `—`(已释放) | 把平台改造成「1 组 Manager(≥2 台,也支持单活)+ N 台 Worker + 共享归属状态」的集群形态;**硬约束 = 全程兼容单例模式** + 每步可单独回滚。**证据**:S0–S7 全绿(冒烟 6/8 与开工基线相同 · 5 个端到端 · lease 单测两后端 10/10)|**真跨机演练**(47 Manager / 106 Worker,跨云)✅|**域名形态访问** ✅|**2026-09-15 17:4x 生产整体切换**(47=Manager+本地 Worker w-47、106=Worker w-106、控制面库=47 的 PG13;存量用户留 w-47、新用户落 w-106;**回滚=删 drop-in**)。⚠️ **残留小项**(已登记 `03-路线图 §二`):`join-worker.sh` 一键装机 · 隧道服务化(心跳重建)· 集中日志/metrics · `smoke-domain` 定性。详见 §9–§16 | **代码**(`src/supervisor/`、`src/db/`、`src/cli.ts`、`src/fs/`)+ **服务器**(**106 另起一套**测试环境;**47 不动**)+ **文档**(本单 + 完工时的 `04-调整方案/101`) | 设计单一来源 = 项目根 `集群化改造方案_Manager-Worker_20260914.md`(19 节);**决策 D1–D5 已定**(双活+支持单活 / 存储可插拔 / 自建 PG / 跨云只当测试床 / 测试环境用 106);⏳ **仅 D6「生产拓扑最终落点」需用户拍板**,且**不阻塞 S0–S5** |
|
||||
| `覆盖网络-序24-内容分发块级寻址.md` | ⏳ **待执行**(2026-09-17 20:4x 立单) | 🔄 已登记 automation `91251b14-9ee8-42a9-9d89-8559b7af75ed`(**2026-09-17 20:42** 起) | 首屏包冷启动改造:**块级内容寻址 + 同网段 peer 优先**(内容源优先级链 本地→同网段 peer→边缘缓存→分发点→公网源)。**主判据 `E1` = 版本发布时回源字节数 ≈ 1 份 × 组数**。🔴 **必须块级,⛔ 绝不做包级**(包级 = 版本一发即全量重拉风暴) | **代码** `src/net/relay/content/{chunker,store,peer,source}.ts` + `index.ts`/`web/server.ts`/`scripts/overlay-probe.cjs`/参数表;**文档** 本单 §8 | 用户拍板 2026-09-17:「**B 内容分发(块级内容寻址)是否立项:做**」;依据 `覆盖网络_瓶颈落地方案_20260916.md §3`;**§7 前缀 `49d0f405e08c909e18ba6825d1442b9d`** |
|
||||
| `覆盖网络-序25-实例逐步拉起.md` | ⏳ **待执行**(2026-09-17 20:4x 立单;**待 序㉔ 收口时登记下一棒**) | ⛔ 未登记(等 序㉔ 收口) | Manager(portal)重启后**逐步接管既有实例**,而不是启动即清空。⚠️ **关键事实**:`orchestrator.ts:208` 构造函数里 `cleanAllStaleScopes()` ⇒ 现在**portal 一启动就把全部实例 scope 清掉** ⇒ 本单 = 把「清空」换成「接管」。**主判据 `E1` = 重启后实例数不变** | **代码** `src/supervisor/orchestrator.ts`(`cleanAllStaleScopes` / `cleanStaleScopes` 一带);**文档** 本单 §8 | 用户拍板 2026-09-17:「**Manager 重启后是否自动拉起既有实例:逐步拉起**」;三条硬约束(⛔ 不许删 `cleanStaleScopes(uid)`/⛔ 不许改成"什么都不做"/⛔ 不许"重启后重新 spawn 一遍");**§7 前缀 `d9d48121e68faa00e1da17ad8fea36ad`** |
|
||||
| `覆盖网络-序26-骨干稳定选路与加密.md` | ⏳ **待执行**(2026-09-17 20:4x 立单;**待 序㉕ 收口时登记下一棒**) | ⛔ 未登记(等 序㉕ 收口) | 骨干节点服务范围落地:**连接稳定高效**(jitter 选路 + 2–3 候选路径 + 中继余量 30%+ + ≤10 成员全互联)+ **数据安全可加密传输**(TLS 已在 + 签名/哈希完整性 + 元数据最小化)。**主判据 `E1` = jitter 更低但 RTT 更高的候选被选中** | **代码** 新增 `src/net/relay/jitter.ts` + `directory.ts`/`switcher.ts`(只加"jitter 劣化即切",⛔ 不改冷却语义)/`server.ts`/`scripts/overlay-jitter.cjs`/参数表;**文档** 本单 §8 | 用户拍板 2026-09-17:「**入口 §4 骨干节点的服务范围:按照连接稳定高效的方式 数据安全可加密传输**」;判定 = **A 起步、口径按 B 的质量标准建设**;**§8 前缀 `dbcbe633aa1aef92f4c35c77fad3ec11`** |
|
||||
|
||||
> **🔒 占用怎么声明(2026-09-12 新增,防两会话撞车)**:开工前先**原子占位** ——
|
||||
> `mkdir 交接单/.doing-<单号>`(`mkdir` 原子:**成功=你拿到;报 File exists=已有人在做 → 停手,别开工**),
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
# 交接单 · 内容分发(块级内容寻址 · 同网段 peer 优先)
|
||||
|
||||
- **序号**:覆盖网络线 **序 ㉔ · 规划棒**
|
||||
- **立单**:2026-09-17 20:3x
|
||||
- **用户拍板**:**「B 内容分发(块级内容寻址)是否立项:做」**(2026-09-17 20:2x)
|
||||
- **上游依据**:`覆盖网络_瓶颈落地方案_20260916.md` **§3**(照抄"内容分发三件套"+验收判据)/`覆盖网络_应用场景与待完善清单_20260916.md` **§五 第 7 步**/`覆盖网络_千台全场景推演_20260916.md`
|
||||
- **状态**:**待执行**(执行棒按本单 §4 顺序开工,⛔ 无须再出规划单)
|
||||
- **⚠️ 用户新增口径**(见 §7):**传输必须"连接稳定高效 + 数据可加密"** ⇒ 本单的传输面按此定档
|
||||
|
||||
---
|
||||
|
||||
## §0 摘要
|
||||
|
||||
把 **10.8 GB/次的首屏包冷启动**(瓶颈榜第 3 项,也是版本发布风暴的第 5/9 项成因)从「每台设备各自回源」改成「**块级内容寻址 + 同网段 peer 优先**」。**一次投资同时治 #3 / #5 / #9 三项瓶颈**(上游口径:三件套覆盖最大三个瓶颈,且**都不需要改传输协议**)。
|
||||
|
||||
**核心判断(一句话)**:**必须做"块级 + 内容寻址",⛔ 不做"包级"。** 这是 BranchCache(块级)vs Peer Cache(包级)的分水岭 —— 包级必须完整下载完才能当 peer 源,**版本一变全部 peer 源同时失效 ⇒ 客户端集体回源 = "版本一发就全量重拉"的风暴成因**(本线已实证过一次)。
|
||||
|
||||
**验收判据(单值可测)**:**版本发布时回源字节数 ≈ 1 份 × 组数**(而不是 1000 份)—— 局域网内多台设备**只回源一次**。
|
||||
|
||||
---
|
||||
|
||||
## §1 目标(可判定"做完了没有")
|
||||
|
||||
| # | 判据 | 期望 | 怎么测 |
|
||||
|---|---|---|---|
|
||||
| **E1** | 回源放大比 | **≈ 1 份 × 组数**(同组 N 台设备只回源 1 份) | 同组内 4 台本地多实例同时拉同一版本 ⇒ 统计源侧出向字节数 |
|
||||
| **E2** | 只拿到一部分也能开始共享 | 下载 30% 即产生可服务的块 | 中断后另一台从该 peer 能取到已持有块 |
|
||||
| **E3** | 版本更新只传变化块 | 变化 5% 的版本 ⇒ 传输量 ≤ 变化块量 × 组内台数 | 改一个文件重打包 ⇒ 对比传输字节数 |
|
||||
| **E4** | 客户端校验哈希 | 篡改块 ⇒ 丢弃并回源,⛔ 不落盘 | 故意改一个块的字节 ⇒ 断言 `hash mismatch` 且回源 |
|
||||
| **E5** | 分组隔离 | 跨组**不**互相穿透(⛔ 不出现 A 组从 B 组取块) | 两组并存 ⇒ 断言跨组 0 命中 |
|
||||
| **E6** | 内容源优先级可观测 | 每次取块**点名**来源档位(`local` / `peer` / `edge` / `origin`) | 判别器计数(⛔ 不许只写日志) |
|
||||
| **E7** | 零回归 | `npm test` **176/175/0/1**、`--scene all --table` **12P/0S/0F**、`overlay-probe --table` **16P/0F/0S** | 三件套跑同值 |
|
||||
|
||||
---
|
||||
|
||||
## §2 只读前置(执行前**必须**先核实的 5 条;⛔ 不许靠推断)
|
||||
|
||||
| # | 要核实什么 | 命令 | 期望 |
|
||||
|---|---|---|---|
|
||||
| **P1** | 首屏包实际形态与大小 | `ls -l` 目标产物 + `du -sh` | 确认 10.8 GB/次 的口径(**是"一份包"还是"N 个文件"**)⇒ 直接决定块大小 |
|
||||
| **P2** | 当前回源路径(几台设备各自回源) | 平台侧出向流量 + 实例启动日志 | 现状 = 每台各自回源(**这是本单的 Before 基线**) |
|
||||
| **P3** | 现有"同网段"判定手段 | 47 / 106 的内网地址段 | 当前只有 2 台真机(47 / 106,**跨云不同网段**)⇒ **同网段 peer 只能在"本机多实例"上验证**(用户已拍板"本机内存大可以模拟多台") |
|
||||
| **P4** | 已加载走 304 的能力 | 平台代理层 | 上游已确认"平台已有此能力"(`瓶颈落地方案 §3.6`)⇒ ⛔ 不重做 |
|
||||
| **P5** | 存储与内存预算 | `df -h` / 空闲内存 | 块存储放哪、peer 缓存上限多少(⚠️ 参考 `MEM_PER_HOST_MB` 现测 **0.06**,块缓存要另算) |
|
||||
|
||||
---
|
||||
|
||||
## §3 范围
|
||||
|
||||
### 3.1 在册文件集(⚠️ **超出此集必须先停下报告** — R7)
|
||||
|
||||
| 面 | 文件 | 说明 |
|
||||
|---|---|---|
|
||||
| 新增 | `src/net/relay/content/chunker.ts` | 块级切分(固定块 + 内容哈希) |
|
||||
| 新增 | `src/net/relay/content/store.ts` | 内容寻址存储(哈希 → 块;含校验) |
|
||||
| 新增 | `src/net/relay/content/peer.ts` | 同网段 peer 发现与取块 |
|
||||
| 新增 | `src/net/relay/content/source.ts` | 内容源优先级链 |
|
||||
| 新增 | `test/overlay-content.test.mjs` | 单测(⛔ 不改 `package.json` 的 test 列表 ⇒ 需与既有 13 个测试文件一致的追加方式) |
|
||||
| 改动 | `src/net/relay/index.ts` | 仅导出 |
|
||||
| 改动 | `src/web/server.ts` | 仅装配(⛔ 不动 presence / 端点翻译既有逻辑) |
|
||||
| 改动 | `scripts/overlay-probe.cjs` | 新增观测项 + 阈值键 |
|
||||
| 改动 | `参数表_覆盖网络_20260917.md` | 新增 `CONTENT_*` 键 |
|
||||
|
||||
⛔ **不在本单范围**:房间层、打洞实现、游戏服、改传输协议、改 `switcher.ts` 冷却语义、删 `/status` 兜底路径。
|
||||
|
||||
### 3.2 顺带治好的既有瓶颈(⛔ 但不扩范围)
|
||||
|
||||
| 瓶颈榜 | 项 | 本单如何覆盖 |
|
||||
|---|---|---|
|
||||
| #3 | 首屏包冷启动 10.8 GB | 主目标 |
|
||||
| #5 | (同族:版本发布风暴) | 块级 ⇒ 只传变化块 |
|
||||
| #9 | 版本碎片 | 与 #3 共用一套内容寻址机制(版本包走同一条链) |
|
||||
|
||||
---
|
||||
|
||||
## §4 步骤 S0–S7(每步自带**一次可执行的验证**)
|
||||
|
||||
> ⚠️ 每步做完**立即验证**,⛔ 不许"全部写完再验"。
|
||||
|
||||
| 步 | 做什么 | 验证(一次可执行) | 回滚 |
|
||||
|---|---|---|---|
|
||||
| **S0** | 只读前置 `P1–P5` + 基线采样(**零改动**) | 输出 Before 回源字节数(= E1 的分母) | 无(只读) |
|
||||
| **S1** | 块级切分 + 内容寻址存储(`chunker.ts` / `store.ts`) | 对同一份内容切两次 ⇒ **块哈希序列完全一致**;改 1 字节 ⇒ **只有 1 块变化** | 删新增文件 |
|
||||
| **S2** | 客户端校验(`E4`) | 篡改块 ⇒ 断言 `hash mismatch` + 丢弃 + 回源 | 同上 |
|
||||
| **S3** | 内容源优先级链(`source.ts`)+ **判别器计数**(`E6`) | 夹具:四档各命中一次 ⇒ 计数逐档递增 | 同上 |
|
||||
| **S4** | 同网段 peer 发现与取块(`peer.ts`)+ 分组(`E5`) | 本机多实例(N ≥ 4):**先让 A 拉完,再让 B 拉 ⇒ B 从 peer 取** | 关 peer 开关 ⇒ 回 S3 行为 |
|
||||
| **S5** | 装配 + 观测(参数表 `CONTENT_*` + 探针新项) | 探针出一项 PASS/FAIL(**⛔ 阈值不许是脚本魔数**) | 还原装配 |
|
||||
| **S6** | 真机验收:`E1`(回源 ≈ 1 份 × 组数)+ `E2`(部分即可共享)+ `E3`(只传变化块) | 本机多实例 4 台同组同时拉同一版本 | 同 S4 |
|
||||
| **S7** | 收口(部署属 lane 内,**直接做**)+ 零回归三件套(`E7`) | 三件套跑同值 | 产物回滚点 |
|
||||
|
||||
---
|
||||
|
||||
## §5 验收判据 E1–E7
|
||||
|
||||
见 **§1**。⚠️ **`E1` 是唯一的主判据**:断它一句话 —— **"回源字节数 ≈ 1 份 × 组数"**。
|
||||
|
||||
---
|
||||
|
||||
## §6 回滚(两层,均秒级)
|
||||
|
||||
1. **装配级**(推荐):`src/web/server.ts` 的 content 装配块整段移除 → `npm run build` → scp `lib/` → `restart dshs` ⇒ 回到"每台各自回源"的旧行为(**新模块文件留着不加载 ⇒ 零副作用**)。
|
||||
2. **产物级**:scp 回滚点 `/opt/dsh/backups/seq24-<ts>/` 的 `lib/{web/server.js,net/relay/*.js}` → `systemctl restart dshs`。
|
||||
🔴 ⛔ **回滚路径里不许出现 `RELAY_FAILOVER_COOLDOWN_MS=0`**(该值看似合法、实际自锁)。
|
||||
|
||||
---
|
||||
|
||||
## §7 传输面定档(**用户本棒新增口径**:连接稳定高效 + 数据可加密)
|
||||
|
||||
用户原话(2026-09-17 20:2x):**「按照连接稳定高效的方式 数据安全可加密传输」** ⇒ 本单的传输面按此定档,**属已定项、⛔ 不再上抛**:
|
||||
|
||||
| 档 | 我选什么(可推翻) | 理由 |
|
||||
|---|---|---|
|
||||
| **传输载体** | **复用既有自研 relay 通道**(`via='relay'` 回环落点 + wss 为主、443/TCP 兜底),⛔ **不新开公网端口** | 已端到端验收(序㉓ E2E 通过);"稳定"靠已有的**失败自动切流 + 冷却语义 + 一跳豁免** |
|
||||
| **传输加密** | **peer 取块走既有 wss(TLS)**;**跨机块传输再加一层内容级校验(哈希)** ⇒ 机密性 + 完整性**双保** | 「数据安全可加密」= ① 传输加密(TLS 已在)② **内容完整性**由哈希兜住(`E4`)⇒ 即使中间节点被控也**改不了块** |
|
||||
| **端到端加密** | **本阶段不做**(⛔ 不引入第二套密钥体系) | 会与"内容寻址 + 跨 peer 共享"**直接冲突**(端到端加密 ⇒ 每个接收者密文不同 ⇒ 无法按哈希共享块)⇒ **要加密就失去共享**,属真取舍;本阶段取"共享优先 + TLS + 哈希校验",把 E2E 登记为**待评估**(见 §9) |
|
||||
| **稳定性指标** | 选路按 **jitter 排序⛔ 不按 RTT**(上游 §4 口径)+ 每连接保 2–3 条候选路径 | 「连接稳定高效」的机器判据 = **每连接 jitter 直方图**(超阈值切路径) |
|
||||
|
||||
---
|
||||
|
||||
## §8 回报格式(执行会话**必须**回填)
|
||||
|
||||
```markdown
|
||||
### 8.x 序 ㉔ 执行棒回报(YYYY-MM-DD HH:MM–HH:MM)
|
||||
|
||||
#### ① 各步结果(S0–S7,逐条给"命令 + 原文输出 + 判定")
|
||||
|
||||
#### ② 主判据 E1:回源字节数 ≈ 1 份 × 组数
|
||||
- 组内台数 = N;实测回源字节 = X;放大比 = X / 一份大小 = ?
|
||||
|
||||
#### ③ 先红后绿(原文级)
|
||||
- (去掉某一档 ⇒ 哪条用例变红;改回 ⇒ 转绿)
|
||||
|
||||
#### ④ 零回归三件套(均带 `--table`)
|
||||
| 项 | 结果 | 基线 |
|
||||
|
||||
#### ⑤ 边界自证
|
||||
⛔ 未改任何生产值 / ⛔ 未新增公网监听口 / ⛔ 未改 nft·nginx / 🔴 `COOLDOWN_MS=0` 计数 = ? / ⛔ 未 commit·未 push
|
||||
|
||||
#### ⑥ 指纹
|
||||
参数表 = ?(前值 `42238175d84319ada99afa56d583f9db`)|探针 = ?|代码面各文件 md5 = ?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §9 回头条件(**一出现必须回头**;⛔ 不许自行扩范围、⛔ 不许调生产值去凑)
|
||||
|
||||
1. 要做"**包级**"(而非块级)⇒ **立即停下** —— 那正是版本风暴的成因(本线已实证)。
|
||||
2. 需要**超出 §3.1 文件集** ⇒ 停下报告(R7)。
|
||||
3. 要**新增公网监听口 / 改 nft·nginx** ⇒ 停下报告(R5)。
|
||||
4. 要**动任何生产值**(`RELAY_FAILOVER_*` / `HB_SEC` / burst / `PRESENCE_*`)⇒ 停下报告。
|
||||
5. **`E1` 放大比跑不出"≈ 1 份 × 组数"**(例如 ≥ 2 份)⇒ 停下报告,⛔ 不许放宽判据凑绿。
|
||||
6. **要求"端到端加密"** ⇒ 属**真取舍**(加密即失去按哈希共享块)⇒ 停下上抛,⛔ 不许自行取舍。
|
||||
7. 零回归三件套任一退化 ⇒ 停下报告。
|
||||
8. 出现**静默放行**(判别器不计数、只写日志)⇒ 停下报告。
|
||||
9. 🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。
|
||||
|
||||
---
|
||||
|
||||
## §10 指纹与状态
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 本单 §7 之前正文前缀指纹 | **`49d0f405e08c909e18ba6825d1442b9d`**(口径 = `sed '/^## §7 /,$d' 交接单_内容分发块级寻址_20260917.md \| md5sum`) |
|
||||
| 参数表指纹(立单时) | **`42238175d84319ada99afa56d583f9db`** |
|
||||
| 代码仓 HEAD(立单时) | `04776af`(工作区 10 处未提交改动) |
|
||||
| 本单全文件 md5(立单时) | `3198288c8b0b102d43c87ca9a3a31cd2`(166 行) |
|
||||
| 本单状态 | **待执行** ⇒ 交**序 ㉔ 执行棒** |
|
||||
@@ -0,0 +1,162 @@
|
||||
# 交接单 · Manager 重启后「逐步拉起」既有实例
|
||||
|
||||
- **序号**:覆盖网络线 **序 ㉕ · 规划棒**
|
||||
- **立单**:2026-09-17 20:3x
|
||||
- **用户拍板**:**「Manager 重启后是否自动拉起既有实例:逐步拉起」**(2026-09-17 20:2x)
|
||||
- **上游依据**:档案 **30**(`dsh-server-docs/04-调整方案/30-编排器孤儿实例清理.md`)/序⑲ §8.8-1("按需拉起、无 reconciler"的实测)/序⑬ P3(`OBS-09` 因无实例而 SKIP)
|
||||
- **状态**:**待执行**
|
||||
|
||||
---
|
||||
|
||||
## §0 摘要 + ⚠️ 一条必须先说的反直觉事实
|
||||
|
||||
用户拍板 = **"逐步拉起"**(staggered rehydrate)。但**读源码发现:现在的架构与目标不是"缺一个 reconciler",而是"启动时主动清空"** ——
|
||||
|
||||
| 位置 | 现状 | 与目标的差距 |
|
||||
|---|---|---|
|
||||
| `src/supervisor/orchestrator.ts:208`(构造函数) | `this.cleanAllStaleScopes()` —— **portal 启动即清掉全部实例 scope** | 🔴 **这是"逐步拉起"的直接阻碍**:重启后 **N=0**,没有任何可接管的实例 |
|
||||
| `:1225` | `stopScopesByPrefix('dsh-', /^dsh-\d+-[0-9a-f]+\.scope$/)` | 清得**很干净**(连"哪些曾经在线"的信息一起丢了) |
|
||||
| `:1218` | `cleanStaleScopes(uid)` —— spawn 前清**同 uid** 名下的残留 scope | ⚠️ 这一条是**必要的**(档案 30 的根因:双实例共 profile ⇒ 写冲突)⇒ **⛔ 不许为了"逐步拉起"把它去掉** |
|
||||
|
||||
**根因链(档案 30 原文)**:实例真实生命周期在 **OS 层(systemd scope)**,而编排器**只靠内存 map 追踪** ⇒ 重启后 map 空 ⇒ 旧 scope 变**孤儿**(编排器不认识)⇒ 双实例共享 profile ⇒ session/settings 写冲突 ⇒ "模型连接异常"。当时的修法是"**统一清掉防孤儿**"。
|
||||
|
||||
⇒ **本单的核心判断**:**"逐步拉起"= 把"清空"换成"接管"** —— 启动时**不要清**,而是**扫描 OS 层既有 scope ⇒ 逐个回填进内存 map ⇒ 按节流逐个 probe/rehydrate**。⚠️ **前提是先有"可恢复的实例账本"**(否则"清"是唯一安全的做法)。
|
||||
|
||||
---
|
||||
|
||||
## §1 目标(可判定"做完了没有")
|
||||
|
||||
| # | 判据 | 期望 | 怎么测 |
|
||||
|---|---|---|---|
|
||||
| **E1** | 重启后实例**不被清掉** | `restart dshs` 后 5 s 内,重启前在跑的 scope **仍在** | 先起 2 个实例 ⇒ `restart dshs` ⇒ `systemctl list-units 'dsh-*.scope'` **仍为 2** |
|
||||
| **E2** | **逐个**(节流)接管,⛔ 不风暴 | 接管速率受限(`REHYDRATE_CONCURRENCY` / `REHYDRATE_STAGGER_MS` 阈值内) | 4 个实例 ⇒ 日志逐条时间差 ≥ 阈值;⛔ 无"同一秒 4 条" |
|
||||
| **E3** | 任一实例都是**原实例**(不是新起) | 接管后 `port` 不变、无新 scope 产生 | 对比重启前后的 scope 名与 `--port` 参数 |
|
||||
| **E4** | 单实例保证**仍成立**(⛔ 不回归档案 30) | 接管后同 uid **只有 1 个** scope;新 spawn 前仍清同 uid 残留 | 断言 `dsh-<uid>-*` 计数 = 1 |
|
||||
| **E5** | 无实例时**不自起**(⛔ 不违反"按需"语义) | 重启前**没有**实例 ⇒ 重启后仍为 0 | 空跑一次 `restart dshs` ⇒ scope = 0 |
|
||||
| **E6** | 内存/启动压力可控 | 接管过程 47 可用内存不跌穿阈值;无 OOM kill | `free` 采样 + `journalctl -u dshs \| grep -c 'oom'` = 0 |
|
||||
| **E7** | 零回归 | `npm test` **176/175/0/1**、`--scene all --table` **12P/0S/0F**、`overlay-probe --table` **16P/0F/0S** | 三件套跑同值 |
|
||||
|
||||
---
|
||||
|
||||
## §2 只读前置(执行前**必须**先核实的 4 条)
|
||||
|
||||
| # | 要核实什么 | 命令 | 期望 |
|
||||
|---|---|---|---|
|
||||
| **P1** | 实例 scope 与 uid 的对应 | `systemctl list-units 'dsh-*.scope' --plain` + 对照 `users` 表 | 确认 `dsh-<uid>-<id>.scope` 里 **`<uid>` = 用户 uid**(档案 30 口径),⛔ 别与"用户 id"混 |
|
||||
| **P2** | scope 的 `--port` 参数**重启后是否可读回** | `cat /proc/<pid>/cmdline` 或 `systemctl show -p MainPID` 后读 `/proc` | ⚠️ **这是可恢复性的关键**:拿不到端口 ⇒ 没法接管(要另想办法) |
|
||||
| **P3** | 47 上当前实例数(T0 现场) | `systemctl list-units 'dsh-*.scope'` | 序㉓ 实测 47 = **0**、106 = **1**(⚠️ 实例在 **106** 上)⇒ 本单验收要**主动先起实例** |
|
||||
| **P4** | 是否有"实例账本"可持久化 | 查 `RemoteSpawner` / `LeasedSpawner` 落库情况 | 若既无 DB 记录也无 /proc 可读 ⇒ **必须先补一步"实例账本"**(见 §4 S1 前置) |
|
||||
|
||||
---
|
||||
|
||||
## §3 范围
|
||||
|
||||
### 3.1 在册文件集(⚠️ **超出必须先停下报告** — R7)
|
||||
|
||||
| 面 | 文件 | 说明 |
|
||||
|---|---|---|
|
||||
| 改动 | `src/supervisor/orchestrator.ts` | ①② 启动流程:清空 → 接管;新增 `rehydrate()` |
|
||||
| 改动 | `参数表_覆盖网络_20260917.md` | 新增 `REHYDRATE_*` 键 |
|
||||
| 改动 | `scripts/overlay-probe.cjs` | 新增观测项(重启后 scope 数 = 重启前) |
|
||||
| 可能新增 | `test/orchestrator-rehydrate.test.mjs` | 单测(⛔ 不改 `package.json` test 列表的结构) |
|
||||
|
||||
⛔ **不在本单范围**:改 bwrap 参数(🔴 **47 是 bubblewrap 0.4.0**,`--perms` 属 0.5+ ⇒ 会起不来)、改 `cleanStaleScopes(uid)` 的"spawn 前清同 uid"语义、动 `RELAY_FAILOVER_*` / `HB_SEC` / burst。
|
||||
|
||||
### 3.2 三条硬约束(**违反即事故**)
|
||||
|
||||
1. 🔴 **`cleanStaleScopes(uid)`(spawn 前清同 uid)⛔ 不许删** —— 它是档案 30 的修法本体,删了就回到"双实例共 profile"。
|
||||
2. 🔴 **`cleanAllStaleScopes()` 只能改成"接管",⛔ 不能改成"什么都不做"** —— 因为内存 map 为空时,**孤儿会失控**(这正是档案 30 的原始故障)。
|
||||
3. 🔴 **接管必须"认原实例"** —— ⛔ 不许"重启后重新 spawn 一遍"(那会**换端口、换 scope 名**,且瞬间 N 个一起起 = 启动风暴)。
|
||||
|
||||
---
|
||||
|
||||
## §4 步骤 S0–S6
|
||||
|
||||
| 步 | 做什么 | 验证(一次可执行) | 回滚 |
|
||||
|---|---|---|---|
|
||||
| **S0** | 只读前置 `P1–P4`(**零改动**) | 拿到"scope 名 ↔ uid ↔ 端口"三者的可读性结论 | 无(只读) |
|
||||
| **S1** | **(可能需要)实例账本**:把"在线实例"持久化(⚠️ 归属判定:跟着用户走 ⇒ **放实例 home**;本机运维用 ⇒ **Worker 本地库**;⛔ 只有 Manager 能写归属/租约) | 重启后能列出"重启前在跑的实例"清单(含 uid / 端口) | 删账本文件 |
|
||||
| **S2** | **接管取代清空**:启动扫描 → 回填 map(⛔ 不 stop、⛔ 不 spawn) | `E1`:`restart dshs` 后 scope 数**不变** | 还原 `cleanAllStaleScopes()` 调用 |
|
||||
| **S3** | **节流**:`REHYDRATE_CONCURRENCY` / `REHYDRATE_STAGGER_MS` | `E2`:4 实例 ⇒ 日志时间差 ≥ 阈值、⛔ 无同秒多条 | 阈值调回 0 ⇒ 回 S2 行为 |
|
||||
| **S4** | **单实例保证复验**(⛔ 不回归档案 30) | `E4`:同 uid 恒 1 个 scope;`E5`:无实例时不自起 | 同 S2 |
|
||||
| **S5** | 观测 + 探针新项 | 探针出一项 PASS/FAIL(⛔ 阈值不许是脚本魔数) | 还原探针 |
|
||||
| **S6** | 真机验收(`E1`–`E6`)+ 零回归(`E7`)+ 收口 | `E6`:内存不跌穿、无 OOM;三件套同值 | 产物回滚点 |
|
||||
|
||||
---
|
||||
|
||||
## §5 真机验收怎么造条件的(⚠️ 关键)
|
||||
|
||||
⚠️ **不能只靠"等用户访问"**(本线已因"无 reconciler ⇒ 不自回"卡过一次)。验收必须:
|
||||
|
||||
1. **先主动起 2–4 个实例**(用 R4 临时 session 走真实 `enter`,或用本机多实例)⇒ 记录 scope 名 / uid / 端口;
|
||||
2. `systemctl restart dshs`;
|
||||
3. **立刻**(≤ 5 s)与 **+60 s** 两个时刻各取一次 `list-units 'dsh-*.scope'`;
|
||||
4. 断言 `E1`(数不变)/`E2`(逐条时间差)/`E3`(端口不变、⛔ 无新 scope)/`E4`(同 uid = 1)。
|
||||
|
||||
⚠️ **已知副作用**:`restart dshs` **会收掉用户实例 scope**(本线既有实测)⇒ 本单要**故意利用**这个副作用做 E1/E5 的对照(重启前有实例 → 应被接管;重启前无实例 → 应保持 0)。
|
||||
|
||||
---
|
||||
|
||||
## §6 回滚(两层)
|
||||
|
||||
1. **代码级**:还原 `orchestrator.ts` 的启动流程为原 `cleanAllStaleScopes()` 调用 → `tsc` → scp `lib/` → `restart dshs` ⇒ 回到"统一清掉防孤儿"(档案 30 行为)。
|
||||
2. **产物级**:scp 回滚点 `/opt/dsh/backups/seq25-<ts>/lib/supervisor/orchestrator.js`。
|
||||
🔴 ⛔ **回滚路径里不许出现 `RELAY_FAILOVER_COOLDOWN_MS=0`**。
|
||||
|
||||
---
|
||||
|
||||
## §7 回报格式(执行会话**必须**回填)
|
||||
|
||||
```markdown
|
||||
### 8.x 序 ㉕ 执行棒回报(YYYY-MM-DD HH:MM–HH:MM)
|
||||
|
||||
#### ① S0–S6 逐条(命令 + 原文输出 + 判定)
|
||||
|
||||
#### ② 主判据 E1:重启后实例数不变
|
||||
- 重启前 scope = ? | +5 s = ? | +60 s = ? | 端口是否全同 = ?
|
||||
|
||||
#### ③ 先红后绿(原文级)
|
||||
- (先跑"仍清空"的旧行为 ⇒ 哪条断言红;改成接管 ⇒ 绿)
|
||||
|
||||
#### ④ 零回归三件套(均带 `--table`)
|
||||
|
||||
#### ⑤ 边界自证
|
||||
⛔ 未改生产值 / ⛔ 未改 bwrap 参数 / ⛔ 未删 `cleanStaleScopes(uid)` / 🔴 `COOLDOWN_MS=0` = ? / ⛔ 未 commit·未 push
|
||||
|
||||
#### ⑥ 指纹
|
||||
参数表 = ?(前值 `42238175d84319ada99afa56d583f9db`)|orchestrator.ts md5 = ?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §8 回头条件(**一出现必须回头**)
|
||||
|
||||
1. `P2` 拿不到 scope 的端口 ⇒ **停下报告**("接管"不可行,需先出"实例账本"方案)。
|
||||
2. 接管导致**双实例共 profile**(档案 30 故障复现)⇒ 立刻回滚 + 报告。
|
||||
3. 需要**超出 §3.1 文件集** ⇒ 停下报告(R7)。
|
||||
4. 要**改 bwrap 参数 / 改配额 / 动生产值** ⇒ 停下报告。
|
||||
5. `E2` 跑不出节流(同秒多条)⇒ 停下报告,⛔ 不许放宽判据。
|
||||
6. 零回归三件套任一退化 ⇒ 停下报告。
|
||||
7. 🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。
|
||||
|
||||
---
|
||||
|
||||
## §9 未验证项
|
||||
|
||||
| # | 项 | 状态 |
|
||||
|---|---|---|
|
||||
| 1 | 重启后能否从 OS 层读回实例端口 | ⚠️ 待 `P2` 取证 |
|
||||
| 2 | 是否需要独立"实例账本" | ⚠️ 待 `P4` 取证 |
|
||||
| 3 | 接管 4 个实例的内存与启动耗时 | ⚠️ 待 S6 实测 |
|
||||
|
||||
---
|
||||
|
||||
## §10 指纹与状态
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 本单 §7 之前正文前缀指纹 | **`d9d48121e68faa00e1da17ad8fea36ad`**(口径 = `sed '/^## §7 /,$d' 交接单_实例逐步拉起_20260917.md \| md5sum`) |
|
||||
| 参数表指纹(立单时) | **`42238175d84319ada99afa56d583f9db`** |
|
||||
| 代码仓 HEAD(立单时) | `04776af` |
|
||||
| 本单全文件 md5(立单时) | `2c53a018c2d9bfc2c422d0758413a485`(161 行) |
|
||||
| 本单状态 | **待执行** ⇒ 交**序 ㉕ 执行棒** |
|
||||
@@ -0,0 +1,177 @@
|
||||
# 交接单 · 骨干节点落地(稳定高效选路 + 传输可加密)
|
||||
|
||||
- **序号**:覆盖网络线 **序 ㉖ · 规划棒**
|
||||
- **立单**:2026-09-17 20:3x
|
||||
- **用户拍板**:**「入口 §4 骨干节点的服务范围:按照连接稳定高效的方式 数据安全可加密传输」**(2026-09-17 20:2x)
|
||||
- **上游依据**:`覆盖网络_骨干层方案_20260916.md` **§7(原 A/B 待拍板)**/**§8 落地顺序**/`覆盖网络_瓶颈落地方案_20260916.md` **§4(jitter 是一等指标)**/`覆盖网络_补遗与参考方案_20260916.md`(45% 设计 / 55% 余量口径)
|
||||
- **状态**:**待执行**
|
||||
|
||||
---
|
||||
|
||||
## §0 摘要 + 我把用户口径翻译成的两条硬判据
|
||||
|
||||
用户**没有按 A/B 选**,而是给了一句**目标导向**的话:**「按照连接稳定高效的方式 数据安全可加密传输」**。
|
||||
|
||||
⇒ **我的解读(已定项,可推翻)**:用户要的不是"服务范围"这个二元选择,而是**两条可验证的工程质量判据**:
|
||||
|
||||
| 口径 | 翻译成机器判据 | 与 A/B 的关系 |
|
||||
|---|---|---|
|
||||
| **连接稳定高效** | **选路按 jitter 排序**(⛔ 不按 RTT)+ 每连接保 2–3 条候选路径 + 中继利用率留 **30%+** 余量 + 骨干间心跳 ≤10 成员全互联 | **与 A/B 正交** —— 无论自用还是全网,这条都要满足 |
|
||||
| **数据安全可加密传输** | ① 传输层加密(**wss/TLS 已在**,⛔ 不新造)② **内容/信令完整性由签名与哈希兜住**(本线已有 relay 签名目录 + 密钥体系)③ **对外只暴露"转发能力",⛔ 不暴露"看到谁连谁"的元数据** | **B 档的最大缺点正是"骨干会看到流量元数据"** ⇒ 用户这句**恰好把 B 档的最大代价按住了** |
|
||||
|
||||
✅ **因此我的判定(可推翻):按 "A 起步、口径按 B 的质量标准建设" 落地** —— 即 **§7 原倾向 A→B 渐进 与用户口径并不冲突**:
|
||||
- **可见范围**仍取 **A**(只服务自己名下设备):无计费/合规纠纷、权限面不变(⛔ 不命中 R5)、元数据暴露面最小 —— **这直接满足"数据安全"**;
|
||||
- **质量与冗余**按 **B 的标准**建设(多中心骨干、jitter 选路、30%+ 余量):**这直接满足"稳定高效"**;
|
||||
- **"可加密"** ⇒ 做成**能力就位**(TLS + 签名 + 内容哈希),**⛔ 不在本单引入端到端加密**(见 §7)。
|
||||
|
||||
---
|
||||
|
||||
## §1 目标(可判定"做完了没有")
|
||||
|
||||
| # | 判据 | 期望 | 怎么测 |
|
||||
|---|---|---|---|
|
||||
| **E1** | **选路按 jitter**(⛔ 不按 RTT) | 两候选路径中 jitter 更低者被选中,**即使其 RTT 更高** | 夹具:候选 A(RTT 20ms/jitter 15ms) vs B(RTT 30ms/jitter 2ms) ⇒ 断言选 **B** |
|
||||
| **E2** | **jitter 可观测** | 每连接有 jitter 直方图 + 超阈值自动切路径并**告警** | 判别器计数 + 直方图落盘 |
|
||||
| **E3** | **路径多样性** | 每连接维护 **2–3 条**候选(直连 / 就近中继 / 备用中继) | `/status` 可查候选数 ≥ 2 |
|
||||
| **E4** | **利用率留余量** | 中继利用率 ≤ **70%**(留 30%+) | `used / capacity` 可查、超限**拒绝新接入**(⛔ 不打满) |
|
||||
| **E5** | **骨干互认只校验不自行批准** | 控制面签发资格;骨干间只验签 | 未签名骨干接入 ⇒ 被拒并**点名** |
|
||||
| **E6** | **元数据最小化**(A 档) | 骨干**只知"转发给谁",不知"谁在连谁"**;跨用户**不可见** | 断言跨用户 0 命中(与内容分发的 `E5` 同族) |
|
||||
| **E7** | 零回归 | `npm test` **176/175/0/1**、`--scene all --table` **12P/0S/0F**、`overlay-probe --table` **16P/0F/0S** | 三件套跑同值 |
|
||||
|
||||
---
|
||||
|
||||
## §2 只读前置(执行前**必须**先核实的 5 条)
|
||||
|
||||
| # | 要核实什么 | 命令 | 期望 |
|
||||
|---|---|---|---|
|
||||
| **P1** | 现行 relay 是否**已**做到"只绑回环 + 443 兜底" | `ss -lntp` + relay ExecStart | 已实测:两台 relay 均**只绑 `127.0.0.1:20080`**、106 复用既有 443 ⇒ **零新增公网口**(⛔ 本单不许破坏这条) |
|
||||
| **P2** | 现行选路是**按什么排序** | 读 `src/net/relay/switcher.ts` / `directory.ts` | ⚠️ 预判:**按健康度/冷却**,**⛔ 不是按 jitter** ⇒ 这是本单的主要缺口 |
|
||||
| **P3** | jitter 现测值 | `scripts/overlay-jitter.cjs` | 已有脚本;序⑥ 实测 `p95(\|ΔRTT\|)` = **3 ms**(达标)⇒ **本单把"点测"变成"持续采样 + 参与选路"** |
|
||||
| **P4** | 骨干"资格"体系现状 | `scripts/overlay-keyring.cjs` + relay `keys` 表 | 已有四层密钥模型(离线根 → 在线签名者 → 每机节点密钥 → 会话)+ 逻辑名索引 + 成员资格校验 ⇒ **E5 大部分已就位** |
|
||||
| **P5** | 45% 容量口径现值 | 参数表 `RELAY_MAX_HOSTS` | 实测 **7515**(序⑥ 重算并已下发两台)⇒ 本单**只读不改**,⛔ 不动容量值 |
|
||||
|
||||
---
|
||||
|
||||
## §3 范围
|
||||
|
||||
### 3.1 在册文件集(⚠️ **超出必须先停下报告** — R7)
|
||||
|
||||
| 面 | 文件 | 说明 |
|
||||
|---|---|---|
|
||||
| 新增 | `src/net/relay/jitter.ts` | jitter 采样与直方图(**选路的输入**) |
|
||||
| 改动 | `src/net/relay/directory.ts` | 候选排序:健康度 → **jitter 为主序**(⛔ 不删既有冷却语义) |
|
||||
| 改动 | `src/net/relay/switcher.ts` | ⚠️ **只加"jitter 劣化即切",⛔ 不改冷却语义** |
|
||||
| 改动 | `src/net/relay/server.ts` | 利用率守卫(`E4`)+ 候选路径可查(`E3`) |
|
||||
| 改动 | `scripts/overlay-jitter.cjs` | 点测 → 持续采样 |
|
||||
| 改动 | `scripts/overlay-probe.cjs` | 新增 `OBS-17`(jitter)/`OBS-18`(余量) |
|
||||
| 改动 | `参数表_覆盖网络_20260917.md` | 新增 `JITTER_*` / `RELAY_UTIL_MAX_PCT` 键 |
|
||||
|
||||
⛔ **不在本单范围**:`RELAY_FAILOVER_*` 任何值、`HB_SEC`、burst、`switcher.ts` 冷却语义、`RELAY_MAX_HOSTS`、房间层、打洞实现、内容分发的块级实现(**另单**,见 `交接单_内容分发块级寻址_20260917.md`)。
|
||||
|
||||
### 3.2 三条硬约束
|
||||
|
||||
1. 🔴 **⛔ 不改 `switcher.ts` 冷却语义**(本线持久禁令)—— 只**新增** jitter 触发条件。
|
||||
2. 🔴 **⛔ 不新增公网监听口 / 不改 nft·nginx**(R5)—— 骨干仍只绑回环 + 443/TCP 兜底复用。
|
||||
3. 🔴 **骨干资格只能控制面签发**(权威状态单点 Manager)—— 骨干**只校验,不自行批准**。
|
||||
|
||||
---
|
||||
|
||||
## §4 步骤 S0–S6
|
||||
|
||||
| 步 | 做什么 | 验证(一次可执行) | 回滚 |
|
||||
|---|---|---|---|
|
||||
| **S0** | 只读前置 `P1–P5` + 基线 jitter 采样(**零改动**) | 输出 Before:现行选路按什么排序(**原文行号级证据**) | 无(只读) |
|
||||
| **S1** | jitter 采样与直方图(`jitter.ts`) | 夹具:喂 3 条已知 jitter 序列 ⇒ 直方图与 p95 **逐项可断言** | 删新增文件 |
|
||||
| **S2** | **候选排序改为 jitter 为主序**(`directory.ts`) | `E1`:**先红后绿**(jitter 更低但 RTT 更高的那条**必须被选中**) | 还原排序函数 |
|
||||
| **S3** | 切换条件新增"jitter 劣化即切"(`switcher.ts`,⛔ 不碰冷却) | `E2`:劣化 ⇒ 切 + 告警;⛔ 冷却语义断言**不变** | 移除新增条件 |
|
||||
| **S4** | 利用率守卫 + 候选可查(`server.ts`) | `E4`:利用率 > 阈值 ⇒ 拒绝新接入并**点名**;`E3`:候选数 ≥ 2 | 还原守卫 |
|
||||
| **S5** | 骨干互认与元数据最小化复验(`E5` / `E6`) | 未签名骨干被拒并点名;跨用户 0 命中 | 同 S2 |
|
||||
| **S6** | 真机验收 + 观测 + 零回归(`E7`)+ 收口 | 三件套同值;探针新增 2 项 PASS | 产物回滚点 |
|
||||
|
||||
---
|
||||
|
||||
## §5 验收判据 E1–E7
|
||||
|
||||
见 **§1**。⚠️ **`E1` 是主判据**("选路按 jitter 排序而非 RTT")—— 这一条**能不能机器断言**,决定了"连接稳定高效"是不是**嘴上说说**。
|
||||
|
||||
---
|
||||
|
||||
## §6 回滚(两层)
|
||||
|
||||
1. **排序级**:还原 `directory.ts` 的排序函数 + 移除 `switcher.ts` 新增条件 → `tsc` → scp `lib/` → `restart dshs` ⇒ 回到"按健康度/冷却"的旧选路。
|
||||
2. **产物级**:scp 回滚点 `/opt/dsh/backups/seq26-<ts>/lib/net/relay/{directory,switcher,server,jitter}.js`。
|
||||
🔴 ⛔ **回滚路径里不许出现 `RELAY_FAILOVER_COOLDOWN_MS=0`**。
|
||||
|
||||
---
|
||||
|
||||
## §7 安全与加密档位(**用户口径的关键落点**;属已定项、⛔ 不再上抛)
|
||||
|
||||
用户原话:**「数据安全可加密传输」**。逐条落法:
|
||||
|
||||
| 层 | 现状 | 本单怎么做 |
|
||||
|---|---|---|
|
||||
| **传输层加密** | ✅ **wss / TLS 已在**(relay 经 `https://alotbuy.com/dshs-relay` 可达、双路 101) | **复用,⛔ 不重造**。骨干之间同样只走 wss |
|
||||
| **身份与授权** | ✅ 四层密钥模型已落地(离线根 → 在线签名者 → 每机节点密钥 → 会话)+ 逻辑名索引 + 成员资格校验 + 吊销演练通过 | `E5`:**骨干间只校验,不自行批准**(补齐"骨干资格"这一档) |
|
||||
| **完整性** | ✅ 有签名目录 | 信令与目录**全程验签**;⛔ 不引入第二套密钥体系 |
|
||||
| **元数据最小化** | ⚠️ B 档的最大缺点是"看到谁连谁" | `E6`:**A 档可见范围** ⇒ 骨干**只知转发目标、不知连接双方**;跨用户不可见 |
|
||||
| **端到端加密(E2E)** | ⛔ **不做** | **属真取舍**:E2E 会让"每个接收者密文不同" ⇒ **与内容分发的按哈希共享块直接冲突**(要加密就失去共享)⇒ 本阶段取 **"TLS + 验签 + 内容哈希"**;E2E 登记为**待评估**(见 §9-3) |
|
||||
|
||||
🔑 **一句话**:**"可加密"= 能力就位(TLS + 验签 + 哈希)+ 元数据最小化**,⛔ **不是**"现在就上端到端加密"。
|
||||
|
||||
---
|
||||
|
||||
## §8 回报格式(执行会话**必须**回填)
|
||||
|
||||
```markdown
|
||||
### 8.x 序 ㉖ 执行棒回报(YYYY-MM-DD HH:MM–HH:MM)
|
||||
|
||||
#### ① S0–S6 逐条(命令 + 原文输出 + 判定)
|
||||
|
||||
#### ② 主判据 E1:jitter 更低(但 RTT 更高)的候选被选中
|
||||
- 候选 A = ? | 候选 B = ? | 实测选中 = ? | 原文 = ?
|
||||
|
||||
#### ③ 先红后绿(原文级)
|
||||
|
||||
#### ④ 零回归三件套(均带 `--table`)
|
||||
|
||||
#### ⑤ 边界自证
|
||||
⛔ 未改 `switcher.ts` 冷却语义 / ⛔ 未改生产值 / ⛔ 未新增公网口 / ⛔ 未改 nft·nginx / 🔴 `COOLDOWN_MS=0` = ? / ⛔ 未 commit·未 push
|
||||
|
||||
#### ⑥ 指纹
|
||||
参数表 = ?(前值 `42238175d84319ada99afa56d583f9db`)|directory.ts / switcher.ts / server.ts md5 = ?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## §9 回头条件(**一出现必须回头**)
|
||||
|
||||
1. 要**改 `switcher.ts` 冷却语义** ⇒ 停下报告(持久禁令)。
|
||||
2. 要**新增公网监听口 / 改 nft·nginx** ⇒ 停下报告(R5)。
|
||||
3. 要引入**端到端加密**(E2E)⇒ **属真取舍**(加密即失去按哈希共享块)⇒ 停下上抛。
|
||||
4. 要**改 `RELAY_MAX_HOSTS` / 45% 容量口径值** ⇒ 停下报告。
|
||||
5. 需要**超出 §3.1 文件集** ⇒ 停下报告(R7)。
|
||||
6. `E1` 跑不出机器断言 ⇒ 停下报告,⛔ 不许放宽判据凑绿。
|
||||
7. 零回归三件套任一退化 ⇒ 停下报告。
|
||||
8. 🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。
|
||||
|
||||
---
|
||||
|
||||
## §10 未验证项
|
||||
|
||||
| # | 项 | 状态 |
|
||||
|---|---|---|
|
||||
| 1 | 各网络类型实际占比(决定骨干数量需求) | ⚠️ 上游仍为推演设定 |
|
||||
| 2 | 骨干上行带宽是否够(家宽上行常远小于下行) | ⚠️ 上游未实测 |
|
||||
| 3 | E2E 加密与块级共享的取舍 | ⚠️ 本单**未做**,登记待评估 |
|
||||
|
||||
---
|
||||
|
||||
## §11 指纹与状态
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 本单 §8 之前正文前缀指纹 | **`dbcbe633aa1aef92f4c35c77fad3ec11`**(口径 = `sed '/^## §8 /,$d' 交接单_骨干稳定选路与加密_20260917.md \| md5sum`) |
|
||||
| 参数表指纹(立单时) | **`42238175d84319ada99afa56d583f9db`** |
|
||||
| 代码仓 HEAD(立单时) | `04776af` |
|
||||
| 本单全文件 md5(立单时) | `f85b86234c2ecfaef5b2e43aa40d86a3`(176 行) |
|
||||
| 本单状态 | **待执行** ⇒ 交**序 ㉖ 执行棒** |
|
||||
Reference in new issue
Block a user