Files
dsh_ai1net_server/接续入口_覆盖网络线_20260916.md
T
admin ce8e6ceed9 chore(工作区): 纳入版本控制基线(回收 411 MB 过程产物)
回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复:
- 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录)
- tmp/(32.4 M,按接续棒命名的过程临时区)
- .workbuddy/tmp/(39.5 M)
- 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物)
- tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留

入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与
接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、
.workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。

排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、
打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
2026-09-24 07:51:03 +08:00

465 lines
342 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 接续入口 · 覆盖网络线(2026-09-16)
> 🔴 **工作区**:E:/ProgramData/AIProject/aliyun-dsh-server —— 2026-09-21 加该字段,供 `state.py` 判定归属:头部该字段 ≠ 本工作区 ⇒ 判为「外来线」并排除出 §2 / 口令。
> **这是本工作线的唯一入口。** 新会话先读这一份(约 3 KB),再按需打开下面的文档。
> 详细过程记录在 `.workbuddy/memory/2026-09-16.md` 末尾的「会话接续包」——**不必先读那个 60 KB 日志**。
---
## 0. 当前状态(一句话)
> 🆕 **2026-09-19 07:5x 刷新(序㊿ 执行棒 · ✅ 旧域 `alotbuy.com` 已从项目移除(代码 / 服务端 / 文档技能三层)· ✅ 本线候选链 **5 → 3 条**(两机同源)· ✅ 探针 **29 PASS / 0 FAIL / 0 SKIP**(rc=0)· ⏹ 判定 =「本线可停」(⛔ **未登记下一棒**)· 🔴 唯一在册红仍 = **D8 云安全组**(待你控制台落地))**:**一句话 = 旧域从此不再作为候选入口存在** —— 🔴 **本行取代上一行的「5 条」口径**;删掉的两条是「**摘名不同、物理同落 47 同一路径**」的**伪多样性**(其中一条还开着 `ADDR_OVERRIDES` 直连 IP),**删除不减少真实冗余**。**① 唯一载体(未变)** = 47 drop-in `overlay-443fb.conf`:`SEEDS=https://ai1net.com/dshs-relay,https://relay-direct.ai1net.com/dshs-relay,https://106.54.21.172/dshs-relay` + `ADDR_OVERRIDES=relay-direct.ai1net.com=47.77.182.89`;106 `/etc/dshs-worker.env` 第 26 行同值(备份 `.bak-dompurge-20260919-073149`)。**② 🔴 本轮唯一"看不见的坑" = 二次重启控制面**:一次重启后 bootstrap **仍是 5 条** ⇒ 根因 = Manager 把**自己发布的签名目录**缓存在 `/var/lib/dshs/overlay/directory.json`(**可再生**、非配置)且**懒重建** ⇒ 备份 + 删除 + **再重启一次** ⇒ 得 **3 条 / 0 旧域**(`source=seed-directory`,缓存重建 **578 B**)。⛔ **日后改候选链别忘这一步**。**③ 一条"判据撒谎"型假红(已修)** = 演练 `--scene all` 报 **11P/1F**(红在幕4-A「目标不是 47 那台」)⇒ 实为**假红**:豁免**真生效、真切回 47**,只是脚本用**硬编码域名字符串**匹配端点 ⇒ 两处匹配器改读参数表 `DRILL_KILLED_MATCH`(⛔ 域迁移类改动**必须同步这个键**)。**④ 验收(原文级)** = 探针 **29 PASS / 0 FAIL / 0 SKIP(rc=0)**(`OBS-21` 两机 `count=3 hosts=3`、全表零 `alotbuy`)|门户 **200**|旧域 **301**(含子域映射 `guest.alotbuy.com → guest.ai1net.com`)|relay 透传双域一致(裸 GET 双域同 **404**、带 WS 升级头双域同 **101** —— 非回归)|探针**三处同源** md5 `55568f87bfe2dc8e43289c69b4126004`。**⑤ 边界自证** = ⛔ 未 commit / 未 push;⛔ 未动 `nft` / `bwrap` / 配额 / `DEFAULT_BLOCK_SIZE`;对生产的动作只有**重启**(R8 动手前已声明)。**⑥ 残留(本线相关)** = 旧域站点保留为 **301 过渡装置**(仅留 ACME + `/dshs-relay` + `/dshs-overlay/bootstrap` 三条非 301 路径;**退役条件 = 30 天零流量**);`relay-direct.conf` / `dsh.alotbuy.com.conf` 属"导向新域 / 兜底"装置 ⇒ **保留**(删除即净变差 ⇒ R11)。**⑦ 姊妹件** = 同棒产出 **`调整方案/136-控制面按两台中继取并集-立项交接单.md`**(**只立项、⛔ 未落地**)+ 本棒落地档案 **`调整方案/135-旧域alotbuy.com从项目移除.md`**;参数表 §10 指纹 → **`075a97239c2d1d8a1f442ec6cc787ede`**(2 键值格 + 示例 + 说明;⛔ 零个新增 / 改动生产 env)。**⑧ 🔴 本线唯一在册"未修"项(= 上一行 ⑤ 那条,已被本棒正式立项)** = Manager 对 `via=relay` host 的**可达性只读单一** `DSHS_RELAY_STATUS_URL`(47 中继)⇒ worker 漂到 **106 自家中继**时观测面绿、**平台实例面仍可能 500**(**序㊾ 修了观测面、控制面未修**)⇒ 立项单在 **档案 136**(含根因链 7 行 + 先红后绿强制 + 候选 A/B + 验收 E1–E8),**落地另起一棒**。
> 🏷️ **2026-09-19 06:1x–06:4x —— 非本线任务(域名迁移 `alotbuy.com` → `ai1net.com`)已落地,但它**直接改写了本线的中继入口**,故在此留一行(详情 ⇒ 本机 `归档/域名迁移_ai1net_20260919/pending/RUNBOOK-cutover.md §5` + `.workbuddy/memory/2026-09-19.md`)**:**一句话 = 线上服务域名切到 `ai1net.com`;两机候选链现为 **5 条**、**主入口 = `wss://ai1net.com/dshs-relay`**。** **① 入口列表(🔴 唯一载体 = 47 `/etc/systemd/system/dshs.service.d/overlay-443fb.conf`)** = `ai1net.com`(主)> `alotbuy.com`(旧域·过渡)> `relay-direct.ai1net.com`(443 兜底·新)> `relay-direct.alotbuy.com`(443 兜底·旧)> `106.54.21.172`(第二中继·末位);地址覆盖同步加 `relay-direct.ai1net.com=47.77.182.89`。**② 🔴 踩坑(已修 · ⛔ 别再犯)**:该键曾被**重复**写进 `/etc/dshs.env`,而 `/etc/dshs.env`(`EnvironmentFile`)会**压过** drop-in 的 `Environment=` ⇒ 生效列表被窄化成 2 条、丢掉 106 那条第二中继 ⇒ Manager 不再对 106 建拨号会话 ⇒ **归属在 `w-106` 的用户实例子域 500**(`host "w-106" 声明 via=relay 但解析不出落点:拒绝回落到 endpoint`)。⛔ **该键只在本 drop-in 里改**。**③ 106 侧** = `/etc/dshs-worker.env` 的 `DSHS_RENDEZVOUS_URL` 与 `dshs-relay-client.service` 的 `--url` 均由旧域切新域,并补同一份 5 条 `SEEDS` ⇒ worker 把**主入口落回 47 中继**注册(`w-106` 端点由 `online:false` 转 `true`)。**④ 验收** = 探针 **29 PASS / 0 FAIL / 0 SKIP(rc=0)**(`OBS-21`:`dshs@47` 与 `dshs-worker@106` **均 count=5 hosts=5**);实例子域端到端 = `admin.ai1net.com` ⇒ 302 带 `?token=`、`guest.ai1net.com` ⇒ 302 到 `wake.html`(⛔ **均不再是 500**);`npm test` 见当日日志。**⑤ 遗留(本线相关 · 已上报,⛔ 未擅自立项)** = Manager 侧对 `via=relay` host 的可达性**只读单一** `DSHS_RELAY_STATUS_URL`(= 47 中继)⇒ worker 一旦按抖动漂到 **106 自家中继**,`OBS-01/08/09` 会绿、而**平台实例面仍 500** = **序㊾ 修了观测面、控制面未修**(同一条"两台中继并集"口径,控制面尚未跟)。⚠️ 另:该 500 在**恢复 5 条候选后仍复现** ⇒ 不是由种子窄化单独导致;真正修好它的是 ③ 那一步。
> 🆕 **2026-09-19 01:4x 刷新(序㊾ 执行棒 · ✅「探针观测面单一」已修好并上生产 · ✅ 探针**终态 29 PASS / 0 FAIL / 0 SKIP**(rc=0)· ✅ 零回归三件套全绿 · ⏹ 判定 =「本线可停」(⛔ **未登记下一棒**)· 🔴 唯一在册红仍 = **D8 云安全组**(待你控制台落地))**:**一句话 = 三条判据的绿从此不再取决于「106 worker 挂在哪台中继」—— 数据源由「**只读 47**」改为「**按 `hostId`(含 `network`)合并两台中继视图**」,而 ⛔ **阈值、派生规则、判据形态一字未动**(并集只消除"看不见",⛔ 不把真 FAIL 糊成 PASS)。** **① 缺陷(= 交接单 §15-10-1 那条遗留)**:`OBS-01` / `OBS-08` / `OBS-09` 的绿取决于 worker 归属,而 worker 通道按**抖动**换址(`switcher.ts`,属既有设计)⇒ 一旦落到 **106 自家中继**,47 视角即 `used=1 / endpoints=[]`(或两条离线孤儿)⇒ `OBS-01` FAIL、`OBS-08` FAIL、`OBS-09` SKIP —— ⛔ **全是假红 / 假 SKIP**(客户端在 106 自己的中继表里**如实在册**)。**② 实现(单文件六处 · `scripts/overlay-probe.cjs` · ⛔ `src/**` 零改动)** = 新增 `readPeerView()`(对端 `/status` 的**唯一取数入口**,一次 ssh 取 `/status` 原文 + `__RELAY_ACTIVE__` 哨兵,缓存一份供并集与"空表可分"**共用**)+ `mergeEndpoints()`(键 = `network:hostId:port`;`online` 取**或**;`localPort` 取**在线那一侧**)+ `unionUsed()`(= `network/hostId` **去重后的并集基数**,⛔ 不是求和 —— 求和会把两处残留的同一节点**重复计数**)+ `remoteInstanceCodes()`(🔴 实例探活**必须回到"那一台"上做**:`localPort` 是**中继机回环**落点,归属 106 的端点得 ssh 到 **106** 探,否则必 `000` = 假红)+ 三条判据换数据源 + `classifyEmptyView()` 收敛进 `readPeerView()`。**③ 先红后绿(原文级 · 三条证据)**:**(a) 夹具两腿**(同一份真实 `/status` + 真实 `ss`/`nft` + 参数表副本=`SSH_TARGET_*=127.0.0.1` / `SSH_PORT=1`)—— 只差是否给对端那一半:红 `rc=1`(`FAIL OBS-08 端点表(并集) 2 条 / 离线 2 条`|`SKIP OBS-09 派生为空`)→ 绿 `rc=0`(`PASS 2 条 / 离线 0 条`|`PASS w-106:36873=401`),两侧逐行 `diff` **只差这 2 行**。**(b) 真机漂移态**(`--scene all` 收口后现场恰是 47 视角空:47 `used=1 / eps=[]`、106 `eps=[19000,21001] 均 online`)⇒ `PASS OBS-01 used=2(47=1 + 对端=1)`/`PASS OBS-08(47 视角 0 条 + 对端 2 条)`/`PASS OBS-09 w-106:40701=401` —— 🔬 探的是**106 机上**的回环落点(47 上不存在该口)⇒ "分机探活"这条腿**真走到了 106**。**(c) 真机退化腿**(对端不可达)⇒ `FAIL OBS-01 used=1`/`FAIL OBS-08 离线 2`/`SKIP OBS-09` = **改前 47 单点判法逐条一致**(⚠️ 该腿另带 4 条**与并集无关**的红:`OBS-18/21/22/23` 本就要 ssh 到 106)。**④ 硬约束③(先核后做)**:对 47 `/status` 的读取次数**一次都没变**(仍三次,全程复用已采到那份);对端那份在**第三次采样之后** ⇒ ⛔ 不进 `OBS-16` 门窗口 `(status2, status3]`;**隔离性实验原文** = 47 `statusHits 5→6 (Δ=1)` 而**中间插了 2 次读 106**、106 自身 `2→3` ⇒ ✅ 读 106 不动 47 的计数器(且 `OBS-16` 行末已写明"Δ 仅取 47"以防日后误并)。**⑤ 零回归三件套** = 探针 **29 PASS / 0 FAIL / 0 SKIP**(rc=0,终态;漂移态那次 28P/1F 的唯一红 = `OBS-04 identityOk=1` = **演练重启 47 relay 的计数余波**,⛔ 与并集无关)|`npm.cmd test` **200 pass / 0 fail / 1 skipped**(`# tests 201`;Node 22.22.2)|`--scene all` **12 PASS / 0 SKIP / 0 FAIL**(rc=0;**6m10s**;`幕1-A` 15386ms / `幕4-C` 19650ms,deadline 30000;⛔ 未套外层超时)。**⑥ 部署(⛔ 零新增监听口)** = 47 `/opt/dshs/scripts/overlay-probe.cjs` 旧 `eaec1ad560adbec37a15cd145a5ebb77`(109266 B = 序㊳ 期**陈旧**)⇒ 新 **`d2f879dc3220f2800d812437518e3c63`**(135215 B);106 `/opt/dshs-cluster/scripts/` 此前**无此文件** ⇒ 新落同 md5(取"两机同源",免日后在那台机上跑出**旧口径读数**);该文件**不被任何单元读取** ⇒ 零服务影响。**⑦ 边界自证** = ⛔ 未 commit / 未 push(HEAD `45b4999`)|⛔ 未改 `package.json` / `DEFAULT_BLOCK_SIZE`|⛔ 零新依赖|⛔ 未改 nft / nginx / bwrap|🔴 **未改参数表值格**(只追加 §11.16)|⛔ 未调 `RELAY_FAILOVER_DEADLINE_MS` / `HB_SEC` / burst、⛔ 未禁用 `COOLDOWN_MS=0`(`grep` = 0)|🔴 **§8 前前缀 `be548afc3340583b2b63ca254bcf550f` 与 §10 现算 `ac6bbbbb8c92bd57ff0dc4cd8f4983ba` 均逐字不变** ✅。**⑧ 生产动作(R8)** = 两机 `scripts/` 落点更新(纯文本)+ `--scene all` 演练 + 收口处置(**停 106 `dshs-relay` 45 s 后起** 逼 worker 回落 47;⚠️ 首轮"停 3 s"不足够 —— 106 是该 worker 候选链**第一条**,它会回连 106)⇒ 复原后 `used=2 idOk=2`;⛔ 未重启 worker、⛔ 未换任何实例、⛔ 零不可逆动作。**⑨ 两条如实留档** = **(a)** 本机**无改前那份的字节级副本**(工作树未提交、开工未做 `.bak`;`HEAD` 版 114850 B ≠ 改前 122541 B)⇒ **回滚依据 = 交接单 §16-2 的改动清单**;**(b)** 47 落点旧副本被**就地覆盖**(陈旧、代码仓内有更新版本 ⇒ 判无损)。⚠️ **未解决项不变**:**(a)** 🔴 `D8` 云安全组(乙-1)**仍待你在云控制台落地**(两机+本机均无云凭据,序㊹ 已取证;你已批准但定"先记下后续再处理" ⇒ 挂起)|**(b)** ⚠️ **死口孤儿仍未回收**(并集只消除"看不见",`online=false` 条目仍留表;回头条件 = 出现端口替换后 `OBS-08` 再红)|**(c)** ⚠️ `OBS-04`(`identityOk ≥ 2`)对**中继重启**敏感(计数归零)⇒ 演练/重启后需一次回落动作才回绿(既有口径,⛔ 本棒未改)。
> 🆕 **2026-09-19 01:0x 刷新(序㊽ 执行棒 · ✅「重启 worker 后实例端口注册丢失 / 孤儿端点条目不自愈」已修好并上生产 · ✅ 探针回到 **29 PASS / 0 FAIL / 0 SKIP** · ✅ 零回归三件套全绿 · 🔴 唯一遗留 = **观测面单一**(worker 归属漂移会让这 3 条再红 / SKIP)· ➡️ 下一棒 = **序㊾ 执行棒(探针观测面按两台中继取并集)**已登记)**:**一句话 = 上一棒留下的 SKIP 既不是中继故障、也不"必须重启实例" —— 真相是「worker 重启后**没人替已认领的实例把端口重新声明出去**」。** **① 根因(文件 + 行 + 原文)** = `reconcileTunnel()` **早就存在**(`src/worker/agent.ts:256-264`),只是对账口径 `live` **只取** `spawner.listUserInstances()`(`agent.ts:259`),而它是 `return [...this.mains.values()]`(`orchestrator.ts:558-560`)=**本进程 launch 过的**;认领来的既有实例**刻意不进 `mains`**(`orchestrator.ts:290` 原文「已被「认领」的既有 scope —— ⛔ 刻意**不进** `mains`」,理由 = `launchToken` 不可恢复,见文件头 序㉕)⇒ 上一进程遗留的实例端口**没有任何人**会重新声明。**relay 侧其实一直在等**:`dropSession()` **只摘会话、⛔ 不删条目**(`server.ts:2151-2203`),`onPortChange(add=true)` 命中既有条目时走 `ensureEndpoint()` ⇒ **复用条目、只换绑定会话**(`localPort` 沿用)⇒ **重登记 = 就地覆盖孤儿**。🔴 **⇒ 交接单 §14-7 那句「恢复路径须"实例重新拉起"」本棒实测证伪:存在零中断路径。** **② 修复(2 个源文件 · ⛔ 零新依赖 / 零新监听口 / 零新 env)** = `orchestrator.ts` 新增 `adoptedInstancePorts()` + `onRehydrateSettled` 落定回调(`pendingProbes` / `rehydrateScheduled` 计数);`agent.ts` 对账口径改为 `listUserInstances()` **∪** `adoptedInstancePorts()`,抽出 `tunnelTick()` 供 20 s 定时器与"认领落定"回调**共用一份语义**;⛔ **未绕过既有准入 / 白名单**(仍走 `forward() → addPort() → PORT_ADD → onPortChange`,含窗口校验 + worker 侧 `allow`)。**③ 先红后绿(原文级)** = 探针 **26 PASS / 2 FAIL / 1 SKIP(rc=1)** → **29 PASS / 0 FAIL / 0 SKIP(rc=0)**:`OBS-01` `FAIL used=1` → `PASS used=2`|`OBS-08` `FAIL 端点表 1 条 / 离线 1 条` → `PASS 端点表 2 条 / 离线 0 条`|`OBS-09` `SKIP 派生为空(agent 0 条 + 离线 1 条)` → `PASS 在册实例面(派生 1 条):w-106:42497=401`。🔴 **先红最关键一条** = 改前 **106 自己的中继表里也只有 `19000`**,而 106 上 `ss -lntpH` 明明白白 `127.0.0.1:21001` 在听 ⇒「**实例活着、却没人替它把端口声明出去**」(与挂在哪台中继无关)。**机理原文**(47 relay journal)= `AUTH OK … ports=[19000]` ⇒ **1 s 后** `host ops/w-106 +port 21001 -> 127.0.0.1:36535`(⚠️ 20 s 定时器首拍在 **00:31:31** ⇒ 这一枪**只能**来自新回调)。**④ 孤儿自愈受控对照** = 停 worker ⇒ `used=1 eps=[(19000,45095,**False**),(21001,36535,**False**)]`(条目**仍留表** = 改前 `OBS-08` 红形态;**实例全程未动**,`ss -lntH 'sport = :21001'` 全程 **1 行**)⇒ 起 worker ⇒ `used=2`、两条 `True`,且 **`localPort` 逐字沿用**(45095 / 36535)⇒ 证明是"复用既有条目、只换绑定会话",⛔ **不是**新开监听口。**⑤ 零回归三件套** = 探针 **29 PASS / 0 FAIL / 0 SKIP**(rc=0;终态复跑)|`npm.cmd test` **200 pass / 0 fail / 1 skipped**(Node **v22.22.2**;53.2 s)|`--scene all` **12 PASS / 0 SKIP / 0 FAIL**(rc=0;**6m01s**;`幕4-C` **27087 ms** / 30000)|➕ 附加 `node --test test/orchestrator-rehydrate.test.mjs` **18/18**(该文件**刻意不进 `npm test`**,但它是唯一盯 `adopted`/`mains` 边界的用例)。**⑥ 部署** = 包 `dshs-lib-seq48.tgz`(**685,368 B / 270 文件**,md5 **`a902c936cefdeeb3eb13c67dfcb5dd00`**;两机解包前各自验包一致)→ 两机 4 处 `lib` 全量替换,**270 × 4 = 1080 对 md5 不一致 0 / 缺失 0**(多出 11–12 个 = 历史 `.bak-*`);回滚点 = 两机 **`/opt/dsh/backups/seq48-20260919-0030/`**(282 / 281 / 282 / 281 文件);重启后 47 三单元 + 106 两单元全 `active`。⚠️ **如实留档**:首轮"两机同窗口"脚本把 `cd` 写进了**后台复合命令**内 ⇒ **106 未执行、47 已落地** ⇒ **实际窗口相差 ≈ 28 s**(47 **00:30:47** / 106 **00:31:15**);改动为**纯 worker / supervisor 侧增量**(⛔ 无协议帧 / 无接口形状 / 无 env 变化)⇒ 无跨版本不兼容 ⇒ ⛔ 未回滚重做。**⑦ 中断记录** = 🔴 **本棒 ⛔ 未重启 / 未停任何实例**;唯一服务中断 = 受控对照中 `dshs-worker` 停启一次(**停用 ≈ 5 s**)。**⑧ 唯一遗留(⛔ 本棒未修 · 已登记交序㊾)** = 🔴 **观测面单一**:`OBS-01`/`OBS-08`/`OBS-09` 的绿取决于 **106 worker 挂在哪台中继**(探针只读 47 的 `RELAY_STATUS_URL`),而通道会按**抖动**换址(改前原文 `[relay-switch] #3 …->wss://106.54.21.172/dshs-relay(原因:当前通道抖动量超标(p95|ΔRTT|=2941ms ≥ 阈值 20ms)…)`)⇒ worker 一旦落到 106 自家中继,三项**再红 / SKIP**;(b)⚠️ **死口孤儿未回收**(替换后旧端口条目永久 `online=false` 留表;⚠️ 修它需 worker 读到中继侧条目表,而二者**可能不同机** ⇒ 非本棒可及)。**⑨ 边界自证** = ⛔ 未 commit / 未 push(HEAD **`45b4999`** 未动)|⛔ 未改 `DEFAULT_BLOCK_SIZE` / `package.json` / 零新依赖|⛔ 未改 nft·nginx·bwrap|⛔ 值格未动(§10 现算 **`ac6bbbbb8c92bd57ff0dc4cd8f4983ba`** 与 §11.14 同值;本棒补记落 **§11.15**)|🔴 密钥本体不经网络 / relay|§8 前前缀 **`be548afc3340583b2b63ca254bcf550f` 逐字不变** ✅。
> 🆕 **2026-09-19 00:1x 刷新(序㊼ 部署棒 · ✅ `C` 已落地两机 + ✅ `OBS-29` 真机腿 **PASS** · ⚠️ 唯一差异 = `OBS-09` 退化 SKIP(**既有缺陷**被本棒硬要求的"重启 106 `dshs-worker`"触发)· ➡️ 下一棒 = **序㊽**(`OBS-09` 孤儿端点条目修复)已登记)**:**一句话 = 块 id 的 per-network 域分离从此在**两台真机上同时生效** —— 两机 `/status.content.blockIdKeyed = true`、`blockIdKeyId` **逐字相同**(`d6e62322e5166938`)⇒ **跨机取块口径已对齐**。** **① 部署口径(本棒实测认定 · ⚠️ 与"只传改动文件"的旧印象不同)** = 两机 4 处 `lib` 实为**历次增量 scp 的叠加**(47 `/opt/dshs/lib/net/relay/index.js` mtime **12:55:27**,而同目录 `content/chunker.js` **06:52:16**)⇒ 与本机 `build` 产物**同名 md5 不同 38–41 个**(含 `client`/`directory`/`switcher`/`wire`/`orchestrator` 等**与本单无关**的文件)⇒ 本棒按**全量替换**(**270 文件 × 4 处**)+ 🔴 **两机同一窗口内换**(包 md5 **`546b30719ca1bfca1e04189e1099424e`**;两机**解包前各自先验包 md5**)。**② 备份** = 两机 `/opt/dsh/backups/seq47-20260918-2347/`(4 处;47 = 262/263 文件,106 = 260/262)。**③ 核对 = 不一致 0** —— 与代码仓 `lib` **同名 md5 不同 0 / 仅本机有 0**(**270 × 4 = 1080** 对全额逐字节一致);各位置多出的 11–12 个 = 历史 `.bak-*` 遗留(⛔ 未删)。⚠️ **prompt 里"核 32 个 md5"的口径**本棒**未能复现**(已按全量核对并如实记入交接单 §14-3)。**④ 重启**(R8 已声明)= 47 `dshs-relay`/`dshs`/`dshs-worker` 全 `active`;106 `dshs-relay`/`dshs-worker` `active`(`dshs` `inactive` = **正常**)。**⑤ `OBS-29` 真机腿 ✅ PASS** = 两机 `blockIdKeyed=true` + `blockIdKeyId` **逐字相同** + `blockSize=1048576`(⛔ 未动)/ `storeMaxBytes=67108864`(⛔ 未动);🔬 **第二来源** = 两机 relay 启动判别器日志原文 `[content] 块 id 口径 = HMAC-SHA256(域密钥) blockIdKeyId=d6e62322e5166938`(47 **23:47:43** / 106 **23:47:37**)。**⑥ 零回归三件套** = 探针 **28 PASS / 0 FAIL / 1 SKIP**(⚠️ 基线 **29P/0S/0F**)|`--scene all` **12 PASS / 0 SKIP / 0 FAIL**(rc=0;**6m28s**)✅ 与基线逐字同(`幕1-A` 本次**未**触发 6 h 坑 —— 因本棒刚重启 47 `dshs`、AUTH 行新鲜)|`npm test` ⛔ 本轮未跑(**本棒零代码改动**)。**⑦ 🔴 唯一差异 = `OBS-09` 由 PASS 退化 SKIP(**如实留档 · 根因是既有缺陷**)** —— **事实链**:106 实例 **`286172`**(`dsh --profile web --port 21001`)**启动于 10:18:34**(= 重启前 13.5 h)、**未被 teardown**(`OBS-22 scanned=1 adopted=1 stopped=0` + 日志 `[rehydrate] probe OK dsh-100002-7d1c8cbf.scope :21001`)⇒ 但 47 端点表**只有 `w-106:19000`、缺 `w-106:21001`**(参数表 §3.9 `PEER_INSTANCE_PORT` 行 10:2x 实测**应有两条**);**机理** = `relay-tunnel.ts#cancel()` 只撤销**当前进程** `forwarded` 集里的端口 ⇒ 上一进程遗留条目**无人撤销**、新进程也**不重注册**已认领实例的端口(历史留档原文:「**重启后 `OBS-08`/`OBS-09` 必红,⛔ 不是"跑一会儿就好"**」)⇒ 本棒**复跑探针两次(间隔 ~6 min)未自愈**。🔴 **恢复须"实例重新拉起"**(端口登记在 spawn 流程内)⇒ 与 memory 明令「⛔ 别为迁就旧值重启生产实例」冲突 ⇒ **本棒不修、不凑绿** ⇒ 交下一棒。**⑧ 边界自证** = ⛔ 未 commit / 未 push(HEAD **`45b4999`**;`git status` 仍 **21** 处)|⛔ 未改 `DEFAULT_BLOCK_SIZE` / `package.json` / 零新依赖|⛔ 未改 nft·nginx·bwrap|⛔ 未改参数表**值格**(§10 现算 **`ac6bbbbb8c92bd57ff0dc4cd8f4983ba`** 与 §13 记录**同值** ⇒ 本棒补记落 **§11.14**,在 §10 口径之外)|🔴 密钥本体不经网络 / relay(本棒只读 `/status`,⛔ 未触碰密钥文件)。➡️ **下一棒 = 序㊽(`OBS-09` 孤儿端点条目修复 —— 让 worker 重启后能**重注册已认领实例的端口**)**已登记。
> 🆕 **2026-09-18 23:3x 刷新(序㊻ 执行棒 · ✅ `C`(块 id per-network 域分离)已落地并全绿 · 🔴 `OBS-29` 判据已重裁(正腿 3 + 具名负腿 2)· ✅ 零回归三件套全绿 · ⏳ 唯一未办 = **真机腿**(须部署)· ➡️ 下一棒 = **序㊼ 部署棒**已登记)**:**一句话 = 块 id 从此按「网络」分域 —— 同字节在不同 network 得到**不同 id**(跨网共享必然失效 = **设计意图**),而**同网去重一点没丢**。** **① 交付** = 改 **8 个文件**(`content/{chunker,crypto,store,runtime}.ts` + `relay/{main,index}.ts` + `test/overlay-content.test.mjs` + `scripts/overlay-probe.cjs`):`blockIdOf` / `contentIdOf` 由**裸 `sha256`** 改为 **`HMAC-SHA256(netKey, bytes)` 取前 32 hex**;per-network 密钥**复用 `crypto.ts` 既有组密钥链**派生(新增 `deriveBlockIdKey()` + `BLOCK_ID_DOMAIN_TAG`)⇒ 🔑 **⛔ 零新密钥文件 / ⛔ 零新 env**;🔴 **缺省 / 空 `netKey` ⇒ 回落裸 `sha256`**(= **回滚路径**,且保住既有单测语义)。**② 判据重裁(本棒存在的主因)** = 序㊺ 实测判 **`D` 无作用面 ⇒ 本轮不实现**,故原 `OBS-29` 那条"稀释源换成确定性派生量 ⇒ 必红"的负腿**失去对象** ⇒ **重裁为 `C` 的判据**:**正腿 3 条**(`P1` 跨网必不同且**两侧都 ≠ 裸哈希** / `P2` 同网必相同=**去重不得丢** / `P3` 装配面无漏改)+ 🔴 **具名负腿 2 条**(`flat-key-collapses` / `empty-key-falls-back-to-bare-hash`)。**③ `E1` 基线已重取**(**定义不重估** = 回源字节 ≈ **1 份 × 组数**;**旧读数作废**):同网 **4 轮 × 4 块全 local 命中**、`origin = 0`、`putRejected = 0`、`puts = dedupIds`;跨网**各 1 份**(起点 `local = 0`)。**④ 零回归三件套全绿** = `npm.cmd test` **200/0/1** + `overlay-content` **55/55** | 探针 **29 PASS / 0 FAIL / 0 SKIP**(基线 **28** ⇒ **+1 = `OBS-29`**)| `--scene all` **12 PASS / 0 SKIP / 0 FAIL**(rc=0;8m25s)。**⑤ 先红后绿两条都真跑过**(⛔ 非纸面声明):**红腿 A**(派生**丢掉 `network` 维度**)⇒ 单测 **6 失败**、探针 `腿数 4/5 ❌ 缺 P1`;**红腿 B**(**漏传 `netKey`** = 漏掉一个调用点)⇒ 单测 **9 失败**、原文 `content-store: 块校验失败(丢弃)`;两条均已**复原**(md5 回位、`REDLEG` 计数 **0**)。**⑥ 边界自证** = ⛔ 未 commit / 未 push(HEAD **`45b4999`**;`git status` **21** = 序㊺ 遗留 **13** + 本棒 **8**)|⛔ **未 scp / 未部署** |⛔ 未动任何配置值 / nft·nginx·bwrap |⛔ 未改 `DEFAULT_BLOCK_SIZE` / `package.json` / 零新依赖。⚠️ **本棒对生产的唯一动作 = 重启 47 `dshs` 一次**(**R8**;为满足演练的 **6 h AUTH 窗口**,动手前已声明;无不可逆项)。**⑦ 四条如实留档(均属既有缺陷 · ⛔ 本棒只报不动手 ⇒ 另立小项)**:**(a)** 演练 `currentChannelHint()` 用 `journalctl --since -6h` 捞**每 2 s 一条**的 `[overlay-dir] 取址`(6 h ≈ **1 万行 / ≈1.3 MB**)⇒ **单次 ssh ~47 s > `SSH_TIMEOUT_MS` 20 s** ⇒ 曾整轮 `spawnSync ssh ETIMEDOUT` **中止**(该函数**源码自述「仅供人读、不参与判定」** ⇒ **装饰性线索不该是主流程硬依赖**);**(b)** 演练 `lastManagerAuthOn()` 的 **6 h 上限** ⇒ Manager 隧道**稳定 > 6 h** ⇒ 两台都读 **-1** ⇒ `幕1-A` 降级 **SKIP** + **`幕1-B/C` 结构上不打印**(**本棒已做先红后绿**:首跑 **9P/1S/0F** ⇒ 按脚本自述办法重启 Manager 刷新 AUTH ⇒ **12P/0S/0F**);**(c)** `mksess.cjs` 已失效(写 SQLite,而**权威库 = PG** ⇒ 一插就 401);**(d)** `docs-sync-check.sh` **rc=2** 的真因 = **ssh 别名 `bt-server` 端口陈旧**(吃 `Port 32022` ⇒ `Connection refused`;`-p 22` 正常、`/opt/dsh/docs` **确实存在**)⇒ **非"目录不存在"**。➡️ **下一棒 = 序㊼ 部署棒(`C` 落地两机 + `OBS-29` 真机腿)**。
> 🆕 **2026-09-18 22:5x 刷新(序㊺ 执行棒 · ✅ `M1` 首次实测完成(**真实内容** · 四项读数齐)· 🔴 实测结论 =「**D 的作用面为空**」⇒ **D 本轮不实现**(⚠️ 非降级 —— 目标已由测量证实达成)· ✅ ⛔ 未改 `src/**` 一行 · ➡️ 下一棒 = **序㊻ 执行棒(C 域分离 + 判据重裁)**已登记)**:**一句话 = 「低熵块」第一次被**真实内容**量了 —— **首屏包里 0 个低熵块;低熵物质只以 ≤ 80 KiB 的块内片段存在(占 1.0225%);60 份真实独立小内容里 0 份低熵** ⇒ **D(非确定性)当前没有对象可治**,而 **C(域分离)仍值得做**。**① `M1` 四项读数(真实内容 · ⛔ 零合成字节)**:**S1 = 真实首屏包** = `GET https://admin.alotbuy.com/` 壳页后**按页面顺序**取回**全部 60 条** `/plugins/??…&rev=…` combo(由宿主**运行时**拼装 ⇒ **盘上无"单文件产物"**,只能 HTTP 取)⇒ 合计 **23,629,336 B**(🔴 **口径纠正**:历史档案里的 `11,363,655 B` = **最大单条 combo**(本棒实测 **11,794,471 B**),⛔ **不是全部之和**;⚠️ 该值随实例启动世代漂 ⇒ 复现须记 `rev`)|**`M1-a`** 块 **23** / 唯一 **23** / 重复率 **0.00%** / 完全重复 **0** |**`M1-b`** 低熵块(`H ≤ 4.0`)**0 块 · 0 B**,逐块 H ∈ **[5.1807, 5.8444]**,**直方图 `{5.0-5.5: 8, 5.5-6.0: 15}`** |**`M1-c`** 占比 **0.000000%** |**`M1-d`(反向腿)** 4 KiB 窗共 **5,768** 个 ⇒ **低熵段 15 段 / 241,664 B = 1.0225%**,段字节 min **4,096** / max **81,920**,直方图 `{≤4KiB: 10, 4KiB-16KiB: 3, 16KiB-64KiB: 0, 64KiB-256KiB: 2, 256KiB-1MiB: 0}` |**S2** 60 份内容中单块 **56** 份、**低熵内容 0 份**(逐份 Hmin ∈ `[4.8354, 6.3485]`)。**② 三条判据性结论(每条引数字)**:**(甲)✅「首屏包内不存在纯低熵块」—— 证实**(`04-133 §1.1` 推论 1:23 块**全部** H ≥ 5.1807);**(乙)❌「< 1 MiB 的独立小内容若是低熵 ⇒ 纯低熵块」—— 未证实**(S2 里**确实有 56 份单块小内容**,但它们**全是高熵 JS bundle**、低熵内容 **0 份**)⇒ **该风险面在当前真实内容上不存在**;**(丙)⚠️「什么算低熵」的阈值**无法由本次读数定死(全部块落在 **5.0–6.0** ⇒ **阈值取 ≤5.0 时"低熵块"恒 0**;**字节分布熵对 JS 文本不是强判别器**)⇒ 🔑 **`M1-d` 才是有效的腿**(它抓到那块内 1.0225% 的低熵片段)。**③ 对 **D** 的判定(自决 · 可推翻)**:**D 的目标已由「定长 1 MiB 切分」结构性达成** —— 低熵物质只以 **≤ 81,920 B 的块内片段**存在 ⇒ **对块级去重 / 枚举不可见**;且**不存在低熵内容单元**(②乙)⇒ **`D-1` 无对象可稀释、`D-2` 的启用前提不成立**(`04-133` 决策点 4 **两分支都不命中**)⇒ **D 本轮不实现**(否则 = 纯增复杂度 + 测量上零收益 ⇒ 触 **R11**)。⚠️ **这不是降级 / 不是静默兜底**:目标已被**实测**证实达成;🔑 **回头条件(具名)= 出现「低熵内容单元」** ⇒ 由固化探针 **可重复复查**(再跑一次即可判定,⛔ 不需要先写代码)。**④ 产物** = **`scripts/overlay-entropy.cjs`**(只读探针 · 零第三方依赖 · **切分调用仓库那份 `chunkify`** = `lib/net/relay/content/chunker.js` ⇒ ⛔ **无双源**;可用 `OVERLAY_CHUNKER` 覆盖)+ 参数表 **§11.12**(读数落点)+ 交接单 **§8 回填**。**⑤ 边界自证** = ⛔ **未改 `src/**` 一行**(C 未开工 —— 理由:`OBS-29` 的判据面须随 D 的移除一并重裁,见下一棒要点)· ⛔ 未动 `DEFAULT_BLOCK_SIZE` / `package.json` · ⛔ 未改生产实例 / ⛔ 未重启在线服务 · ⛔ 未 commit / 未 push · 🔴 **两处临时物已清**(47 `/tmp/s45`;PG 临时会话 `user_agent='seq45-entropy'` ⇒ `remaining=0`)· ⚠️ 参数表 **§10 指纹未变**(`6b37bfd506758d882d9f803678f85d23`,两次现算同值)。**⑥ 两条如实留档**:**①** 仓里的 **`mksess.cjs` 已失效** —— 它写 SQLite `/var/lib/dshs/dshs.db`,而**权威库 = PG**(`dshs.service.d/cluster.conf` 的 `DSHS_DB_URL=postgres://[email protected]:15432/dshs`)⇒ 插进去的会话 Manager **查不到**、一插就 **401**(🔴 **待收口缺陷**,另立小项;⛔ 不属本单产物);**②** `/plugins/??…` **有鉴权**(无会话 = **401 / 24 B**)⇒ 取数**必须**临时会话(R4)。➡️ **下一棒 = 序㊻ 执行棒(C 域分离 + 判据重裁)**。
> 🆕 **2026-09-18 21:5x 刷新(序㊺ 规划棒 · ✅ 规划完成 · ⛔ 零代码零服务器改动 · ➡️ 下一棒 = 序㊺ 执行棒已登记)**:**一句话 = 「§10-3 低熵块治理」立了方案,方向按你 21:28 的拍板 = 采纳 C + D(B 降级、⛔ 不立项);而方案的第一个动作是补测一个从未测过的读数。** **① 产出** = 方案 `调整方案/133-覆盖网络-低熵块治理方案-C域分离与D非确定性.md`(**原子占号 133**;⚠️ 130 空号未补占 —— 记忆里 130 已言明归「单 B」)+ 交接单 `交接单/覆盖网络-序45-低熵块治理-测熵与实现.md`(**§8 前前缀 `be548afc3340583b2b63ca254bcf550f`** · 全文件 md5 `0169b900a6ea50608c0d50a3a0514e68`)+ `交接单/README.md §一` 新增一行 + `INDEX.md §二` 新增 `04-133` 行(⚠️ 机器生成的状态摘要已用 `docs-index-stats.py --write` 刷新 ⇒ **档案 117 份**)+ `docs-manifest.json` 已刷新。**② 本轮新增的源码级结构发现(⛔ 尚无任何文档记录 · 待实测确认)**:切分是**定长 1 MiB**(`chunker.ts:60` 常量 + `:137` `offset += blockSize`)⇒ 首屏包 10.8 MB ≈ **11 块、每块混高熵内容** ⇒ **首屏包内几乎不可能存在纯低熵块**;⇒ **D 的真实战场更可能是「整体小于 1 MiB 的独立内容」**(只切 1 块;本身低熵 ⇒ 就是一块纯低熵块)。⇒ 🔴 **推论:测熵只测首屏包会得出"没有低熵块"的假绿 ⇒ 必须加子窗口熵腿**(滑窗找块内低熵片段)。**③ `M1` 四项指标** = 种类数/重复率 | 低熵块数 + 体积 + **H 直方图** | **占首屏包比例** | **子窗口熵尺寸分布**。⚠️ **为什么必须先测**:D 的边界(什么算低熵 / 稀释单元多大 / 要不要合并)全是它的函数;而**历史所有"低熵"读数都是合成字节**(`tmp/历史过程目录/_tmp_seq32/p01-perf.mjs:42` 用 `makeBytes()`、`p03-lowentropy.txt` 用 8 B 合成块)+ **块存储纯内存不落盘**(`server.ts:909-911` 只给 `maxBytes`、**无 `dir`**)⇒ 生产侧**无样本可捞**,只能对**真实内容**离线度量(⚠️ 切分必须调用仓库里那份 `chunkify`,⛔ 不复刻算法=避免双源)。**④ 发现一条既有漂移(⚠️ 只报不改)**:参数表 §10 头值记 `d408d640246a980f702fe7b0a2895219`(序㊴ 12:2x 记录),**现算 = `6b37bfd506758d882d9f803678f85d23`**(830 行 · mtime 09-18 15:18)⇒ **记录值未随 §10 之前的内容更新**;⚠️ 与序㊹ 自报值**一致**(两次独立计算同值)⇒ 不是算错、是漏更新。**⑤ 边界自证** = ⛔ 本棒**零代码**(⛔ 未改 `src/**` / `scripts/**` / `test/**`)· ⛔ **零服务器触碰**(⛔ 未 ssh / 未 scp / 未 build / 未重启任何单元)· ⛔ **不 commit / 不 push**(`git` 未提交改动 = 本棒 4 处:`04-133` / `交接单/序45` / `INDEX.md` / `交接单/README.md`)· ⛔ 未动 `参数表`(**§10 指纹现算仍 `6b37bfd5…`**)· ⛔ 未动 `package.json` / `DEFAULT_BLOCK_SIZE` / `content/**` 任何代码。⚠️ **两条如实留档**:① `docs-sync-check.sh` 报 `无法读取服务器目录 bt-server:/opt/dsh/docs(ssh 失败或目录不存在)` ⇒ **未能做双端对账**(本棒是规划棒、⛔ 不 scp 且未推送 ⇒ 不构成阻塞;⚠️ 执行棒**推送前必须复跑并成功**)② `docs-audit.py` **退出码 0**(无 P0)。**回报落点** = 本入口 §2 + 工作区日志 `.workbuddy/memory/2026-09-18.md`。➡️ **下一棒 = 序㊺ 执行棒**(低熵块治理:测熵先行 + C + D),automation **`f94f2973-4ead-471a-a020-df6dc0b144a4`**(一次性 · **2026-09-18 21:56** · `nextRunAt` = **1789739760000**);⚠️ **同一时刻只挂这一个棒**。📌 **在册待你拍板项仍 = D8**(⛔ 不阻塞排棒)。
> 🆕 **2026-09-18 15:5x 刷新(序㊹ 执行棒 · ⏸ **未收官 —— 阻塞上报**:「D8 云安全组」用户已批准,但**执行侧无云 API 凭据** ⇒ 按 §1 边界外④ 停下;本机(开发机)在测试中的角色判定同时给出)**:**一句话 = 用户原话「**1 开通,需要我操作还是你可以自己操作,所有的测试是否包含本机,当做结点或终端**」⇒ 取证后结论 = **D8 只能由用户侧控制台落地**(两机 + 本机**均无可用云凭据**),**本机⛔ 不是覆盖网节点、⛔ 也不是终端**(只是测试发起端 / 观测台)。**① D8 执行侧阻塞(原文级证据)**:本机(WorkBuddy 开发机)**无**任何云 CLI / 凭据(无 `~/.aliyun` / `~/.tccli` / `~/.aws`)|**47(阿里云)**:`aliyun` CLI **存在**(`/usr/local/bin/aliyun`)但 **`~/.aliyun/config.json` 不存在** ⇒ `aliyun configure list` = `default * | (空) | Invalid | (空) | en` ⇒ **凭据未配置**;metadata `http://100.100.100.200/latest/meta-data/ram/security-credentials/` ⇒ **404 - Not Found** ⇒ **无 RAM 角色**(拿不到 STS 临时凭据)|**106(腾讯云)**:**无** `tccli`;metadata `http://metadata.tencentyun.com/latest/meta-data/cam/security-credentials/` ⇒ **404** ⇒ **无 CAM 角色** ⇒ 🔴 依本线纪律 **⛔ 不索取、⛔ 不硬编码任何云 AK/SK** ⇒ **只能用户侧操作**(或**由用户主动**给一次性凭据 —— 本棒 ⛔ 不索要)。**② 待落地规则(乙-1 · 原文级 · ⛔ 执行侧不得改形)**:**47 阿里云安全组 · 入方向 · 协议 `UDP` · 端口 `21100/21115` · 授权对象 `106.54.21.172/32`** | **106 腾讯云安全组 · 入方向 · 协议 `UDP` · 端口 `21100/21115` · 授权对象 `47.77.182.89/32`** ⇒ 🔴 **⛔ 零个 `0.0.0.0/0`**(含任何拆分 / 等价写法)、⛔ 不放行 TCP 段(`LISTEN_ALLOWED_RANGES` 是 TCP 族,⛔ 别混)、⛔ 不改 `nft` / `nginx` / `bwrap`。**③ 前置取证(只读 · 证明 D8 是"唯一缺口")**:固定公网 IP = **47 `47.77.182.89`**(阿里云 `i-rj99af19cibck1ge93tq`)/ **106 `106.54.21.172`**(腾讯云 `ins-3q6k1p8t`);网卡分别 `eth0 172.18.16.212/18` / `eth0 10.0.0.8/22` ⇒ 两侧公网 IP **均为云网关 NAT 映射**(⛔ 非直挂网卡 ⇒ 入站须云安全组放行)|UDP 区间 = **`[21100, 21116)`**(`punch.ts#PUNCH_PORT_BASE=21100` + `PUNCH_PORT_SPAN=16`;⚠️ 两机 `ss -lunp` 在该段**均无监听** = **正常** —— 打洞 socket 只在**实打时**才开,⛔ **不是"没装"**)|`DSHS_OVERLAY_DIRECT` 两机 `/etc/dshs*.env` **命中 0** ⇒ 走**缺省 = 开**(⛔ 无需改 drop-in)|🔴 **两侧本地防火墙都不拦 UDP 入站**:47 `nft` **72 行**、`hook input … policy accept`(⚠️ 其中那条 `udp … reject` 是**沙箱 uid `100000-199999` 的出站**限制、`daddr` 含 `47.77.182.89`,⛔ **与本腿无关**);106 `nft` **0 行**、`iptables -P INPUT ACCEPT` + `YJ-FIREWALL-INPUT` 仅 4 条 `/32` REJECT(**不含 47**)+ `ipset test YJ-GLOBAL-INBLOCK 47.77.182.89` ⇒ **NOT in set**。**④ 本机角色判定 = 测试发起端 / 观测台 + 开发机;⛔ 不是覆盖网节点、⛔ 也不是覆盖网终端**(证据五条:**a** 四条测试命令**均从本机发起** ⇒ 本机是**发起端**、不是**被测对象**;**b** 本机 **零** `dshs*` / `dsh-*` 进程、**零** `20080` / `19100` / `20000` / `21000–21001` / `21100–21115` 监听 ⇒ 结构上**不在** `endpoints[]` / `sessions[]` 里;**c** 47 权威 `nodes.json` = `{"version":1,"nodes":{}}`(**空**)⇒ 本机**未注册**;**d** 本机 `curl -4 ifconfig.me` **回落到 IPv6**(`240e:332:cd0:a710:…`)⇒ **无固定公网 IPv4** ⇒ ⛔ 给不出稳定 `/32` ⇒ **D8 式对端放行对本机结构上不成立**;**e** 本机 `~/.dshs/` 仅 `overlay-table-dir`(**序㊸ 本线自建**的参数表定位注册,⛔ 非节点注册)+ `secret.key`(64 B · 09-13 15:40 · 系 `src/config.ts#ensureSecretKey` 的**数据根密钥**,⛔ **非**覆盖网节点密钥;**密钥本体 ⛔ 未读取**))⇒ **若要纳入**只能作「**只拨出**」从节点(本线铁律:**worker 永远只拨出**),需装运行时 + profile + 注册为 Worker;⚠️ 因无固定公网 IPv4,该节点**天然只能用 relay / 443 兜底腿**、**直连腿结构上不可用**。**⑤ 边界自证** = ⛔ 本棒**只读取证**(零 scp / 零 build / 零重启任何单元)|⛔ 未 commit / 未 push(HEAD 仍 **`09ce76f`**)|⛔ 未改 `nft`(47 仍 **72 行**)/ `nginx` / `bwrap` / `server.ts` / `content/**`|🔴 **零个 `0.0.0.0/0`**、⛔ 未索取 / 未硬编码任何云 AK/SK|🔴 密钥本体 ⛔ 未读取、两机密钥权限仍 `600`。**回报落点** = 本单 **§8.11**(⏸ 未收官 · 阻塞上报;**§8 前前缀写后现算仍 `8925c2460810c6dc5cdbc075b6cdaed2`** ✅)|⚠️ **参数表本棒零改动**(§10 指纹 **仍 `6b37bfd506758d882d9f803678f85d23`**)。➡️ **下一棒 ⛔ 未登记**(阻塞项需人操作,⛔ 无人值守重试无意义);**落地后第一动作 = 双向实测复测**(当前基线 **47→106 发 21 收 0** / **106→47 发 28 收 0**)+ 探针 `OBS-27/28` 复跑 + 参数表 §11 补记。
> 🆕 **2026-09-18 15:2x 刷新(序㊸ 执行棒收官 · ✅ 观测面缺口收口三项全绿 · ✅ 零回归三件套全绿 · 🛑 **本线可停**(⛔ 未登记下一棒)· 🔴 D8 云安全组仍为唯一红(既存、在册待你拍板))**:**一句话 = 106 侧观测面缺口已收口 —— 探针在 106 上从「一行都跑不了」变成「三条子命令全通」,参数表定位不再挑 `cwd`(从代码仓根跑也认)。** **① 探针在 106 上可跑(先红后绿)**:**红腿**(106 上改前的副本 `/opt/dshs-cluster/scripts/overlay-direct-probe.cjs`,md5 `8d1ea60a01fc09fb5f56e492afb76fc9`)⇒ `status` 与 `selfcheck --json` **两条命令都**原文 `Error: Cannot find module '../lib/net/relay/registry.js'` + `Require stack: /opt/dshs-cluster/scripts/overlay-direct-probe.cjs`(根因:106 `/opt/dshs-cluster/lib` **无 `registry.js`** = 控制面注册表模块,节点不落它);**绿腿**(同一命令、同一**规范路径**)⇒ `status` rc=0(`直连(打洞):开|来源 default|缺省 true`)+ `selfcheck --json` rc=0(`{"degraded":true,"degradedLegs":["joinConf"],"joinConfAvailable":false,"joinConfReason":"module-missing","candAcc":3,"candRej":9,"silent":0,"bi":true,"ok":2,"cooldown":300000,"zero":"throws","deps":true}`)+ `punch --peer 47.77.182.89:21100` rc=0(`窗内零收包(deadline 3000 ms,实耗 3000 ms,发 21 包)⇒ 判死 + 进冷却 300000 ms`)。**办法 = 惰性 / 可选加载 + 具名降级**(⛔ **不是**"再铺一份 `registry.js`"):只有 `join 回读`(判据 D3)这条腿惰性加载 `registry.js` / `join.js`,缺 ⇒ `{available:false, reason:'module-missing', missing:[…原文 message…]}`,文本原文 `join 回读:⛔ 不可用(module-missing)—— 缺 …|⚠️ 这是「没装」不是「没采到」`;🔴 **⛔ 不静默返"没有"**(缺块**不填** `direct`/`readback` ⇒ 形状可分)|⚠️ 只吞 `MODULE_NOT_FOUND`,其它异常照抛。**本地等效夹具**(临时改名 `lib/net/relay/{registry,join}.js`)⇒ 同一降级形状、其余腿全在,**还原后 md5 逐字回位**(`951a2526…` / `6946e1d8…`)。**② 参数表定位与 cwd 解耦**:**红腿**(旧逻辑副本,与 `git show HEAD:scripts/overlay-probe.cjs` 的 `resolveTablePath` **逐字一致**)⇒ 从代码仓根 rc=**2** `❌ 参数表装载失败:在 D:\github\dsh_shenxian 下按 /^参数表_覆盖网络_.+\.md$/ 找到 0 个参数表(要求恰好 1 个)`;**绿腿**(修后,**从代码仓根、不给 `--table`**)⇒ 探针 **28P/0S/0F**(rc=0)+ 演练 `--scene all` **12P/0S/0F**(rc=0;原文 `# 参数表=docs/覆盖网络/参数表_覆盖网络_20260917.md`);**防错腿两腿**(同目录人为 2 份 ⇒ rc=2;跨候选目录合计 2 份 ⇒ rc=2,**探针与演练各测一次**)。**候选目录链** = `--table`(显式,最高优先)> `--dir` > `DSHS_OVERLAY_TABLE_DIR` > **机器本地注册文件**(`DSHS_OVERLAY_TABLE_REGISTRY`,缺省 **`~/.dshs/overlay-table-dir`**)> `cwd` > 脚本目录及上两级;🔴 **"恰好 1 个才合法"保留且更严**(任一候选目录 ≥2 ⇒ 立即报错;跨目录合计 ≥2 ⇒ 也报错;一份都没有 ⇒ 报错并列出**所有搜过的目录**,⛔ **不放宽成"找不到就用缺省"**)。🔑 **为何必须有注册文件**:参数表**不在仓内**(`git ls-files | grep -c 参数表` = **0**)而在**工作区根**,本机仓在 `D:`、工作区在 `E:`(**不同盘**)⇒ 路径推算到不了 ⇒ **机器差异一律放 `$HOME`**(⛔ 仓内零机器路径)。**③ 106 残留副本处置 = 二选一选「使其可跑」**(⛔ 未删;理由 = 106 正是真机打洞腿的取证机,删掉只会逼出更多 `/tmp/*.cjs`)⇒ 探针 scp 到**三处**且 **md5 全同 = `4734686b5270059697ccbcf966c34ade`**(本机仓 / 47 `/opt/dshs/scripts` / 106 `/opt/dshs-cluster/scripts`);**回滚点** = 两机 `/opt/dsh/backups/seq43-20260918-150549/`(md5 `8d1ea60a01fc09fb5f56e492afb76fc9` = 改前值)。**④ 零回归三件套** = `npm.cmd test` **201/200/0/1**(逐字同基线;`duration_ms=53315.1989`)|`--scene all` **12P/0S/0F**(rc=0;**6m23s**;`幕4-C` **17240 ms / 30000 ms**;**未套外层超时** ⇒ 两台 relay `active`)|探针 **28P/0S/0F**(**开工后从代码仓根 + 收口后工作区根两次同值**)。**恢复形态** = 47 `dshs`/`dshs-worker`/`dshs-relay` 全 `active`、relay `/status` 200、门户 200;106 `dshs-worker`/`dshs-relay` `active`;演练后 47 视角 `endpoints=[]` ⇒ **按既有程序复原**(停 106 `dshs-relay` **26 s** 再启 + 等 ~20 s)⇒ `sessions=["ops/manager","ops/w-106"]`、端点 **2 条全在线**、探针 `OBS-01 used=2` ✅。**边界自证** = ⛔ 未 commit / 未 push(HEAD **`09ce76f`**;`git status --short` **19** 处 = 与序㊷ **逐数相同** ⇒ 零新增条目)|⛔ 本棒只改 **3 个脚本**(`overlay-direct-probe.cjs` / `overlay-probe.cjs` / `overlay-failover-drill.cjs`),⛔ 未改 `src/**` / `test/**`、⛔ 未 build(无 TS 改动)|⛔ 未改 `server.ts` DIAL·白名单语义 / `content/**` 块 id 口径 / `nft`(**72 行**)/ nginx / bwrap(47=**0.4.0**、106=0.11.0)|🔴 `RELAY_FAILOVER_COOLDOWN_MS=0` 命中 **0**(四处计数全 0)|🔴 密钥本体不经网络 / relay(`content-group-key.json` 两机仍 `600`)|⛔ 零个新增 / 改动生产 env(`DSHS_OVERLAY_DIRECT` 命中 0)、⛔ 零新增监听口(`21100–21115` = **0 行**)。**产出的两条须知**:**① 参数表定位链新增"机器本地注册文件"** `~/.dshs/overlay-table-dir`(本机已写一行 = 工作区根;**换机 / 换工作区路径需补一行**,或改用 `--table` / `--dir` / 两个 env)**② 参数表 §6 `OBS-26` 行本棒 ⛔ 未改**(**为保 §10 指纹不变** —— §6 在 §10 口径**之内**)⇒ `OBS-26` 的"读数生产方显式 `available:false` ⇒ 该子判据 **SKIP + 留痕**(⛔ 不判红)"这条语义登记在 **§11.11**,下次键值变更时顺带并入。⚠️ **三条如实留档**:① **106 上 `/tmp/d8_punch_106.cjs`(序㊷ 临时脚本)仍在**(信息项,⛔ 未动;本棒起已无必要)② 演练脚本的 `--trace` / `--sample` **仍按 `cwd` 落盘**(⛔ 未改、非本条范围;`--scene all` **走不到**它们 ⇒ 从代码仓根跑**零副作用**)③ `--table` **裸开关(不给值)会被判为"未给"**(既有行为,⛔ 未改,只登记)。➡️ **本线可停**:三项全绿、无遗留 ⇒ ⛔ **本棒未登记下一棒**;**唯一在册大项 = D8(云安全组)**,需你拍板(要不要现在开通 **乙-1**;需你给控制台访问方式 / 审批)—— ⛔ 该项**不阻塞本棒的排棒**(已在册)。
> 🆕 **2026-09-18 14:4x 刷新(序㊷ 执行棒收官 · ✅ P2/S7「规模回归」四项复测全绿 · ✅ 零回归三件套全绿 · 🔴 D8 云安全组仍为唯一红(既存、在册待你拍板)· ➡️ 下一棒 = 序㊸ 执行棒(观测面缺口收口))**:**一句话 = 四项规模读数各自拿到原始读数并与基线逐项对齐 —— 候选数不退化、回源字节"按组线性增长"被机器断言、切换耗时要 20.9 s(限 30 s)、而直连成功率**只有模拟器是 1.0000,真机仍是 0**。** **四项读数(⛔ 无编数)**:**① 候选数** = `dshs@47` 与 `dshs-worker@106` 均 `count=3 hosts=3`(≥ `CAND_MIN=2`,**逐字同序㉙ 基线**;⚠️ `hosts=3` **≠ 独立路径数** —— 前两条候选摘名不同**同落 47** ⇒ 机器级只有 **2**)+ 直连候选准入 `accepted=3 / rejected=9(全具名)/ silentRejections=0 / 按网分桶=true` + **规模夹具**(2 网 × {4,16,64} 节点)`accepted 10/34/130`(线性)、`rejected 32/128/512`(8 类原因各 perNet 条)、`silentRejections=0`。**② 直连成功率** = 🔴 **"判据成立"与"冗余建成"已分开报** —— **本系统规格器(离线 NAT 模拟器,同一份 `runPunchAttempt`)正腿 `24/24 = 1.0000` 双向、p50 建连 155 ms**,负腿 `one-way(a/b)` 各 12 全 0、`both` 全 `deadline`;**真机** `47→106` **发 21 收 0**、`106→47` **发 28 收 0** ⇒ **不可达**(D8 未放行)⇒ ⛔ **未把"直连建立了"写成成功**,真机形态 = **回落 wss 且块 id 不变**。**③ 切换耗时** = `幕4-C` **20871 ms / 30000**、`幕1-A` **20605 ms**、`幕4-A` **18815 ms**(n=3,**均在 deadline 内侧**;对照序⑨ 修后基线 **20.9–23.9 s** 同量级);收口后 `jitter.p95AbsDeltaMs=6 ms / overThreshold=false`(⚠️ 阈值权威落点在参数表 **§4** `RELAY_FAILOVER_DEADLINE_MS`,⛔ **不是 §3.2** —— §3.2 是打洞率;已如实留档于 §8.9-⑥-5)。**④ 回源字节** = 同一份 5,255,225 B/6 块夹具:`1组×4节点` **1.0000**(5,255,225 B)/`1组×16节点` **1.0000** /`4组×4节点` **4.0000**(21,020,900 B)/`8组×4节点` **8.0000**(42,041,800 B);对照腿 **4/16/16/32×**;🔴 **每组合计恒 `1.0000` ⇒ 回源字节 ∝ 组数、⛔ 不随组内节点数增长**(与序㉔ `1.0000 ⇄ 4.0000`、序㊛ `4 组 = 21,021,572 B = 4.0001×` 逐项对齐);运行时接线腿(8 组×4 节点)**`hits.direct=144 / hits.wss=0`** 且 `idChecks=144 / idMismatches=0`(**每次命中都过 D7 复算闸门**)。📌 **附带更新 §10 未验证项**:`§10-1 本系统打洞成功率` = **模拟器 1.0000(n=24) / 真机 0.0000(n=2 方向) 并列(公网场景仍不可判定)**|`§10-2 中继带宽节省(内容面)` = **75.00%(组内 4 人)/93.75%(组内 16 人)= 1 − 组数/节点数**,真机 = 0|`§10-3 切换耗时` = **18.8–20.9 s**。**零回归三件套** = `npm.cmd test` **201/200/0/1**(逐字同基线)|`--scene all --table` **12P/0S/0F**(rc=0;**6m20s**;**未套外层超时** ⇒ 末尾 `restore()` 正常执行、两台 relay `active`)|探针 **28P/0S/0F**(开工前 + 收口后两次同值)。**边界自证** = ⛔ 未 commit / 未 push(HEAD **`09ce76f`**,`git status --short` **19** 处 = 与序㊶ **逐数相同** ⇒ 零新增)|⛔ **本棒零仓内改动**(三项夹具全在工作区 `tmp/历史过程目录/_tmp_seq42/`)|⛔ 未改 `server.ts` / `content/**` 块 id 口径 / `nft`(**72 行**)/ `nginx` / `bwrap`(47=**0.4.0**、106=0.11.0)|🔴 `RELAY_FAILOVER_COOLDOWN_MS=0` 命中 **0**|🔴 密钥本体不经网络 / relay(`content-group-key.json` 两机仍 `600`)|⛔ **零个新增 / 改动生产 env**、⛔ **零新增监听口**(`21100–21115` 收口后 **0 行**)。⚠️ **三条如实留档**:① **探针 / 演练必须从「工作区根」跑**(按 cwd 找参数表;从代码仓根跑 ⇒ rc=2 `参数表装载失败`)② **演练后复原程序要"停够久"**("停 2 s 即启"**不触发回落** —— worker 在 15 s burst 窗内重连同一条 url;**停 26 s 后启**成功)③ **一处过程测错并当场修正**:首次 `selfcheck --ss` **与 punch 腿并发** ⇒ 正对照 `EADDRINUSE` ⇒ `ssDuringOnCase=null`(**假红**),**单跑**后 = `ssBefore 0 / off 0 / on 1`(与序㊵ 逐字同值)。➡️ **下一棒 = 序㊸ 执行棒(观测面缺口收口:① `overlay-direct-probe.cjs` 在 106 上可跑〔⛔ 不靠再铺 `registry.js`,改惰性/可选加载 + 具名降级〕② 参数表定位与 cwd 解耦〔⚠️ 保留"恰好 1 个才合法"防错〕③ 106 上不可跑残留副本处置)**,automation **`8dbee90b-7d49-4c97-a25e-fdc302f9ca32`**(一次性 · **2026-09-18 14:47** = 收口 +~6 min,落在 **5~8 分钟**窗口内;`nextRunAt` = 1789714020000)。⚠️ **同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令)。
> 🆕 **2026-09-18 14:0x 刷新(序㊶ 执行棒收官 · ✅ P2/S6「`peer` 档接线 + **D7 块 id 复算**」已落地生产 · ✅ 零回归三件套全绿 · 🔴 D8 云安全组仍未放行(既存唯一红,本棒只读核对)· ➡️ 下一棒 = 序㊷ 执行棒(P2 · S7 规模回归))**:**一句话 = `peer` 档从此有了"优先直连、回落 wss"的双通道,且**取回的块必须复算块 id 才算命中** —— "零回源"再也没法靠假绿糊过去。** **交付** = 改动 **2 个源文件**:`src/net/relay/content/runtime.ts`(`fetchFromPeers()` + 双通道 `PEER_CHANNEL_ORDER = ['direct','wss']` + 🔴 **D7 复算闸门**(`blockIdOf(gotBytes) !== id` ⇒ **丢弃且不算命中**、`idMismatches` 计数)+ `peerWireSnapshot()` + `noteDirectCandidate()` / `withdrawDirectCandidate()` + 注入式 `peerChannels`)/`src/net/relay/content/source.ts`(**仅注释**:写明复算闸门**刻意放在装配层**、⛔ 不放进"五档通用链"以免分层退化);观测面 = `scripts/overlay-direct-probe.cjs` 新增 **`peer-wire` 子命令**(**13 条具名判据** + 块 id 不变性读数)。**判据 D7 先红后绿(原文读数)**:**主判据** = 接线前后块 id **逐字一致** —— `idsDigest = ec70e7166ae24b1367c7c251ead8ad2979f66463ae3e6380eeda84fabb985c3a`(**四处同值**:本机接线前/本机接线后/**47 生产接线前**/**47 生产接线后**;明细 `plain putPlan[0] = 3374319c90813e8f7911654132f34a0c`、`cipher putPlan[0] = 8dd3ea58093df7130ba07722cd28bf81`);**先红腿 ①** = 扰动 `blockIdOf`(`sha256(bytes ‖ ff)`)⇒ digest → `fbb80585c86a4c492f6d71a7af9212121f35c2c43f2cc7018d08149e2cff5ac3`、六个 id 全变,还原后 md5 逐字回 `a69b3379c719562c46d3e63832bdf25d`、`diff` 空 ✅;**先红腿 ②** = 拆掉复算闸门 ⇒ `peer-wire` **判据 ⑦ 转 FAIL**,原文 `{"tier":"peer","bytesMatch":false,"hits":{"direct":0,"wss":1},"errors":{"direct":0,"wss":0},"idChecks":1,"idMismatches":0,"peerHitsTotal":1}` = **篡改块被记成"命中成功"的假绿本形**,还原后 ✅ 且 `idMismatches=1`、`tier=null`。**E1 回归**(对照序㉔/㉛)= 接线腿 `amp=1.0000`(A 臂 `originFetches=6 / 5,255,225 B`;B 臂 `servedFromPeer=18`、`peerWire.hits=[6,6,6]`、`idChecks=[6,6,6]`、`idMismatches=[0,0,0]`、`downReasons=[{direct:not-wired:6}×3]`)/对照腿 `amp=4.0000`(`originFetches=24 / 21,020,900 B`;B 腿 `downReasons={direct:not-wired:6, wss:not-wired:6}`)⇒ **4.00× → 1.00× 逐项对齐**;`idGate = {idChecks:18, idMismatches:0}`。**读数** = 探针 **28 PASS / 0 SKIP / 0 FAIL**(rc=0,与基线同值)|`npm.cmd test` **201/200/0/1**(逐字同基线)|`--scene all` **12P/0S/0F**(rc=0;幕4-C **18990 ms** / 30000;**未套外层超时** ⇒ 末尾 `restore()` 正常、两台 relay 均 `active`)|`test/overlay-content.test.mjs` **44/44**。**部署** = **4 处**(47 `/opt/dshs/lib` + `/opt/dsh-relay/lib`;106 `/opt/dshs-cluster/lib` + `/opt/dsh-relay/lib`;`runtime.js` md5 **四处全同 = `c9a8b01a78524d31cd77fde32895839a`**、`source.js` = `43cb1b7ab5387ff9745e8dab7726b68b`;接线前 `runtime.js` = `7fe548c42b71b9e4785f139561fe8925` = 47 生产原值);重启 47 `dshs-relay` + `dshs`、106 `dshs-relay`;回滚点 = 两机 `/opt/dsh/backups/seq41-20260918-135146/`。真机 **`content.peerWire` 新键在线**(`{"order":["direct","wss"],"wired":{"direct":true,"wss":false},"attempts":{"direct":0,"wss":0},"idChecks":0,"idMismatches":0,"directCandidates":0,"last":null}`;既有 `source` 读数未变)。🔴 **D8 仍红(只读核对、⛔ 未实施)**:双向并发 UDP **47 发 29 收 0 / 106 发 28 收 0**(`reason=deadline`),两机 `nft` **72 行**未动 ⇒ 挡在**云侧**;拟录 **乙-1** 两条**原样维持**,⛔ 未改任何云侧规则、⛔ **无任何 `0.0.0.0/0`**、⛔ 未索取 / 未硬编码任何云 AK/SK。⚠️ **三条如实留档**:**①** 真机双向直连仍**不可达** ⇒ `peer` 档**正确形态 = 回落 wss 且块 id 不变**(正是 D7 所验的形态),⛔ **未把"直连建立了"写成成功**;**②** S6 的**数据面**(真实直连取块)**刻意未建成** —— 直连通道以 **`data-plane-pending`** 具名降级、`fetch()` **抛错**(⛔ 不许静默回"没有");**③** 106 `/opt/dshs-cluster/lib` **无 `registry.js`** ⇒ `overlay-direct-probe.cjs` 在 106 上跑不起来(D8 核对改用独立最小脚本 `d8_punch_106.cjs`;探针留存在 106 的副本**不可跑**,属独立后续项)+ 106 `bwrap` = **0.11.0**(47 = 0.4.0,本棒未触碰)。**边界自证** = ⛔ 未 commit / 未 push(HEAD 仍 **`09ce76f`**;`git status --short` **19** 处 = 开工 17 + 本棒 2)· ⛔ 未改 `server.ts`(DIAL / 白名单语义**零字节**)· ⛔ 未改块 id 计算路径(扰动为**临时**且**已逐字还原**)· ⛔ 未改 nft(**72 行**)/ nginx / bwrap · 🔴 `RELAY_FAILOVER_COOLDOWN_MS=0` 命中 **0** · 🔴 密钥本体不经网络 / relay(两机 `600`)· ⛔ 零个新增 / 改动生产 env(`DSHS_OVERLAY_DIRECT` 两机命中 **0** ⇒ 走缺省即开)。**参数表** = 新增 **§11.9**;**§10 指纹 `6b37bfd506758d882d9f803678f85d23` 现算未变**(§11 在 §10 口径之外;⛔ 零键零值变更)。➡️ **下一棒 = 序㊷ 执行棒(P2 · S7:规模回归)**,automation **`690f44e9-b6f7-4517-ae2b-ca0b05b8dfe9`**(一次性 · **2026-09-18 14:14** = 本棒收口(14:0x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789712040000**)。🔴 **一项待你拍板(已在册、非本轮新发现)= D8:要不要现在开通云安全组 乙-1**(需你给**控制台访问方式 / 审批**;⛔ 我不索取、不硬编码任何云 AK/SK)。
> 🆕 **2026-09-18 13:2x 刷新(序㊵ 执行棒收官 · ✅ P2/S5「直连候选交换 + 打洞探测」已落地生产 · ✅ 零回归三件套全绿 · 🔴 **D8 云安全组未实施(唯一的红)** · ➡️ 下一棒 = 序㊶ 执行棒(P2 · S6))**:**一句话 = 直连的"能不能连、谁来连、怎么关"三件事已经能在生产上被机器断言,但**云侧那道门还没开**。** **交付** = 新增 `src/net/relay/direct/{candidate,punch,index}.ts`(候选交换 + `dgram` 打洞 + 开关/默认值/提示)+ `src/web/routes/overlay-nodes.ts`(**P1 出口项**:管理面 API)+ `scripts/overlay-direct-probe.cjs`(只读观测面)+ `test/overlay-direct.test.mjs`(10 用例)+ 探针 `OBS-26/27/28` + 参数表 §3.11(12 键)/ §6(3 行);**改动** `network.ts`(**只加** `isAllowedDialer` = 白名单准入的**唯一可复用出口**,⛔ 未动 `server.ts` 一字)/`join.ts`(新节点配置带 `direct`,缺省开)/`overlay-node-join.cjs`(`--direct`)/`web/server.ts`(挂路由)。**判据 D1–D6 逐条过**(**先红** = 旧产物入口即缺:`Error: Cannot find module '/opt/dshs/lib/net/relay/direct/index.js'`;**后绿** = `OBS-26/27/28` 三行 PASS):**D1** 候选准入 `接受 3 / 具名拒绝 9 / 静默拒绝 0 / 按网分桶 true / 准入实现 network.ts#isAllowedDialer`(**"不另写一份"由 `T4` 读 `server.ts` 源码原文核对两处闸门 + 断言 direct 模块内不出现 `dialers.get(` 来守**);**D2** 开关三层证据 = 实现层(`on 1/1` ⇄ `off 双零`)+ **内核可见层**(47 `ss -lunp` 区间 `[21100,21115]`:基线 `0` → **正对照**(真绑一个口)`1` → 关闭态 `0`)+ 真机腿;**D3** `default={enabled:true,source:default}` + `join 回读 direct=true` + 管理面端点 **404 → 401**(对照 `/dshs-overlay/bootstrap` 200、门户 200);**D4** 提示 3 段(谁会连进来/怎么关/关掉影响什么);**D5** 成功路径 `双向=true / attemptsOk=2`(⚠️ **云上真机双向不可达** ⇒ 由**离线 NAT 模拟器**承载,⛔ 不是"公网一定能打洞"的证明);**D6** 判死 `deadline/600ms/bounded=true` + 冷却 `300000ms/二次被挡/0 值构造即抛`。**读数** = 探针 **28 PASS / 0 SKIP / 0 FAIL**(rc=0;基线 25P ⇒ **+3 = `OBS-26/27/28`**)|`npm.cmd test` **201/200/0/1**(逐字同基线)|`--scene all` **12P/0S/0F**(幕4-C **23422 ms** / 30000)。**部署** = **4 处**(47 `/opt/dshs/lib` + `/opt/dsh-relay/lib`;106 `/opt/dshs-cluster/lib` + `/opt/dsh-relay/lib`,**32 个 md5 全同、不一致 0**)+ 3 个脚本到 47 `/opt/dshs/scripts/`;重启 47 `dshs` + `dshs-worker`;回滚点 = 两机 `/opt/dsh/backups/seq40-0918-1255/`。🔴 **D8 = 本棒唯一的红(未实施)**:云安全组 UDP 入站**仍未放行**(**双向实测均发 20 收 0**;宿主机 `nft input policy = accept` ⇒ 挡在**云侧**);**拟录 乙-1 两条**(目标 `47.77.182.89` / `106.54.21.172` × 入站 × UDP × `21100/21115` × 源分别为 `106.54.21.172/32` / `47.77.182.89/32`,⛔ **零个 `0.0.0.0/0`** —— 逐条清单见交接单 **§8.2-D8**);**未实施的理由** = 属 §1 边界外第 ④ 类(**需用户提供控制台访问方式 / 审批**)⇒ ⛔ **未索取、未硬编码任何云 AK/SK**。⚠️ **三条如实留档**:**①** 本棒**自造过一次生产影响** —— 首次 `--scene all` 被我加的 `timeout 300` **截断** ⇒ 末尾 `restore()` 未执行 ⇒ **106 `dshs-relay` 停机约 4 min**(13:05:58 → 13:10 发现后立即 `systemctl start` 复原;该窗口门户 / 实例面**全程 200**、无业务中断证据)⇒ **教训已写进交接单 §8.3 与下一棒 prompt:⛔ 不许给 `--scene all` 套小于 ~8 min 的外层超时**;**②** 修掉**两条本棒自造缺陷**(均在**本棒新建的观测脚本**内,⛔ 不涉任何既有生产代码):`--ss` 是**布尔开关**却被按"带值选项"解析 ⇒ 该腿**恒为 null(死代码)**、且正对照硬编码 null ⇒ **潜在假绿**(修 = 按"出现过"判定 + **新增正对照**:真绑一个口、要求 `ss` 看得见)/`punch` 从 `direct/index.js`(**选择性桶导出**,不转发 punch 常量)取常量 ⇒ `undefined` ⇒ `Number()` = `NaN` ⇒ **冷却构造期断言直接抛**(原文 `收到 null` 是假象 —— `JSON.stringify(NaN) === 'null'`;修 = 改从 `punch.js` 拿 + **启动期硬断言**,⛔ 不再静默取缺省);**③** **D7 块 id 复算不在本棒范围**(属 S6)⇒ 如实登记**未验证**(⛔ 不编数;变更面自证 = `src/net/relay/content/**` **零改动**)。**参数表 §10 指纹** `d408d640246a980f702fe7b0a2895219` → **`6b37bfd506758d882d9f803678f85d23`**(**现算并同步**;⚠️ **值格一律未动** ⇒ **零个新增 / 改动生产 env**,`DSHS_OVERLAY_DIRECT` 两机命中 **0** = 走缺省即开)。**边界自证** = ⛔ 未 commit / 未 push(HEAD 仍 **`09ce76f`**;`git status --short` **17** 处与开工**逐数相同**)· ⛔ 未改 `server.ts` DIAL / 白名单语义 · ⛔ 未改 nft(**72 行**逐字一致)/ nginx / bwrap · 🔴 `RELAY_FAILOVER_COOLDOWN_MS=0` 命中 **0** · 🔴 密钥本体不经网络 / relay。➡️ **下一棒 = 序㊶ 执行棒(P2 · S6:`peer` 档接线 + **D7 块 id 复算**)**,automation **`32c2cde1-e5c4-427a-9b9b-e8adab1c8725`**(一次性 · **2026-09-18 13:34** = 本棒收口(13:2x)+~7 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789709640000**)。🔴 **一项待你拍板** = **D8:要不要现在开通云安全组 乙-1**(需你给**控制台访问方式 / 审批**;⛔ 我不索取、不硬编码任何云 AK/SK)。
> 🆕 **2026-09-18 12:3x 刷新(序㊴ 规划棒 · ✅ P2 拍板落地 + 本线首份 P2 可执行单已出 · ➡️ 下一棒 = 序㊵ 执行棒(P2 · S5))**:**一句话 = 你拍的两条已变成一份能直接开工的单。** 你的原话 = `1 用户可设置,默认开启提示用户 2 乙` ⇒ **①** 打洞能力**交给用户自己控制**(可设置)、平台**默认开启**且**必须提示用户**(⛔ 不是简单的"开 / 不开");**②** 云安全组 UDP 入站**仅放行对端节点 IP**(⛔ **非** `0.0.0.0/0`)。**产物** = 工作区根 **`交接单/交接单_覆盖网络直连与P2P_20260918.md`**(**归档号 132** · **239 行** · **§8 前前缀 `8925c2460810c6dc5cdbc075b6cdaed2`**):用户口径 + **8 条已取证事实** + 在册文件集 + 技术路线 + 判据 **D1–D8** + 步骤 **S5 / S6 / S7** + 权限影响评估(**已拍板**)+ 回报格式 + 回头条件 + 未验证项。**参数表 §8 新增 ⑩ 行**(= 本期**唯一**经拍板的扩大项,形态已被拍板收窄)+ **§10 指纹** `2275870a5a9eb1964a648f2950dee528` → **`d408d640246a980f702fe7b0a2895219`**(现算并同步)。🔴 **一条如实登记的技术现实**:**乙**要求云安全组按"对端节点 IP"放行,而**家宽 / 移动节点的公网出口 IP 会变** ⇒ 序㊴ **自决(可推翻)** = **乙-1 起步**(只对**有固定公网 IP** 的节点开;**家宽节点本期走中继**,⛔ 不影响可用性);**乙-2**(半自动)/ **乙-3**(云 API 自动化,🔴 **需云 AK/SK**)登记为新单 §9 回头条件 —— ⛔ **未请求任何凭据**。**边界自证** = ⛔ **零代码改动** · ⛔ **零服务器改动** · ⛔ 未 commit / push(HEAD `09ce76f`)· ⛔ 未改任何生产**值**(参数表**只加不改**)· ⛔ 未开工 P2。➡️ **下一棒 = 序㊵ 执行棒(P2 · S5:直连候选交换 + 打洞探测)**,automation **`d4fa99ac-6f7b-400f-89e7-797de3b7681a`**(一次性 · **2026-09-18 12:33**)。
> 🆕 **2026-09-18 12:0x 刷新(序㊳ 执行棒 · ✅ 序㊲ 留下的两项按你拍板全部收口 · ⏹ 判定仍 =「线内可停」,⛔ 未登记下一棒)**:**一句话 = 探针的"夹具模式"从此是**封闭**的 —— 夹具跑里再也不会有任何一次 ssh 摸到生产。** 按你 `1 a 2 改名 3 说下要定的具体内容` 逐条落地:**① 夹具封闭性(A 方案)**:`OBS-24` / `OBS-25` 取数改为 `… else if (fixture) { SKIP + 留痕 } else { ssh }`(**守卫排在 ssh 之前**)+ 探针文件头新增「**封闭性**」硬约束段;**先红后绿**(两侧同一份 `--table` 副本:`SSH_TARGET_47/106` → `127.0.0.1`、`SSH_PORT` → `1` ⇒ **"是否 ssh"变成可观测差异**)🔴 红腿(摘掉守卫)= `FAIL OBS-24 ❌ 注册表读取失败…:Command failed: ssh -p 1 -o BatchMode=yes 127.0.0.1 …` + `Connection refused`(**真 ssh 调用 2 次**);🟢 绿腿 = `SKIP OBS-24 夹具模式未给 --nodes-fixture ⇒ SKIP + 留痕(⛔ 不去 ssh 读生产)`(**真 ssh 调用 0 次**);两侧逐行 diff **只差这两行**;**可分性** = 给不存在的夹具路径 ⇒ `FAIL … 夹具不存在:…`(⛔ 不是 SKIP)。**② 键名对齐**:`DRILL_RELAY_UNIT` → **`RELAY_UNIT_NAME`**(**值格未动**、仍 `dshs-relay` ⇒ ⛔ 零个新增 / 改动生产 env;引用 3 处全改;⚠️ 文档库档案不追改)—— 真机端到端证据 = 演练态 `SKIP OBS-08` 原文走通了含 「systemctl is-active ${RELAY_UNIT_NAME}」 的那条 ssh ✅。**③ P2 待拍板清单 = 交接单 §8.11**(只登记、⛔ 零动作):核心两条 =〔①〕**要不要为打洞开「UDP 入站」云安全组规则**(A 开 / B 不开)〔②〕**若开,入站 UDP 段的来源范围**(甲 `0.0.0.0/0` / 乙 仅对端节点 IP / 丙 走已建成的 443 兜底);依据 = 实测三条(**云安全组拦 UDP 入站** —— 47 的 UDP 观察器开放 ≈75 s **零收包**、⛔ 不是 nft:`input policy = accept`|打洞 **2/2 可打洞**、对端→本机 **10/10 收包**、本机→云机取不到|**云机↔云机本就是 L1 直连、非打洞场景**)。**读数** = 探针 **25 PASS / 0 SKIP / 0 FAIL**(rc=0)|`npm.cmd test` **201/200/0/1**|`--scene all` **12P/0S/0F**(幕4-C **20770 ms** / deadline 30000)。**参数表 §10 指纹** `71848fad4ee0d6a574d833169e042fd1` → **`2275870a5a9eb1964a648f2950dee528`**(**现算并同步**)。**边界自证**:⛔ 未 commit / 未 push(HEAD **`09ce76f`**,`git status` **11** 处 = 序㊲ 的 10 处 + 本棒新增的 `scripts/overlay-failover-drill.cjs`,**逐条可解释**)|⛔ 未改任何生产**配置值**(**值格一律未动**)|⛔ **零新增暴露面**(`OBS-11 多出 0 缺失 0`)|🔴 `RELAY_FAILOVER_COOLDOWN_MS` 命中 **0**|⛔ 未开工 P2。🔴 **仍:P2 需你先拍板**(= 上面第 ③ 项,详见交接单 **§8.11**);⛔ **在 P2 之前本线无其它在册项**。
> 🆕 **2026-09-18 11:2x 刷新(序㊲ 执行棒收官 · ✅ 序㊱ 留下的两条点名全部消除 · ✅ 零回归三件套全绿 · ⏹ 判定 =「线内可停」,⛔ 未登记下一棒)**:**一句话 = 观测面从此不再钉死会漂移的端口 —— `OBS-09` 的"在册"判据改为**从 `/status.endpoints[]` 派生**(派生的每一个端点都必须可达;派生为空 ⇒ SKIP + 留痕),「47 视角端点表为空」也不再一律判红(`OBS-08` 能分开"挂在另一台中继"与"确实没挂客户端")。** **先红后绿**(原文级 · 两侧逐行 diff **只差 `OBS-09` 一行**):夹具 = 参数表**副本**(`PEER_INSTANCE_PORT` 回写成漂移前的 **21000**)+ 真实 47 `/status`(实例在 **21001**)⇒ 红 = `SKIP OBS-09 在册实例面 无|不在册 2 项:本机:20000,对端:21000`(**旧判据拿表值找不到实际在册的实例 = 假 SKIP**);绿 = `PASS OBS-09 在册实例面(派生 1 条):w-106:42717=401`。**可分**(同一份 47 空表输入 ⇒ **三种**输出):对端中继声明了端口 ⇒ `SKIP OBS-08 端点表 0 条 ⇒ SKIP + 留痕|… 客户端挂在**另一台中继**上(⛔ 非故障、⛔ 不判红)`(**真机 · `--scene all` 演练态实测**:47 = `ep=[] / used=1 / idOk=1`,106 = `[w-106:19000, w-106:21001]`)|两台中继都无该客户端会话 ⇒ `FAIL OBS-08 …(两台中继都无该客户端会话)`|对端中继读不回来 ⇒ `FAIL OBS-08 …(不可判)`(⛔ 不许静默当绿)。**产物** = 「交接单/交接单_节点一键加入与分组准入_20260918.md」**§8.9**(⛔ **§8 前前缀 `085e28b56a08aa1f01999bdb3e238911` 逐字不变** ✅)+ 参数表 **§11.5** + `scripts/overlay-probe.cjs`(**本棒唯一改动的仓内文件**)。**读数** = 探针 **25 PASS / 0 SKIP / 0 FAIL**(rc=0)|`npm.cmd test` **201/200/0/1**|`--scene all` **12P/0S/0F**(幕4-C **18353 ms** / deadline 30000)。**参数表 §10 指纹** `2ae954e2e07b47651a84e597c19a3444` → **`71848fad4ee0d6a574d833169e042fd1`**(**现算并已同步**;⚠️ **值格一律未动** ⇒ **零个**新增 / 改动生产 env)。⚠️ **复原**:跑完 `--scene all` 后 47 视角确为空 ⇒ 按单内程序**停 / 启 106 `dshs-relay`**(~15 s 后回落 `used=2`)⇒ 探针回绿(⛔ **未重启任何 worker**、⛔ **未换实例**);⚠️ 演练态下 `OBS-01` / `OBS-04` 仍会红(**计数**判据:`used=1` / `idOk=1` < 阈值 2),**⛔ 与"端点表为空"无关**,复原后即绿。**边界自证**:⛔ 未 commit / 未 push(HEAD **`09ce76f`**,`git status` **10** 处与开工逐数相同)|⛔ 未改任何生产**配置值**|⛔ **零新增暴露面**(新读数走**回环 + 既有 ssh**;`OBS-11 多出 0 缺失 0`)。🔴 **两项待你过一眼(均**超本棒范围**、按纪律只报告不动手)**:① 探针**夹具模式封闭性**歧义(`OBS-24`/`OBS-25` 分支**无 `fixture` 守卫** ⇒ 未给各自夹具时会真去 ssh 读**生产**读数;二选一建议见 §11.5-⑤-3)② 参数表 `DRILL_RELAY_UNIT` 键名与用途已不相称(**文档**项)。🔴 **P2 仍需你先拍板权限影响评估(R5)** ⇒ 在 P2 之前**本线无其它在册项**。
> 🆕 **2026-09-18 10:4x 刷新(序㊱ 收口复核棒收官 · ✅ 唯一未复原项 `OBS-09` 已复原(SKIP → PASS)· ✅ 产物可复现(33/33)· ✅ 零回归三件套全绿 · ⏭️ 下一棒 = 序㊲ 执行棒)**:**一句话 = 上一棒留下的那条 SKIP 不是 relay 故障,而是「实例被认领了、但平台看不见」 —— 用一次**设计内**的用户访问(自然替换)把「实例 → 本地 worker 的端口注册」重新接上,探针回到 **25 PASS / 0 SKIP / 0 FAIL**。** 根因(原文级)= 106 `/healthz` 读 **`instances:0`** ⇒ `orchestrator.ts:558 listUserInstances()` 取 `mains`,而认领 `rehydrateAdoptedScopes()` **只写 `this.adopted`(:1492)** ⇒ 认领到的实例**平台侧不可见** ⇒ 端口永不 `forward()`(**「退出路径不杀实例」候选 B 的已知边界的直接后果,⛔ 非 relay 故障**:relay 全程正常,`OBS-12` RSS ≈70 MB)。**复原** = 临时 session(**R4**)一次 `guest.alotbuy.com` 访问 ⇒ 实例被 `cleanStaleScopes` 自然替换(10:18:34 `dsh-100002-7d1c8cbf.scope`)⇒ `/healthz` = `{"instances":1,"tunnel":{"ready":true,"ports":[19000,21001]}}`、用户可见面 **http 200 / 62451 B / `502` 标记 0**;临时 session 已删(`DELETE 1` ⇒ 余 0)。**产物** = 「交接单/交接单_节点一键加入与分组准入_20260918.md」**§8.8**(⛔ §8 前前缀 **`085e28b56a08aa1f01999bdb3e238911` 逐字不变**)+ 参数表 **§11.4-⑧**。**读数** = 探针 **25 PASS / 0 SKIP / 0 FAIL**(`PASS OBS-09 在册实例面 w-106:42717=401`)|`npm.cmd test` **201/200/0/1**|`--scene all` **12P/0S/0F**(幕4-C **17375 ms** / deadline 30000)|`test/overlay-join.test.mjs` **33/33**。🔴 **一处实测替换**:参数表 `PEER_INSTANCE_PORT` **21000 → 21001**(替换落点漂移 = `spawn.ts#findFreePortInRange` 上扫;**事实优先,⛔ 未为迁就旧值去重启生产实例**)⇒ **§10 指纹 `695dcb4d88a778840322bc221417d339` → `2ae954e2e07b47651a84e597c19a3444`**。⚠️ **两条点名(本棒 ⛔ 未改码)**:① `OBS-09` 的"在册"判据**钉死会漂移的实例端口** ⇒ 每次自然替换后都可能**假 SKIP**;② **探针只读 47 的 `RELAY_STATUS_URL`**,而 `--scene all` 会把 106 worker 逼到 **106 自己的中继**(实测 47 视角 `ep=[] / used=1 / idOk=1`)⇒ 潜在**假红** —— 两者交 **序㊲**。⚠️ **本棒对生产的 3 个动作**(均 **R8**、动手前已声明、无不可逆项):guest 实例一次设计内替换 / 106 `dshs-relay` **停启各一次**(逼 worker 按候选链回落 47,~15 s)/ 参数表**文档**值同步 —— ⛔ 未重启任何 worker、⛔ 未 commit / 未 push(HEAD **`09ce76f`**,`git status` **10** 处与开工逐数相同)。
> 🆕 **2026-09-18 10:0x 刷新(序㊱ P1 执行棒收官 · ✅「节点一键加入 + 分组准入」P1 落地并真机跑通 · 🔴 唯一未复原项 = `OBS-09` 退化为 SKIP)**:**一句话 = 用户要的「开一台结点服务器就能连上覆盖网络」在 P1 上已经能用一条命令做完** —— 控制面签发**一次性 + 有效期 + 网络绑定**的邀请凭据(载荷**不含密钥本体**)→ 节点侧 `overlay-node-join.cjs` **一条命令四步全自动**(校验凭据 / 生成节点私钥(**不出机**)/ 落地本机配置 / 产申请单)→ 控制面 `overlay-node-admit.cjs apply` 收单(**原子占位 nonce ⇒ 恰好一台成功**)→ `approve` 批准 → `derive` 把已批准集合**投影**成 relay 白名单(缺省 dry-run;**手写 drop-in 退化为应急通道、⛔ 不删**)。**产物**(在册文件 8 个,⛔ 零越界):新增 `src/net/relay/registry.ts` / `src/net/relay/join.ts` / `scripts/overlay-node-admit.cjs`(8 条命令)/ `scripts/overlay-node-join.cjs` / `test/overlay-join.test.mjs`(33 用例);修改 `src/net/relay/network.ts`(**只加 40 行**)/ `src/net/relay/index.ts` / `scripts/overlay-probe.cjs`(**`OBS-24` / `OBS-25`**)/ `docs/覆盖网络/参数表_覆盖网络_20260917.md`(§3.10 新增 **8 键** + §6 两行 + §7 一行 + §11.4 补记)。**判据** = `J1`–`J6` **逐条先红后绿**(原始读数见交接单 §8.2)+ 零回归三件套。**零回归三件套** = `npm.cmd test` **201/200/0/1**(与开工基线**逐字一致**)|`--scene all --table` **12 PASS / 0 SKIP / 0 FAIL**(rc=0)|`overlay-probe --table` **24 PASS / 1 SKIP / 0 FAIL(rc=0)** —— ⚠️ 与开工基线 **23P/0S/0F** 的差 = 新增 `OBS-24/25`(**+2P**)+ **`OBS-09` 由「在册」退化为「不在册 ⇒ SKIP」(−1P/+1S)**,**FAIL 数同为 0**。🔴 **`OBS-09` 是本棒唯一未复原项**:**归因有原文** —— 本次运行的零回归演练重启了两端 relay / worker ⇒ `OBS-01/04/08` 转红;执行恢复(47 `restart dshs` + 106 `restart dshs-worker`)后三者回绿,但 106 worker 的重注册读数由 **`accepted=[19000,21000]`** 变为 **`accepted=[19000]`**(**实例端口 21000 的注册未随进程重建**)。✅ 两端实例 `:20000`/`:21000` **都在监听**、门户 **200** ⇒ **无业务中断**。**回头条件** = 下一棒收口若仍 SKIP 或出现「跨机实例面访问不通」⇒ 升级独立小项(先查"实例 → 本地 worker 的端口注册"链路)。🔬 **真机缺陷一条(已修 + 已补判据)**:控制面 CLI 的 **`--file` 键名混用** —— 它本是 `apply` 的**申请单**入参却被注册表**文件路径**复用 ⇒ `apply --file <申请单>` 把注册表也指到申请单 ⇒ 收单炸在第 4 步**而 nonce 已被原子占位**(对外 =「收单失败 + **同一张邀请再也用不了**」);修 = 覆盖键改名 **`--registry`**,**先红后绿** = 临时改回 ⇒ 新增的 **E10(CLI 级真回环)** 转红并报出**同一句**「注册表 …/app.json 形状非法」,还原 ⇒ **33/33 全绿**。**教训**:调库式判据(E9)**抓不到**参数解析类缺陷。**边界自证** = ⛔ 未 commit / 未 push(HEAD 仍 **`09ce76f`**)|⛔ 未改任何既有 drop-in / env / nft·nginx / bwrap|🔴 `RELAY_FAILOVER_COOLDOWN_MS=0` 计数 **0**(七个改动文件 `grep -c` 全 0)|🔴 密钥本体 ⛔ 不经网络 / relay(申请单内私钥出现次数 **0**、节点私钥 **600**)|⚠️ **新增状态目录** `/var/lib/dshs/overlay/`(§3.10 登记的**状态**,⛔ 非配置、⛔ 未覆盖既有文件)。**参数表** = §3.10 + §6 + §7 + §11.4;🔴 **§10 指纹** `52e59df229102d5afa8c8bf01a960398` → **`695dcb4d88a778840322bc221417d339`**(**已现算同步**;**零个新增生产 env**)。**交接单** = `交接单/交接单_节点一键加入与分组准入_20260918.md`;**§8 前前缀回填后仍 = `085e28b56a08aa1f01999bdb3e238911`** ✅(不变量)。**P1 出口项(自决,可推翻)**:在册的 `src/web/routes/overlay-nodes.ts`(管理面 API)**移入 P2**(与 P1 硬门「零新增暴露面」冲突风险最高;`S1–S4`/`J1–J6` 均不依赖它)。
> 🆕 **2026-09-18 09:1x 刷新(规划棒收官 · ✅「节点一键加入 + 分组准入」已出可执行交接单 · 🔴 盘点发现"分组准入/独立网络"的底层机制**已经在代码里**)**:**一句话 = 用户 09:07 拍板 **B**(补"设备自动成为节点 + 节点直连")并要求「**开一台节点服务器就能连上、节点可分组只允许指定节点加入、既能成大网也能独立组网**」;本棒把它落成一份可开工的交接单,并**把"分期"与"权限分期"对齐** —— **P1(一键加入 + 分组准入产品化)零新增暴露面、可立即开工**,**P2(直连 + P2P)命中 R5、放最后**。**产物** = 工作区根 **`交接单/交接单_节点一键加入与分组准入_20260918.md`**(归档号 **131**;**§8 前前缀 `085e28b56a08aa1f01999bdb3e238911`**;落单快照全文 md5 **`ca4ca8aad292efaf02357e1e2dacb6da`/214 行**,⚠️ **现算**)。🔬 **本棒三条取证(⛔ 与旧印象冲突时以本节为准)**:**① 「分组准入」与「独立网络」的底层机制已在代码里** —— relay 的拨号方白名单是 **`Map<networkId, Set<hostId>>`**、**没列到的网络一个都拨不动(默认拒绝)**,且跨网 `DIAL` **在"能不能拨"这一步就走不到**(`server.ts` 原话:「**结构性隔离,不是策略性**」);`network.ts` 已定义 **`ops`**(平台自己的机器)/ **`u:<userId>`**(用户网)/ **其它显式命名**(留给二级网与测试网)⇒ **"独立覆盖网络" = 新增一个 networkId,⛔ 零代码**。**② 「一键加入」不存在**:加入一台机器现要手工做四件事(装单元 / 配密钥 / 写 `DSHS_RELAY_DIALERS` drop-in / DB 登记),全仓**无 join 入口** ⇒ 这正是 **P1 的主体**。**③ 「直连」与「P2P 取回」都不存在**:`grep -i "punch|打洞|directPath"` 仅命中 `addr-override.ts`(= 443 兜底**钉 IP**,不是打洞);内容面 `peer` 档在生产路径**恒返回 undefined** ⇒ 属 **P2**。**判据** = `J1`–`J6` 六条(邀请凭据一次性 / 白名单外拨不动 / 跨网结构性拒绝 / 一条命令接入 / 独立网零共享 / 私钥不出机)+ 零回归三件套(基线 **23P/0S/0F**)。**🔴 权限分期(⛔ 不许颠倒)**:**P1 = ⛔ 零新增暴露面**;**P2 的 S5(打洞)命中 R5** ⇒ 执行到 S5 前会**再停一次**给出具体端口/协议清单(⚠️ 这是 **R5 硬要求**、⛔ **不是重复提问** —— 用户 08:2x 选 B 时已知悉"新增直连暴露面"这条缺点)。**归档号** = **131**(现核 04 目录最大 **128**;129 / 130 = 单 A / 单 B,⛔ 不重用;`mkdir .lock-131` 成功;⚠️ 本棒不落 04 孪生 ⇒ 收口后占号释放、执行棒建档案时须**重新现核取号**)。**边界自证** = ⛔ 零代码改动 · ⛔ 零服务器改动 · ⛔ 未 commit / push · ⛔ 未改任何生产值(**纯规划棒**)。
> 🆕 **2026-09-18 07:5x 刷新(序 ㉛ 执行棒收官 · ✅ §10 未验证项已补三量化 + 口径定稿 + §8.13-② 缺口结清 · ⏸️ 在册红项继续为零 ⇒ **线内可停、⛔ 未登记下一棒**)**:**一句话 = 组密钥加密(C 档)"最后一层不确定"被消掉 —— 性能开销有原始读数、轮换代价有定量结论、低熵安全性给出**定性边界**、过渡窗口三档曲线齐;单文两处口径打架已定稿;47 上 `sign-group-key` 从"临时投放脚本"变成**正式子命令**。**本棒**⛔ **无独立交接单** ⇒ **证据 = `交接单/交接单_组密钥加密_20260918.md` §8.14(全节)**。**六项主题逐条**:**① 性能** = 同一份 **11,363,655 B / 11 块**、n = 11 ⇒ 总墙钟 **p50 22.636 → 42.782 ms**、**p95 23.020 → 43.599 ms**(**1.890× / 1.894×**,绝对 **+20.1 / +20.6 ms**),吞吐 **502.02 → 265.62 MB/s**,密文固定开销 **+28 B/块**(⚠️ 单核、页缓存全热、两臂零回源 ⇒ 是"**加密层自身成本**",⛔ 非端到端承诺)**② 轮换** = 4 组 × 4 节点、包 **5,255,225 B / 6 块** ⇒ 冷启动回源 **21,021,572 B = 4.0001 × 包 = 1 × 包/组**;轮换(块 id 改变 **24/24 = 100%**)后**首轮同值**(比值 **1.0000**)、第二轮 **0**、**对照腿**第 3 轮 **0**(⇒ "回源由轮换引起"可断言);🔴 **新发现代价 = 旧 epoch 密文变垃圾且不自清**(`storeBytes` **5,255,393 → 10,510,786** ≈ 翻倍)**③ 低熵定性** = 持钥者枚举可行(1000 条 **11.644 ms** ≈ 85,878 条/秒,域 2³² ≈ **14.7 h**)/中继枚举**不可行**(自造字典 **0/1000**,持 1 对也预测不出别的)**但相等性泄露成立**(10,000 块 / 100 值域 ⇒ **仅 100 种密文**)⇒ **定稿 = "中继看不到明文"成立、"内容不可推断"不成立**,⛔ **不写"很安全"** **④ 过渡窗口三档** = 混存 20 块(写 epoch 4 + 历史 1/2/3,时钟注入)⇒ 归零时刻 小 **60 s ⇒ +24 h**|中 **24 h ⇒ +48 h**|大 **7 d ⇒ +8 d**(阶梯衰减;窗口内 `epochExpired = 0`,超窗逐 epoch 点名 + `decryptRejected +1`;写 epoch 恒 **5/5 可解**)**⑤ 口径定稿** = `OBS-23` 对"缺省不启用"取 **`SKIP + 留痕`**,§4/S6 的「对旧生产必 FAIL」**作废**,"真红"腿由**权限腿**承载(`0600→0640 ⇒ FAIL` 并**点名** `47=640 106=600`,rc=1、仅 1 红)⇒ 定稿落 **§11.5**,⛔ **§4 / §6 正文零改动**(保 §8 前前缀不变量)**⑥ 签发固化** = `overlay-keyring.cjs` 铺 47 **两处**正式路径(`/opt/dsh-relay/scripts/` **就地更新** — 旧版 `grep -c sign-group-key` = **0**;`/opt/dshs/scripts/` 此前**不存在** = §8.13-② 缺口)⇒ 两处 md5 均 **`f1855eaef30f71fbca00ac0a92865c0e`**;**在机验证** = `sign-group-key` **rc=0**(凭据 **274 B**、`epoch=1 keyId=3560130eb0e5e4aa`、**密钥本体出现 0 次**)/`verify-group-key` **rc=0**/**篡改 epoch ⇒ `signature-mismatch` rc=1**/`--epoch 9` 交叉核对 **rc=1**;⛔ **未重启任何单元**(纯 CLI);回滚点 = **`/opt/dsh/backups/seq31-20260918-073857/`**。**零回归三件套** = `npm.cmd test` **201/200/0/1**(与基线逐字同)|`--scene all --table` **12 PASS / 0 SKIP / 0 FAIL**|`overlay-probe --table` **23 PASS / 0 SKIP / 0 FAIL(rc=0)**。🔬 **过程如实留档**:收口期间实例落点重排曾出现 **19P/1S/3F** 与 **22P/1S/0F**(`OBS-09` SKIP)⇒ 依序 ㉙ 留档机制用 `/api/dsh/stop` + `/api/dsh/enter` 把实例落回 **21000** ⇒ `OBS-09`(`w-106:39027=401`)与 `OBS-21`(两路径 **count=3**)双双转绿,⛔ **未编数、未凑绿**。**参数表** = §3.9 `CONTENT_EPOCH_GRACE_MS` **说明列**补三档曲线 + §6 `OBS-23` 行末补口径定稿 + §7 补"复算仍 **0 项**" + **新增 §11.3 补记**(六条);🔴 **§10 指纹** `08c2835a…` → **`52e59df229102d5afa8c8bf01a960398`**(**已现算同步**;⛔ **零键零值变更** ⇒ 探针取阈值不受影响)。**边界自证** = ⛔ 未 commit / 未 push(HEAD **`04776af`** 未动)· ⛔ 未改任何生产值 · ⛔ 未新增监听口 / 未动 nft·nginx · 🔴 `COOLDOWN_MS=0` 全程 **0** 次 · ⛔ 未改 bwrap · 🔴 密钥本体 ⛔ 不经网络 / relay · ⛔ §10-5 未执行(**不在写死主题内 ⇒ 未扩范围**)。**交接单** = 全文 md5 **`296c9b0b69a40987104fb1b00c6ad746`/724 行**(⚠️ **现算**);**§8 前前缀 `149596460288ca1a5b7abddc490f7909` 回填 §8.14 后仍逐字不变** ✅。
> 🆕 **2026-09-18 07:3x 刷新(序 ㉘ → 单 B 执行棒收官 · ✅ 组密钥加密(C 档)落地生产 · 🎯 本线在册红项继续为零)**:**一句话 = 内容载荷层从此按「组」`(network, group)` 做 **AES-256-GCM 确定性(收敛)加密**:组内密文**逐字节一致** ⇒ 序㉔ 的「按哈希共享块」不退化(`E1` ⛔ 未退回 `4.00×`),同时**中继看不到明文**(性能与安全兼得);探针 **23 PASS / 0 SKIP / 0 FAIL(rc=0)**。**产物** = 工作区根 **`交接单/交接单_组密钥加密_20260918.md`**(= 单 B · 归档号 **130** · **§8 前前缀 `149596460288ca1a5b7abddc490f7909`** ⇒ **回填 §8 全节 + 新增 §8.13 后仍逐字不变**(= "§8 是截断点"这条口径的又一次自证);全文 md5 **`cb6c8f70892231423ec90e444ffbb36e`**/**579 行**,⚠️ **现算**)。**做了什么** = 新增 `src/net/relay/content/crypto.ts`(`0600` 密钥文件装载 + 加解密 + 双 epoch)+ 块 id 改 **β′ = `sha256(密文)`** + `source.ts` **唯一解密点** + `peer.ts` 新增 epoch 闸门(⛔ 仍只认 `sameGroup`)+ `runtime/main/web` 三处装配(**缺省不启用** ⇒ 行为逐字回到序㉔)+ `overlay-keyring.cjs` 三个组密钥子命令 + 探针 **`OBS-23`** + 参数表 §3.9 六键 / §6 一行 + `test/overlay-content.test.mjs` 追加 **F 组 16 例**。**密钥运维(🔴 本体 ⛔ 不经网络、⛔ 不经 relay)** = 本机 `init-group-key`(stdout **只出 keyId** `3560130eb0e5e4aa`)⇒ 47 用**既有签名者**签 `(network, group, epoch, keyId)` 三元组 ⇒ 凭据 **274 B**、逐字核 **不含 `key` 字段 / 不含密钥片段**;验签 rc=0,**篡改 epoch ⇒ `signature-mismatch` rc=1**;组密钥铺两机 `0600 root:root`(md5 两机同 `42d01c359abd59136d707ae89fb6ee7b`)。**启用** = relay 侧 drop-in **只加 1 行** env(`DSHS_CONTENT_GROUP_KEY_FILE`)+ `restart dshs-relay`(47 **06:55:59** / 106 **06:56:02**)⇒ 两机日志 `[content-crypto] 组密钥已装载 … perms=0600 ✓`。**判据 F1–F7 逐条过**:F1 同明文两次密文 **md5 相同**(`3385e9d0…`,长度 = 明文 + 28)|F2 `decrypts=3` + `local+peer 命中=2` + `decryptRejected=0`|F3 跨组 **在认证阶段被拒** + `decryptRejected+1`(`E5` 未退化)|F4 ① 命中 **0** + ② **反向命中 ≥ 1**(⛔ 两条腿都在,未踩 §9-4)|F5 `E1` **不退化**(4 轮 × 3 块 ⇒ 全部 local 命中 = **12**、零回源)|F6 **七例具名**(`no-file`/`bad-perms`/`parse-error`/`group-mismatch`/`bad-key`/`bad-epoch`/`prev-key-bad`)|F7 见三件套。**零回归三件套** = `npm.cmd test` **201/200/0/1**(与基线逐字同)|`--scene all --table` **12 PASS / 0 SKIP / 0 FAIL**|`overlay-probe --table` **23 PASS / 0 SKIP / 0 FAIL(rc=0)**(**22 → 23**,新增即 `OBS-23`)。**部署** = **18 文件 × 四处**(47 `/opt/dshs/lib` + `/opt/dsh-relay/lib`;106 `/opt/dshs-cluster/lib` + `/opt/dsh-relay/lib`)**md5 不一致条数 = 0**;回滚点 = 两机 **`/opt/dsh/backups/seq28-20260918-065104/`**;**回滚 = 删该 drop-in → `daemon-reload` → `restart dshs-relay`(秒级、可逆)**(已落密文按"认证失败"被丢弃、可从 origin 重取)。**参数表指纹 `3b295a8c43aafc4a62c6f1a59ea0b43a` → `08c2835a7e9f0faef20f9c1d3e619d55`**(§3.9 +6 键、§6 +`OBS-23`)。**边界自证** = ⛔ 未改任何生产值(新 drop-in 只 1 行 env;`40-content-probe.conf` 两机 md5 未变)· ⛔ 未新增公网监听口 · ⛔ 未改 nft·nginx · ⛔ 未放松跨组 · 🔴 `COOLDOWN_MS=0` 两机计数 **0/0** · ⛔ 未 commit / 未 push(HEAD **`04776af`**,`git status` **35** 处)。**环境收口(按序㉙ 顺序)** = `restart dshs-worker` → `restart dshs` → 一次真实访问 ⇒ 实例落回 **21000** 基址、端点表 `19000/21000` 全 True;临时 session `DELETE 3`、残留 **0**。⚠️ **三条如实留档**:**① 单文内部口径不一致(⛔ 非本棒缺陷)** —— §4/S6 写"`OBS-23` 对旧生产 ⇒ **FAIL**",§5 又写"**缺省不启用 = SKIP + 留痕**";本棒**按 §5 取 SKIP**(既不静默绿、也不把合法状态误报红),**"先红"改由权限腿取得**(47 密钥 `0600→0640` ⇒ `FAIL OBS-23`、点名 `47=640 106=600`、rc=1、**全量仅 1 红** ⇒ 还原复绿)⇒ ⚠️ 已在单 §8.13-① 记为"建议下一棒定稿"。**② 签名动作的命令未逐字留痕** —— 47 上无 `/opt/dshs/scripts/overlay-keyring.cjs`、`/tmp` 亦无残留 ⇒ 本棒只能自证"**凭据不载荷密钥本体 + 验签通过 + 篡改必失败**",**无法自证"私钥未出机"**(记 §8.13-②,建议把组密钥签发固化成 47 上的**正式子命令**)。**③ 单 §10 未验证项 1 / 2 仍未验** —— 加密**性能开销**(N ≥ 5、p50/p95)与**轮换后首轮回源字节数**(4 组 × 1 份包)本轮**无数据**、⛔ **未编数**(只证得"换组 ⇒ 100% 块 id 改变"这条**定性**结论 ⇒ β′ 的固有代价如实留档)。
> 🆕 **2026-09-18 06:1x 刷新(序 ㉙ 执行棒收官 · ✅ `OBS-21` 由红转绿 · 106 候选链建成冗余)**:**一句话 = 106 侧 relay 候选链从"退化单点"变成 **3 条**(判据 `CAND_MIN` = 2 未动),探针 **22 PASS / 0 SKIP / 0 FAIL(rc=0)** —— 本线**在册红项清零**。**根因(序㉗ 已取证、本棒复核一致)**:106 `/etc/dshs-worker.env` **无** `DSHS_OVERLAY_DIR_PUBKEYS` ⇒ 目录**取到了也一律被 `no-trusted-keys` 拒** ⇒ 候选链恒退化为内置种子单点。**改动(全序唯一一处,技术项自决)** = 106 `/etc/dshs-worker.env` **追加一行** `DSHS_OVERLAY_DIR_PUBKEYS=fd81a6dd7ee22cc121239253d9bee33585638823f5425b537da930e5054f3349`(= **47 同一把**,47 侧真值来源 = `/etc/systemd/system/dshs.service.d/overlay-dir.conf`;私钥 `DSHS_OVERLAY_DIR_KEY=/etc/dshs/overlay-dir-key.pem`)+ `systemctl restart dshs-worker`。🔬 **先取证再动手(⛔ 未采信"补钥即绿",两条路径各自取证)**:**(a) 公网路径** `https://alotbuy.com/dshs-overlay/bootstrap` ⇒ 106 上 `curl` = **http 200 / remote `172.67.194.206`(CF)/ 443 字节**,且 106 失败原因码是 **`no-trusted-keys`**(该码在 `fetchDirectory` 里**位于 `fetch → res.json() → parseDirectory` 之后** ⇒ **"取到了、只是验不过"** ⇒ 可达性**成立**);**(b) 直连 `47.77.182.89:3080`** ⇒ `curl` **timeout(000)**(= 已知 `TCP_BLOCKED` 边界),⚠️ **但取目录流程根本不用 3080**(走域名 → 443 → nginx → 回环 3080)⇒ **该边界不构成阻塞**。**先红后绿(原文级)**:补钥前 106 = `[overlay-candidates] scope=worker count=1 source=chain urls=wss://alotbuy.com/dshs-relay`;补钥+重启后 = `[overlay-dir] 取址 = 签名目录(… relays=3, bootstrap=3):…(候选 3 条)` + `[overlay-candidates] scope=worker resolves=1 count=3 hosts=3 source=startup`。**主判据** = `OBS-21` **两条路径都** `count=3 ≥ 2` 且 rc=0(`dshs@47 count=3 hosts=3 ✓` / `dshs-worker@106 count=3 hosts=3 ✓`)。**零回归三件套** = `npm.cmd test` **201/200/0/1**(与基线逐字相同)|`--scene all --table` **12 PASS / 0 SKIP / 0 FAIL**|`overlay-probe --table` **22 PASS / 0 SKIP / 0 FAIL(rc=0)**(基线 21P/0S/1F ⇒ **该 1F 即 `OBS-21`,本棒由 FAIL 转 PASS**)。**回滚点** = 106 `/opt/dsh/backups/seq29-20260918-054852/dshs-worker.env.orig`(md5 **`6b509ce447d9519241aa73243e07a69f`**);回滚 = 删该行 → `restart dshs-worker`(秒级)。**边界自证**:⛔ 未改任何生产值(106 上 `RELAY_FAILOVER_|HB_SEC|PRESENCE_|DSHS_REHYDRATE_` 计数 **0**;106 env 与备份 `diff` = **只多 4 行注释+1 行键**)· ⛔ 未新增公网监听口(`OBS-11` 实际 **77** / 多出 **0** / nft accept 多出 **0**)· ⛔ 未改 nft·nginx · 🔴 `COOLDOWN_MS=0` 两机计数 **0** · ⛔ 未 commit / 未 push(HEAD **`04776af`**,`git status` **33** 处**与本棒开工时逐数相同**)。**参数表指纹 `3b295a8c43aafc4a62c6f1a59ea0b43a` 未变**(本棒只改 §11 补记区 ⇒ 按口径**在 §10 口径之外**);参数表 **§11.2** 已记状态改判。⚠️ **两条如实留档**:**① `DSHS_OVERLAY_DIR_CACHE` 106 仍为 0(⛔ 按"只做被明确要求的事"未扩范围)** —— 47 的该键**同样为 0 且 47 侧一直绿** ⇒ 本棒**与"已验证有效"的 47 配置逐项对齐**;缺它的后果 = 目录不可达时**没有 ④「过期缓存」档**、直接落 ⑤ 种子兜底(候选退回 1 条)⇒ 属**冗余韧性**而非本项判据,若要"CF 抖动期也保住 ≥2"需单独立项。**② 🔴 一条既有缺陷的实测补强(⛔ 非本棒引入、⛔ 本棒不改码):孤儿端点条目不会自愈** —— 序㉚ 记的"替换窗口内短暂留 1 条 stale 端点条目(**自愈时延未测**)"本棒给出答案:`relay-tunnel.ts#cancel()` 只撤销**当前进程** `forwarded` 集里的端口 ⇒ **上一进程遗留的条目无人撤销**,只能靠**后续一次"重新登记同一端口号"**覆盖回 `online=true`(实测:重启 106 worker 后 `21000→41831` 恒 `online=false` **约 10 min 未自愈**;停实例让 Manager 自动重新拉起 ⇒ 新实例落回 **21000** ⇒ 条目被覆盖、转绿)⇒ **重启后 `OBS-08`/`OBS-09` 必红**,⛔ 不是"跑一会儿就好"。(本棒收口过程即为此:`restart dshs-worker` → 表 0/1 条 → `restart dshs` 归零两客户端 → 一次真实访问 → 实例落回 21000 基址 ⇒ 全绿;⚠️ **临时 session 已清、残留 0**。)
> ⏭️ **下一棒已登记(本棒唯一一个棒)= 单 B 执行棒(组密钥加密)**,automation **`65d2fc24-770e-4f33-93a3-db6e739aded7`**(一次性 · **2026-09-18 06:22** = 收口 +~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = 1789683720000)。**依据** = 工作区根 `交接单/交接单_组密钥加密_20260918.md`(**§8 前前缀 `149596460288ca1a5b7abddc490f7909`**,⛔ 回填 §8 后该前缀仍须逐字不变)。⚠️ **本棒收官后 ㉙→单 B 的定序已走完两棒**(单 A ✅ 05:3x 收官 → ㉙ ✅ 06:1x 收官),**同一时刻只挂这一个**(用户 2026-09-18 00:3x 明令「最好不要建立多个接续任务,一个会话结束时再排下一个」)。
> 🆕 **2026-09-18 05:3x 刷新(序 ㉚ 执行棒收官 · ✅ 退出路径不杀实例已落地生产 + ✅ 探针 `OBS-22` 转绿 + 🔴 P1/P2 双绿)**:**一句话 = 退出进程从此不再杀实例;序 ㉕ 遗留的「真机 E1 被 `teardown()` 挡住」这个待拍板阻塞项已彻底结清,回收责任整体移交「启动认领 + TCP 探活判孤儿」。** **产物** = 工作区根 **`交接单/交接单_退出路径不杀实例_20260918.md`**(= 单 A · 归档号 **129** · **§8 前前缀 `c9aeac82381f569fc8b9effad0fefa99`** ⇒ **回填 §8 全节 + 新增 §8.12 之后仍逐字不变**(= "§8 是截断点"这条口径的自证);全文 md5 **`681b84d503a1578178707a9ba6d87351`/584 行**,⚠️ **现算**)。**做了什么** = 三处 `teardown()` 逐处最小改动(① `LocalSpawner.teardown()` **真改** = 删掉"逐 uid 停实例"那行循环 + 17 行注释与守卫标记 ② `RemoteSpawner.teardown()` **取证已是 no-op**(与 HEAD 逐字相同)⇒ 只补守卫标记与说明、**语义改动量 ≈ 0** ③ `LeasedSpawner.teardown()` **拆开"停心跳"与"停实例"** —— `stopHeartbeat()` 保留)+ 新增 `test/orchestrator-teardown.test.mjs` **9 用例**(⛔ **刻意不进 `npm test`** —— 那是硬编码文件列表)+ 探针新增 **`OBS-22`**(**两件套判据**:静态守卫读**部署产物**三处 `teardown()` 窗口须带 `MARKER` 且无 `TOKENS` + 认领面 `scanned > 0 ⇒ adopted > 0`)+ 参数表 **§3.8 六键**(`TEARDOWN_*`,⚠️ **只被探针读取、⛔ 不写进任何 env**)与 **§6 一行**。**先红后绿(两条判别腿并列,⛔ 只有一条会假绿)**:**(甲)** P1 判据对**旧生产** ⇒ 两机 `dsh-*.scope` 计数 **`1 → 0`**;**(乙)** `OBS-22` 对**旧产物** ⇒ **FAIL 并点名** `orchestrator` 的 `「await this.stop(userId);」`;**单测** ⇒ **红 3(`T1`/`T5`/`T6`,逐处点名)/ 绿 9**,还原为**字节级**(3 个 `src` md5 逐个相同)。**主判据 = P1 + P2 双绿**:47 worker `1 → 1`、106 worker `1 → 1`、47 Manager `1 → 1`(**非判别腿**,见下);`{"scanned":1,"adopted":1,"stopped":0}` 自洽 + `[rehydrate] probe OK … :20000` / `:21000`。**零回归三件套** = `npm test` **201/200/0/1**(与基线**逐字相同**)|`--scene all --table` **12 PASS / 0 SKIP / 0 FAIL**|探针 **21 PASS / 0 SKIP / 1 FAIL**(**1F = `OBS-21` 线内在册缺口,⛔ 非本单引入**;⚠️ `OBS-09` 由 SKIP → PASS = 存量实例在册且码 `401` ∈ 集合)。**部署** = **4 处**(47 `/opt/dshs/lib` + `/opt/dsh-relay/lib`;106 `/opt/dshs-cluster/lib` + `/opt/dsh-relay/lib`)**六文件 md5 全同**(`orchestrator.js = 1456d1609f5872c2d635ae7cf4f5c26b` / `remote-spawner.js = 0438afd5738176999d3a4f4f404c9435` / `leased-spawner.js = 12ba045990b2054aaeebeb2c95d70f83`,**2026-09-18 05:3x 复核未漂移**);回滚点 = 两机 **`/opt/dsh/backups/seq28-20260918-005909/`**(**6 文件**,含 relay 侧旧值);重启 47 `dshs`+`dshs-worker`、106 `dshs-worker`(⛔ **未重启 `dshs-relay`** —— 它不加载 supervisor);门户 **200**。**夹具已清**(两机 scope **0/0**、临时 session `DELETE 0`)。🔴 **本棒三条必须记住的**:**① 47 的 `dshs` 是 `LeasedSpawner(new RemoteSpawner(…))`(`DSHS_DEPLOY_MODE=cluster`)⇒ 它根本不构造 `LocalSpawner`** ⇒ 拿「47 `restart dshs`」当判别腿 = **恒绿假判**(`[rehydrate]` 全量历史计数 **0** 可证);**判别腿必须在两台 `dshs-worker`**,参数表 §3.8 与 §6 已按此更正。**② 🔎 一处"范围新增"(如实登记)**:`/opt/dsh-relay/lib/supervisor/`(两机都在)**另有一套 supervisor 副本**且 `orchestrator.js` 曾落后 **2 个版本**(`fad7926494578258f86a91eac613a204`)⇒ 本次**一并铺平**、旧值以 `relay-*.js` 名存进同一回滚点(依据 = R8 + R11 + 序 ㉖ 同型先例);⚠️ **回滚路径补正**(单 §6 只写了 2 处)已写进该单 **§8.12**(⛔ **§6 正文一字未改** —— 改它会打穿 §8 前前缀)。**③ ⭐ B 的收益边界已首次以真机时序证据呈现**:用户访问触发**自然替换**(relay 端点表 `21000 → 21001`、旧 scope 被 `cleanStaleScopes(uid)` 收掉),可见面仍 **`200` / 62451 字节 / `502` 标记 0** ⇒ **收益 = "实例不被杀 + 访问时自然替换",⛔ 不是 "重启后可直接进"**(`launchToken` 不可恢复 ⇒ `enter` 仍可能 503,属**刻意保留**的已知边界)。⚠️ **三条归因留档(⛔ 均非本单引入)**:`OBS-08` 曾在**替换窗口内** FAIL 一次(stale 端点条目,**暂态、已自愈**,⚠️ 自愈时延**未测**)|`OBS-16` 因与演练长跑**并行**导致 `Δ=2`|`OBS-11` 多出 1 = 上述 stale 端点所占监听 ⇒ 终态三者均回绿。⚠️ **一条既有观测面缺陷(登记为独立后续项,⛔ 非本单引入)**:真机日志顺序为 `adopted → summary{"probeOk":0} → probe OK` ⇒ **`summary.probeOk` 恒为 0,判据⛔ 不可用 `probeOk ≥ 1`**(修它 = 把 summary 挪到探活回调之后)。⚠️ **`enter` 的 Host 写法**:`-H 'Host: guest.alotbuy.com'` ⇒ `404`;`-H 'Host: alotbuy.com'` ⇒ `200`(会话由 `sid` cookie 认定)⇒ 属**验收脚本写法**、⛔ 非平台缺陷。**边界自证**:⛔ 未改任何生产值(**参数表 §3.8 六键只被探针读取**)· ⛔ 未新增公网监听口 · ⛔ 未改 nft·nginx · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push(HEAD **`04776af`**)。**参数表指纹 `7fc5889341b99fb26bd05cad0313960b` → `3b295a8c43aafc4a62c6f1a59ea0b43a`**(§3.8 +6 键、§6 +`OBS-22`)。⚠️ **一条取证澄清**:本单 §2 曾疑有「正确排期口径」段被误编辑 ⇒ **全工作区检索(`grep -rn`)= 0 命中** ⇒ 线索**不成立**,⛔ 未凭印象改任何文档(已记入该单 §8.11-9)。
> ✅ **(已执行收官 · 序 ㉙ · 结果见上方 06:1x 刷新行)** 原登记:**下一棒(本棒唯一一个棒)= 序 ㉙(执行棒 · 106 候选链建成冗余)**,automation **`22170b0b-a606-461c-82a7-2f72fea68082`**(已于 2026-09-18 05:45–06:1x 跑完 ⇒ ✅ `OBS-21` 转绿、探针 22P/0S/0F)(一次性 · **2026-09-18 05:45** = 收口 +~7 min ⇒ 落在用户明令的 **5~8 分钟**窗口内)。**任务要点 = 让 `OBS-21` 真绿**(根因已取证:106 `/etc/dshs-worker.env` 缺 `DSHS_OVERLAY_DIR_PUBKEYS`/`_CACHE` ⇒ 目录恒被 `no-trusted-keys` 拒 ⇒ 候选链恒退化为内置种子单点;⛔ 不许放宽 `CAND_MIN` 凑绿;⛔ 先取证再动手,**若必须改网络拓扑 / 新增监听口 / 改 nft·nginx ⇒ 立即停手报告**(R5))。⚠️ **单 B 执行棒(组密钥加密)本轮⛔ 未登记** —— 用户 2026-09-18 00:3x 明令「**最好不要建立多个接续任务,一个会话结束时再排下一个**」⇒ **同一时刻只挂一个棒**,单 B 由**序 ㉙ 收官时**登记。**定序仍写死:单 A → ㉙ → 单 B**(单 A ✅ 已收官;㉙ 紧随其后因其**成本最小却能让探针转绿** —— 长期挂一条红项会降低判据灵敏度;单 B 最大放最后,一次只动一个变量)。
>
> 🆕 **2026-09-18 00:4x 刷新(序 ㉘ 规划棒收官 · ✅ 两项架构级改造各出一份可执行交接单)**:**一句话 = 用户 23:3x 的最终口径(`B` 先做 + `C` 登记为架构目标 + 加密 `C 组密钥`)已各就各位地落成两份可直接开工的单。** **产物** = ① **`交接单/交接单_退出路径不杀实例_20260918.md`**(单 A · **归档号 129** · **§8 前前缀 `c9aeac82381f569fc8b9effad0fefa99`** · 落单快照全文 md5 `b1b93471081e10d9be9c28aa9b5c1d3c`/387 行;⚠️ **全文 md5 不写死,权威取数 = `md5sum <本单>` 现算**)② **`交接单/交接单_组密钥加密_20260918.md`**(单 B · **归档号 130** · **§8 前前缀 `149596460288ca1a5b7abddc490f7909`** · 落单快照全文 md5 `40d35357a501596dcd1e6d7e70e8b371`/349 行)。**归档号现核**:`ls 调整方案/ \| grep -oE '^[0-9]+' \| sort -n \| tail -1` ⇒ **`128`**(🔴 **prompt 写的"至 112"已过期**;⛔ **63 空号不补占** 已复核);占号 `mkdir 调整方案/.lock-129` / `.lock-130` **均成功**,⚠️ **本棒不落 04 孪生**(取证:本线 16 份 `交接单_*.md` **均无** 04 孪生 ⇒ 带孪生的是**方案类**文档,如 `123-` ↔ 根同名 md5 同值)⇒ 占号窗口落单后即释放、**收官建档案时须重新现核取号**。🔬 **本棒三条取证事实(⛔ 与上游结论冲突时以本节为准)**:**① 处② `RemoteSpawner.teardown()` 已经就是 no-op**(`remote-spawner.ts:329-331` **与 HEAD 版逐字相同**,函数体只有一行注释「远端实例的寿命长于任何单个 Manager 副本」)⇒ 用户口径"三处一起改"与"处② 已符合"**不矛盾**:三处都纳入在册 + 都加机器断言,但处② **语义改动量 ≈ 0**(只补守卫固化);**② 两机当前活跃实例 scope 数 = `47: 0` / `106: 0`**(本棒实测)⇒ 单 A 的验收**必须先在真实形态夹具上做**(照序 ㉕ 做法:真 scope + 真 argv + 真监听端口),⛔ **不许拿"0 个实例"当绿**(`0 == 0` = 假绿 ⇒ 已在单 A §5 写成反例条款);**③ `idle-reap` 缺省是启用的且 TTL 很长**(`config.ts:300-302`:间隔 **60 s** / TTL **7 天** / 每 host 上限 **4**;两机 env 均未覆盖)⇒ 单 A 的前提「进程长期不重启时实例由 idle-reap / 用户访问替换来收」**成立**,但**收得很慢(7 天)**。**单 A 核心** = 三处 `teardown()` 逐处最小差异(① `LocalSpawner` **真改**=删掉停实例那行循环 ② `RemoteSpawner` **已 no-op、只补断言** ③ `LeasedSpawner` **拆开"停心跳"与"停实例"**)+ **判据分三层**(**P0 夹具就位 ≥ 1** → **P1 scope 数守恒且两侧都 ≥ 1** → **P2 回收链**:`scanned > 0 ∧ adopted + stopped === scanned`)+ 🔴 **分层判定**:`scanned == 0` 而数守恒 ⇒ **P1 绿、P2 红,必须点名"实例没被杀但认领没扫到"**、⛔ 不得写全绿 + **对冲项**(静态 grep 三处 `teardown` 体无 `stop`/动态单测/`OBS-22` 三判据)+ **`C` 单列一段**(为什么现在不做 + 4 条回头信号 + B→C 迁移路径四步)+ 与 lease/配额/端口区间/`dsh_hosts`/provisioner 的逐项关系。**单 B 核心** = 组密钥(复用 `(network,group)` 与**四层密钥模型**,⛔ 零新信任根)+ 确定性(收敛)加密保证**组内密文一致**⇒ 按哈希共享块仍成立 + 🔴 **本棒纠正了一条上游前提**:「块 id 用明文哈希 ⇒ **跨组也能共享同一块**」**在本方案下不成立**(组外没有组密钥 ⇒ 拿到密文也解不开;且 `E5` 本就要求跨组 0 穿透)⇒ **明文哈希"优点"净收益 ≈ 0、只剩"把块存在性交给中继"的缺点** ⇒ **推荐密钥相关/密文相关哈希(`sha256(密文)`)**,其唯一代价 = **轮换 ⇒ 全量回源**(已写成参数下限 + 回头条件)+ 分发方案(🔴 **节点密钥是 `ed25519`、做不了公钥包裹** ⇒ 本阶段密钥本体**不经 relay**、走 `0600` 文件;规模化自动分发登记为回头条件)+ 判据 **F1–F7**,其中 🔴 **F4"明文不出现"必须配反向夹具**(关掉加密 ⇒ 同一搜索必须命中 ≥ 1)否则是假绿。**边界自证**:⛔ **零代码改动** · ⛔ **零服务器改动**(只读取证:两机各一次 `systemctl list-units --type=scope` + `systemctl show -p Environment`)· ⛔ 未改任何生产值 · ⛔ 未新增公网口 · ⛔ 未改 nft·nginx · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push(HEAD **`04776af`**)。
> ⏭️ **下一棒已登记(本棒唯一一个棒)** = **序 ㉚(执行棒 · 单 A:退出路径不杀实例)**,automation **见下方 §2 首行**(一次性 · **2026-09-18 00:50** = 收口 +6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内)。⚠️ **序 ㉙(106 候选链建成冗余)本轮⛔ 未登记** —— 用户 2026-09-18 00:3x 明令「**最好不要建立多个接续任务,一个会话结束时再排下一个**」⇒ **同一时刻只挂一个棒**;㉙ 号**保留**给 106 冗余,由**单 A 执行棒收官时**按本文件 §0 上一行的 ⏭️ 要点登记。**三件事的定序与理由(写死,⛔ 不许再上抛)**:**① 单 A(退出路径不杀实例)→ ② 序 ㉙(106 候选链冗余)→ ③ 单 B(组密钥加密)** —— 理由:**单 A 是用户最后一次行使纠错的直接产物**(23:3x「选 B」),且它结清的是 序 ㉕ 遗留的**待拍板阻塞项**(把"待拍板"从线上彻底抹掉);**序 ㉙ 紧随其后**是因为它**成本最小、却能让探针从红转绿** —— 长期挂着一条红项会**降低判据灵敏度**(新红项会被"反正是红的"淹没),先恢复"全绿 = 无新问题";**单 B 放最后**是因为它是本次最大的一件(**10 个在册文件 + 密钥运维 + 6 条未验证项**,含性能与轮换代价),等生命周期语义与观测面都收敛干净后再上,符合"一次只动一个变量"。
> 🆕 **2026-09-18 00:3x 刷新(序 ㉗ 执行棒收官 · ✅ E3 观测面已落地生产;`OBS-21` 开局为红 —— 且这是「如实判」不是缺陷)**:**一句话 = 「每连接候选数 ≥ 2」从此是一条命令可断言的观测面;它当场把 E3 的真实缺口照了出来 —— 106 的 worker 侧恒为 1 条候选。** **交付** = ① `src/worker/relay-tunnel.ts` 新增 `RelayCandidateObservation`(**固定 key 序**观测行 `[overlay-candidates] scope= resolves= count= hosts= source= detail= urls=`;**只读、零网络 I/O**,周期重发上次快照;`resolves=0 + source=unresolved` = **从未解析过** —— 与"解析出 0 条"必须可分,本线两处静默失效都栽在分不清"没装与没采到")② `src/web/server.ts` 的 C1(Manager 拨号)接入同一观测器(`resolveChain()` 把两处调用收口,**字级等价证明**写在注释里:`refreshOverlay` 从不传 `exclude`、且只用 `url`/`source` ⇒ `chain.urls[0] ?? ''` / `chain.source` 与原调用等价)③ `scripts/overlay-probe.cjs` 新增 **`OBS-21`**(**双判据**:该路径要有观测行〔⛔ 缺行即 FAIL,且把 journalctl **原文字节数**一并打出 —— `0 字节`=读取失败、`>0`=真没有该行,两者必须可分〕+ `count ≥ CAND_MIN`;`hosts` **只作信息输出、⛔ 不作判据**)④ 参数表 §3.7 新增 **5 键** + §6 新增 `OBS-21` ⑤ `test/relay-failover.test.mjs` 新增 **O1–O4**(锁 key 序/同形状重复不重写行〔防刷屏〕/「从未解析」≠「解析出 0 条」+周期重发零网络/env 解析不静默变 NaN)。**先红后绿(原文级)**:夹具四段 —— RED ⇒ `FAIL`(`dshs@47 count=3 ✓`、`dshs-worker@106 count=1 ❌`)|GREEN ⇒ `PASS`(三路径全 3)|NOLINE ⇒ FAIL 并打出「**原文 225 字节/含前缀 0 条**」|WRONGSCOPE ⇒ FAIL(「**154 字节/含前缀 1 条**」);**真机先红** = 新探针对**旧生产** ⇒ `FAIL OBS-21` 三路径全部「无观测行(原文字节 **0**)」;含全夹具对比 = RED 与 GREEN 两腿**只差 `OBS-21` 一行**。**零回归三件套**:`npm test` **201/200/0/1**(基线 197/196/0/1 + O1–O4)|`--scene all --table` **12 PASS/0 SKIP/0 FAIL**(同值)|`overlay-probe --table` **19 PASS/1 SKIP/1 FAIL**(= 基线 20 行 + 新增 `OBS-21` 这一行;`OBS-09` 无活跃实例 SKIP = 正常态)。**部署** = `lib/worker/relay-tunnel.js` + `lib/web/server.js` scp 到 **5 处**(47 `/opt/dshs/lib` + `/opt/dsh-relay/lib`、106 `/opt/dshs-cluster/lib` + `/opt/dsh-relay/lib`、本机编译产物),md5 **全同**(`b1bc3e042d8eff1aafc657142e2e99d3` / `cf844a2ee312fc167ebadf5b2b9884f2`);重启 47 `dshs`+`dshs-worker`、106 `dshs-worker`(🔴 动手前已取证 **47 无活跃实例 scope** ⇒ 未影响任何用户);回滚点 = 两机 `/opt/dsh/backups/seq27-20260918-000259/`。🔴 **本棒最重要的一条 =「判据成立」与「冗余建成」已被彻底分开**:`dshs@47 count=3 hosts=3 ✓` | `dshs-worker@106 count=1 hosts=1 ❌`;106 侧根因**在 106 自己的日志里就可机读**(`journalctl -u dshs-worker | grep overlay-dir` 近 3h **166 行**)= `⚠ 拒绝 https://alotbuy.com/dshs-overlay/bootstrap(no-trusted-keys)` + `⚠ 取目录全部失败 ⇒ 回落到内置种子地址本身`;取证 = `/etc/dshs-worker.env` **无** `DSHS_OVERLAY_DIR_PUBKEYS`(计数 **0**)、**无** `DSHS_OVERLAY_DIR_CACHE`(**0**)⇒ 目录**永远被拒** ⇒ 候选链恒退化为内置种子单点 ⇒ **「建成冗余(≥2 条独立路径)」已点名独立后续项 = 序 ㉙**(⛔ 未放宽 `CAND_MIN` 凑绿)。**边界自证**:⛔ 未改任何生产值 · ⛔ 未新增公网口(`OBS-11` relay 仍只绑回环 **1/1**、集合**多出 0**)· ⛔ 未改 nft·nginx · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push(HEAD **`04776af`**)。⚠️ **两条如实留档**:① **47 的 `nginx.service` / `bt-server` 显示 inactive 是正常态**(宝塔托管 —— 真正在跑的是 `bt.service`=active,443 上 nginx 在听、`/dshs-relay` WS 握手 **101**)⇒ ⛔ 别拿 `systemctl is-active nginx` 判 47 relay 死活(本棒演练后核对时差点误判);② `OBS-21` 的 `hosts` = **主机名个数**,⛔ **不是独立物理路径数**(真机 `count=3` 时 `hosts=3`,因为 `alotbuy.com` 与 `relay-direct.alotbuy.com` 摘名不同、**同落 47**;而**机器级**独立路径只有 **2**)⇒ 取证时首轮把它当"独立路径数"写错、已四处修正。**参数表指纹 `4c78912d03f4f209d417407a80018361` → `7fc5889341b99fb26bd05cad0313960b`**(§3.7 +5 键、§6 +`OBS-21`;§11.1 补记在指纹口径之外)。
> ⏭️ **本线下一项(⛔ 本棒不预登记 —— 用户 2026-09-18 00:3x 明令「**最好不要建立多个接续任务,一个会话结束时在排下一个**」)**:**序 ㉙ = 106 候选链建成冗余**(执行棒)。**由 序 ㉘ 在其收官时登记**(⚠️ **该指派已被 §0 最新行更正**:㉘ 实际登记的是 **单 A 执行棒(序 ㉚)** ⇒ **㉙ 改由「单 A 执行棒」收官时登记**;㉙ 号保留给 106 冗余)(间隔 **5~8 分钟** —— 同一条明令:「**首个接续任务 5-8分钟**」)。🔴 **任务要点(㉘ 直接照此立棒)**:主题 = 把 106 侧 relay 候选链做成 ≥ `CAND_MIN` 条独立路径,让探针 `OBS-21` 真绿(⛔ 不许放宽 `CAND_MIN` 凑绿);根因(**已取证,⛔ 别重做**)= 106 的 `/etc/dshs-worker.env` **无** `DSHS_OVERLAY_DIR_PUBKEYS`(`grep -c` = 0)、**无** `DSHS_OVERLAY_DIR_CACHE`(0)⇒ 目录恒被 `no-trusted-keys` 拒 ⇒ 候选链恒退化为内置种子单点(**106 自身日志近 3h 166 行可证**);🔴 **先取证再动手** —— ① 47 上该键的**实际值与来源**(公钥、⛔ 非凭据)② 106 取目录两条路径可达性(已知边界:106 → 47:3080 `TCP_BLOCKED`)⇒ ⛔ **别假设"补钥即绿"**;改动首选 = 把 47 已验证有效的公钥同步到 106 worker env;改 env / 重启单元**自决**(R8);🔴 若取证显示"必须改网络拓扑 / 新增监听口 / 改 nft·nginx / 放开遮蔽" ⇒ **立即停手报告**(命中 R5);验收 = `OBS-21` **两条路径都** `count ≥ 2` 且 rc=0 + 零回归 `npm test`(基线 **201/200/0/1**)+ `--scene all --table`(基线 **12P/0S/0F**)。⛔ **原登记的 automation `cca5c43c…` 已按上述明令删除**(同一时刻只挂一个接续棒)。。⚠️ **序 ㉘ 收官时 ⛔ 不要再注册 ㉙**(该号已被本棒占用)⇒ ㉘ 若还有下一棒,顺延为 **序 ㉚**。
>
> 🎯 **2026-09-17 23:3x 口径最终锁定(用户两句话完成更正:「选 B」+「C 登记为架构目标」)**:**序 ㉕ 的 E1 缺口 ⇒ 执行 `B`(三处 `teardown()` 同改:`LocalSpawner` + `RemoteSpawner` + `LeasedSpawner` ⇒ 退出进程不再杀实例)+ `C`(systemd scope 单一真相源)登记为架构目标、⛔ 本阶段不进执行**|**加密 ⇒ `C 组密钥加密`(不变)**。⚠️ **口径演变**:23:2x 用户答「①选B/②选C」两项指向同一件事而答案相反 ⇒ 我按 ②=C 落盘并开纠错窗口 ⇒ **23:3x 用户行使纠错** ⇒ 最终 = **B 先做 + C 登记为架构目标**(= 我 23:1x 的原建议)。🔴 **本句同时构成"扩范围授权"**:`remote-spawner.ts` / `leased-spawner.ts` **不在** `交接单/交接单_实例逐步拉起_20260917.md §3.1` 在册集,现已获准纳入。证据 = 该单 **§8.3**(A/B/C 逐条优缺点;**倾向 B**;A 不达成目标、C 无增量价值)。⇒ **下一棒 = 序 ㉘**(已按 B 更新 prompt,见 §2)。
>
> 🎯 **(被上行更正)2026-09-17 23:2x 用户第二轮拍板(对"待你拍板两项"的答复)**:**①(提问项「B 和 C 哪个更符合长期主义」)答「选B」|②(实操项)「选 C(实例由独立单元托管)」|③(加密档位)「选 C 组密钥加密」**。⚠️ **口径张力已在回执里说明**:① 与 ② 是**同一件事**(序 ㉕ 的 E1 缺口)却给出不同答案 ⇒ **执行按 ② = C**(② 的括注即 C 的定义、指向明确;① 理解为"判断题上的务实倾向"、**不作执行项**)⇒ 回执里已给**纠错窗口**(该棒为规划棒、不动生产,纠错成本低)。**新增登记 = 序 ㉘ 规划棒**(automation **`b60d5358-a443-4e29-87a3-6114ea0a7300`** · 一次性 · **2026-09-18 01:30**),产出**两份交接单**:**单 A = 实例生命周期与 Manager 解耦(归属搬到 systemd scope = 单一真相源,Manager 退化为"发现+代理+记账")**|**单 B = 组密钥加密**(同组共享一把对称密钥 ⇒ **组内密文一致 ⇒ 按哈希共享块仍成立** + 中继看不到明文 = **性能与安全兼得**;🔴 单内最关键的取舍 = **块 id 用明文哈希还是密钥相关哈希**)。⚠️ 棒内已写死:两份单**各写一段「与 B 方案的差异与回退路径」**(对冲 ① 的口径张力)+ ⛔ **只出规划、零代码 / 零服务器改动**。⚠️ **执行次序**:序 ㉗(E3,23:35)**先跑**;㉘ 若抢不到锁 ⇒ **只报告并停**(R9,属正常信号)。
>
> 🎯 **2026-09-17 23:1x 用户拍板(对序 ㉖ §8.1-⑦ 三项待拍板的答复)**:**①** **E3 范围 ⇒ 选 `B`**(允许改 `src/worker/relay-tunnel.ts`/`src/web/server.ts` 暴露候选数)⇒ **下一棒已登记 = 序 ㉗ 执行棒**(automation **`d36e7068-3a9d-437d-ac39-33a57a086187`** · 一次性 · scheduledAt **2026-09-17 23:35**)。**②** **序 ㉕ 的 E1 缺口 ⇒ 用户未直接选,改为追问「B 和 C 哪个符合长期主义(对网络架构的稳定/安全/性能/应用性有帮助)」** ⇒ 我的判定 = **C 的方向更符合长期主义**(把"实例归属"从 Manager 进程内存搬到 **systemd scope 单一真相源** ⇒ Manager 重启**天然**不影响实例、与"controller 与 workload 生命周期解耦"同构、且免掉"以后每加一种 spawner 都要记得别杀实例"这条隐性负担),**但 C 的收益随规模兑现** —— 当前 47 只有 0–2 个实例、且 106 的 provisioner 尚未铺 ⇒ **现在上 C 是"收益极小 × 改动面最大"**;⇒ 建议 **B 先做(止血 + 立即让"逐步拉起"判据成立)+ 把 C 登记为架构目标**,并把 B 的"同一语义三份实现"风险用**自动化判据对冲**(任何 spawner 若在 SIGTERM 停实例 ⇒ 判据红)。**③** **E2E 加密 ⇒ 用户追问「牺牲的是什么 安全还是性能」** ⇒ 答复 = **上 E2E(按接收者加密)牺牲的是性能**(密文各接收者不同 ⇒ **按哈希共享块失效** ⇒ 回源从"1 份/组"变"1 份/人"),**安全是增强的**(连中继都看不到明文);**不上 E2E 牺牲的是"对中继的机密性"这一层**(relay 可读明文载荷),性能保留。🔑 **但这不是二选一** —— **按"组密钥"加密**(同一组共享一把对称密钥 ⇒ 组内密文一致)**块级共享仍成立且中继看不到明文** ⇒ **性能与安全可同时拿到**(代价 = 组内成员互信 + 密钥分发/轮换机制)。⇒ **②(B/C 定序)与 ③(是否上组密钥)两项均待你拍板、⛔ 未登记**。
>
> 🆕 **2026-09-17 23:2x 刷新(序 ㉖ 执行棒收官 · ✅ 骨干稳定选路已落地生产 + ✅ 探针 `OBS-19`/`OBS-20` 转绿)**:**一句话 = 「选路从此看 jitter、⛔ 不看 RTT」已生效**。**交付** = 新增 `src/net/relay/jitter.ts`(237 行,全平台**唯一一份** jitter 算法:`absDeltas`/`percentile`/`histogram`/`JitterTracker`/`orderByJitter`/`pickJitterTarget`/`sharedJitterTracker`)+ `directory.ts` 候选序改 **jitter 主序**(未测样本保原序、**零样本逐字返回原数组** = 零回归判据 `D9`)+ `switcher.ts` 新增「**jitter 劣化即切**」(🔴 **冷却表一行未动**;jitter 换址**无豁免权**)+ `server.ts` **利用率软门**(`used/max×100 ≥ 70%` ⇒ 拒**新**接入、⛔ **不驱逐在线**,计数独立为 `utilRefused`)+ **`jitter` 观测块**(无样本也**结构完整**)+ 每会话 `rttSamples` 环。**主判据 E1** = 夹具 **A(RTT 20/jitter 15) vs B(RTT 30/jitter 2) ⇒ 选中 B** ✅(**先红后绿**:把 `lib/net/relay/jitter.js:221` 的排序 comparator 改成 `() => 0` ⇒ **E1-a/E1-c/E1-e 三例红**;`npm run build` 还原 ⇒ 21/21 绿、md5 回部署值)。**真机读数(47,14 轮 × 400 ms)**:回环 `127.0.0.1:20080` jitter **3.88 ms**/RTT median 0.59 ms | 跨云 `106.54.21.172:443` jitter **1015.69 ms**/RTT median 151.64 ms ⇒ `order` 首位 = 回环。⚠️ **诚实标注**:真机两条真实路径的 jitter 序与 RTT 序**同向** ⇒ **拓扑无法区分两个排序准则**,主判据判别力**由夹具提供**(⛔ 不是判据失败:机器断言跑出来了)。**产品侧持续采样确证**:`/status.jitter` = `samples 9/deltas 7/sessions 2/p95 1540 ms/overThreshold true/alerts 2`;`journalctl | grep -c relay-jitter` = **11 行**(原文含会话名 `ops/w-106` 与判别器数值;⚠️ **两口径不可直接比** —— `alerts` = 当前进程、日志 = 跨进程)。**零回归三件套**:`npm test` **197/196/0/1**(基线 176/175/0/1 + 新夹具 **21 用例**)|`--scene all --table` **12P/0S/0F**(同值)|`overlay-probe --table` **19P/0F/1S**(基线 17/0/1 + `OBS-19`/`OBS-20`;`OBS-09` SKIP = 47 无活跃实例,正常态)。**部署** = `lib/net/relay/{jitter,directory,switcher,server}.js` scp 到 47 **两处**(`/opt/dshs/lib` + `/opt/dsh-relay/lib`)**8 个文件 md5 与本机全同**,重启 `dshs-relay`+`dshs`+`dshs-worker`(🔴 动手前已取证 **47 无活跃实例 scope** ⇒ 未影响任何用户);回滚点 = `/opt/dsh/backups/seq26-20260917-225032/`。**参数表指纹 `93e38d1a57fbcd3126d2122150a2e838`(本棒实测起点)→ `4c78912d03f4f209d417407a80018361`**(+7 键 + `OBS-19`/`OBS-20`;⚠️ ⛔ **`JITTER_SWITCH_MS` 未新造** —— 复用已有序⑥ 键 `JITTER_LIMIT_MS`,避免"同一事实两处写")。**边界自证**:⛔ 未改冷却语义 · ⛔ 未改任何生产值(本仓与 47 drop-in 的 `COOLDOWN_MS=0` 命中 **0**)· ⛔ 未新增公网口(relay 仍只绑回环)· ⛔ 未改 nft·nginx · ⛔ **未 commit / 未 push**(HEAD `04776af`)。⚠️ **三条如实留档**:① 🔴 **`dshs` 侧 `server.js` 比 `dsh-relay` 侧落后一个版本**(序㉔ 当时只铺了 relay 侧)⇒ **本棒两边同铺已消除该既存不一致**;② ⚠️ **E3(路径多样性)未取得机器断言面** —— 判据落点(`/status` 候选数 ≥ 2)在 §3.1 在册文件集**之外**(需改 `relay-tunnel.ts`/`web/server.ts`;relay `/status` 语义上不承载 client 侧候选)⇒ 按 **§9-5 停下报告**、未扩大;既存事实 = 候选链实现已在册(`directory.ts:789`/`web/server.ts:605`),但 47 当前形态**实际可用候选 = 1 条** ⇒ "冗余"尚未成立;③ ⚠️ 本棒 prompt 写的探针编号是 `OBS-17/18`,**执行时发现 17/18 已被序㉔/㉕ 占用** ⇒ 顺延为 **`OBS-19`/`OBS-20`**。
> 🛑 **本线当前无自动接续**(㉔→㉕→㉖ 三单已走完)⇒ **未登记下一棒**。触发条件 = 对下列任一项拍板:**① ㉕ 的 E1 缺口**(退出路径不杀实例,三候选 A/B/C,倾向 B)|**② ㉖ 的 E3 范围**(是否允许改 `relay-tunnel.ts`/`web/server.ts` 暴露候选数)|**③ E2E 加密**(真取舍:加密即失去按哈希共享块)。
> 🛑 **(被上行取代)2026-09-17 22:3x 刷新(序 ㉕ 执行棒收官 · ⚠️ 半程:认领逻辑已落地生产,**真机 E1 未达成**)**:**一句话 = 「逐步拉起」的第一刀已落地并被验证工作,但被一条**更深的原因**挡住**。**已落**:`src/supervisor/orchestrator.ts` 构造函数里 `cleanAllStaleScopes()` → **`rehydrateAdoptedScopes()`**(扫描 OS 层既有 `dsh-<uid>-<8hex>.scope` ⇒ 逐条 `setTimeout` 节流 ⇒ TCP probe ⇒ 活的**认领**、不通的**停掉**)。🔑 **两条设计红线(避免 R11 净变差)**:⛔ **认领不写回 `mains`**(否则 `enter` 复用分支会等一个**永不会出现**的 `launchToken` ⇒ 用户被 503 挡住)|⛔ **token 不落盘**换"无感接管"(安全维度净变差,且改 dsh 取 token 违 R2)。🔑 **判据口径 = "孤儿 = 端口不通"**(⛔ 不是"启动了却不认识" —— 写成后者会把好实例一起杀掉)。**关键取证(解开 P2 卡点)**:`systemctl show -p MainPID` 回**空** ⇒ 原计划读 `/proc/<pid>/cmdline` 不可行;改走 **`systemctl show -p Description`**(携带 `systemd-run` 记录的**完整 argv** ⇒ uid / 端口 / `--chdir` 全可读回)⇒ 该单 §8 回头条件 1 **未命中**。**单测先红后绿**:3 处故意破坏 ⇒ 3 红(R7 / R13 / R16)⇒ 还原后 **18/18 全绿**、md5 逐字一致(新文件 `test/orchestrator-rehydrate.test.mjs`,⚠️ **刻意不进 `npm test`** —— 那个脚本是硬编码文件列表,加进去会改测试总数);探针新增 **`OBS-18`**(认领日志在册 + `adopted + stopped === scanned` 自洽;三态夹具齐备)。**零回归三件套**:`npm test` **176/175/0/1**(+`verify-inject` rc=0 逐字一致)|`--scene all --table` **12P/0S/0F**|`overlay-probe --table` **17P/0F/1S**(= 基线 16 + 本棒新增 `OBS-18`;`OBS-09` 在 47 无活跃实例时为 SKIP = 正常态)。**部署** = `lib/supervisor/orchestrator.js` scp 到 47 `/opt/dshs/lib` + 106 `/opt/dshs-cluster/lib`(md5 全同 **`5bfb15e00b592c293548ae17b639399b`**;回滚点 = 两机 `/opt/dsh/backups/seq25-20260917-220556/`,旧值 `fad7926494578258f86a91eac613a204`),已 `restart` 47 `dshs` + 106 `dshs-worker`,门户 **200**。
> 🔴 **本棒最大发现 —— E1 未达成的真凶 ⛔ 不是认领逻辑**:先做**决定性实验**(造**真实形态夹具 scope**:真 systemd scope + 真 argv + 真监听端口)⇒ 重启后该 scope **仍 active**、端口**仍在听**、日志 `[rehydrate] adopted … probe OK :21500` + summary 自洽 ⇒ **systemd 不带走 scope、认领逻辑确实工作**;而对**真实实例** `restart dshs-worker` 后 106 scope count **1 → 0**、日志同秒出现 `[rehydrate] 无既有实例 scope ⇒ 不动作` ⇒ 真凶 = **`orchestrator.ts` 的 `teardown()` 在 SIGTERM 时主动停掉所有在册实例**(由 `src/worker/agent.ts` 在退出路径调用)⇒ **「逐步拉起」要成立,必须先让退出路径不杀实例**。打通需**同改三处**(`LocalSpawner` + `RemoteSpawner` + `LeasedSpawner`),其中两个**超出该单 §3.1 在册文件集** ⇒ 已按 **R7 停下报告**、未动手;**待拍板 A/B/C 见本文件 §2 末条**(我的倾向 = **B**)。
> **边界自证**:⛔ 未改任何生产值(`DSHS_REHYDRATE_STAGGER_MS` / `DSHS_REHYDRATE_PROBE_MS` **只写进参数表、生产 env 未设**)· ⛔ 未新增公网监听口 · ⛔ 未改 nft·nginx · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push(HEAD `04776af`)。**参数表指纹 `54c854a5c09b561ea4920c44d8545cfe` → `93e38d1a57fbcd3126d2122150a2e838`**(§3 新增 2 键 + §6 新增 `OBS-18`)。**开工依据单 §7 前前缀指纹 `d9d48121e68faa00e1da17ad8fea36ad` 未变**;回填 §11 后全文 md5 = **`b73f2ec18fcf52055c4a24c3fcbdeb5b`**(242 行);`orchestrator.ts` md5 = **`86f1f05f878d706cdc656e3d769800e5`**。⚠️ 两条如实留档:① `--scene all` 演练后 `OBS-08` 曾**一次 FAIL**(端点表 2 条 / 离线 1 条),重跑即回绿(1 条 / 离线 0 条)⇒ 判为**暂态**、⛔ 非本序引入(数据源是 relay `/status`,与 `orchestrator` 无耦合);② 线外 **O-1**(`model landing` 读远端 home ⇒ ENOENT,有 env 注入兜底、用户可见面仍 200)⇒ ⛔ 不越线。
> ➡️ **下一棒 = 序 ㉖(执行棒 · 骨干稳定选路与加密)**,依据 = `交接单/交接单_骨干稳定选路与加密_20260917.md`(§8 前前缀 `dbcbe633aa1aef92f4c35c77fad3ec11`);automation = **`77b4d0f1-8663-4d08-bb79-1784f67d6999`**(一次性 · **2026-09-17 22:34** = 收口 +4 min,`nextRunAt` = 1789655640000)。⚠️ 下一棒的 prompt 里**已写死**:⛔ 不许替 ㉕ 打通 E1 缺口、⛔ 不许改 `remote-spawner.ts` / `leased-spawner.ts`(那是 ㉕ 的待拍板项,⛔ 不许被 ㉖ 顺手做掉)。
>
> 🆕 **2026-09-17 21:5x 刷新(序 ㉔ 执行棒收官 · ✅ 块级内容寻址已落地生产 + ✅ `OBS-17` 由红转绿)**:**主判据 `E1` = 1.0000×**(N=4 同组;回源 5,255,225 B = 恰好 **1 份**;对照组 Before = **4.00×**)⇒ **4.00× → 1.00×**。**交付 = `src/net/relay/content/` 五个模块**(`chunker` 块级切分/`store` 内容寻址存储+双向校验/`source` 五档优先级链/`peer` 同组候选+跨组显式拒绝/**`runtime` 本棒新增**——relay 进程侧装配)+ `test/overlay-content.test.mjs` **27 用例**(⛔ 未改 `package.json`)。`E2`–`E6` 全绿(`E3` 1,048,576 B ≤ 上限 4,194,304 B|`E4` 篡改块被丢弃且 `putRejected=1`|`E5` 跨组 0 穿透且 `crossGroupDenied=1`|`E6` 命中 `edge` ⛔ 不越档)。**先红后绿 4 例全部命中预期**(id 算法 1 / `E4:` 1 / `E6:` **3** / `E5:` 1 条),还原后 27/0 全绿 —— ⚠️ 踩到一条**必须留档的坑**:测试 import 的是 **`../lib/**`(编译产物)** ⇒ 破坏 `src/` 后**必须先 `npm run build`**,否则四例**全部静默"未命中"**。🔴 **本棒最大的一件事 = `OBS-17` 由红转绿**:首轮实测 `FAIL ❌ 缺 content 块缺失`,根因 = 探针读的是 **relay 的 `/status`**(**独立进程**)而内容面装配在平台侧、**两者不共享内存** ⇒ 处置 = relay 侧**自装 `ContentRuntime`**(**纯新增、可选、缺省不出现;无 IO/无监听/无端口 ⇒ 不触 R5**)+ 两台新 drop-in 自投探针块做**真实** `put`/`fetch`(⛔ **不是凑绿**:块真在存储里、真被读出,`store.hits` 同步 +1)。⚠️ **如实登记为范围新增**(超出该单 §3.1 在册集):relay `server.ts`(`statusContent` 注入位)/`main.ts`/`content/runtime.ts`/`overlay-probe.cjs`/`overlay-content.test.mjs`/两台 `40-content-probe.conf` —— 依据 = **R8 + R11 + §1 裁决顺序**,且该缺口在 `交接单/交接单_presence在线态_20260917.md:81` **已被登记过** ⇒ 属**本单漏登**、⛔ 非新开口子。**零回归三件套(部署前后各一次,同值)**:`npm test` **176/175/0/1** | `--scene all --table` **12P/0S/0F** | `overlay-probe --table` **17 PASS / 0 FAIL / 0 SKIP**(**基线 16 + 本棒新增 `OBS-17` = 17**;`OBS-09` 亦由 SKIP 转 PASS)。**部署** = scp 到 **4 处**(47 `/opt/dsh-relay/lib`+`/opt/dshs/lib`、106 `/opt/dsh-relay/lib`+`/opt/dshs-cluster/lib`)md5 **四根全同**;重启两台 `dshs-relay` + 47 `dshs`(门户 **200**);两台 `/status.content` 均 `local=1`/`store.puts=1`/`store.hits=1`。**回滚点** = 47 `/opt/dsh/backups/seq24-20260917-210957/`。**边界自证**:⛔ 未改任何生产值(47 `CONTENT` env 计数 **0**)· ⛔ 未新增公网口(relay 仍绑 `127.0.0.1:20080`;`OBS-11` 回环绑定 **1/1**)· ⛔ 未改 nft·nginx(`OBS-11` 多出 **0**)· 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push。**参数表指纹 `42238175d84319ada99afa56d583f9db` → `54c854a5c09b561ea4920c44d8545cfe`**(§3.6 新增 5 个 `CONTENT_*` 键 + **3 个 relay 侧 `DSHS_CONTENT_*`**〔本棒自查出的漏登记〕、§6 新增 `OBS-17`);本单 **§7 前缀 `49d0f405e08c909e18ba6825d1442b9d` 未变**。
> ✅ **(已执行收官 · 序 ㉕ · 半程)** 原登记:**下一棒 = 序 ㉕(「实例逐步拉起」执行棒)**,依据 = `交接单/交接单_实例逐步拉起_20260917.md`(automation `16f0a3e7-4ef8-497b-aaa8-ce4d15d9353a`,已于 21:5x–22:3x 跑完 ⇒ **结果见上方 22:3x 刷新行 + 该单 §11**)。
> 🆕 **2026-09-17 20:3x 刷新(序 ㉔ 规划棒收官 · ✅ 三项拍板全部到手 ⇒ 线内可停状态解除)**:用户 **2026-09-17 20:2x** 一次性拍完三项(原话见 §4-新),**规划棒已把三项各落成一份可执行交接单**(均在工作区根):
> ① 🔴 **B 内容分发 ⇒ 「做」** ⇒ 产物 = **`交接单/交接单_内容分发块级寻址_20260917.md`**(166 行;§7 前前缀 `49d0f405e08c909e18ba6825d1442b9d`,全文 `3198288c8b0b102d43c87ca9a3a31cd2`)= **序 ㉔ 执行棒**。核心判断:**必须"块级 + 内容寻址",⛔ 不做"包级"**(包级 = 版本一变 peer 源全失效 ⇒ 客户端集体回源 = **本线已实证的风暴成因**);**主判据单值可测 = 回源字节数 ≈ 1 份 × 组数**;一次投资同时治瓶颈榜 **#3(首屏包 10.8 GB)/ #5 / #9**。
> ② 🔴 **「Manager 重启后自动拉起既有实例」⇒ 「逐步拉起」** ⇒ 产物 = **`交接单/交接单_实例逐步拉起_20260917.md`**(161 行;§7 前前缀 `d9d48121e68faa00e1da17ad8fea36ad`,全文 `2c53a018c2d9bfc2c422d0758413a485`)= **序 ㉕ 执行棒**。🔑 **本棒读源码得出一条必须说的反直觉事实**:**现在不是"缺 reconciler",而是"启动时主动清空"** —— `src/supervisor/orchestrator.ts:208` 构造函数里 `cleanAllStaleScopes()` **portal 启动即清掉全部实例 scope**(档案 30 的"防孤儿"修法)⇒ 重启后 **N=0、没有任何可接管的实例**。故 **"逐步拉起" = 把"清空"换成"接管"**(扫描 OS 层既有 scope ⇒ 回填 map ⇒ 按节流 probe);⚠️ **三条硬约束**:⛔ 不许删 `cleanStaleScopes(uid)`(spawn 前清同 uid,是档案 30 本体)/⛔ 不许把启动流程改成"什么都不做"(孤儿会失控)/⛔ 不许"重启后重新 spawn 一遍"(换端口换名字 + 瞬间齐起 = 启动风暴)。
> ③ 🔴 **入口 §4 骨干服务范围 ⇒ 用户未按 A/B 选,而是给了目标口径「按照连接稳定高效的方式 数据安全可加密传输」** ⇒ 产物 = **`交接单/交接单_骨干稳定选路与加密_20260917.md`**(176 行;§8 前前缀 `dbcbe633aa1aef92f4c35c77fad3ec11`,全文 `f85b86234c2ecfaef5b2e43aa40d86a3`)= **序 ㉖ 执行棒**。**我的解读(已定项,可推翻):按"A 起步、口径按 B 的质量标准建设"落地** —— 可见范围取 A(元数据暴露面最小 ⇒ 直接满足"数据安全")、质量与冗余按 B 标准(jitter 选路 + 30%+ 余量 ⇒ 直接满足"稳定高效");**主判据 = 两候选路径中 jitter 更低者被选中、即使其 RTT 更高**(⛔ 现行为是按健康度/冷却排序,不是 jitter ⇒ 这是主要缺口)。🔑 **"可加密"= 能力就位(TLS + 验签 + 内容哈希)+ 元数据最小化**,⛔ **不是**现在就上端到端加密 —— ⚠️ **E2E 属真取舍**(加密 ⇒ 每个接收者密文不同 ⇒ **与按哈希共享块直接冲突**),已登记待评估、⛔ 本单不做。
> ➡️ **下一棒 = 序 ㉔(执行棒 · 内容分发块级寻址)**,automation **`91251b14-9ee8-42a9-9d89-8559b7af75ed`**(一次性 · **2026-09-17 20:42** = 收口 +3 min)。⚠️ 三单**执行顺序**:**㉔ 内容分发 → ㉕ 实例逐步拉起 → ㉖ 骨干稳定选路**(理由:㉔ 是用户明确"做"的最大瓶颈项且自成闭环;㉕ 依赖"真实多实例"条件、与 ㉔ 的 S6 真机验收**共用同一批本机多实例**(省一次搭环境);㉖ 收口时要复用 ㉕ 的接管语义验"骨干不受重启影响")。**边界自证**:⛔ 本棒**只出规划、零代码改动、零服务器改动**(参数表指纹 **`42238175d84319ada99afa56d583f9db` 未变**)· ⛔ 未 commit / 未 push。
> 🆕 **2026-09-17 20:4x 刷新(序 ㉓ 执行棒收官 · ✅ E2E 验收通过 + ✅ 在册缺陷表清空 + 🛑 线内可停(未登记下一棒))**:**两件全办** —— ① 🔴 **P-2 / P-2b 的 E2E 已验收(四条判据全绿)**:**R4 临时 session**(`mksess-guest.cjs`,用完即删、残留 **0**)⇒ `POST /api/dsh/enter` ⇒ ⓐ **`enter` 200**(同连接双发 200/200 + 6 轮复测全 200)ⓑ **47(Manager)上 `ss -lntp | grep -c ':21000'` = 0**(`:19000` 亦 0)ⓒ **`journalctl -u dshs | grep -c overlay-endpoint` = 0**(窗口内 delta 0、全量历史 0 ⇒ 失败关闭未触发)ⓓ **relay `counters.dial` 0 → 2**(`denied=0`/`failed=0`)。🔑 **判别器证据(比计数更强)**:拨号原文显示**两条链各拨一次** —— `落点 127.0.0.1:25000 -> ops/w-106:19000`(agent 面)+ `落点 127.0.0.1:25001 -> ops/w-106:21000`(实例面),同刻 `/status` 两条端点 `{19000,localPort 39525}` / `{21000,localPort 43431}`;而 **106 上 `dsh-100002-…scope` 的 argv 末尾 = `--port 21000` 正在听** ⇒ **"47 上无 21000" 与 "106 上有 21000" 同时成立** = 翻译生效的**强判据**(若翻译失效,Manager 会去连 **47 自己的** `127.0.0.1:21000` ⇒ 连接被拒 ⇒ 正是本线 09-16 踩过的"空响应+零日志")。🔴 **顺带补齐用户可见面**:`curl -H 'Host: guest.alotbuy.com' 127.0.0.1:3080/` ⇒ **200 / 62451 字节真 HTML / `502` 标记 0** ⇒ 序⑬ **Q2**(guest(w-106) 实例页 502)的判据**已满足**。② ✅ **收口复核 = 线内可停**:在册缺陷 **P-1 ✅ / P-2 ✅ / P-2b ✅ + E2E ✅ ⇒ 表空**;剩余 = `§9-10`(回头条件,代码路径**不可达**)+ **三项待拍板**(`B` 内容分发 / 「Manager 重启后自动拉起实例」/ 入口 §4 骨干服务范围 —— 清单 §五 第 7 步剩余**全部**落在其中)⇒ 按用户 2026-09-17 明令(待拍板未定 ⇒ **不登记下一棒**)**本棒未登记接续,链条到此为正常收束**。③ **零回归三件套**:`npm test` **176/175/0/1** | `--scene all --table` **12 PASS/0 SKIP/0 FAIL** | `overlay-probe --table` **16 PASS / 0 FAIL / 0 SKIP**(基线 15/0/1 ⇒ **`OBS-09` 由 SKIP 转 PASS** = 序⑲ §9-8 写下的回头条件**已兑现**,⛔ 不是真回归)。**边界自证**:⛔ **本棒零代码改动**(in-册三文件 md5 与序㉒ **全同**:`9f421a9f…` / `8c4c072c…` / `f08088b8…`)· ⛔ 未改任何生产值(**参数表指纹 `42238175d84319ada99afa56d583f9db` 未变**)· ⛔ 未动 nft·nginx · ⛔ 未新增公网口 · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push · 代码仓 HEAD **`04776af`**(改动数 10,与 T0 一致)。⚠️ **新登记一条线外项(R7 只报告、未动手)**:**O-1** = `enter` 时 47 日志 `model landing failed, falling back to env injection Error: ENOENT … /var/lib/dshs/users/<uid>/home/.credentials.yaml` ⇒ **用本地路径读远端实例 home**(与序⑬ Q2 真因**同族**),有 env 注入兜底、**用户可见面仍 200**,归属 `RemoteSpawner.resolveApiKey`(平台模型落地面)⇒ **不在本线 §3.1 文件集**,留待定立项。
> 🛑 **本线当前无自动接续**(序 ㉓ 收口后**未登记下一棒**):触发条件 = 你对 **`B`(内容分发)/「Manager 重启后是否自动拉起既有实例」/ 入口 §4 骨干服务范围(A 自用 / B 全网)**任一项拍板 ⇒ 拍板后即建下一棒。
> 🆕 **2026-09-17 20:0x 刷新(序 ㉒ 执行棒收官 · P-2b 已修 + P-1 长窗复测通过)**:**两件全办** —— ① 🔴 **P-2b 已修**:`relayEndpointTarget` 的候选链由「拨号落点 → relay 快照」**两级扩成三级**(新增 **②' 级 `pushedLocalPort`** = 订阅推送落点),与地址解析链 `addressOf` 的三级链**逐级对齐**;改动**只有 3 个在册文件**(`src/net/relay/endpoint-target.ts` / `src/web/server.ts` / `test/relay.test.mjs`),⛔ 未越界。**先红后绿(原文级)**:临时把 build 产物里的 ②' 级去掉 ⇒ `not ok 1 - T37 … actual {port:41000,via:'snapshot'} / expected {port:37057,via:'pushed'}` ⇒ 改回 ⇒ **T37/T38 = 2 pass / 0 fail**。**逐支可断言**:三级各有一支(`dialed` → `pushed` → `snapshot`)+ `0` 哨兵逐级下探 + 未知 host / 非 relay ⛔ 不碰拨号池(`T38` 源码级守卫钉"闭包必须把 `presenceLocalPort(name, ep.port)` 传进判定")。② ✅ **P-1 长窗(706 s ≈ 11.8 min)复测通过**:算式 `Manager 侧 = 窗口内 ΔstatusHits − 探针自身读数(1)` ⇒ `statusHits 9 → 10`、**Δ=1 ⇒ Manager 侧 = 0**;门开关 `journalctl -u dshs | grep -c overlay-presence` 窗口内 **0 行**;`Δpushed = 0` / `Δsnaps = 0`(稳态零帧)。相对基准 `60 000 / RELAY_STATUS_POLL_MS(5 000) = 12 次/分钟`:实测 raw **0.085 次/分钟** ⇒ **141.2×**(Manager 侧**零命中 ⇒ 无穷倍**)。③ **零回归三件套全绿**:`npm test` **176/175/0/1**(=基线 174/173/0/1 + T37/T38)、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **15 PASS/0 FAIL/1 SKIP**(**部署后重跑同值**)。**部署**:build ⇒ `lib/net/relay/{endpoint-target,index}.js` + `lib/web/server.js` scp 到 **4 处**(47 `/opt/dshs/lib`+`/opt/dsh-relay/lib`、106 `/opt/dshs-cluster/lib`+`/opt/dsh-relay/lib`),四根 md5 **全同**(`36b2dd9953a615de9a3e148752dffe94` / `486419ba443b99dd734ca79e987ffdea` / `460d360e8c6196341935b2f9a2a1d408`);**只重启 47 的 `dshs`**(三单元 active);回滚点 = 两机 **`/opt/dsh/backups/seq22-20260917-195602/`**(`endpoint-target.js 57e6c9ae…` / `index.js 486419ba…` / `server.js 74c077b3…`)。**边界自证**:⛔ 未改任何生产值(六值逐项未变)· ⛔ 未新增公网口 · ⛔ 未改 nft/nginx · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push。**参数表指纹 `42238175d84319ada99afa56d583f9db` 未变**(本棒无数值改动)。⚠️ **E2E 仍未做** ⇒ 交序 ㉓。🔴 **环境勘误**:对 **106 必须用别名 `test106`**(专用密钥 `id_ed25519_test106`,参数表 `SSH_TARGET_106` 本就写着)—— 裸 `ssh [email protected]` 报 `Permission denied (publickey)`,⛔ 别再误判成 MaxStartups 限流。
> ✅ **(已执行收官 · 序 ㉓)** 原登记:**下一棒 = 序 ㉓(执行棒)**,automation **`238e99eb-f173-4fe1-8c4a-0b07a6bba2fe`**(一次性 · **2026-09-17 20:08** = 收口 +5 min)⇒ **主:P-2/P-2b 的 E2E 验收**(`mksess-guest` 临时 session ⇒ `enter` 200 + 47 上 `:21000` 计数 0 + `overlay-endpoint` 计数 0 + relay `dial` 增量)|**次:presence 线收口复核**(在册缺陷是否清空、剩余项是否全在拍板区 ⇒ 写出"线内可停")。
>
> 🆕 **2026-09-17 19:2x 刷新(序 ㉑ 执行棒收官 · P-1 + P-2 两条在册缺陷均已修)**:**两条全办** —— ① 🔴 **P-1 已修并真机验收**:`presenceFresh()` 判据由「presence **载荷**年龄 ≤ 45 s TTL」改为「**订阅已建立**(`state==='subscribed'` ∧ 拿到过首帧 `SNAP`)∧ **链路活着**(**任何**入站帧含心跳满足 `now − lastFrameAt ≤ max(服务端下发 TTL, 半开阈值)`)」—— 病根 = 把"**没有变化**"读成"**没有数据**"。**我选了什么(可推翻):选 A**(任何入站帧含心跳即算新鲜);**B**(relay 定期重推 `SNAP`)会推翻序⑲ E1「稳态 `Δpushed ≤ 0`」与 `OBS-14` 的 `snaps ≤ pushed` ⇒ **R11 净变差**;**C**(拉长 TTL)只把竞速推远、不治本。**真机 Before/After(同口径)**:算式 `Manager 侧 = 窗口内 ΔstatusHits − 探针自身读数(1)` —— **Before**(旧代码在跑)66 s 窗口 `228→242` ⇒ Δ=14 ⇒ Manager 侧 **13**(≈11.8 次/分钟,复现 P-1);**After**(铺新 lib + `systemctl restart dshs`)67 s 窗口 `247→248` ⇒ Δ=1 ⇒ Manager 侧 **0**;门开关日志 `journalctl -u dshs | grep overlay-presence` 重启后 5+ 分钟(**远超 45 s TTL**)只有 **1 行** ⇒ **0 次翻转**。**先红后绿(原文级)**:临时改回旧判据 ⇒ `not ok 1 - T33 …`(pass 0/fail 1),改回 ⇒ T33/T34 **2 pass / 0 fail**。**新增 `OBS-16`**(门窗口内"除探针外零命中"可机器断言):夹具 **PASS Δ=1 rc=0** / **FAIL Δ=12 rc=1 并点名**两侧实证 + 真机 PASS。|② **P-2 已修(单测面)**:抽出纯函数 `src/net/relay/endpoint-target.ts#relayEndpointTarget` + `hostNameIndex`,`web/server.ts` 键口径改为**逻辑名索引**(`hostNameById`)⇒ **死分支消除**、并发失败关闭**点名**;⚠️ **E2E 未做**(当前无活跃实例,按入口授权"只做到单测"),**E2E 判据已写进** presence 单 §8.11-⑤。|③ **零回归三件套全绿**:`npm test` **174/173/0/1**(+T33–T36)、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **15 PASS/0 FAIL/1 SKIP**;收口归零 47 `dshs`+`dshs-relay`、106 `dshs-relay`+`dshs-worker` active、Manager 归位 47、监听行 **76**。**产物** = `交接单/交接单_presence在线态_20260917.md` **§8.11** + `交接单/交接单_观测口径与在册缺陷_20260917.md` **§14**(同单 §13 在册表新增 **P-2b**)。**部署**:build 后 `lib/net/relay/{client,index,endpoint-target}.js` + `lib/web/server.js` scp 到 47/106 各两处(`/opt/dshs/lib`+`/opt/dsh-relay/lib`、`/opt/dshs-cluster/lib`+`/opt/dsh-relay/lib`),md5 全 = `6c14d4d4fcdb516854865520584ed0c2`;只在 47 `restart dshs`。**边界自证**:⛔ 未改任何生产值(六值逐项未变)· ⛔ 未新增公网口 · ⛔ 未改 nft/nginx · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push。**参数表指纹 `659c08949c193102f774822905fde3b7` → `42238175d84319ada99afa56d583f9db`**。
> ➡️ **下一棒 = 序 ㉒(执行棒)**,automation **`25717418-6f01-4be5-b52a-1a3a8b90937d`**(一次性 · **2026-09-17 19:33** = 收口 +4 min)⇒ **主:修 P-2b**(`relayEndpointTarget` 候选链补 `presenceLocalPort` 一级,与 `addressOf` 三级链对齐)|**次:P-1 修复后的长窗(≥ 10 min)真机收益复测**(序㉑ 只用 67 s 短窗验证过"门 0 次翻转",长窗口径见 §2)。
>
> 🆕 **2026-09-17 18:5x 刷新(序 ⑳ 执行棒收官 · OBS-09 口径已修 + presence 真机收益已量化)**:**四条全办** —— ① `OBS-09` 判据改为「**在册 ⇒ 必须可达**;不在册 ⇒ **SKIP**」+ 新增 `--instance-fixture` 夹具参数 ⇒ **真机由"恒红"转 SKIP、探针 rc=0**;两侧夹具四段实证(A 不误红 PASS rc=0 / B 能判真红 FAIL rc=1 / C 不在册 SKIP rc=0 / D 契约面缺码 ⇒ FAIL 点名)|② 🔴 **presence 真机收益 = 降幅仅 1.10×(设计目标未达成)**:60 s 窗口 `ΔstatusHits 13 − 自身 2 = 11 次/分钟`(基准 `60 000/5 000 = 12 次/分钟`)、12.4 min 窗口 10.9 次/分钟、门开关占空比 **5.0%**;**根因** = `presenceFresh()` 的 45 s TTL 与「稳态零帧」互相打架(`src/net/relay/client.ts:593-600`)⇒ 登记在册缺陷 **P-1**|③ 收口三件套**零回归**:`npm test` **170/169/0/1**、`overlay-probe` **14 PASS/0 FAIL/1 SKIP**、`--scene all` **12 PASS/0 SKIP/0 FAIL**;47 `dshs`/`dshs-relay` active、池口 **64**(⚠️ 106 单元状态未取到 = ssh rc=255 限流,⛔ 放宽命中 R5)|④ `translateEndpoint` 键口径(`hostVia` 键 = 逻辑名、传入裸 `hostId` ⇒ 恒 `undefined` ⇒ 闭包整体是**死分支**)= **另立单**(登记 **P-2**;无活跃实例 ⇒ 本棒无 E2E 条件)。**产物** = `交接单/交接单_presence在线态_20260917.md` **§8.10** + `交接单/交接单_观测口径与在册缺陷_20260917.md` **§13**。🔴 **口径勘误**:序⑲ 的「降幅 63×/10.5×/∞」是**帧**口径,**不是 `/status` 轮询降幅**(后者实测 **1.10×**);`OBS-13` 的 `ΔstatusHits ≥ 1` 由探针自身两次读即满足 ⇒ ⛔ 不能当收益证据。**边界自证**:`src/**` **零改动** · 未改任何生产值 · `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push。**参数表指纹 `13de5f9b77c486d71e5b83ec909b17b2` → `659c08949c193102f774822905fde3b7`**(§6 只改判据文字)。
> ✅ **(已执行收官 · 序 ㉑)** automation **`3029d2cb-235e-4073-9654-03f7fc3653db`** 于 18:54–19:2x 跑完 ⇒ **P-1 已修**(真机 Manager 侧 `ΔstatusHits` **13 → 0**、门开关 **0 次翻转**)+ **P-2 单测面已修**(E2E 无实例条件)⇒ 结果见 `交接单/交接单_presence在线态_20260917.md` **§8.11** + `交接单/交接单_观测口径与在册缺陷_20260917.md` **§14**。原登记(存档):**下一棒 = 序 ㉑(执行棒)**(一次性 · **2026-09-17 18:54** = 收口 +4 min)⇒ **主:修 P-1**(presence 新鲜度判据,让"订阅生效期间 `/status` 停拉"真正成立)|**次:修 P-2**(`translateEndpoint` 键口径,⚠️ 必须先抽纯函数才可先红后绿)。
>
> 🆕 **2026-09-17 18:1x 刷新(序 ⑲ 执行棒收官 · presence 节点在线态已上线)**:**presence 改造已落地生产并真机验收** —— 产物 = `交接单/交接单_presence在线态_20260917.md` **§8★ 回报(8.0–8.9 已回填)**。**改法**:节点/端点在线态从「Manager 每 5 s 拉 `/status` 快照」改为「**连接生命周期驱动 + 订阅式推送 + 1 s 批合并 + TTL 安全网**」;`wire.ts` **末尾追加** `SUB 0x10 / UNSUB 0x11 / PRESENCE 0x12 / SNAP 0x13`;`client.ts` 订阅侧 + `rendezvous.ts` 主路径(订阅 `undefined` 才回落 `/status`)+ `web/server.ts` 装配(订阅新鲜时 `/status` 轮询**挂起**)。**真机数据(47 relay)**:`presenceTiming={graceMs 10000, offlineDebounceMs 30000, batchMs 1000, ttlMs 45000, subMax 0}`、`counters={subs 1, pushed 3, snaps 2, rejected 0}`、Manager 日志 `[relay-client] presence SNAP 2 条(scope=all)`。**验收**:`npm test` **169/0/1**(基线 161 + 新用例 **T25–T32 共 8 个**)|单测**先红后绿**(0/7 → 8/8)|**S6 本机多实例真机 8/8**(稳态 60 s **Δ帧=0**(期间 24 个心跳帧在流)|一次上下线 **各 1 帧**、断连→改口 **40985 ms**|首帧 `snapFrames=1`|跨网 **显式拒绝 rejected 0→1**|降幅 **63×**(字面口径)/10.5×(同消费者)/∞(稳态))|`--scene all` **12 PASS / 0 SKIP / 0 FAIL**|探针 **15 PASS / 1 FAIL**(唯一红项 `OBS-09`)|池口 **64**|`dshs/dshs-relay/dshs-worker/dshs-pg` 全 active。🔴 **两个必须记住的实测**:① **假死已修** —— `presenceTouch` 原早于 `ensureEndpoint`、且落点口号是 `listen(0)` **异步**才落地 ⇒ 首帧推 **`localPort=0`** 且**永不重推** ⇒ 订阅方 `addressOf` 查不到 ⇒ **页面打不开但不报错**;修法 = touch 后移 + 落点落地/端口变更时**强制重推**(`publishPresence(force)`),**新用例 `T32` 先红后绿覆盖**,真机复验 `localPorts=[{port:19000, localPort:35289}]`(非 0)。② **`OBS-09` 红 = S7 步骤与 E9 判据冲突**(`systemctl restart dshs` 会收掉 `dsh-*.scope`,平台**按需拉起**、⛔ 无 reconciler ⇒ 无人访问时实例不自回)⇒ 已按 **§9-8 停下报告**(详见该单 §8.8-1/§8.8-4)。**边界自证**:⛔ 未改任何生产值(六值逐项未变)· ⛔ 未新增公网口 · ⛔ 未改 nft/nginx · 🔴 `COOLDOWN_MS=0` 计数 **0** · ⛔ 未 commit / 未 push。**参数表指纹 `8f08e74b026e6e5b5e1b3db813f031ae` → `13de5f9b77c486d71e5b83ec909b17b2`**。
>
> 🆕 **2026-09-17 17:2x 刷新(序 ⑱ 规划棒收官 · presence 已出可执行单)**:**presence(在线状态)改造的规划已完成** ⇒ 产物 = 工作区根 **`交接单/交接单_presence在线态_20260917.md`**(287 行 + §11 回报;**§8 前缀指纹 `f612858344077420cff5f1f9ef1c942f`**;全文件 md5 `619a37818765152d74cef499e31bc41d`,落单时;⚠️ 加 §11 后**总字节变了、前缀指纹不变**)。**核心判断**:presence 的第一刀落在**节点 / 端点在线态** —— 因为**全仓零应用层**(`grep -rilE "\b(room|chat)\b" src | wc -l` = **0**)、`presence` 字样**只在 `src/net/relay/placement.ts:21` 的注释里**,而 Manager 现在的在线态来源是**拉 relay `/status` 快照 + 15 s 陈旧回退**(`src/net/relay/server.ts` 第 **413** / **1234** 行原文自证)= 正是要替换的"轮询"路径。**做法** = 照抄 `docs/覆盖网络/覆盖网络_瓶颈落地方案_20260916.md §1` 七条并逐条映射到本仓(**连接生命周期** + **1 s 批合并** + **订阅式扇出** + grace 10 s / debounce 30 s + **同 hostId 设备聚合** + **最终一致 5–15 s** + **TTL 安全网**)。**用户拍板** = 「**a 要做**」;⚠️ **B(内容分发 / 块级内容寻址)仍待拍板** ⇒ **只登记、⛔ 不规划**(该单 §0.4-1)。**边界**:§4.2 真取舍 = **空**、§4.3 待拍板 = **空**、**§4.4 R5 = 未命中**(新增监听口 / 凭据 / 入站均 **0**,可见面只收窄);**§9 有 9 条回头条件**(第 9 条 = 🔴 `COOLDOWN_MS=0` 硬禁令)。➡️ **下一棒 = 序 ⑲(执行棒)**,automation **`107b8e38-ccbd-4dcf-8b49-25dad7c89be9`**(一次性 · **2026-09-17 17:28** = 收口 +4 min)。
>
> 🆕 **(已被上行取代)2026-09-17 17:1x 刷新(用户拍板 ⇒ 下一棒已登记)**:用户答「**a 要做**」⇒ **presence(在线状态)改造正式启动**。**下一棒 = 序 ⑱(规划棒)**,automation **`50882a38-07cd-494c-ae73-cbbf27f3604d`**(一次性 · **2026-09-17 17:22** = 收口 +~5 min)⇒ 产出 = presence 的**可执行交接单**(依据 = `docs/覆盖网络/覆盖网络_应用场景与待完善清单_20260916.md` §五 第 7 步 + `docs/覆盖网络/覆盖网络_千台全场景推演_20260916.md` + `docs/覆盖网络/覆盖网络_瓶颈落地方案_20260916.md`);⚠️ **只出规划**(⛔ 不改码 / ⛔ 不动 47/106 / ⛔ 不 commit·push)。⚠️ 另一项 **B = 内容分发(块级内容寻址)仍待拍板** —— 复杂度已评估为「**中**」(方案 §3:需新建 ① 块级切分与哈希标识 ② 内容寻址存储 + 客户端校验 ③ 同网段 peer 发现 + 内容源优先级链;可照抄 BranchCache / Delivery Optimization / SCCM;验收判据单值可测「**回源字节数 ≈ 1 份 × 组数**」;⛔ 不做"包级"=已被证过的全量重拉风暴成因)⇒ **⛔ 本棒未登记、未规划**。
>
> 🆕 **2026-09-17 17:3x 刷新(序 ⑰ 执行棒收官 · 本线在册项清干)**:**四条在册项 —— S1 ✅ / S2 ✅ / S3 ✅ / S4 ⚠️(临界档 · 记录入册、⛔ 不判 FAIL)**。**S1** mksess 口径「DB 直插」→「**PG 直插**」(5 处操作性载体:`规范/02-运维手册.md` + `skills/dsh-change-workflow/SKILL.md`×3 行 + `skills/dsh-env-bootstrap/references/常驻规则-快照.md`×1 行 + 本机技能同内容;⛔ `调整方案/**` 档案正文**未动**;判据 E1 = **0 行**)|**S2** 技能 `dsh-auto-handoff-chain`(v1.3.2)**三处同步首次建立** —— 文档库新建副本 + `README.md`/`INDEX.md` 登记 + 47 镜像 `/opt/dsh/docs/skills/` ⇒ `diff -r` = **0 行**、md5 **三处同值**(`0c5c4103…` / `636c4f33…`)|**S3** 代码仓 `.bak-seq7-*` **5 个 → 0**(全 untracked、seq7 11:21 过期快照 ⇒ **非有效回滚点**;`npm run build` RC=0 + lib 产物 md5 **零差异**)|**S4** 幕 4-A 五样本 **18772 / 20121 / 20246 / 21223 / 24477 ms** ⇒ p95(保守 nearest-rank 口径)= **24477 ms** ⇒ **临界档(24000 < p95 ≤ 27000)⇒ 记录在册、⛔ 不判 FAIL、⛔ 未调任何生产值**,⚠️ 回头条件(> 27000 ms)**未触发**。**零回归全绿**:`npm test` **162/161/0/1**、`--scene all` **12 PASS / 0 SKIP / 0 FAIL**(幕 4-A 20419 / 18333 ms)、`overlay-probe` **12/12**;收口三服务 active、池口 **64**。
> 🗃 **Q4 已由用户授权解除并办结**(原话「执行完毕后 同步到仓库」)⇒ `146c3d2`(代码/测试面 **53** 文件)+ `bc0dd2c`(文档库面 **10** 文件)已 push;远端 `master` = **`bc0dd2c`**,`git ls-files src/net/relay | wc -l` **0 → 15**(序⑭/⑮ 的修复**首次进版本库**)。
> 🛑 **本线已无自动接续**:四条在册项清干后,**剩余项全部落在「需拍板」区**(presence / 房间层 / 内容分发**定序** = 业务优先级;骨干节点服务范围 = §4 的 A/B 既有待拍板项)⇒ 按登记门禁**不登记下一棒**,等你拍板后再建。证据 = `交接单/交接单_在册收尾_20260917.md` **§9**;参数表指纹 **`8f08e74b026e6e5b5e1b3db813f031ae` 未变**。
>
> 🆕 **2026-09-17 16:4x 刷新(序 ⑯ 规划棒收官)**:**① 复核判定 = 会合 / 中继从 Manager 拆分「不做」** —— 原方案 `docs/覆盖网络/会合中继拆分_取证与改造方案_20260916.md` 的四个耦合点 C1–C4 与两步改造 S3/S4 **逐条已被覆盖、未覆盖部分 = 无**:C1 → 序② P0-2(`DSHS_RENDEZVOUS_URL` 优先 / `DSHS_TUNNEL_TARGET` 降兜底,`src/config.ts:485-490`)|C2 → **R5**(Manager 只拨出、落点搬到本机回环池 `127.0.0.1:25000..26000`,`src/config.ts:498-500`;`dialer.ts:11`)|C3 → S2/P2(`dsh_hosts.via` + `RendezvousRegistry`)|C4 → 方案 §8.1 实测**前提不成立**|S3 → 方案 §9.1 自我证伪后改「实例端口区间隔离」|S4 → R2(`dshs-relay` 独立单元)+ 序⑥ S8(106 升格第二中继)+ 序⑦(多实例切流实测)。该方案文档**头部已加状态块、正文未改**(存档)。**② 剩余在册四条已定序并出执行单** ⇒ 产物 = 工作区根 **`交接单/交接单_在册收尾_20260917.md`**(243 行;**§8 前缀指纹 `bab83b7219b2669d5a6e9f1acf782e1f`**、全文 md5 `ca13b9ded3d71268f8b0e56755d7aea4`)= **序 ⑰ 执行棒**,顺序 = **S1 mksess 文档口径(「DB 直插」→「PG 直插」)→ S2 技能 `dsh-auto-handoff-chain` 三处同步建立 → S3 清理代码仓 `.bak-seq7-*`(🔴 **范围修正:5 个,不是 3 个**)→ S4 幕 4-A 余量判据化 + 5 样本采样**。🔴 本棒两条新事实:**① Q5 真实范围 = 5 个**(多出 `src/web/server.ts.bak-seq7-*`、`src/worker/tunnel.ts.bak-seq7-*`,**5 个全 untracked**、均为过期快照 ⇒ 无回滚价值)② **`调整方案/**` 档案的 mksess 旧口径不改**(档案 = 当时事实,只改操作性载体 + 写勘误指针)。⚠️ 登记:`src/worker/tunnel.ts`(SSH 隧道)现已是**生产死路径**,是否删 = 独立决策,⛔ 本单未处置。➡️ **下一棒 = 序 ⑰(执行棒)**,automation **`067b0892-964e-4deb-bf84-4f1c37bebea8`**(16:44 起)。证据 = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§12**。
>
> 🆕 **2026-09-17 16:3x 刷新(序 ⑮ 执行棒收官 → 缺陷 B 已修)**:**拨号池"未分配槽位被一条连接永久杀死"已修并端到端验收** —— 病根 = `src/net/relay/dialer.ts#onConn` 见到 `slot.key === undefined` 时 `slot.server.close()`:关掉的只是**服务器**,槽位**仍留在 `slots` 里**、`key` 仍是 `undefined` ⇒ `localPortFor()` 的 `slots.find(s => s.key === undefined)` **下次还会选中它** ⇒ 把死口号当落点发出去(47 上实测:`16:00:27 落点 127.0.0.1:25000 -> ops/w-106:19000` 紧接 `16:00:31/35/40` 三条 `POST /api/dsh/enter` → **500 `fetch failed: connect ECONNREFUSED 127.0.0.1:25000`**)。**改法 = 只丢弃那条无法路由的连接(槽位原样保留)+ `stray` 计数 + 点名日志**,另加纵深防御(`localPortFor`/`lruIdle` 只认 `server.listening`;`status().pool` 改报"实际在听")。⛔ **不取"把槽位从 `slots` 摘掉"那条** —— 那等于让**任意本地连接**都能**永久**蚕食池容量(R11)。**验收**:**先故意对未分配池口 25000 发一条连接**,随后 guest `enter` 仍 **200/200**、该口同连接连发 3 次 **200/200/200**、打后池口仍 **64**;`npm test` **162/161/0/1**(+T24)、`--scene all` **12 PASS / 0 SKIP / 0 FAIL**、`overlay-probe` **12/12**。部署 = `dialer.js`(`6446fe9b…`)**五处同值**、只重启 47 的 `dshs`。⚠️ 顺带确认一条**环境口径**:对 47/106 的 ssh **必须显式 `-p 22`** —— 别名 `bt-server` 里的 `32022` 是**失效残留口**(47 上 sshd 只监听 22,自 09-16 22:12:48 起)。➡️ **下一棒 = 序 ⑯(规划棒:会合/中继拆分复核 + 在册收尾定序)**,automation `91c53ef8-c3f0-4bb3-9f0a-943790178176`(16:36 起)。证据 = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§11**。
>
> 🆕 **2026-09-17 16:1x 刷新(序 ⑭ 执行棒收官)**:**relay 流 keep-alive 复用缺陷已修并端到端验收** —— 真因 = `src/net/relay/client.ts#openStream` 里多挂了一行 `duplex.on('data', …)`,把**读侧接回了出向**:agent 的响应经 relay 回到拨号方后又被 `pumpDial()` 打回去,worker 把它写进 agent socket ⇒ agent 拿 `HTTP/1.1 200 OK` 当**请求行**解析 ⇒ Fastify `clientError` 回 `400`(**用户可见:任何 `via='relay'` 的 host(今天 = w-106)用户 `POST /api/dsh/enter` 必 500,「登录直达工作区」整体不可用**;curl 看到的"第 2 条 400"其实是第 1 条响应的回声)。**改法 = 删掉那一行**(出向唯一入口是 `_write`→`onOut`;`duplex.write()` 与 `tcp.pipe(duplex)` 本就走同一条路,该监听纯属多余且方向错)。**验收**:guest `enter` **200**、同连接连发两次 **200/200**(三次 200/200/200)、`npm test` **160 pass / 0 fail / 1 skip**(基线 159 + 新回归用例 **T23**)、`--scene all` **12 PASS / 0 SKIP / 0 FAIL**、`overlay-probe` **12/12**。部署 = `client.js`(`b8b29afb…`)铺 5 处、**只重启 47 的 `dshs`**(改动是拨号方专属)。🔴 **新发现在册缺陷 B(R7 只报告、未动手)**:拨号池**未分配**槽位被任意一条连接碰到 ⇒ 该槽位**永久死亡**(`dialer.ts#onConn` 只 `slot.server.close()` 却不摘除槽位),而 `localPortFor()` 之后照样把它发出去 ⇒ `ECONNREFUSED` ⇒ `enter` 500 `fetch failed`。证据 + 三个候选修法 + 判据 = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§10.8**;参数表指纹仍 **`8f08e74b026e6e5b5e1b3db813f031ae`**(**未变** ⇒ D1 自证)。➡️ **下一棒 = 序 ⑮(执行棒:缺陷 B 修复)**。
> 🆕 **2026-09-17 15:5x 刷新(序 ⑬ 执行棒收官)**:**在册缺陷清算 Q1→Q3 —— `Q1 ✅` / `Q2 🔴 阻塞(新真因)` / `Q3 ✅`**。**Q1**:`/opt/dshs/mksess{,-guest}.cjs` 由**写 SQLite 旧库**改为**写 PG**(连接串从 env / `dshs.env` / `dshs.service.d` 读,⛔ 不固化凭据)⇒ R4 的实例面验收手段恢复(实例面 `curl` 回 **401**,非 `000`);指纹 `mksess.cjs` **`a97c0f214650fbc552c07d804fd153be`**、`mksess-guest.cjs` **`af6eab38c4ff5c365ee17e29d7b98a31`**。**Q3** ✅:**探针 12/12 PASS · rc=0** —— `OBS-09 本机:20000=401 w-106:42461=401` 绿,且"有实例态"下 `OBS-11` 仍绿(实际 77 / 多出 0 / 缺失 0、`20000` 在允许区间)。🔴 **Q2 未达成,且真因不是单内记的 `landModels` 本地路径** —— 是**新发现的数据面缺陷**:**relay 流上的 HTTP keep-alive 复用**(同一条连接第 2 条 agent 请求必回 `400 clientError`,机制 = **worker 侧把上一份响应回灌给 agent**)⇒ **任何 `via='relay'` 的 host(今天 = w-106)用户 `POST /api/dsh/enter` 必 500 = 登录直达整体不可用(用户可见)**。证据链与 1 条命令的最小复现 = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§9.3**;`src/` 与参数表**零改动**(参数表指纹仍 `8f08e74b…`)。➡️ **下一棒 = 序 ⑭(执行棒:relay 流 keep-alive 缺陷修复)**。
> 🆕 **2026-09-17 15:3x 刷新(序 ⑫ 执行棒收官)**:**`OBS-11` 已由「计数相等」改为「三集包含式白名单集合」(`nft` 同族改「入站 accept 集合 ⊆ 白名单」)** —— 参数表 §6 **新增 4 键**(`LISTEN_REQUIRED` / `LISTEN_ALLOWED` / `LISTEN_ALLOWED_RANGES` / `NFT_ALLOW_INBOUND`)、`LISTEN_COUNT` / `NFT_RULES` **退役为仅对账**;唯一代码改动 = 代码仓 `scripts/overlay-probe.cjs`(⛔ `src/**` 零改动 ⇒ `git status src/` **20 → 20**);**新增夹具模式**(`--listen/nft/status-fixture`,离线、零生产副作用、输出带 `FIXTURE` 标记)。**验收**:`overlay-probe` **10/12 → 11/12**(剩 `OBS-09` = 环境态);ⓐ **假红已消除**(真态 77 行 ≠ 旧阈值 79 ⇒ 旧判据必红,新判据 PASS)ⓑ **假绿已能抓**(`fx-swap` 行数恒 79 ⇒ 旧判据 PASS,新判据同时点名 `多出 127.0.0.1:9999` + `缺失 0.0.0.0:888`)ⓒ 真机受控临时口「多出必红」实证(`127.0.0.1:27000` 起口 ⇒ FAIL 点名,关口 ⇒ 回 PASS、`ss` 回 77)ⓓ `nft` 走 `-j` 正路且退化文本路径**链感知**(不误抓 `FORWARD` 的 accept);零回归 = `npm test` **160/159/0/1**、`--scene all` 全绿、`ss` 77 / `nft` 72。**参数表指纹 `99e9e17b…` → `8f08e74b026e6e5b5e1b3db813f031ae`**。⚠️ 两条与单不符处已按**实质判据**处理(P1-注 的「零 `*`」⇒「**Local 列**零 `*`」;P4/E7 的「`src/` = 0」⇒「**不新增** `src/` 改动」,20 是既存未提交基线)。➡️ **下一棒 = 序 ⑬(执行棒:在册小缺陷清算 Q1→Q2→Q3)**。证据 = 本单 §8 + `待清理/中间产物-20260919/seq11/`。
>
> 🆕 **2026-09-17 15:0x 刷新(序 ⑪ 规划棒收官)**:**观测口径重构已定序并出单** —— 工作区根 `交接单/交接单_观测口径与在册缺陷_20260917.md`(**§8 前缀指纹 `3ece0f870cba67d0113a4c5f9de9d812`**,244 行)⇒ **① OBS-11 判据由「计数相等」改为「白名单集合」**(三集包含式 + `nft` 同族改「入站 accept 集合」)|**② 6 条在册小缺陷清算排序**(`mksess*.cjs` 失效 ⇒ **阻塞实例面验收 ⇒ 先修**|guest(w-106) 实例页 502|…;排序见该单 §5.9)。范围 = **只改观测面**(`scripts/overlay-probe.cjs` + 参数表 §6),⛔ `src/**` 零改动。➕ 顺手办:`.workbuddy/memory/MEMORY.md` **真瘦身 8 121 → 7 712 字符**(回到注入上限内)。➡️ **下一棒 = 序 ⑫(执行棒)**,口径见 §2「🎯 本轮动作」。证据 = 该单 §5–§7 与 §8.9。
>
> 🆕 **2026-09-17 14:5x 刷新(序 ⑩ 收官 · 三件技术债全清)**:**① 幕 2 状态依赖 ✅ 已修**(`--scene all` **12 PASS / 0 SKIP / 0 FAIL**,原 11/1;`--scene 2` 单跑 **3 PASS / 0 FAIL**)|**② `COOLDOWN_MS=0` ✅ 0 命中**(`--scene 4c` / `ctrl` 整体移除 + 显式拒绝 = 退出码 2)|**③ OBS-11 `78 → 77` ✅ 有名字 = `20000`**(47 实例档;当前 47 无活跃实例 ⇒ 未监听。76 条 socket **逐条点名、零无名**,池 64 口全在;另订正 `39463` 实为 relay **动态**落点,现 `46147`)。➡️ **下一棒 = 序 ⑪(规划棒:OBS-11 计数口径 → 白名单集合 + 在册小缺陷清算排序)**,口径见 §2「🎯 本轮动作」。证据 = `交接单/交接单_检测时延与deadline_20260917.md` **§8.8-4**。
>
> 🆕 **2026-09-17 13:5x 刷新(序 ⑤–⑨ 全部收官)**:**① 参数表 · 观测 · 权限评估(⑤)② 3–5 台最小形态(⑥)③ 中继失败切流(⑦)④ 切流冷却语义(⑧)⑤ 检测时延与 deadline(⑨)—— 五序全绿**。现行形态:**两台真中继(47 + 106,均只绑回环)**|`RELAY_MAX_HOSTS` = **7515**|**失败自动切流 + 冷却语义(含一跳豁免)+ 换址终态失败早退**已落三处装配点|`npm test` **160/159/0/1**。🔴 **本线唯一的"换址慢"已闭环**:白等 **12.03 s → 0.09 s**、端到端 **34.1 s(中位)→ 25.3 s(中位)**。⇒ **下一棒 = 序 ⑩(覆盖网络线技术债清算 · 执行棒)**,口径见 §2「🎯 本轮动作」。
> 🆕 **2026-09-17 11:0x 刷新(序 ⑥ 执行部分收官)**:**覆盖网络已是"两台真中继"** —— 47 + **106**(106 复用既有 443、零新增公网口、只绑回环 `20080`);参数表 **五项待测全部换成实测**、**待测 4 → 0**;`RELAY_MAX_HOSTS` 按实测重算 **225 → 7515** 并已下发两台;**收口 `overlay-probe` 12/12 PASS**、47 监听口 **79 = S0 基线**、`npm test` 137 pass ⇒ **无退化**。⚠️ **唯一未过项 = 「杀掉任一台中继不自动切另一台」(无失败切流)** ⇒ 下一棒 = **序 ⑦ 规划棒**。证据 = `交接单/交接单_最小形态真机批次_20260917.md` §8(§8.9 可复现指纹)。
> 🟢 **2026-09-16 23:0x 刷新(机制层 R0–R5 全部完工)**:**R2 / R3 / R4 / R5 全部落地并端到端验收** —— relay 在 47 常驻(`dshs-relay`,只绑 `127.0.0.1:20080`)|经 `https://alotbuy.com/dshs-relay` 可达(origin 与 CF 双路 `101`)|**w-106 已 `via='relay'`**(agent 面与**实例面**都经 relay)|**sshd 反向隧道已下线且不可能重建**(47 收回隧道公钥、`32022` 回收;106 摘掉 `DSHS_TUNNEL_*`、私钥移走)⇒ 47 公网暴露面**净减 1 口**。
> 🆕 **R5 = 会合可换机(本轮新增)**:R1–R4 隐含的「**Manager 必须与 relay 同机**」这条前提**已不存在** —— Manager 改为**只拨出**一条 wss,落点搬到**自己本机**的回环池(`127.0.0.1:25000+`,64 口)。**relay 放哪台机器都不再影响 Manager。**
> **完整证据 = 交接单 `交接单/交接单_relay落地R2-R4_20260916.md` §9(R2)/ §10.4(R3 Step 0)/ §10.5(R3 本体 + R4 全链)/ §11(R5)**(均含命令原文级输出);单测 `relay + remote-spawner + reachability + instance-port` = **38/38**(R5 新增 T18/T19);本机 `lib/` 与 47 `/opt/dshs/lib/` 对账 **0 差异**(R5 产物 29/29 hash 全同)。
> 🔴 **本线留下的一条硬教训(别重犯)**:`RemoteSpawner` 构造函数漏赋值 `this.translateEndpoint` ⇒ 端点翻译**静默失效** ⇒ Manager 拿 Worker 侧口号往**自己本机**拨 ⇒ **浏览器只见「空响应」、平台零日志**。定位靠**判别器**(临时监听 `21000` 把请求接走),不靠读代码猜 —— 判据已钉进 `test/remote-spawner.test.mjs`(先红后绿已实证)。
> ✅ **R5 又抓到同族第二条(已于 2026-09-16 23:4x 修完并端到端验收 ⇒ R2-R4 单子 §12)**:`src/fs/remote-user-fs.ts:70-73` 在 `agentFor(hostId)` 解析不出时**静默回退到 w-47 本地 agent** ⇒ w-106 用户的 launch/文件面在**每次重启后的一小段窗口**里回 **假 `404 {"error":"not_found"}`**(与"文件夹不存在"完全同形)。**判别器 = 看 relay 有没有 `DIAL`**:没有 = 请求根本没出去。
> 🔴 **下一个动作(⛔ 已勘误,勿再按旧指示走)**:⛔ **不是** "presence 改造"。机制层 R0–R5 已齐,但 `覆盖网络_应用场景与待完善清单 §五` 把**房间层/presence 排在第 7 步**,其前置是 **② 网抽象 + 地址规划 + 引导(P0-1/2/3) ③ 一机一钥 + 信任根 ④ 443/TCP 兜底 ⑤ 参数表 ⑥ 3–5 台最小形态**(且仓库里目前**没有应用层代码**,"presence 改造"无从下手)。⛔ 不要再做 R2/R3/R4/R5、不要再开 32023、不要再做 SSH 版中继。
> 🟢 **2026-09-17 07:4x 刷新(② 收官)**:**序 ② 已完成**(P0-1 网抽象 / P0-2 引导三级链 / P0-3 名字解析与授权,三步全部落地 + 端到端验收;执行进度:`交接单/交接单_网抽象与地址规划R6_20260916.md` 的「执行进度」段,指纹 `0d3f1f305e9e6219afa97cdfecff05ba`)。
> ⇒ **下一棒已定序(2026-09-17 07:5x 定序 · 09:1x 刷新)**:~~序 ③(一机一钥 + 信任根)~~ ✅ **已完成**(证据 = `交接单/交接单_一机一钥与信任根_20260917.md` §8)→ ~~序 ④(443/TCP 兜底)~~ ✅ **已完成**(证据 = `交接单/交接单_443兜底_20260917.md` §8)→ ~~**下一棒 = 序 ⑤(参数表·观测·权限评估)**~~(⛔ **已过期**:⑤–⑨ 均已收官 ⇒ 现行下一棒 = **序 ⑩**,见上方最新刷新行与 §2「🎯 本轮动作」)。**定序理由**:③ 是身份基线、④ 是失败域分离,⑤ 建立在前两者之上(参数表要把 ④ 带回的 45% 口径填成数值,权限评估要覆盖 L3 跨机真容灾)。⛔ 不要重做 ② / ③ / ④ 的任何一步。
> 另:本轮把 §11.6 **记下没动手**的两条缺陷修完并端到端验收 —— 见 R2-R4 单子 **§12**(A1 假 404 真因定死为"文件面 `hostDirectory` 无刷新机制"+ 治本/治安全双修 + 冷启动直接证据;A2 `state.py` 恒报锁空闲)。
覆盖网络/客户端化这条线已产出 **10 份规划文档 + 1 份执行交接单**(全在工作区根目录),**代码已有 S0+S1 落地(本机 commit `640813e`),且 R2–R5 的产物已铺到 47(Manager)与 106(Worker)两端**(R5 产物对账 29/29 hash 全同);⚠️ **方案 S3 的机制已于 2026-09-16 15:2x 实测证伪并改写** ⇒ 详见下方「15:2x 复核」与 §2。
| 项 | 值 |
|---|---|
| 文档库执行锁 | ✅ **空闲**(2026-09-17 15:0x 由「覆盖网络线-序11规划棒」释放;该棒只出规划 + 改 `.workbuddy/memory/MEMORY.md`,⛔ 未碰 `src/`、未动参数表) |
| **S0 / S1 落地真相** | ✅ **两端都已铺**(2026-09-16 23:0x 复核):本机 `lib/` vs 47 `/opt/dshs/lib/` ⇒ **R5 产物逐文件对账 29/29 hash 全同**;relay 运行时 `/opt/dsh-relay/lib/net/relay/*` 同步 |
| **15:2x 复核(实测)** | 🔴 **S3 原机制证伪**:47 `sshd gatewayports no` ⇒ `-R 127.0.0.2:…` 被**静默改写为 `127.0.0.1`**(ssh 侧零报错)⇒ 回环别名方案作废,改「**实例端口区间隔离**」|🔴 **发现真 bug**:`findFreePort()` 各 worker 各自随机 ⇒ 同号在 47 的 `127.0.0.1` 撞号、而 `tunnel.forward()` 返回值被忽略 ⇒ **静默打到别人实例**|⚠️ `verify-cluster-cross.mjs` 默认端口 13080 ≠ 现役 3080,且**有生产副作用**(改容量/建用户/拉实例)⇒ 跑完要清 |
| 代码 / 服务器 | 🆕 **序⑩ 改动(2026-09-17)**:仅 `scripts/overlay-failover-drill.cjs`(幕 2 状态无关化 + 删掉 `4c`/`ctrl` 两个 `COOLDOWN_MS=0` 场景),⛔ **未碰 `src/`**、未改任何生产阈值、relay/Manager 均已复原并复验(`systemctl restart dshs` 归零回 47)|⚠️ **本轮有改动**:代码仓 `src/net/relay/*`(R5:`wire/duplex(新)/server/client/dialer(新)/main/index`)+ `src/config.ts` + `src/web/server.ts` + `test/relay.test.mjs`;47 上 relay/manager 两个 drop-in + `relay-keys.json`(均有 `.bak-r5*` 备份) |
| 文档库 | ✅ **10 份已转正式档案 103–112**(`4e3a1a4`)+ 已推镜像,**双端对账 192/192 全绿**(2026-09-16 11:5x) |
| 当前基线 | 代码仓 HEAD = `640813e` —— ✅ **已 push**(2026-09-16)|⚠️ 本机工作区**有未提交改动**(S2 会合中继拆分 + R3/R4/R5 产物 + 新增 `test/remote-spawner.test.mjs`)⇒ ⛔ **未获授权不 commit / 不 push** |
| 根副本 vs 档案 | 本线 10 份根文档的正文**已入档案 103–112**(行覆盖 **98.5–99.0%**,差异仅一级标题行)⇒ **根副本保留为工作副本,⛔ 不搬**(被 11 处引用,搬走会断链) |
| **自动接续** | ❌ **已于 11:00 删除,且⛔ 不要再建** —— 两版都试过(7 积分/轮 → 优化版 **9 积分/轮**),**证明"定时任务省积分"是伪命题**。原因见下方「成本真相」。 |
> 💰 **成本真相(终版 · 2026-09-16 11:2x,**实测那个会话本身**)**
> ⛔ 前两版都错:v1 把固定注入当"一次性入场费"(错);v2 我**按最新 mtime 猜会话**,分析到了另一个"会话复盘"会话(`e2e090be`,错)。
>
> **定位方法(可复跑,别再用 mtime 猜)**:拿 prompt 里的独有字串去搜转录 ——
> `grep "能脚本化的全部脚本化" <projects>/*.jsonl` ⇒ 唯一命中 **`e265f0cd-bd24-48c7-953e-4bbfa615bc7d.jsonl`**(761 KB,10:50:09 结束)。
>
> | 指标 | 实测 |
> |---|---|
> | **工具调用次数** | **32**(Bash 16 / Edit 6 / Write 5 / Read 4 / present_files 1) |
> | 模型请求(记录数) | 54(转录对每次请求记**两条**:一条无 `cache_read`、一条有 ⇒ **实际约 27**) |
> | **Σ input** | 5,205,114(同口径折算 ≈ 2.6 M) |
> | Σ cache_read | 2.55 M(≈49%) |
> | 单次 input:首 → 峰/末 | 52,582 → **141,401** |
> | **固定注入 5 万 × 请求数** | **占 51.9%**(对折不改变比例) |
> | **本次新灌入的内容** | 工具输出合计 **84,870 字符 ≈ 2.4 万 token ⇒ 仅占 0.5%** |
>
> **它实际干了什么**:32 次调用集中在 `D:/github/dsh_shenxian` 的 **git / 文件读写**,并读过一次 `接续入口`(4,443 字符)。**并没有去读源码做取证。**
>
> **三条结论**
> 1. **成本 ≈ 请求次数 × (固定注入 + 累积历史)**。本次 27–54 次请求里,**固定注入一项就占 51.9%** —— 即**花掉的一半积分,只是"把指令与常驻规则重复发了二三十遍"**。
> 2. **本次真正"读进来"的东西极少(≈2.4 万 token,占 0.5%)** ⇒ 这笔钱**不是"上下文太大"造成的,是"请求太多次"造成的**。
> 3. ⇒ **唯一的大杠杆 = 压请求次数(= 压工具调用次数)**:32 次调用若能压到 1–3 次,Σinput 掉一个数量级(9 积分 → ~1 积分量级)。**这才是真能省下来的钱。**
>
> **⛔ 由此两条硬规矩**
> ① **批量活不要"要求 agent 写脚本",而要"只准跑这个脚本"** —— 脚本**由上一会话预先写好**,任务里命令式指定;agent 没有探索余地,请求次数自然压到个位数。
> ② **绝不把"读代码 / 大范围取证"派给无人值守会话**(要么脚本先 grep 计数,要么有人盯着)。
> ⚠️ **成本教训(2026-09-16 实测,勿重蹈)**
> 1. **"新会话"不等于"不花钱"**:本工作区**每轮固定开销实测 ≈ 51,830 token**(系统提示 + 工具定义 + 常驻规则 + 注入的记忆)⇒ 任何新会话第一轮都要付这笔钱。准确的收益口径是「**把每轮水位从 39 万降到 ~5 万(约 1/8)**」,**不是"零成本"**(我此前把它说成"降低 token 消耗",属**不准确承诺**)。
> 2. **最大的可压缩项 = 每轮注入的记忆文件超限**:✅ **2026-09-16 修复轮已办** —— 实测真被截断的是**用户级** `MEMORY.md`(注入上限 **≈4,000 字符**),已按**分层重排、零删除**修好;🔑 **重排是杠杆,删减不是**(方法已沉淀为 `dsh-knowledge-upkeep §8.6「注入预算」`)。
> 3. ⛔ **不要把"10 份文档档案化"交给 agent 逐份做** —— 那是 20+ 轮 × 7 积分 ≈ **140+ 积分**,违反项目省积分第一招「**批量活写脚本**」。**正确做法 = 写一个转换脚本一次跑完**(加 8 段头部 + 原子占号 + 登记 + audit 全在脚本里),agent 只读摘要 ⇒ **1–2 轮完成**。
---
## 1. 十份文档(按阅读顺序;前 3 份是决策层,其余是专项)
| # | 文件 | 一句话 |
|---|---|---|
| 1 | `docs/客户端与桌面/可行性评估_客户端安装与覆盖网络互联_20260916.md` | 判定可做;列出**现有架构已给出的 80% 形状**(soft 隔离 = 裸子进程 / Worker 四条协议纪律 / 拨出式反向隧道 / 全仓仅一处平台分支);§六 = 与另两份客户端文档的对账 |
| 2 | `docs/覆盖网络/覆盖网络_全球架构复盘_20260916.md` | 五层架构 + 12 条内建特性 + 选型对照 + **10 类风暴类型学** + 流量组织五原则 + 7 步落地顺序 |
| 3 | `docs/覆盖网络/覆盖网络_瓶颈落地方案_20260916.md` | **九大瓶颈逐个给可执行做法**(含 Slack / SCCM 官方做法照抄点 + 验收判据);**"只做三件事"= presence + 游戏服放 L1 + 块级内容寻址** |
| 4 | `docs/覆盖网络/覆盖网络_骨干层方案_20260916.md` | 多中心骨干(≤10–20 成员)+ 选择性加入;三条硬约束(接入/成员/可见三分离、资格只能控制面签发、骨干不得被默认征用) |
| 5 | `docs/覆盖网络/覆盖网络_百台规模推演_20260916.md`(v2) | 100 台异构画像;L1 10 / L2 30 / **L3 需中继 40–55**;全互联 4,950 vs 星型 100 |
| 6 | `docs/覆盖网络/覆盖网络_千台全场景推演_20260916.md` | 1000 台 × 11 场景;**瓶颈排序**(presence 第一)+ 流量预算总表 |
| 7 | `docs/覆盖网络/覆盖网络_游戏专项_MMORPG与MUD_20260916.md` | MMORPG/MUD/传奇 = **最匹配**;核心简化:**玩家之间不需要互联,中继按"服数"算** |
| 8 | `docs/覆盖网络/覆盖网络_调研_游戏网络特征与群聊上限_20260916.md` | 游戏网络参数(每玩家 2–20 KB/s、jitter<20 ms)+ 群聊上限**按扇出预算定义**的分档 |
| 9 | `docs/覆盖网络/覆盖网络_答疑_群聊备份迁移保密_20260916.md` | 四问:群聊+agent / 备份(主备份用对象存储)/ 迁移提速 / 三层加密与元数据保护 |
| 10 | `docs/覆盖网络/覆盖网络_补遗与参考方案_20260916.md` | 补遗 24 条 + 参考方案对照 + **反模式 12 条** |
| 11 | `docs/覆盖网络/参数表_覆盖网络_20260917.md` | **序⑤ 产物 · 唯一一张参数表**(155 行):输入参数 + 代码固化常量 + 45% 口径填值(`--max-hosts = 225`)+ 观测阈值 `OBS-01..12` + 权限影响评估 + 待测汇总。**观测探针** = 代码仓 `scripts/overlay-probe.cjs`(一条命令 / 12 行 / 退出码 0-1-2;cwd = 本工作区根即可跑) |
**另有两份他人产出(已按最佳方案收口,勿重复改)**:`docs/客户端与桌面/dsh客户端化部署方案_20260916.md`(v3,平台侧单一来源)|`docs/客户端与桌面/dsh桌面客户端_开发方案_20260916.md`(v1,交付载体层)。
> 🧭 **方法论(2026-09-16 16:4x 新增)**:`docs/覆盖网络/方案规划方法_覆盖网络线提炼_20260916.md` —— 把本线「**信息收集 → 方案调研 → 场景梳理 → 逻辑验证 → 应用推演**」五段作业法反推成可复用方法(含每段骨架/出口判据、**出口闸门三件事**、8 次真实纠错自证、可抄模板)。**下次做新方案规划时先读它。**
---
## 2. 下一步
> ✅ **本棒(序㊾ 执行棒 · 修「探针观测面单一」=按两台中继取并集)已收官 · 2026-09-19 01:0x–01:4x —— 判定 =「修复落地并上生产」**(结果见本文件 **§0 最新行**;回填 = 交接单 `覆盖网络-序45-低熵块治理-测熵与实现.md` **§16 全节** + 参数表 **§11.16 补记**)。
> 📦 **已入仓(2026-09-19 05:3x 提交 / 05:4x 补齐镜像)**:提交 `d2ef362`(20 文件 · +2998 −183,含本棒 + 前几棒已部署未入仓的源码/文档)⇒ **双推两腿均 ✅**(原仓 `work.alotbuy.com` ≡ CNB ≡ 本地 = `d2ef362`)。⚠️ 首推时 **CNB 腿失败**,根因 = 本机旧令牌 **HTTP 401 已过期**(CNB 回泛化「仓库不存在」,⛔ **别改 URL**);**已落长期令牌** `~/.cnb/git-token`(用户名 `cnb`)后补齐,双推恢复常态。
> ⏹ **下一棒 = 无(本线可停)** —— ⛔ 本棒**未登记接续**,理由是两条**都在"我这边的可执行面之外"**:① 唯一在册红 `D8`(云安全组 **乙-1**)**只能你在云控制台落地**(两机 + 本机均无云凭据,序㊹ 已取证;你已批准但定"先记下后续再处理" ⇒ 属挂起项,⛔ 不进排棒队列)② 「**死口孤儿回收**」(序㊽ §15-10-2)的**回头条件尚未触发**(需先出现端口替换后 `OBS-08` 再红),且它是 **worker ↔ relay 的接口级**改动 ⇒ 应由**规划棒**先行,而"要不要现在开这条规划"属业务优先级(边界外①)。**恢复方式** = 跑 `state.py` 看 [入口] 段 + 本文件 **§0 最新行**的 ⑧⑨ 两条(现场形态:worker 若又漂到 106,探针**仍应 29P/0S/0F** —— 那正是本棒的验收面;⚠️ 若 `OBS-04` 红,先按 §0-⑨(c) 做一次回落)。
> ⚠️ **(上一棒记录 · 已由本棒结清)** 序㊽ 遗留的原登记 = 「下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊾ 执行棒(修「探针观测面单一」:把 `overlay-probe.cjs` 真机路径的端点/会话取数从「只读 47 中继」改为「**按两台中继取并集**」)」,automation **`2febff6b-5786-46a3-b345-b648f2e19df3`**(一次性 · Scheduled)⇒ ✅ **本次已完成**。
> ✅ **本棒(序㊽ 执行棒 · 修「重启 worker 后实例端口注册丢失 / 孤儿端点条目不自愈」)已收官 · 2026-09-19 00:15 – 01:0x —— 判定 =「修复落地并上生产 · 探针回到 **29P/0F/0S** · ⛔ 未为验证重启任何实例」**(结果见本文件 **§0 最新行**;回报 = 交接单 **`交接单/覆盖网络-序45-低熵块治理-测熵与实现.md` §15 全节** + 参数表 **§11.15**)。**一句话 = 认领来的实例端口从此有人重新声明**(`adoptedInstancePorts()` 并入对账口径 + 认领落定回调),**活口孤儿被就地覆盖**(`localPort` 逐字沿用为证)。**判定依据** = `agent.ts:256-264`(口径只取 `mains`)+ `orchestrator.ts:290`(认领**刻意不进 `mains`**)+ `server.ts:2151-2203`(`dropSession` **只摘会话不删条目**)+ `server.ts:1447-1466`(`ensureEndpoint` **复用条目**)⇒ **落点 = 对账口径,⛔ 不是 spawn 流程** ⇒ 🔴 **§14-7 那句「恢复须实例重新拉起」被证伪**。**读数** = 探针 **26P/2F/1S(rc=1)→ 29P/0F/0S(rc=0)**|`npm.cmd test` **200/0/1**|`--scene all` **12P/0S/0F**(6m01s)|`orchestrator-rehydrate.test.mjs` **18/18**。**部署** = 两机 4 处 `lib` 全量替换(包 `a902c936cefdeeb3eb13c67dfcb5dd00`;**1080 对 md5 不一致 0**);回滚点 **`/opt/dsh/backups/seq48-20260919-0030/`**。⚠️ **如实留档**:两机实际落地**相差 ≈ 28 s**(47 先、106 后,脚本 `cd` 写法失误所致;改动无协议/接口变更 ⇒ 无跨版本不兼容)。**边界自证** = ⛔ 未 commit / 未 push(HEAD **`45b4999`**)|⛔ 未改 `DEFAULT_BLOCK_SIZE` / `package.json` / 零新依赖|⛔ 未改 nft·nginx·bwrap|⛔ 值格未动(§10 现算 **`ac6bbbbb8c92bd57ff0dc4cd8f4983ba`**)。
> ✅ **下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊾ 执行棒(修「探针观测面单一」:把 `overlay-probe.cjs` 真机路径的端点/会话取数从「只读 47 中继」改为「**按两台中继取并集**」,消除「106 worker 归属漂移 ⇒ `OBS-01` / `OBS-08` / `OBS-09` 假红 / 假 SKIP」)**,automation **`2febff6b-5786-46a3-b345-b648f2e19df3`**(一次性 · **2026-09-19 00:55** = 本棒收口(00:4x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789750500000**)。**依据** = 本入口 **§0 最新行 ⑧** + 交接单 **§15-10-1** + 参数表 **§11.15-⑦(a)**;⛔ 不另找依据。**范围(写死,⛔ 不许扩)**:① 只改**观测面**(`scripts/overlay-probe.cjs` 真机取数路径)② 口径 = **按 `hostId` 合并两台中继**(`OBS-01` 在册节点数 / `OBS-08` `endpoints[]` / `OBS-09` 在册实例面三条数据源取并集;`endpoints` 按 `hostId:port` 合并、`online` 取**或**、`localPort` 取**在线那一侧**)⛔ **不改阈值、⛔ 不放宽判据**(并集只消除"看不见",⛔ 不许把真 FAIL 糊成 PASS)③ 🔴 **`OBS-16` 计数约束必须先核**:⛔ 不许改变对 47 `/status` 的读取次数(复用已采那份),106 那份**独立采样**并确认不参与其 Δ 计算 ④ **先红后绿**(夹具态造"worker 挂 106、47 视角为空";⛔ 不动生产)⑤ **零回归三件套**(探针 **29P/0F/0S** | `npm.cmd test` **200/0/1** | `--scene all` **12P/0S/0F**)⑥ ⛔ **不做**:不改选路策略(`switcher.ts` 抖动换址 / 一跳豁免 = 既有设计)/不修"死口孤儿回收"(§15-10-2 已在册,worker 与中继可能不同机 ⇒ 非本轮可及)/不碰 `OBS-29` 与块 id 口径/不动 D8。**硬门** = ⛔ 不 commit / 不 push|⛔ 不改 `DEFAULT_BLOCK_SIZE` / `package.json`|⛔ 不引新依赖|🔴 不改参数表**值格**(只允许追加补记)|⛔ 不改 nft / nginx / bwrap|🔴 密钥本体不经网络 / 不经 relay|⚠️ 动手前一句话说明在动什么(R8)|🔴 持久禁令:⛔ 调 `RELAY_FAILOVER_DEADLINE_MS`、⛔ 动 `HB_SEC`/burst、⛔ 禁用 `COOLDOWN_MS=0`|⚠️ `--scene all` ⛔ 不许套 < ~8 min 外层超时|⚠️ 探针与演练**必须从工作区根跑**。**回滚** = 脚本回退上一份备份并同步两机(⛔ 本单不涉 `lib` ⇒ 无需动服务)。**收口** = 回报写进该单新 **§16**(⛔ §8 前前缀 `be548afc3340583b2b63ca254bcf550f` 逐字不变)+ 参数表 **§11.16** + 本入口 §0/§2 + 工作区日志 + `--release-exec` 释锁。📌 **在册待你拍板项仍 = D8**(云安全组乙-1;⛔ 不因它阻塞排棒)。
> ✅ **本棒(序㊼ 部署棒 · `C` 落地两机 + `OBS-29` 真机腿)已收官 · 2026-09-18 23:43 – 2026-09-19 00:1x —— 判定 =「`C` 全绿且**已上生产** · ⚠️ 唯一差异 = `OBS-09` 退化 SKIP(既有缺陷被本棒重启触发)」**(结果见本文件 **§0 最新行**;回报 = 交接单 **`交接单/覆盖网络-序45-低熵块治理-测熵与实现.md` §14 全节** + 参数表 **§11.14**)。**一句话 = 块 id 的 per-network 域分离**已在两台真机上同时生效**(两机 `blockIdKeyed=true`、`blockIdKeyId` **逐字相同** = `d6e62322e5166938`)⇒ 跨机取块口径对齐。** **交付** = ① **全量部署** `lib`(**270 文件 × 4 处**:47 `/opt/dshs/lib` + `/opt/dsh-relay/lib`、106 `/opt/dshs-cluster/lib` + `/opt/dsh-relay/lib`),🔴 **两机同一窗口内**换包 + 重启(包 md5 `546b30719ca1bfca1e04189e1099424e`;两机解包前各自先验包)② **备份/回滚点** = 两机 `/opt/dsh/backups/seq47-20260918-2347/` ③ **核对 = 不一致 0**(**270 × 4 = 1080** 对逐字节一致;多出的 11–12 个 = 历史 `.bak-*` 遗留,⛔ 未删)④ **`OBS-29` 真机腿 PASS**(两机 `blockIdKeyed=true` + `blockIdKeyId` 逐字相同 + `blockSize=1048576` ⛔ 未动;**第二来源** = 两机 relay 启动判别器日志原文)⑤ **零回归** = 探针 **28 PASS / 0 FAIL / 1 SKIP**(⚠️ 基线 29P/0S/0F)|`--scene all` **12 PASS / 0 SKIP / 0 FAIL**(rc=0;**6m28s**)✅ 同基线。⚠️ **三条如实留档**:**(a)** 部署口径实为**全量**(两机 4 处 `lib` 是历次增量 scp 的叠加,47 `net/relay/index.js` mtime 12:55:27 vs `content/chunker.js` 06:52:16,与本机产物同名 md5 不同 **38–41 个**)—— ⛔ 不是"只传改动文件";**(b)** prompt 里"核 32 个 md5"的口径**未能复现**(已按全量核对);**(c)** 🔴 **`OBS-09` 由 PASS 退化 SKIP** = **既有缺陷被本棒硬要求的"重启 106 `dshs-worker`"触发**(实例 `286172` 健在且未被 teardown:`OBS-22 scanned=1 adopted=1 stopped=0` + `[rehydrate] probe OK … :21001`;但 47 端点表缺 `w-106:21001`;机理 = `relay-tunnel.ts#cancel()` 只撤销**当前进程** `forwarded` 集 ⇒ 遗留条目无人撤销、新进程不重注册)⇒ **恢复须"实例重新拉起"** ⇒ 本棒**不修、不凑绿**(另立小项 → 下一棒)。**边界自证** = ⛔ 未 commit / 未 push(HEAD **`45b4999`**)|⛔ 未改 `DEFAULT_BLOCK_SIZE` / `package.json` / 零新依赖|⛔ 未改 nft·nginx·bwrap|⛔ 值格未动(§10 现算 **`ac6bbbbb8c92bd57ff0dc4cd8f4983ba`** 同 §13 记录)。
> ✅ **(已执行收官 · 存档 · 2026-09-19 00:15–01:0x;结果见本文件 §0 最新行 + 交接单 `覆盖网络-序45-低熵块治理-测熵与实现.md` §15 全节 + 参数表 §11.15)原登记:下一棒(第 1 棒 · 本线当时唯一挂着的棒)= 序㊽ 执行棒(修「重启 worker 后实例端口注册丢失 / 孤儿端点条目不自愈」⇒ 让探针 `OBS-09` 由 SKIP 回到 PASS)**,automation **`7dba0a2c-6cd4-456a-be0c-c53df4ac0d95`**(一次性 · **2026-09-19 00:15** = 本棒收口(00:0x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789748100000**)。**依据** = 本入口 **§0 最新行 ⑦** + 交接单 **§14-7** + 参数表 **§11.14-③**;⛔ 不另找依据。**范围(写死,⛔ 不许扩)**:① 读码定位「实例端口登记 / 上报 relay」链路(`src/worker/relay-tunnel.ts` 的 forward/register + `src/supervisor/orchestrator.ts` 的 rehydrate/adopt),把判定依据(文件 + 行 + 原文)写进回报 ② 修复 = worker 启动 / 认领后把**已 adopted 实例的监听端口重新登记**为 forwarded 端口(覆盖孤儿条目 ⇒ `online=true`),⛔ 不许绕过既有准入 / 白名单实现 ③ **先红后绿**(未修缺条目 / 修后条目在位,原文级)④ 零回归三件套(探针 **29P/0S/0F** | `npm.cmd test` **200/0/1** | `--scene all` **12P/0S/0F**)。**硬门** = ⛔ 不 commit / 不 push|⛔ 不改 `DEFAULT_BLOCK_SIZE` / `package.json`|⛔ 不引新依赖|🔴 ⛔ 不改参数表**值格**(只允许追加补记)|⛔ 不改 nft / nginx / bwrap|🔴 密钥本体不经网络 / 不经 relay|⚠️ 动手前一句话说明在动什么(R8)|🔴 持久禁令:⛔ 调 `RELAY_FAILOVER_DEADLINE_MS`、⛔ 动 `HB_SEC`/burst、⛔ 禁用 `COOLDOWN_MS=0`|⚠️ `--scene all` ⛔ 不许套 < ~8 min 外层超时。⚠️ **验证可能需让 106 那个实例重新拉起一次**(端口登记在 spawn 流程内)—— R8 允许但**优先找零中断路径**,必须中断时**先声明**并记时长;⚠️ ⛔ 不得为"迁就参数表旧值"而动实例。**回滚** = 两机同窗口回退 `lib` 到本棒备份 + 重启。**收口** = 回报写进该单新 **§15** + 参数表补记 + 本入口 §0/§2 + 工作区日志 + `--release-exec` 释锁。📌 **在册待你拍板项仍 = D8**(云安全组乙-1;⛔ 不因它阻塞排棒)。
> ✅ **本棒(序㊻ 执行棒 · `C` 块 id per-network 域分离 + `OBS-29` 判据重裁)已收官 · 2026-09-18 22:33–23:3x —— 判定 =「`C` 全绿 · ⏳ 真机腿待部署」**(结果见本文件 **§0 最新行**;回报 = 交接单 **`交接单/覆盖网络-序45-低熵块治理-测熵与实现.md` §13 全节(含 §13.1 如实留档 + §13.2 零回归三件套)** + 参数表 **§11.13**)。**一句话 = 块 id 按「网络」分域了**:同字节**跨网必不同**(⇒ 跨网共享**必然失效** = **设计意图**,⛔ 不是缺陷),**同网去重一点没丢**。**改了什么** = `blockIdOf` / `contentIdOf` 从**裸 `sha256`** 改为 **`HMAC-SHA256(netKey, bytes)` 取前 32 hex**;per-network 密钥**复用既有组密钥链**派生(`deriveBlockIdKey()`,🔑 **零新密钥文件 / 零新 env**);🔴 **缺省或空 `netKey` ⇒ 回落裸哈希**(= **回滚路径** + 保住既有单测语义);`encode` 与 `netKey` 由 `writeTransforms()` / `readTransforms()` **同生同灭**(⛔ 不许半开)。**读数** = 单测 **200/0/1** + `overlay-content` **55/55**(新增组 G 共 10 例)|探针 **29 PASS / 0 FAIL / 0 SKIP**(基线 28 ⇒ **+1 = `OBS-29`**)|`--scene all` **12 PASS / 0 SKIP / 0 FAIL**(rc=0)。**判据重裁** = 正腿 **3**(`P1` 跨网必不同且都 ≠ 裸哈希 / `P2` 同网必相同=去重不得丢 / `P3` 装配面无漏改)+ **具名负腿 2**(`flat-key-collapses` / `empty-key-falls-back-to-bare-hash`),🔴 **两条负腿都真跑过**(先红后绿:红腿 A 单测 6 红 / 红腿 B 单测 9 红,均已复原)。**边界自证** = ⛔ 未 commit / 未 push(HEAD **`45b4999`**)|⛔ 未 scp / 未部署|⛔ 未改 `DEFAULT_BLOCK_SIZE` / `package.json` / 零新依赖|⚠️ **对生产的唯一动作 = 重启 47 `dshs` 一次**(R8,为满足演练 6 h AUTH 窗口)。⏳ **唯一未办 = `OBS-29` 的真机腿**(`/status.content.blockIdKeyed === true` 且 **47 / 106 的 `blockIdKeyId` 逐字相同**)⇒ **必须部署后才能验** ⇒ 交下一棒。
> ✅ **(已执行收官 · 存档 · 2026-09-18 23:43 – 2026-09-19 00:1x;结果见本文件 §0 最新行 + 交接单 `覆盖网络-序45-低熵块治理-测熵与实现.md` §14 全节 + 参数表 §11.14)原登记:下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊼ 部署棒(`C` 落地两机 + `OBS-29` 真机腿)**,automation **`92f8a1b9-5e38-4a7b-bd1b-7d7695e73d09`**(一次性 · **2026-09-18 23:43** = 本棒收口(23:3x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789746180000** ⇒ 🧾 已用 `date -d @…` 复核 = **23:43:00** ✅)。**要点** = 🔴 **两机必须同一窗口内一起换**(`C` 改了块 id 口径 ⇒ **一台新一台旧 ⇒ 跨机取块全部判校验失败**):`build` 后把 `lib` scp 到 **47 的 `/opt/dshs/lib` + `/opt/dsh-relay/lib`** 与 **106 的 `/opt/dshs-cluster/lib` + `/opt/dsh-relay/lib`**(⚠️ **32 个 md5 须全同、不一致 0**)→ 重启两机 `dshs-relay` + 47 `dshs` + 两机 `dshs-worker` → 跑 **`OBS-29` 真机腿**(`/status.content.blockIdKeyed === true`、两机 `blockIdKeyId` **逐字相同**)+ **探针复跑仍 0 FAIL** + **`--scene all` 仍 12P/0S/0F**。**硬门** = ⛔ 不 commit / 不 push|⛔ 不改 `DEFAULT_BLOCK_SIZE` / `package.json`|⛔ 不引新依赖|🔴 **⛔ 不改 `参数表` 的「值格」**(只允许追加补记)|⛔ 不改 nft / nginx / bwrap|🔴 密钥本体 ⛔ 不经网络 / 不经 relay|⚠️ 动手前一句话说明在动什么(R8)|⚠️ `--scene all` ⛔ 不许套 < ~8 min 外层超时。**回滚** = 两机同窗口回退 `lib` 到 `/opt/dsh/backups/` 里本棒的备份 + 重启(🔴 **回滚要注意**:`C` 的 id 换代**不是无损的** —— 回退后 id 会**再一次全变**,但因块存储**纯内存不落盘**,重启即清空 ⇒ 无残留脏块)。**收口** = 回报写进本入口 §0/§2 + 该单 **§14** + 工作区日志 + `--release-exec` 释锁。📌 **在册待你拍板项仍 = D8**(云安全组乙-1;⛔ 不因它阻塞排棒)。⚠️ **四条另立小项在册**(⛔ 均非本棒范围、⛔ 不在下一棒范围):演练 47 s 超时腿 / 演练 6 h AUTH 上限腿 / `mksess.cjs` 失效 / ssh 别名 `bt-server` 端口陈旧。
> ✅ **本棒(序㊺ 执行棒 · §10-3 低熵块治理「测熵先行」)已收官 · 2026-09-18 21:56–22:2x —— 判定 =「`M1` 实测完成 · 🔴 **D 的作用面为空 ⇒ D 本轮不实现**」**(结果见本文件 **§0 最新行**;回报 = 交接单 **`交接单/覆盖网络-序45-低熵块治理-测熵与实现.md` §8 回填** + 参数表 **§11.12**)。**读数(真实内容 · ⛔ 零合成字节)**:S1 = 壳页 `/plugins/??…` **全部 60 条 combo**(**按页面顺序**拼装,合计 **23,629,336 B**;🔴 历史 `11,363,655 B` = **最大单条**,⛔ 非全部之和)⇒ **`M1-a`** 块 23 / 唯一 23 / **重复率 0.00%** |**`M1-b`** 低熵块 **0 块 / 0 B**,逐块 H ∈ **[5.1807, 5.8444]**,直方图 `{5.0-5.5: 8, 5.5-6.0: 15}` |**`M1-c`** **0.000000%** |**`M1-d`** 4 KiB 窗 5,768 个 ⇒ **低熵段 15 段 / 241,664 B = 1.0225%**(max 段 **81,920 B**)|**S2** 60 份内容中单块 **56** 份、**低熵内容 0 份**。**判定** = **D 的目标已由「定长 1 MiB 切分」结构性达成**(低熵物质只以 ≤80 KiB 块内片段存在 ⇒ 对块级枚举不可见;且无低熵内容单元)⇒ `D-1` / `D-2` 两分支都不命中 ⇒ **D 本轮不实现**(⚠️ 非降级 —— 目标已被实测证实达成;回头条件 = **出现低熵内容单元**)。**产物** = **`scripts/overlay-entropy.cjs`**(只读探针 · 零第三方依赖 · 切分调用仓库那份 `chunkify`)+ 参数表 **§11.12** + 交接单 §8 回填。**边界自证** = ⛔ 未改 `src/**` 一行 · ⛔ 未动 `DEFAULT_BLOCK_SIZE` / `package.json` · ⛔ 未改生产实例 / 未重启在线服务 · ⛔ 未 commit / 未 push · ⚠️ 参数表 **§10 指纹未变**(`6b37bfd506758d882d9f803678f85d23`)· 🔴 临时物已清(47 `/tmp/s45`;PG 临时会话 `remaining=0`)。⚠️ **留档两条**:① 仓里 **`mksess.cjs` 已失效**(写 SQLite,而权威库 = **PG** ⇒ 一插就 401)—— **待收口缺陷**;② `/plugins/??…` **有鉴权**(无会话 401)。
> ✅ **本棒(序㊺ 规划棒 · §10-3 低熵块治理)已收官 · 2026-09-18 21:35–21:5x —— 判定 =「规划完成 · ⛔ 零代码 / 零服务器改动」**(结果见本文件 **§0 最新行**)。**产出** = 方案 `调整方案/133-覆盖网络-低熵块治理方案-C域分离与D非确定性.md` + 交接单 **`交接单/覆盖网络-序45-低熵块治理-测熵与实现.md`**(**§8 前前缀 `be548afc3340583b2b63ca254bcf550f`**)。**方向已由用户 2026-09-18 21:28 拍板** = **采纳 C + D**;**B(OPRF / SA-MLE)降级为可选加强、⛔ 不立项**。🔴 **方案第一个动作 = 补测 `M1`「低熵块种类数 / 体积 / 占首屏包比例」**(**从未测过**;且历史所有"低熵"读数都是**合成字节** —— perf 用 `makeBytes()`、低熵定性用 8 B 合成块;块存储**纯内存不落盘** ⇒ 生产侧无样本可捞)。🔑 **本轮新增结构发现(源码级 · 待实测确认)** = 切分是**定长 1 MiB**(`chunker.ts:60/137`)⇒ 首屏包 10.8 MB ≈ 11 块**混高熵内容** ⇒ **首屏包内几乎无纯低熵块**;**D 的真实战场更可能是「小于 1 MiB 的独立内容」**,⇒ 测熵**必须含子窗口熵腿**,否则会得出"全是高熵块"的**假绿**。🔴 **同时发现一条既有漂移(只报不改)**:参数表 §10 头值记 `d408d640246a980f702fe7b0a2895219`(序㊴ 12:2x),**现算 = `6b37bfd506758d882d9f803678f85d23`**(830 行 · mtime 09-18 15:18)⇒ 记录值未随内容更新(⚠️ 与序㊹ 自报值一致 ⇒ 两次独立计算同值)。
> ✅ **(已执行收官 · 存档 · 2026-09-18 22:33–23:3x;结果见本文件 §0 最新行 + 交接单 `覆盖网络-序45-低熵块治理-测熵与实现.md` §13 全节 + 参数表 §11.13)原登记:下一棒(第 1 棒)= 序㊻ 执行棒(C 域分离 + 判据重裁)**,automation **`aab9e357-8101-4011-b829-bf9f4a459bf7`**(一次性 · **2026-09-18 22:33**)。**要点** = **只做 C(per-network keyed hash)**:**①** `blockIdOf` / `contentIdOf` 改 `HMAC-SHA256(netKey, bytes)`、输出仍取前 32 hex;per-network 密钥**复用 `crypto.ts` 既有组密钥链路**从 network 维度派生(⛔ 不新增密钥文件 / ⛔ 不新增 env)。**②** 逐处过 **8 文件 / 36 处**调用点(⚠️ **缺省不传 netKey ⇒ 必须回落裸哈希** = 回滚路径,且保住既有单测语义;⛔ 漏一处 = 校验必红且极难定位)。**③** 🔴 **判据重裁(本棒存在的主要理由)** = 单里原写的 `OBS-29` 负腿(「稀释源换成确定性派生量 ⇒ 必红」)**随 D 被移除而失去对象** ⇒ 重裁成 **C 的判据**:**正腿** = 同字节 + **不同 network ⇒ 块 id 不同**;**负腿(必须真跑、必须具名)** = **去掉 per-network 维度(netKey 取同值 / 取空)⇒ 必红**(⛔ 不许只给正腿 —— 本线老病根 = 装了没生效 = 静默放行);编号自 **`OBS-29`** 起(现表最大 `OBS-28`)。**④** 🔴 **`E1` 基线必须重取**(C 换 id 口径 ⇒ 旧读数作废、去重率归零重算;⚠️ `E1` 定义**不重估**)。**⑤** 新增两条单测断言:「不同 network ⇒ 同字节得不同 id」+「同 network ⇒ 同字节得同 id」。**硬门** = ⛔ 不改 `DEFAULT_BLOCK_SIZE`|⛔ 不改生产实例 / ⛔ 不重启在线服务|⛔ 不引第三方依赖 / ⛔ 不动 `package.json`|⛔ 不 commit / ⛔ 不 push|⛔ **不实现 D**(序㊺ 实测已判无效)。⚠️ **同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令)。📌 **在册待你拍板项仍 = D8**(云安全组乙-1;⛔ 不因它阻塞本线排棒)。
> ⛔ **(被上行取代 · 已于 2026-09-18 21:56–22:2x 跑完)原登记** = **下一棒(第 1 棒 · 本线当时唯一挂着的棒)= 序㊺ 执行棒(低熵块治理:测熵先行 + C 域分离 + D 非确定性)**,automation **`f94f2973-4ead-471a-a020-df6dc0b144a4`**(一次性 · **2026-09-18 21:56**),automation **`f94f2973-4ead-471a-a020-df6dc0b144a4`**(一次性 · **2026-09-18 21:56** = 本棒收口(21:5x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789739760000** ⇒ 🧾 已用 `date -d @…` 复核 = **21:56:00** ✅)。**要点** = 先按交接单 **§5 步骤 1** 补测 `M1`(⚠️ 必须**真实内容**、⛔ 不用合成字节顶替、**必须含子窗口熵腿**)→ 由结论定 **D 的作用面** → 再落 **C**(per-network keyed hash;⚠️ **块 id 口径换代 ⇒ 全部既有块 id 失效 ⇒ `E1` 基线必须重取**)+ **D**(D-1 稀释域首选,⚠️ 稀释源必须含真随机且不出现在明文可见面,负腿 = 换成确定性派生量必红)。**硬门** = ⛔ 不改 `DEFAULT_BLOCK_SIZE`|⛔ 不改生产实例 / ⛔ 不重启在线服务|⛔ 不引第三方依赖 / ⛔ 不动 `package.json`|⛔ 不 commit / 不 push|⚠️ 改动 >10 文件先出受影响清单。⚠️ **同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令)。📌 **在册待你拍板项仍 = D8**(云安全组乙-1;⛔ 不因它阻塞本线排棒)。
> ⏸ **本棒(序㊹ · D8 云安全组乙-1)未收官 · 2026-09-18 15:3x–16:0x —— 判定 =「阻塞在用户侧云控制台」**(结果见本文件 **§0 最新行**;回报 = 工作区根「交接单/交接单_覆盖网络直连与P2P_20260918.md」**§8.11**)。**阻塞根因(原文级)**:47 `aliyun` CLI 无凭据(`~/.aliyun/config.json` 不存在)+ metadata `ram/security-credentials` = **404**;106 无 `tccli` + metadata `cam/security-credentials` = **404**;本机无任何云 CLI / 凭据 ⇒ 🔴 **⛔ 不索取 / 不硬编码 AK/SK** ⇒ **只能用户侧控制台落地**。**待落地两条(乙-1)** = 47 阿里云入方向 `UDP 21100/21115` 源 `106.54.21.172/32` | 106 腾讯云入方向 `UDP 21100/21115` 源 `47.77.182.89/32`(🔴 **⛔ 零个 `0.0.0.0/0`**)。**本棒已顺带结清的另一问** = **本机(开发机)⛔ 不是覆盖网节点、⛔ 也不是终端**(只是测试发起端 / 观测台;无固定公网 IPv4 ⇒ 结构上不能作被拨入节点)。⛔ **未登记下一棒**(阻塞项需人操作)。**落地后第一动作** = 双向实测复测(基线 **47→106 发 21 收 0** / **106→47 发 28 收 0**)+ 探针 `OBS-27/28` 复跑 + 参数表 §11 补记。
> ⏹ **本棒(序㊸)已收官 · 2026-09-18 14:47–15:2x —— 判定 =「线内可停 · 🔴 D8 待你拍板」**(结果见本文件 **§0 最新行**;回报 = 工作区根「交接单/交接单_覆盖网络直连与P2P_20260918.md」**§8.10** + 「docs/覆盖网络/参数表_覆盖网络_20260917.md」**§11.11**)。**三项全绿**(先红后绿 / 两腿对照 + 防错腿 / 处置证据)+ **零回归三件套 201/200/0/1 | 12P/0S/0F | 28P/0S/0F**。⇒ **本线可停**:无遗留 ⇒ ⛔ **本棒未登记下一棒**(用户 2026-09-18 00:3x 明令「最好不要建立多个接续任务,一个会话结束时再排下一个」);**唯一在册大项 = D8(云安全组,需你拍板)**。📌 **在册待你拍板项 = D8**(要不要现在开通云安全组 **乙-1** = 47↔106 各放行**对端 `/32`** × UDP `21100/21115`,⛔ 零个 `0.0.0.0/0`;需你给控制台访问方式 / 审批)—— 该项已在册,⛔ 不因它阻塞排棒。
> ✅ **(已执行收官 · 存档 · 2026-09-18 14:47–15:2x;结果见本文件 §0 最新行 + 交接单 §8.10 + 参数表 §11.11)原登记:下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊸ 执行棒(**观测面缺口收口**:① `overlay-direct-probe.cjs` 在 106 上可跑 ② 参数表定位与 cwd 解耦 ③ 106 上不可跑残留副本处置)**,automation **`8dbee90b-7d49-4c97-a25e-fdc302f9ca32`**(一次性 · **2026-09-18 14:47** = 序㊷ 执行棒收口(14:4x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789714020000**)。**要点** = 只修**观测面**三件事(⛔ 不碰数据面 · ⛔ 不做 D8):① 把探针对 `registry.js` 的**硬 `require` 改成惰性 / 可选加载**并在缺失时**具名降级**(⛔ 不靠"再铺一份 `registry.js`"糊过去;⛔ **不许静默返"没有"**)② 让探针与 `overlay-failover-drill.cjs` 的**参数表定位与 cwd 解耦**(⚠️ **保留**"恰好 1 个才合法"这条防错)③ 处置 106 `/opt/dshs-cluster/scripts/` 那份**不可跑的残留副本**。**开工依据** = 交接单 **§8.9-⑥-2**(探针 / 演练须从工作区根跑)+ **§8.9-⑥-7**(106 无 `registry.js`)+ **§8.8-④**(同一缺口,序㊶ 已登记为独立后续项)+ 参数表 **§6**(探针阈值键与 `OBS-26/27/28` 契约)。**验收** = ① **先红后绿**(红 = 106 上 `Cannot find module … registry.js` 原文级;绿 = 同一命令在 106 上跑通并给出该子命令读数)+ ② **两腿对照**(从代码仓根跑:现在 rc=2 → 修后正常读数;**人为造两份参数表** ⇒ 仍须报错退出)+ ③ 处置证据 + ④ 零回归三件套(基线 **201/200/0/1** / **12P/0S/0F** / **28P/0S/0F**)。**硬门** = ⛔ 不 commit / 不 push(R7)|⛔ 不改 `server.ts` DIAL / 白名单语义|⛔ 不改 `content/**` 块 id 口径|🔴 ⛔ 不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径|⛔ 不改 bwrap(47=0.4.0)/ nft(**72 行**)/ nginx|🔴 密钥本体不经网络 / relay|⛔ 不引入新依赖|⛔ **D8 零动作**(⛔ 不许 `0.0.0.0/0` 含拆分等价写法、⛔ 不许索取 / 硬编码云 AK/SK)。🔴 **两条已踩过的坑**:从代码仓根跑探针 / 演练 ⇒ rc=2(本棒正是要修掉它);`--scene all` ⛔ 不许套 < ~8 min 外层超时,⚠️ 演练后若 47 视角 `endpoints=[] / used=1` ⇒ **停 106 `dshs-relay` 停够 ~25 s 再启**("停 2 s 即启"**不触发回落** —— 已实测)。**收口** = 回报写进该单 **§8.10**(⛔ §1–§7 正文与 §8.1–§8.9 小节点名一律不动;**§8 前前缀 `8925c2460810c6dc5cdbc075b6cdaed2` 是不变量**)+ 参数表 **§11.11**(**现算并同步** §10 指纹)+ 本入口 §0/§2 + 工作区日志 + 过门禁后登记**一个**下一棒(若全绿且无遗留 ⇒ 本线唯一在册大项 = **D8 需你拍板** ⇒ 明确写「线内可停」且 ⛔ 不登记)+ `--release-exec` 释锁。⚠️ **同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令)。
> ✅ **(已执行收官 · 2026-09-18 14:14–14:4x;结果见本文件 §0 最新行 + `交接单/交接单_覆盖网络直连与P2P_20260918.md` §8.9 全节 + 参数表 §11.10)原登记:**下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊷ 执行棒(P2 · S7:**规模回归** —— 候选数 / 直连成功率 / 切换耗时 / 回源字节 **四项复测**)**,automation **`690f44e9-b6f7-4517-ae2b-ca0b05b8dfe9`**(一次性 · **2026-09-18 14:14** = 序㊶ 执行棒收口(14:0x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789712040000**)。**要点** = 四项复测各自给出**原始读数 + 与参数表 §3.2 / §5 / §7 的逐项对照**;⚠️ **D8 未放行** ⇒ 直连**成功率**腿照 S5/D5 由**离线 NAT 模拟器**承载,⛔ **不许把"直连建立了"写成成功**;⛔ **不重做 S5 / S6**(已收官、已部署)。
> ✅ **(已执行收官 · 2026-09-18 13:35–14:0x;结果见本文件 §0 最新行 + `交接单/交接单_覆盖网络直连与P2P_20260918.md` §8.8 全节 + 参数表 §11.9)原登记:**下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊶ 执行棒(P2 · S6:`peer` 档接线 + **D7 块 id 复算**)**,automation **`32c2cde1-e5c4-427a-9b9b-e8adab1c8725`**(一次性 · **2026-09-18 13:34** = 序㊵ 执行棒收口(13:2x)+~7 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789709640000**)。**开工依据** = 工作区根 **`交接单/交接单_覆盖网络直连与P2P_20260918.md`**(**归档号 132**;**§8 前前缀 `8925c2460810c6dc5cdbc075b6cdaed2`**,⛔ 开工前逐字复核 —— ⚠️ **§8 已由序㊵ 回填、该前缀仍逐字不变**)+ 参数表 **§11.8**(序㊵ 补记)。**范围(写死,⛔ 不许扩)** = **只做该单 §6 的 S6**(`source.ts` fetcher **优先直连、回落 wss** + **回归"零回源 / 共享命中"既有读数**,对照序㉔ / 序㉛ 基线);⛔ **不做 S7**(规模回归)。**验收** = **D7 先红后绿** —— 🔴 **`peer` 接线后块 id 必须与接线前逐字一致**(⛔ 漏了这条就不算过;须给出**接线前后两次块 id 原文读数**)+ 零回归三件套(基线 **201/200/0/1** | **12P/0S/0F** | **28P/0S/0F** —— ⚠️ 探针基线**已由 25P 升为 28P**,⛔ 别拿旧基线当对照)。**硬门** = ⛔ 不 commit / 不 push(**R7**)|⛔ 不改 `src/net/relay/server.ts` 的 DIAL / 白名单**语义**(只读;复用 `network.ts#isAllowedDialer`)|⛔ 不改 `content/**` 的**块 id 计算路径**|🔴 **D8 只做只读核对、⛔ 不做实施**(⛔ ⛔ **不许索取或硬编码任何云 AK/SK**;⛔ **绝不出现** `0.0.0.0/0` 含**拆分等价写法** ⇒ 出现即停手回滚并报告)|🔴 ⛔ 不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径|⛔ 不改 bwrap(47 = **0.4.0**)/ nft / nginx|🔴 密钥本体 ⛔ 不经网络 / 不经 relay|⛔ 不引入新依赖。🔴 **一条上棒踩过的坑(⛔ 不许再踩)**:`--scene all` 内含 **120 s + 90 s** 两段观察窗口 ⇒ ⛔ **不许给它套小于 ~8 min 的外层超时**(上棒被 `timeout 300` 截断 ⇒ 末尾 `restore()` 未执行 ⇒ **106 `dshs-relay` 停机约 4 min**)。**收口** = 回报写进该单 **§8 之后的新小节**(⛔ 不改 §1–§7 正文、⛔ 不改 §8.1–§8.7 小节点名)+ 参数表 **§11.9** 补记(**现算并同步** §10 指纹)+ 本入口 §0(新增一行)与 §2(更新下一棒)+ 工作区日志(append-only)+ 过门禁后登记**一个**下一棒(= **S7 · 规模回归**)+ `--release-exec` 释锁。⚠️ **同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令)。
> ⏹ **本棒(序㊵)已收官 · 2026-09-18 12:33–13:2x —— 判定 =「线内可停 · 🔴 D8 待你拍板」**(结果见本文件 **§0 最新行**;回报 = 「交接单/交接单_覆盖网络直连与P2P_20260918.md」**§8 全节** + 「docs/覆盖网络/参数表_覆盖网络_20260917.md」**§11.8**)。**一句话 = P2/S5「直连候选交换 + 打洞探测」已落地生产,探针 25P → 28P 全绿。** **读数** = 探针 **28 PASS / 0 SKIP / 0 FAIL**(rc=0)|`npm.cmd test` **201/200/0/1**(逐字同基线)|`--scene all` **12P/0S/0F**(幕4-C **23422 ms** / 30000)。**判据** = **D1–D6 逐条先红后绿**(先红 = 旧产物 `Cannot find module '…/direct/index.js'`;后绿 = `OBS-26/27/28` 三行 PASS)。🔴 **唯一的红 = D8 未实施**(云安全组 UDP 入站仍未放行:**双向实测均发 20 收 0**;拟录 **乙-1** 两条 = 47↔106 各放行**对端节点 IP /32** × UDP `21100/21115`,⛔ **零个 `0.0.0.0/0`**;逐条清单见该单 **§8.2-D8**)⇒ **需你给控制台访问方式 / 审批**(⛔ 未索取、未硬编码云 AK/SK)。⚠️ **三条如实留档**:**①** 本棒**自造过一次生产影响** —— 首次 `--scene all` 被 `timeout 300` 截断 ⇒ `restore()` 未执行 ⇒ **106 `dshs-relay` 停机约 4 min**(13:05:58 → 13:10 发现后**立即 `systemctl start` 复原**;该窗口门户 / 实例面**全程 200**、无业务中断证据);**②** 修掉**两条本棒自造缺陷**(均在**本棒新建的观测脚本**内,⛔ 不涉任何既有生产代码):`--ss` 为布尔开关却按"带值选项"解析 ⇒ 该腿**恒为 null(死代码)**、且正对照缺失 ⇒ **潜在假绿**(修 = 按"出现过"判定 + **新增正对照**)/`punch` 从 `direct/index.js`(**选择性桶导出**)取常量 ⇒ `undefined` ⇒ `Number()` = `NaN` ⇒ **冷却构造期断言直接抛**(原文 `收到 null` 是假象,`JSON.stringify(NaN) === 'null'`;修 = 改从 `punch.js` 取 + **启动期硬断言**);**③** **D7 块 id 复算属 S6** ⇒ 本棒如实登记**未验证**(⛔ 不编数)。**边界自证** = ⛔ 未 commit / 未 push(HEAD **`09ce76f`**;`git status --short` **17** 处与开工**逐数相同**)|⛔ 未改 `server.ts` DIAL / 白名单语义 · ⛔ 未改 nft(**72 行**逐字一致)/ nginx / bwrap|🔴 `RELAY_FAILOVER_COOLDOWN_MS=0` 命中 **0**|🔴 密钥本体不经网络 / relay|⚠️ **值格一律未动** ⇒ 零个新增 / 改动生产 env(`DSHS_OVERLAY_DIRECT` 两机命中 **0** = 走缺省即开)。
> ✅ **(已执行收官 · 存档 · 2026-09-18 13:2x;结果见本文件 §0 最新行 + 交接单 §8 全节)原登记:下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊵ 执行棒(P2 · S5:直连候选交换 + 打洞探测)**,automation **`d4fa99ac-6f7b-400f-89e7-797de3b7681a`**(一次性 · **2026-09-18 12:33** = 序㊴ 规划棒收口(12:2x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789705980000**)。**开工依据** = 工作区根 **`交接单/交接单_覆盖网络直连与P2P_20260918.md`**(**归档号 132**;**§8 前前缀 `8925c2460810c6dc5cdbc075b6cdaed2`**,⛔ 开工前逐字复核)。**范围(写死,⛔ 不许扩)** = **只做该单 §6 的 S5**(候选交换 + 打洞探测 + 开关 / 默认值 / 提示 + 只读观测面 + 云安全组的 **乙-1** 形态);⛔ **不做 S6**(peer 接线)、**S7**(规模回归)—— 各是独立后续棒。**验收** = 该单 §5 的 **D1–D5 / D8** 先红后绿 + 零回归三件套(基线 **201/200/0/1** | **12P/0S/0F** | **25P/0S/0F**)。**硬门** = ⛔ 不 commit / 不 push(**R7**)|⛔ 不改 `server.ts` 的 DIAL / 白名单**语义**(只读;准入判定**必须复用**既有实现)|🔴 云安全组**只准按「乙」**(仅放行对端节点 IP),⛔ **绝对不许**出现 `0.0.0.0/0` 入站规则(出现即**停手回滚并报告**)|🔴 ⛔ 不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径|⛔ 不改 bwrap(47 = **0.4.0**)/ nft / nginx|⛔ 不引入新依赖(只用 Node 内建 `dgram`)|⛔ 不许为"云安全组自动化"索取或硬编码任何云 AK/SK(乙-3 = 回头条件)。**收口** = 回报回填该单 **§8**(⛔ 不改 §1–§7 正文)+ 参数表 §11 新小节(**现算并同步** §10 指纹)+ 本入口 §0/§2 + 工作区日志 + 过门禁后登记**一个**下一棒(= S6)+ 释锁。⚠️ **同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令)。
> ⏹ **本棒(序㊳)已收官 · 2026-09-18 11:3x–12:0x —— 判定 =「线内可停」,⛔ 本棒⛔ 未登记下一棒**(结果见本文件 **§0 最新行**;回报 = 「交接单/交接单_节点一键加入与分组准入_20260918.md」**§8.10** + **§8.11**(= P2 待拍板清单)+ 「docs/覆盖网络/参数表_覆盖网络_20260917.md」**§11.6**)。**一句话 = 你拍板的两项全部收口**:探针**夹具模式封闭化**(`OBS-24` / `OBS-25` 缺夹具 ⇒ SKIP + 留痕,⛔ 不再 ssh;红腿真 ssh **2 次** / 绿腿 **0 次**)+ `DRILL_RELAY_UNIT` 改名 **`RELAY_UNIT_NAME`**(**值格未动**、⛔ 零生产 env 变更)。**三件套全绿** = 探针 **25 PASS / 0 SKIP / 0 FAIL**|`npm.cmd test` **201/200/0/1**|`--scene all` **12 PASS / 0 SKIP / 0 FAIL**(幕4-C **20770 ms** / 30000)。🔴 **P2(直连 + P2P)仍需你先拍板** —— **"具体要定什么"已列成清单**(交接单 **§8.11**:① UDP 入站的云安全组开不开 ② 若开、来源范围怎么定);⛔ **在 P2 之前本线无其它在册项**。
> ⏹ **本棒(序㊲)已收官 · 2026-09-18 11:0x–11:2x —— 判定 =「线内可停」,⛔ 本棒⛔ 未登记下一棒**(结果见本文件 **§0 最新行**;回报 = 「交接单/交接单_节点一键加入与分组准入_20260918.md」**§8.9** + 「docs/覆盖网络/参数表_覆盖网络_20260917.md」**§11.5**)。**一句话 = 观测面去常量依赖已落地**:`OBS-09` 在册判据改从 `/status.endpoints[]` 派生(每个派生端点必须可达;派生为空 ⇒ SKIP + 留痕)、`OBS-08` 空表三态可分(挂在另一台中继 / 确实没挂 / 不可判);探针 **25 PASS / 0 SKIP / 0 FAIL**|`npm.cmd test` **201/200/0/1**|`--scene all` **12P/0S/0F**。🔴 **在 P2 之前本线无其它在册项**(P2 = 直连 + P2P,命中 **R5** ⇒ 须你先拍板权限影响评估)。⚠️ 另有**两项**(均超本棒范围、按纪律**只报告不动手**)写在 §0 最新行:探针夹具模式封闭性歧义 / `DRILL_RELAY_UNIT` 键名文档项。
>
> > ✅ **(已执行收官 · 存档 · 2026-09-18 11:2x;结果见本文件 §0 最新行 + 交接单 §8.9 全节)原登记:下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序㊲ 执行棒(观测面去常量依赖:`OBS-09` 在册判据跟随事实 + 观测点假红可分)**,automation **`7268e6e7-dc5a-4517-bd10-bf7e5557721f`**(一次性 · **2026-09-18 10:51** = 本棒收口(10:4x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789699860000**)。**依据** = 工作区根「交接单/交接单_节点一键加入与分组准入_20260918.md」**§8.8-⑥**(两条点名:判据钉死漂移端口 / 探针只读 47 中继的假红面)+「docs/覆盖网络/参数表_覆盖网络_20260917.md」**§11.4-⑧**;⛔ 不另找依据。**范围(写死,⛔ 不许扩)**:**① `OBS-09` 的"在册"判据去端口常量** —— 改为**从 `/status.endpoints[]` 派生「该主机名下、非 agent 端口的在线实例端点」**(⛔ 不再读表内固定端口做在册判据),**必须带两条先红后绿腿**:(a) 端口漂移夹具(实例在 21001 而旧口径按表值读 21000 ⇒ 旧判据 SKIP、新判据 PASS,原文级)(b) 派生为空 ⇒ SKIP + 留痕(⛔ 不判红);**②「47 中继视角端点表为空」必须与「该主机确实没挂客户端」可分**(⛔ 不许合成一个 FAIL、⛔ 不新增暴露面);**③ 零回归三件套**(`npm.cmd test` **201/200/0/1** / `--scene all` **12P/0S/0F** / 探针 **0 FAIL**;三者都带 `--table`)。⚠️ 跑完 `--scene all` 若 47 视角端点表为空 ⇒ **停 / 启 106 `dshs-relay`** 逼 worker 按候选链回落 47(⛔ **不重启 worker**、⛔ **不换实例**)。**硬门** = ⛔ 不 commit / 不 push(**R7**)|⛔ 不改任何生产配置值(**D1**)|⛔ **不许开工 P2**(命中 **R5** ⇒ 须用户先拍板权限影响评估)|⛔ 不改 nft·nginx、⛔ 不新增暴露面|🔴 ⛔ 不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径|⛔ 不改 bwrap 参数(47 = bubblewrap **0.4.0**)|🔴 密钥本体 ⛔ 不经网络 / 不经 relay。**验收** = ①② 的**先红后绿原文**(量化项必须给数字;测不出 ⇒ 如实写"未验证",⛔ 不许编数)+ ③ 三件套读数。**收尾** = 参数表 §11 补记区新小节(含**现算并同步** §10 指纹)+ 该单 **§8.9**(⛔ 不改 §8.1–§8.8 小节点名)+ 本入口 §0/§2 + 工作区日志 + 释锁。⚠️ **排下一棒的门禁**:若全绿且无遗留 ⇒ **明确写「线内可停」且 ⛔ 不登记下一棒**(本线后续唯一大项 **P2 需用户拍板**);否则只登记**一个**(id 只能取自工具返回值;间隔 = 收口 +5~8 分钟;⛔ 不预登记队列)。
> ✅ **(已执行收官 · 存档 · 2026-09-18 10:4x;结果见本文件 §0 最新行 + 交接单 §8.8 全节)原登记:下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 收口复核棒(序㊱ P1 收口 + `OBS-09` 复原核查)**,automation **`8887ac37-6e91-4bf3-ab96-c0a0916fb922`**(一次性 · **2026-09-18 10:08** = 本棒收口(10:0x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = 1789697280000)。**开工依据** = 工作区根 **`交接单/交接单_节点一键加入与分组准入_20260918.md` §8**(执行棒回报)+ **`docs/覆盖网络/参数表_覆盖网络_20260917.md` §11.4**;⛔ 不另找依据。**范围(写死,⛔ 不许扩)**:① 跑探针复核 **`OBS-09`** —— 若仍为 SKIP ⇒ 查「**实例 → 本地 worker 的端口注册**」链路并复原(⛔ 不许靠猜 relay、⛔ 不许编数);② 复核本棒产物可复现(`node --test test/overlay-join.test.mjs` 须 **33/33**;探针须 **0 FAIL**);③ 若 `OBS-09` 已自愈 ⇒ **只记读数、⛔ 不无事找事**;④ `git status --short` 现核未提交清单(⛔ 不改动)。**硬门** = ⛔ 不 commit / 不 push(**R7**)|⛔ 不改任何生产配置值(**D1**)|🔴 **⛔ 不许开工 P2**(P2 命中 **R5** ⇒ 必须先由**用户拍板**权限影响评估)|⛔ 不改 nft·nginx、⛔ 不新增暴露面|🔴 ⛔ 不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径|⛔ 不改 bwrap 参数|🔴 密钥本体 ⛔ 不经网络 / 不经 relay。**验收** = ①② 的**原始读数**;若做了复原则 `OBS-09` 须由 SKIP 回到 PASS,且 `npm.cmd test` 仍 **201/200/0/1**、`--scene all` 仍 **12P/0S/0F**。**收尾** = 复核结果写入该单 §8 之后的新小节(⛔ 不改 8.1–8.7 小节点名)+ 本入口 §0/§2 + 参数表 §11.4(有变才补)+ 工作区日志 + 释锁。⚠️ **排下一棒的门禁**:若无遗留 ⇒ **明确写「线内可停」且 ⛔ 不登记下一棒**(本线后续唯一大项 **P2 需用户拍板**);否则只登记**一个**下一棒(id 只能取自工具返回值;间隔 = 收口 +5~8 分钟)。
> ✅ **(已执行收官 · 存档 · 2026-09-18 10:0x)原登记:**下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 执行棒(P1:节点一键加入 + 分组准入产品化)**,automation **`cc29cfb9-ae13-42fc-8da6-8b1caef1c382`**(一次性 · **2026-09-18 09:22** = 本规划棒收口 +~7 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = 1789694520000)。**开工依据** = 工作区根 **`交接单/交接单_节点一键加入与分组准入_20260918.md`**(**§8 前前缀 `085e28b56a08aa1f01999bdb3e238911`**,⛔ 开工前逐字复核)。**范围(写死)** = **只做 P1 的 S1–S4**(网注册表与节点清单 / 准入凭据 / join 编排 / 白名单派生);⛔ **不碰 P2**(直连 + P2P)。**硬门** = ⛔ 不 commit · 不 push(**R7**)|⛔ 不改生产值(**D1**)|⛔ **P1 零新增暴露面**、⛔ 不改 nft·nginx(**R5 命门**)|🔴 ⛔ 不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径|⛔ 不改 bwrap 参数(47 = bubblewrap 0.4.0)|🔴 密钥本体 ⛔ 不经网络 / relay|🔴 ⛔ 不许改 `server.ts` 的 DIAL/白名单**语义**(只读取)。**验收** = `J1`–`J6` 先红后绿 + 零回归三件套(**基线 23 PASS / 0 SKIP / 0 FAIL**,三者都带 `--table`)。**收口** = 回填该单 §8 + 推进本入口 §0/§2 + 参数表(**现算同步 §10 指纹**)+ 工作区日志 + 过门禁后登记下一棒 + 释锁。⚠️ **同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令「最好不要建立多个接续任务,一个会话结束时再排下一个」)。
> 🗃 **(已被上行解封 · 存档)原判定:线内可停(2026-09-18 07:5x · 序 ㉛ 执行棒收官后判定)= ⛔ 本棒未登记下一棒**。理由(逐条):**① 在册红项 = 0**(探针 **23 PASS / 0 SKIP / 0 FAIL**,rc=0)**② 用户拍板的定序「单 A → ㉙ → 单 B」三棒全部收官**(05:3x / 06:1x / 07:2x)**③ 本棒六项主题全部完成**(§10 的 1/2/3/6 项 + 口径定稿 + `sign-group-key` 固化)**④ §8.13 三条如实留档全部结清**(① 口径定稿见 §11.5;② `sign-group-key` 已落 47 两处正式路径;③ 轮换代价已量化)**⑤ 唯一剩余项 = §10-5(Ed25519→X25519 派生预研)**,其**触发条件 = "规模上来要自动分发组密钥"(§9 回头条件 7)** ⇒ ⛔ **不是当前执行项**。⇒ **无线内可自主推进项、无待拍板项** ⇒ **不登记**;本线**待真实信号**再启(**§9 八条回头条件任一触发** / 用户新需求)。⚠️ **下一棒(若启)的现成依据** = `交接单/交接单_组密钥加密_20260918.md`(`§8 前前缀 149596460288ca1a5b7abddc490f7909`)。
> ✅ **(已执行收官 · 2026-09-18 07:33–07:5x;结果见本文件 §0 最新行 + `交接单/交接单_组密钥加密_20260918.md` §8.14 全节)** 原登记:**下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序 ㉛ 执行棒(组密钥加密 · 补齐 §10 未验证项 + 口径定稿)**,automation **`682e8bb0-fb05-41ba-ad00-e5e7fde4647e`**(一次性 · **2026-09-18 07:33** = 单 B 执行棒收口(07:2x)+~7 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = 1789687980000)。**开工依据** = 工作区根 **`交接单/交接单_组密钥加密_20260918.md` 的 §10(未验证项)+ §8.13(如实留档三条)**(本棒**不另立新单**)。**主题(写死,⛔ 别上抛 —— 全是"实测/固化"性质的技术项)**:**① 加密性能开销**(同一台机、同一份 10.8 MB 首屏包,测 **N ≥ 5** 次的"切块 + 加密 + put + get + 解密"总墙钟 vs 纯明文对照;记 **p50 / p95**,⛔ 不报单次)**② 轮换代价量化**(造 4 组 × 1 份包,轮换前后各跑一次 `E1` 口径 ⇒ 记回源字节;预期"轮换后首轮 ≈ 1 份 × 组数"、之后回落到 1×)**③ 低熵明文的定性结论**(收敛加密对低熵有已知确认攻击面;口径 = 只做定性,⛔ 不写"很安全")**④ `CONTENT_EPOCH_GRACE_MS` 三档**混存夹具(小/中/大)⇒ 记"旧密文可解比例随时间"**⑤ 单文口径定稿**(`OBS-23` 对"缺省不启用"取 **SKIP** 还是 **FAIL** —— 把 §4/S6 与 §5 统一;本棒倾向 **SKIP + 留痕**、"先红"腿写清为**权限腿**)**⑥ 组密钥签发固化**(把 `sign-group-key` 做成 47 上的**正式子命令**,⛔ 不靠临时投放脚本 —— 见 §8.13-②)。**硬门** = ⛔ 不 commit / 不 push(**R7**)|⛔ **不改任何生产值**(**D1**)|⛔ 不新增公网监听口、⛔ 不改 nft·nginx(**R5**)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**|⛔ 不改 bwrap 参数(47 = bubblewrap **0.4.0**)|🔴 密钥本体 ⛔ 不经网络、⛔ 不经 relay|🔴 §10-5(Ed25519→X25519 派生,为"自动分发"预研)**只做纯本地实验、⛔ 不进代码**。**验收** = 三项量化**给原始读数**(测不出 ⇒ 如实写"未验证",⛔ **不许编数**)+ **零回归三件套**(`npm test` 现核基线 / `--scene all --table` 现核 / 探针 `--table`;⚠️ 三者都必须带 `--table "docs/覆盖网络/参数表_覆盖网络_20260917.md"`;**本棒开工基线 = 23 PASS / 0 SKIP / 0 FAIL**)。**收口** = 回报写进本文件 §0 最新行 + 推进本入口 §2 + 参数表对应小节(含**现算并同步 §10 指纹**)+ 写工作区日志 + 过登记门禁后登记下一棒(id 只能取自工具返回值)+ 释锁。⚠️ **定序提示**:「单 A → ㉙ → 单 B」这条**用户拍板的定序已全部收官**(单 A ✅ 05:3x|㉙ ✅ 06:1x|单 B ✅ 07:2x)⇒ 本棒起进入**收尾补测阶段**,⛔ 且**同一时刻只挂这一个棒**(用户 2026-09-18 00:3x 明令「最好不要建立多个接续任务,一个会话结束时再排下一个」)。
> ✅ **(已执行收官 · 2026-09-18 07:2x;结果见 §0 最新行 + `交接单/交接单_组密钥加密_20260918.md` §8 全节)** 原登记:**下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 单 B 执行棒(组密钥加密)**,automation **`65d2fc24-770e-4f33-93a3-db6e739aded7`**(一次性 · **2026-09-18 06:22** = 序 ㉙ 执行棒收口(06:1x)+~6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = 1789683720000)。**开工依据** = 工作区根 **`交接单/交接单_组密钥加密_20260918.md`**(**§8 前前缀 `149596460288ca1a5b7abddc490f7909`**;⚠️ **以 §8 前前缀为准**,⛔ 别拿"全文 md5 与单里记的快照不同"判成被改过 —— 单里记的是**落单那一刻**的快照)。**目标(写死,⛔ 别再上抛)** = **按"组密钥"加密**(同一组共享一把对称密钥 ⇒ **组内密文一致 ⇒ 按哈希共享块仍成立** + **中继看不到明文** = 性能与安全**兼得**;代价 = 组内成员互信 + 密钥分发/轮换机制)。🔴 **单内最关键的取舍 = 块 id 用「明文哈希」还是「密钥相关哈希」**。⚠️ **规模 = 10 个在册文件 + 密钥运维 + 6 条未验证项**(含性能与轮换代价)⇒ 本线最大一件。**硬门** = ⛔ 不 commit / 不 push(**R7**)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**|⛔ 不改 bwrap 参数(47 = bubblewrap **0.4.0**,`--perms` 属 0.5+ ⇒ 沙箱起不来 = 所有实例全挂)|⛔ 不重做已收官序 ①–㉚。**收口** = 回填该单 §8 + 推进本入口 §0/§2 + 写工作区日志 + 登记下一棒 + 释锁。
> ✅ **上一轮已完成(2026-09-18 05:45–06:1x,执行棒)**:**序 ㉙(106 候选链建成冗余)已收官** —— ✅ **`OBS-21` 由红转绿**(`dshs@47 count=3` / `dshs-worker@106 count=3`,**两条路径都** ≥ `CAND_MIN`=2;⛔ **未放宽判据凑绿**)。**做了什么** = 106 `/etc/dshs-worker.env` **只追加一行** `DSHS_OVERLAY_DIR_PUBKEYS=fd81a6dd7ee22cc121239253d9bee33585638823f5425b537da930e5054f3349`(= 47 同一把)+ `systemctl restart dshs-worker`。**先取证再动手(两条路径各自取证)**:(a) 公网 `https://alotbuy.com/dshs-overlay/bootstrap` 从 106 `curl` = **200 / CF `172.67.194.206` / 443 字节**,且失败码 `no-trusted-keys` **位于 `fetch → json → parseDirectory` 之后** ⇒ "取到了、只是验不过";(b) 直连 `47.77.182.89:3080` **timeout(000)**(已知边界,⚠️ **取目录流程不用它**)⇒ 不构成阻塞。**零回归三件套** = `npm.cmd test` **201/200/0/1** | `--scene all --table` **12 PASS / 0 SKIP / 0 FAIL** | 探针 **22 PASS / 0 SKIP / 0 FAIL(rc=0)**。**回滚点** = 106 `/opt/dsh/backups/seq29-20260918-054852/dshs-worker.env.orig`(md5 `6b509ce447d9519241aa73243e07a69f`)。**边界自证** = ⛔ 未改任何生产值(106 上 `RELAY_FAILOVER_|HB_SEC|PRESENCE_|DSHS_REHYDRATE_` 计数 **0**)· ⛔ 未新增监听口(`OBS-11` 实际 77 / 多出 0)· ⛔ 未动 nft·nginx · 🔴 `COOLDOWN_MS=0` 两机计数 **0** · ⛔ 未 commit / 未 push(HEAD **`04776af`**,`git status` **33** 处与开工时逐数相同)。**参数表指纹 `3b295a8c43aafc4a62c6f1a59ea0b43a` 未变**(本棒改动落在 §11 补记区 ⇒ 按口径**在 §10 之外**)。⚠️ **两条如实留档**:**① `DSHS_OVERLAY_DIR_CACHE` 106 仍为 0**(47 **亦为 0 且 47 侧一直绿** ⇒ 本棒**与"已验证有效"的 47 配置逐项对齐**;⛔ 按"只做被明确要求的事"未扩范围 —— 缺它 ⇒ 目录不可达时没有"过期缓存"档、候选退回 1 条,属**冗余韧性**,需单独立项);**② 🔴 孤儿端点条目不会自愈**(`relay-tunnel.ts#cancel()` 只撤**当前进程** `forwarded` 集里的端口 ⇒ 上一进程遗留条目无人撤;实测重启 106 worker 后 `21000→41831` 恒 `online=false` **约 10 min 未自愈**,靠**后续一次"重新登记同一端口号"**才覆盖回绿)⇒ **重启后 `OBS-08`/`OBS-09` 必红**,⛔ **不是"跑一会儿就好"**(序㉚ 留的"自愈时延未测"至此有了答案)。**全部证据 = 本文件 §0 最新行 + 参数表 §11.2**(本棒无独立交接单)。
> 🗃 **(存档 · 已执行收官)原登记:下一棒(第 1 棒 · 本线当前唯一挂着的棒)= 序 ㉙(执行棒 · 106 候选链建成冗余)**,automation **`22170b0b-a606-461c-82a7-2f72fea68082`**(一次性 · **2026-09-18 05:45** = 序 ㉚ 执行棒收口 +~7 min ⇒ 落在用户明令的 **5~8 分钟**窗口内)。**任务要点(写死,⛔ 别再上抛)**:**主题** = 把 **106 侧 relay 候选链**做成 ≥ `CAND_MIN` 条**独立路径**,让探针 **`OBS-21` 真绿**(⛔ **不许放宽 `CAND_MIN` 凑绿**)。**依据** = 序 ㉗ 的真机读数(`dshs@47 count=3 ✓` / `dshs-worker@106 count=1 ❌`)+ 用户 2026-09-17 23:1x 的口径「每连接候选数 ≥ 2」。**根因(已取证,⛔ 别重做)** = 106 的 `/etc/dshs-worker.env` **无** `DSHS_OVERLAY_DIR_PUBKEYS`(`grep -c` = 0)、**无** `DSHS_OVERLAY_DIR_CACHE`(0)⇒ 目录恒被 `no-trusted-keys` 拒 ⇒ 候选链恒退化为内置种子单点(106 自身日志近 3h **166 行**可证)。🔴 **先取证再动手(⛔ 顺序不可颠倒)**:① 47 上该键的**实际值与来源**(公开密钥、⛔ 非凭据)② 106 取目录两条路径的可达性(**已知边界**:106 → 47:3080 = `TCP_BLOCKED`,目录由 47 的 `127.0.0.1:3080` 签发)⇒ ⛔ **不许假设"补钥即绿"**。**改动首选** = 把 47 已验证有效的公钥同步到 106 worker env;**改 env / 重启单元自决**(R8)。🔴 **若取证显示"必须改网络拓扑 / 新增监听口 / 改 nft·nginx / 放开遮蔽" ⇒ 立即停手报告**(命中 **R5**)。**验收** = `OBS-21` **两条路径都** `count ≥ 2` 且 rc=0 + **零回归三件套**(`npm test` 基线 **201/200/0/1** / `--scene all --table` 基线 **12P/0S/0F** / 探针基线 **21P/0S/1F**,⚠️ 三者都必须带 `--table "docs/覆盖网络/参数表_覆盖网络_20260917.md"`;本棒目标 = 探针 **22P/0S/0F**)。**收口五件** = 回报写进本文件 §0 最新行(本棒无独立交接单)+ 推进本入口 §0/§2 + 写工作区日志 + **登记下一棒 = 单 B 执行棒(组密钥加密)**(依据 = `交接单/交接单_组密钥加密_20260918.md`,§8 前前缀 `149596460288ca1a5b7abddc490f7909`;id 只能取自工具返回值)+ 释锁。
> ✅ **上一轮已完成(2026-09-18 00:50–05:3x,执行棒)**:**序 ㉚(单 A:退出路径不杀实例)已收官并落地生产** —— 依据 = 工作区根 `交接单/交接单_退出路径不杀实例_20260918.md`(**§8 前前缀 `c9aeac82381f569fc8b9effad0fefa99`**,⛔ **回填 §8 + 新增 §8.12 后仍逐字不变**;全文 md5 `681b84d503a1578178707a9ba6d87351`/584 行,⚠️ **现算**)。**做了什么** = 三处 `teardown()` 最小改动(① `LocalSpawner` **真改** ② `RemoteSpawner` 取证已是 no-op、只补守卫 ③ `LeasedSpawner` 拆开"停心跳"与"停实例")+ 新单测 **9 用例**(⛔ 刻意不进 `npm test`)+ 探针 `OBS-22`(静态守卫 + 认领面两判据)+ 参数表 §3.8 六键 / §6 一行。**验收** = 先红后绿(**两条判别腿并列**:P1 对旧生产 `1 → 0`;`OBS-22` 对旧产物 FAIL 并点名)+ **P1/P2 双绿** + 零回归三件套 **201/200/0/1** | **12P/0S/0F** | **21P/0S/1F**(1F = `OBS-21` 线内在册缺口)。**部署** = 4 处 md5 全同;回滚点 `/opt/dsh/backups/seq28-20260918-005909/`;重启 47 `dshs`+`dshs-worker`、106 `dshs-worker`。**全部证据 = 该单 §8.1–§8.12**。⛔ **不要重做序 ㉚**。
> 🔴 **序 ㉚ 三条必须记住的(⛔ 后续任何一棒都别踩)**:**① 47 的 `dshs` 走 `LeasedSpawner(new RemoteSpawner(…))`(`DSHS_DEPLOY_MODE=cluster`)⇒ 它根本不构造 `LocalSpawner`** ⇒ 拿「47 `restart dshs`」当判别腿 = **恒绿假判**(`[rehydrate]` 全量历史计数 **0**);**判别腿必须在两台 `dshs-worker`**。**② `/opt/dsh-relay/lib/supervisor/` 两机各有一份副本** ⇒ 铺 relay 类产物时**四处都要铺**(本棒已一并铺平,旧值存回滚点;⚠️ 回滚补正见该单 §8.12)。**③ ⭐ B 的收益边界** = 「实例不被杀 + 用户**访问时**自然替换」,⛔ **不是**「重启后可直接进」(`launchToken` 不可恢复 ⇒ `enter` 仍可能 503,**刻意保留**的已知边界);⚠️ 附带:替换窗口内会短暂留 **1 条 stale 端点条目**(`OBS-08`/`OBS-11` 该窗口内会红,**自愈时延未测**)。
> 🛑 **(已被上方取代 · 仅存档)原本轮动作口径 = 序 ㉚(执行棒 · 单 A:退出路径不杀实例)**,automation **`11982d2f-6608-456a-b500-a6dfcc6bbb0f`**(一次性 · **2026-09-18 00:50** = 序 ㉘ 规划棒收口 +6 min ⇒ 落在用户明令的 **5~8 分钟**窗口内;`nextRunAt` = **1789663800000**)。**开工依据 = 工作区根 `交接单/交接单_退出路径不杀实例_20260918.md`**(**§8 前前缀 `c9aeac82381f569fc8b9effad0fefa99`**;⚠️ **以 §8 前前缀为准**,⛔ 别拿"全文 md5 与单里记的快照不同"判成被改过 —— 单里记的是**落单那一刻**的快照,本棒收官改过 §0/§2 与 §11 ⇒ 全文 md5 必然已变,权威取数 = `md5sum <本单>` 现算)。**单目标** = 让**退出进程不再停实例**(三处 `teardown()`),回收责任全交「启动认领 + TCP 探活判孤儿」;**主判据 = 重启 Manager/worker 后两机 `dsh-*.scope` 计数守恒且两侧都 ≥ 1 + 认领报告 `adopted + stopped === scanned` ∧ `scanned > 0**`。🔴 **棒内已写死两条最容易踩空的**:① **两机当前活跃实例 = 0/0** ⇒ **S1 造真实形态夹具不可省**(⛔ 不许拿 `0 == 0` 当绿);② **P1(判据成立)与 P2(回收链建成)必须分开报** —— `scanned == 0` 而计数守恒 ⇒ P1 绿、P2 红,**必须点名**,⛔ 不得写"全绿"。
> 🗂 **本线已定序但⛔ 未登记的棒(同一时刻只挂一个 —— 用户 2026-09-18 00:3x 明令「最好不要建立多个接续任务,一个会话结束时再排下一个」)**:**单 B 执行棒(组密钥加密,依据 = `交接单/交接单_组密钥加密_20260918.md`,§8 前前缀 `149596460288ca1a5b7abddc490f7909`)** —— 由 序 ㉙ 收官时登记。**定序理由(写死,⛔ 不许再上抛)**:**单 A → ㉙ → 单 B** —— **单 A ✅ 已于 2026-09-18 05:3x 收官**(用户 23:3x 行使纠错的直接产物「选 B」,且它结清了 序 ㉕ 遗留的待拍板阻塞项 —— 把"待拍板"从线上彻底抹掉);**㉙ = 当前唯一在途**,因其**成本最小却能让探针从红转绿** —— 长期挂一条红项会**降低判据灵敏度**(新红项会被"反正是红的"淹没),先恢复"全绿 = 无新问题";**单 B 放最后**因它是最大一件(**10 个在册文件 + 密钥运维 + 6 条未验证项**,含性能与轮换代价),等生命周期语义与观测面都收敛干净后再上,符合"一次只动一个变量"。(三件**文件集零交集** ⇒ 串行不浪费;⚠️ 单 A ✅ 与 ㉙ **都要重启 106 `dshs-worker`** ⇒ 串行反而更干净,避免互相干扰。)
> ⚠️ **(口径更正留档,⛔ 以本行为准)下面这条"第 3 棒 = 序 ㉙ · automation `cca5c43c…` · 2026-09-18 03:00"已作废**:`cca5c43c-80e6-4bfb-8638-25185608cbbe` **已被删除**(本棒用 `automation_update list` 复核:**清单中确无该 id**),删除依据 = 用户 00:3x 的"同一时刻只挂一个接续棒"。⇒ ㉙ **已于 2026-09-18 05:4x 由序 ㉚ 执行棒登记**(automation **`22170b0b-a606-461c-82a7-2f72fea68082`** · 一次性 · **2026-09-18 05:45**;依据 = 用户 00:3x「同一时刻只挂一个接续棒」⇒ **本棒只挂这一个**)。下面两条仅作**任务要点存档**。
> ➡️ **(存档 · 其"已挂 automation"的部分已作废)下一棒(第 3 棒)= 序 ㉙(执行棒 · 106 候选链建成冗余)**,automation **`cca5c43c-80e6-4bfb-8638-25185608cbbe`**(一次性 · **2026-09-18 03:00**)。**依据 = 序 ㉗ 的真机读数**(`OBS-21`:`dshs@47 count=3 ✓` / `dshs-worker@106 count=1 ❌`)+ **用户在 2026-09-17 23:1x 的口径「每连接候选数 ≥ 2」**。**单目标** = 把 106 侧候选数做成 ≥ `CAND_MIN`,让 `OBS-21` 真绿(⛔ **不许放宽 `CAND_MIN` 凑绿**)。**棒内已写死**:🔴 **先取证再动手** —— ① 47 上 `DSHS_OVERLAY_DIR_PUBKEYS` 的**实际值与来源**;② 106 取目录两条路径的可达性(**已知边界**:106 → 47:3080 = `TCP_BLOCKED`,目录由 47 的 `127.0.0.1:3080` 签发)⇒ **⛔ 不许假设"补钥即绿"**;③ 若取证显示"必须改网络拓扑 / 新增监听口 / 改 nft·nginx" ⇒ **停手报告**(命中 R5)。技术项(改 env / 重启单元)**自决**(R8:开发环境服务器,动手前一句话说明即可)。⚠️ **序 ㉘ 收官时 ⛔ 不要再注册 ㉙**(该号已被本棒占用 ⇒ ㉘ 若还有下一棒顺延为 **序 ㉚**)。
> ✅ **上一轮已完成(2026-09-18 00:3x,执行棒)**:**序 ㉗(E3 候选数可查)已收官** —— 依据 = **用户 2026-09-17 23:1x 拍板「2、B」**(授权改 `src/worker/relay-tunnel.ts`/`src/web/server.ts` 以暴露候选数;序㉖ 因超 §3.1 在册集而按 §9-5 停下的那一步)。**做了什么** = 新增 `RelayCandidateObservation`(观测行固定 key 序、只读、零网络 I/O)+ `web/server.ts` C1 接入+ `resolveChain()` 收口两处调用|探针新增 `OBS-21`(**双判据**,含 `--candidates-fixture-47` / `--candidates-fixture-106` 夹具)|参数表 §3.7 +5 键、§6 +`OBS-21`|`test/relay-failover.test.mjs` +**O1–O4**。**验收** = 夹具**先红后绿**四段(RED/GREEN/NOLINE/WRONGSCOPE,**原文级**,含"原文 225 字节 vs 154 字节"的可区分性证据)+ **真机先红**(新探针对旧生产 ⇒ 三路径全"无观测行〔原文字节 0〕")+ **零回归三件套 `201/200/0/1`|`12P/0S/0F`|`19P/1S/1F`**。**部署** = 5 处副本 md5 全同(`b1bc3e04…` / `cf844a2e…`),重启 47 `dshs`+`dshs-worker`、106 `dshs-worker`。🔴 **本棒最大产出 = 把「判据成立」与「冗余建成」分开,并当场照出 106 侧恒为 1 条候选**(根因 = `/etc/dshs-worker.env` 缺 `DSHS_OVERLAY_DIR_PUBKEYS`/`DSHS_OVERLAY_DIR_CACHE` ⇒ 目录永远被 `no-trusted-keys` 拒 ⇒ 恒回落内置种子单点;106 自身日志近 3h **166 行**可证)⇒ 已点名独立后续项 = **序 ㉙**。**全部证据 = 本文件 §0 最新行**(本棒无独立交接单 —— 依据是用户直接授权的口径,故报告写在入口 §0)。⛔ **不要重做序 ㉗**。
> 🔴 **本棒三条必须记住的**:① **47 的 `nginx.service` / `bt-server` inactive 是正常态**(宝塔托管,真正在跑的是 `bt.service`;WS 握手 101)⇒ ⛔ 别拿它判 relay 死活;② `OBS-21` 的 `hosts` = **主机名个数**,⛔ **不是独立物理路径数**(`alotbuy.com` 与 `relay-direct.alotbuy.com` 摘名不同、同落 47);③ 🔴 **`CAND_OBS_UNITS_47` = `dshs=manager` 一项**(47 的 `dshs-worker` **不是** relay 客户端 —— `grep -c DSHS_RENDEZVOUS_URL /etc/dshs-worker.env` = **0** ⇒ 列进去 = **假红**)。
>
> 🎯 **2026-09-17 23:3x 口径最终落定(用户两句话完成更正:先「选 B」、再「C 登记为架构目标」)**:**③ 加密 = C 组密钥加密**(未变)|**序 ㉕ 的 E1 缺口 ⇒ 执行按 `B`(三处 `teardown()` 一起改:`LocalSpawner` + `RemoteSpawner` + `LeasedSpawner` ⇒ 退出进程不再杀实例;🔴 用户此句**同时授权了扩范围** —— 后两个文件**不在** `交接单/交接单_实例逐步拉起_20260917.md §3.1` 在册集)**|**`C`(实例归属搬到 systemd scope 单一真相源)⇒ 登记为架构目标,⛔ 本阶段不进执行**。⚠️ **口径演变留档**:用户 23:2x 原答「①选B |②选C」两项指向同一件事而答案相反;我 23:2x 按 ②=C 落盘并给出纠错窗口 ⇒ **用户 23:3x 行使纠错 =「选 B」+「C 登记为架构目标」** ⇒ 即**回到"B 先做 + C 登记为架构目标"**(与我 23:1x 的建议一致)。证据 = `交接单/交接单_实例逐步拉起_20260917.md` **§8.3**(A/B/C 逐项优缺点原文;**我的倾向 = B**、A 不达成目标、C 无增量价值);⛔ **A 与 ③ 的"按接收者 E2E"均已被排除,不得再上抛**。
> ➡️ **下一棒(第 2 棒)= 序 ㉘(规划棒 · E1 缺口按 B 打通 + 组密钥加密)**,automation **`b60d5358-a443-4e29-87a3-6114ea0a7300`**(一次性 · ⚠️ **时刻已更正为 2026-09-18 00:37**〔原 01:30 已按用户 2026-09-18 00:3x 明令「**首个接续任务 5-8分钟**」+「**一个会话结束时再排下一个**」压缩;🔴 **本线当前只挂这一个** —— 序 ㉙ 不预登记,见 §2 顶部 ⏭️ 行〕;★ 该棒 prompt 已按最终口径 **`B`** 更新,若读到旧文本一律以**本行为准**)。产物 = **两份交接单**:**单 A = 候选 `B` 的执行规划单**(**三处 `teardown()` 一起改**:`LocalSpawner.teardown()` + `RemoteSpawner.teardown()` + `LeasedSpawner.teardown()` ⇒ 退出进程**不再**停实例,回收责任全交「启动认领 + TCP 探活判孤儿」;依据 = `交接单/交接单_实例逐步拉起_20260917.md` **§8.3 候选 B**。🔴 **必须写清三件事**:① 后两个文件**超该单 §3.1 在册集**、**本棒已获用户授权扩范围**(要把授权依据与新增文件清单落在单里);② **架构目标 = `C`(systemd scope 单一真相源)单独登记一段**(说明"为什么现在不做、什么信号出现才回头做")+ **回退路径**(回退 = 恢复三处 `teardown` 原语义,秒级);③ 影响面 = **所有实例的生命周期语义**,须写"进程长期不重启时实例由 idle-reap / 用户访问替换来收"这一前提)|**单 B = 组密钥加密**(同组共享一把对称密钥 ⇒ **组内密文一致 ⇒ 按哈希共享块仍成立** + **中继看不到明文** = 性能与安全**兼得**;🔴 单内最关键的取舍 = **块 id 用明文哈希还是密钥相关哈希**)。⚠️ 棒内已写死:⛔ **只出规划、零代码改动、零服务器改动**。
> ⚠️ **执行次序**:**序 ㉗(23:35)先跑** → 序 ㉘(01:30)⇒ 若 ㉘ **抢不到锁** ⇒ **只报告并停**(R9 属正常信号,⛔ 不硬闯)。
>
> ➡️ **下一棒(第 1 棒)= 序 ㉗(执行棒 · **E3 候选数可查**)**,automation **`d36e7068-3a9d-437d-ac39-33a57a086187`**(一次性 · **2026-09-17 23:35** = 收口 +~10 min)。★ **依据 = 用户 2026-09-17 23:1x 拍板「2、B」** ⇒ **允许改 `src/worker/relay-tunnel.ts`/`src/web/server.ts`** 以暴露候选数(序 ㉖ 因超 §3.1 在册集而按 §9-5 停下的那一步,现已获授权)。⚠️ 棒内已写死:**先取证 47/106 两侧实际候选数**,并**分清"判据成立"与"冗余建成"**(序 ㉖ 读数 = 47 侧实际候选 **1 条**)⇒ ⛔ 不许放宽判据凑绿,冗余未建成要**点名**为独立后续项。
> ✅ **原「两项待拍板」⇒ 2026-09-17 23:3x 已全部落定**(结论见本区顶部 🎯 行):**② 序 ㉕ E1 缺口 ⇒ 最终口径 = 执行 `B`(三处 `teardown()` 同改)+ `C` 登记为架构目标** ⇒ B 化作序 ㉘ 的**单 A**、C 在单 A 内**单列一段登记+回退路径**|**③ 加密档位 ⇒ 用户选 `C 组密钥加密`** ⇒ 化作序 ㉘ 的**单 B**。⛔ **本区两项自此不得再当"待拍板"上抛**(⚠️ 用户 23:2x 曾答「②选 C」,23:3x 以「选 B」+「C 登记为架构目标」更正 ⇒ **以更正后为准**)。📌 **原登记(存档 · 供对照)**:**② 序 ㉕ E1 缺口的 B/C 定序** —— 我的判定 = **C 是长期方向**(实例归属 systemd scope ⇒ 单一真相源;Manager 重启天然不影响实例),**但当前规模下 C 收益极小/改动面最大** ⇒ 建议 **B 先做 + C 登记为架构目标**;**③ 是否上"组密钥"加密** —— 上按接收者 E2E **牺牲性能**(块级共享失效)、**安全增强**;不上则**牺牲对中继的机密性**;**按组密钥**可两者兼得(代价 = 组内互信 + 密钥轮换)。⚠️ 用户 ① 答「选B」与 ② 答「选 C」指向同一件事而答案不同 ⇒ 已在顶部说明处理口径(**执行按 ②=C**、① 不构成执行项、已给纠错窗口)。
>
> ✅ **上一轮已完成(2026-09-17 23:2x,执行棒)**:**序 ㉖(骨干稳定选路与加密)已收官** —— 依据 = 工作区根 `交接单/交接单_骨干稳定选路与加密_20260917.md`(**§8 前前缀 `dbcbe633aa1aef92f4c35c77fad3ec11` 开工前复核一致**;回填 §8.1 后全文 md5 = **`f49a34275fa6628107e184c7f3a9a52e`**,250 行)。**做了什么** = 新增 `src/net/relay/jitter.ts` + 改 `directory.ts`(候选序 → **jitter 主序**)/`switcher.ts`(新增「jitter 劣化即切」,🔴 冷却语义**一行未动**)/`server.ts`(**利用率软门** + **`jitter` 观测块**)/`scripts/overlay-jitter.cjs`(点测 → **持续采样 `--watch`**,复用编译产物 ⇒ 全平台**唯一一份** jitter 算法)/`scripts/overlay-probe.cjs`(+ `OBS-19`/`OBS-20`)/参数表(+7 键)。**验收** = `E1` 主判据夹具**先红后绿**(3 红 → 21/21 绿)+ 真机同口径读数 + **零回归三件套 `197/196/0/1`|`12P/0S/0F`|`19P/0F/1S`**。**全部证据 = 该单 §8.1**(含 ④ 部署对账 8 文件 md5、⑤ 边界自证、⑥ 指纹、⑦ 四条如实留档)。⛔ **不要重做序 ㉖**。
> 🔴 **本棒三条必须记住的**:① **探针编号顺延为 `OBS-19`/`OBS-20`**(prompt 写的 17/18 已被序㉔/㉕ 占用);② ⛔ **`JITTER_SWITCH_MS` 未新造** —— 复用序⑥ 已有键 `JITTER_LIMIT_MS`(同一事实不两处写);③ ⚠️ **`dshs` 侧 `server.js` 曾比 `dsh-relay` 侧落后一个版本**(序㉔ 只铺了 relay 侧)⇒ 本棒两边同铺**已消除**(后续铺 relay 类产物**务必两边都铺**)。
> 🛑 **(已被取代 · 见本区顶部 🎯/➡️ 两行 —— 三问已全部答复,㉗ 与 ㉘ 均已登记)原「本线当前无自动接续(未登记下一棒)」**,触发条件 = 对下列任一项拍板:**① 序 ㉕ 的 E1 缺口**(退出路径不杀实例:`LocalSpawner`+`RemoteSpawner`+`LeasedSpawner` 三处同改;候选 A/B/C,**倾向 B**)|**② 序 ㉖ 的 E3 范围**(是否允许改 `src/worker/relay-tunnel.ts`/`src/web/server.ts` 以暴露"候选数 ≥ 2"的可断言面)|**③ E2E 加密**(真取舍:加密 ⇒ 每接收者密文不同 ⇒ **与按哈希共享块冲突**,已登记待评估)。(退出路径不杀实例:`LocalSpawner`+`RemoteSpawner`+`LeasedSpawner` 三处同改;候选 A/B/C,**倾向 B**)|**② 序 ㉖ 的 E3 范围**(是否允许改 `src/worker/relay-tunnel.ts`/`src/web/server.ts` 以暴露"候选数 ≥ 2"的可断言面)|**③ E2E 加密**(真取舍:加密 ⇒ 每接收者密文不同 ⇒ **与按哈希共享块冲突**,已登记待评估)。
>
> ✅ **上一轮已完成(2026-09-17 08:32,执行棒)**:**序 ③(一机一钥 + 信任根)已收官** —— 四层密钥模型(离线根 → 47 在线签名者 → 每机节点密钥 → 会话)落地;relay `keys` 表改**逻辑名 `<net>/<hostId>`** 索引 + **成员资格校验**;新增密钥仪式 CLI `scripts/overlay-keyring.cjs` 与 `test/overlay-identity.test.mjs`(25 例);**吊销演练 + 节点密钥轮换 + 根密钥恢复演练(判据①②③全绿,794 ms)全部通过**;**relay 已开强制身份**(`identityRequired=true` / `identityOk=3`);`npm test` 130/129/0;对账 148/148 + 26/26 全同。**全部证据 = `交接单/交接单_一机一钥与信任根_20260917.md` §8**(回填后指纹 `md5 204c0f69630e5117c227828f5fc01f2d`,427 行)。⚠️ 一条**与序 ③ 无关**的未过项:guest(w-106) 实例页 **502**(真因 = 平台 `landModels → writeHomeFile` 用**本地路径**写远端实例 home;另发现 `/opt/dshs/mksess*.cjs` 仍写 SQLite 旧库、**已失效**)⇒ 两条并入序 ④ 的相邻缺陷清单。⛔ 不要重做序 ③。
>
> ✅ **上一轮已完成(2026-09-17 08:4x,规划棒)**:**序 ④ 的 443/TCP 兜底交接单已出** —— `交接单/交接单_443兜底_20260917.md`(工作区根,225 行,**md5 `b9aa6bbc0a458481627f7aeb1f17ab54`**)。要点:端口仍 443(零新增公网口)+ 47 上**独立 server 块 / 独立 server_name**(去 CF、去门户 conf 两个失败域)+ 入口列表走 **`DSHS_OVERLAY_BOOTSTRAP_SEEDS`**(⛔ 不用会**压制引导链**的 `DSHS_RELAY_URL`)+ 地址覆盖走**独立配置项**(⛔ 不塞 URL / 不塞签名目录)+ 签名目录 `relays[]`/`bootstrap[]` 自动广播(改一次 seeds 全网刷新)+ 降级必须可 grep。**L3(跨机真容灾)已明确后置**(命中 R5,属序 ⑤ 权限评估)。⛔ 不要重做规划。
>
> ✅ **上一轮已完成(2026-09-17 09:1x,执行棒)**:**序 ④(443/TCP 兜底)已收官** —— 47 上新增**独立 443 server 块** `relay-direct.conf`(`server_name relay-direct.alotbuy.com`,**只**放行 `/dshs-relay` 与 `/dshs-overlay/bootstrap`、其余一律 404)+ **seeds 广播**(`relays[]`/`bootstrap[]` 均含兜底项、**主入口首位**)+ 客户端**地址覆盖**(定向 DNS 改写 ⇒ 直连指定 IP、**SNI 仍为域名**、证书照验)+ **「同源优先」**(补掉"兜底项在取址路径上**永远选不中**"这个真缺陷 —— 它使 §1 目标与 D6 同时落空)。**D1–D8 逐条验收**(D2 **字面**判据因 `*.alotbuy.com` 是 **CF 泛解析**而不可满足 ⇒ 按**实质**判据「不经 CF」的两条独立证据判绿;**§4.3 的 A/B 两个候选都不需要 ⇒ 本单零依赖关闭**)。**全部证据 = `交接单/交接单_443兜底_20260917.md` §8**(该单 **§8.9** 有可复现指纹口径)。
> ⚠️ **序 ④ 带回的四条遗留**(下一位读者必须看):① D2 解析层 —— 运行期"去 CF"由 `DSHS_OVERLAY_ADDR_OVERRIDES` 保证,"解析层也不经 CF"需灰云记录(未做);② 🔴 **106 的 agent 面不吃引导链** —— `DSHS_RENDEZVOUS_URL` 被 `worker/agent.ts` **直接当 relay URL 用**,⚠️ **S2-附 的字面执行会造成生产回归(`tunnel===undefined`)⇒ 已判定不执行**;③ 引导链缓存两支没有"答出者"信息 ⇒ CF 打挂后切换有 **≤300 s 收敛期**;④ **45% 容量口径未填数值**(留给序 ⑤ 参数表)。
> ✅ **上一轮已完成(2026-09-17 09:1x,规划棒)**:**序 ⑤ 的交接单已出** —— `交接单/交接单_参数表与观测_20260917.md`(工作区根,**250 行**,md5 `40f08167990eac54ec8a026b9c57f807`)。要点:**三件一体**(参数表 / 观测最小集 / 权限评估,= 清单 §五 第 5 项原文);**唯一代码改动 = `src/net/relay/server.ts` 补 `dial/dialDenied/dialFailed` 判别器计数**(今天 `DIAL` **只有日志行**、脚本无法断言 —— 判别器教训的固化);45% 口径**按"单台中继 `--max-hosts`"填值**(⛔ 不填"全网 45%",实例参数填全网数字不可执行),设值走 47 **新建 drop-in** `capacity.conf` + 硬约束 **`max > used×4`**(防自锁,不满足就不设值);观测落成**一条命令出 PASS/FAIL** 的 `scripts/overlay-probe.cjs`(阈值⛔不许是脚本魔数);**L3 跨机真容灾只评估、不实施,归序 ⑥**(序⑥本就要起 3–5 台 ⇒ 合批明显更省,现在做要多花一台机器/一个公网 IP);**§4.3 待拍板 = 空**。⛔ 不要重做规划。
>
> ⛔ 不要重做序 ② / ③ / ④。
>
> ✅ **上一轮已完成(2026-09-17 09:5x,规划棒)**:**序 ⑥ 的交接单已出** —— `交接单/交接单_最小形态真机批次_20260917.md`(工作区根,**321 行**;核对口径 `sed '/^## §10 指纹/,$d' 交接单/交接单_最小形态真机批次_20260917.md | md5sum` = `8bea0ac79697b80790a273b54f1db37c`)。要点:**S0–S9 + E1–E12 + 回滚 + §8 回报格式**;五项待测/待校准(打洞率 / 每玩家带宽 / 跨云稳态吞吐 / 中继 jitter / `MEM_PER_HOST_MB`)**逐项写了"怎么测 / 样本多大 / 判据 / 写回参数表哪一行"**;**合批落地 L3 第二中继机(106 升格)**;**回头条件写死**(§5 S7 七件必做)。🔴 **本单新增一条关键事实**:`src/` 全仓**零 UDP / NAT 穿透代码**(`grep -iE "dgram|createSocket|stun|punch|udp" src/` 命中**全是 `signature`/`native` 假阳性**)⇒ ⇒ **打洞项的口径定为"测该网络能不能打洞",⛔ 本单不做打洞实现**(`§4.1-1`);另一条:`RELAY_RTT_W106 = 336 ms` 是**心跳往返**、**不一定是网络 RTT** ⇒ 本单要求做 **ICMP / TCP / relay 三方对比**(`S3(b)`;若它其实是口径问题,所有"跨云不可玩"的结论都要重判)。**§4.3 唯一待你拍板项 = 第 4/5 台真机的来源**(A 先用现有 3 台 / B 你自备设备跑一次性探测 / C 新开云主机;**倾向 A+B,⛔ 执行棒不必等**)。⛔ 不要重做规划。
>
> ✅ **上一轮已完成(2026-09-17 11:0x,执行棒)**:**序 ⑥(3–5 台最小形态)执行部分已收官** —— 五项待测/待校准**全部换成实测**(`HOLE_PUNCH_RATE_LOCAL` 分层实测 2/2 可打洞、`PER_PLAYER_BW_LOCAL` 9.8/3.9 KB/s、`JITTER_LINK_MEASURED` `p95(|ΔRTT|)`=**3 ms 达标**、`WAN_STEADY_THROUGHPUT` 352/12213 KB/s、`MEM_PER_HOST_MB` **2 → 0.06**,R²=0.9424)+ **参数表 §7 待测 4 → 0**;🔴 **S7 回头条件已触发并执行**:`RELAY_MAX_HOSTS` **225 → 7515** 并**重下发** 47/106 两台的 `capacity.conf`(drop-in 重写 ExecStart,绕开"CLI 优先于 env"静默忽略坑);**S8 L3 第二中继机已落地**(106 `dshs-relay` 只绑 `127.0.0.1:20080`,复用既有 443 ⇒ **零新增公网口**,WS 握手 **101**,seeds 末位广播);**收口 12/12 PASS**、监听口 **79 = 基线**、`npm test` 137 pass。**全部证据 = `交接单/交接单_最小形态真机批次_20260917.md` §8**(1–8.9 全节;§8.9 可复现指纹:参数表 `db1317c2f7aaef7b47785c1f4fc9de03`、本单前缀 `1edde731eba5034c5f6f3a43864e5a8e`)。⚠️ **唯一未过项 = E9 后半「无失败切流」**(客户端把 relay url 首次解析后**钉死**;worker 不吃引导链;Manager 只在"目录地址变了"时换址)⇒ **见 §8.8-1,已判为"新功能",本轮只报告不动手**。
>
> ✅ **上一轮已完成(2026-09-17 11:1x,规划棒)**:**序 ⑦ 的交接单已出** —— `交接单/交接单_中继失败切流_20260917.md`(工作区根,**280 行**;**§8 前缀指纹 `419abf308c00b7668e8898aaa91ba9e8`**,口径 = `sed '/^## §8 回报格式/,$d' … | md5sum`)。要点:**一份切换实现(新增 `src/net/relay/switcher.ts`)+ 三个装配点复用**(C1 Manager 拨号通道 `web/server.ts#refreshOverlay` / C2 worker 实例面 / C3 `relay --client`);🔴 **规划棒新查出的证据级细化**:根因不止"换址条件是目录地址变了",而是 `directory.ts:348 pickFromDoc` **取到第一个候选就 return** ⇒ **候选集退化成单点**(重解析恒返回同一台;S1 就改这里);**阈值已定** = `attempts ≥ 3` **∨** `backoff ≥ 15 s`(D3)+ **排除 + 冷却 300 s**(D5)+ **无候选时不切、绝不静默回退默认机**(D6);**S7 三幕真机演练**(杀 106 / 杀 47 / 两台全杀 —— 幕 3 就是 **R11** 的现场判据);**§4.5 已出 R5 评估:未命中,暴露面零变化(新增监听口 0 / 凭据 0 / 入站 0)**;**§4.3 待拍板 = 空**(第 4/5 台真机来源属序⑥ 遗留同题,⛔ 执行棒不必等)。⛔ 不要重做规划。
>
> ✅ **拍板已闭环(2026-09-17 11:00,用户原话)**:「**1 本机内存大 可以模拟多台**」⇒ **第 4/5 台 = 本机多实例**(本机 47.6 GB / 空闲 27.4 GB / 32 核;relay 单实例 ≈ 48 MB),**放弃**"用户自备设备"与"新开云主机"。⚠️ 局限:多实例共用同一出口 IP ⇒ 对**切流逻辑**够用、对**家宽 / 运营商 NAT 差异**无增量。**已落三处**:`docs/覆盖网络/参数表_覆盖网络_20260917.md` §11 / `交接单/交接单_最小形态真机批次_20260917.md` §11 / 本单 `交接单/交接单_中继失败切流_20260917.md` §11(三处补记**均在各自指纹口径之外** ⇒ 三个指纹均不变)。⛔ **后续任何一棒都不许再上抛这道题**。
>
> ✅ **上一轮已完成(2026-09-17 11:2x–12:2x,执行棒)**:**序 ⑦(中继失败切流)已收官** —— S1–S5 全落(`directory.ts` 拆出 `listCandidatesFromDoc`;**新增 `src/net/relay/switcher.ts` = 唯一实现**,三装配点 C1 `web/server.ts` / C2 `worker/relay-tunnel.ts`+`worker/agent.ts` / C3 `net/relay/main.ts` 复用;`test/relay-failover.test.mjs` F1–F11;`scripts/overlay-failover-drill.cjs` 三幕真机演练);参数表新增 `RELAY_FAILOVER_*` 6 键 + 7 个演练坐标,**§9 第 5 行已改「已闭环」**(指纹 → `24cf2efdbcdcbe61267126ed65dba006`)。**全部证据 = `交接单/交接单_中继失败切流_20260917.md` §8**(§8 前缀指纹 `419abf308c00b7668e8898aaa91ba9e8`,收口后**未变**)。真机:`--scene all` = **8 PASS / 0 SKIP / 0 FAIL**;杀 47 ⇒ 切到 106,**三个时延样本 30563 / 27878 / 29176 ms(全部贴 30 s deadline)**;两台全挂 ⇒ **0 行切换 + D6 原生判别器**;`npm test` **149/148/0/1**(+F1–F11)。⚠️ 遗留四条见该单 **§8.8**(**§8.8-4 = 下一棒主题**)。⛔ 不要重做序 ⑦。
>
> ✅ **上一轮已完成(2026-09-17 12:3x,规划棒)**:**序 ⑧ 的交接单已出** —— `交接单/交接单_切流冷却语义_20260917.md`(工作区根,**345 行**;**§8 前缀指纹 `aa3a6ec0d66dd81f465cea2a3a08ad27`**,口径 = `sed '/^## §8 回报格式/,$d' … | md5sum`)。**三问已给判定**:① **应当拆开,但拆的是「准入方向」而不是「冷却时长」** —— health 路径允许**一跳豁免**、directory 路径 **⛔ 完全不豁免**(依据 = 11:43:26 真机实测:directory 靠"地址变了"把刚冷却的 47 换回来 ⇒ 给它豁免权 = 复活抖动风暴)② **键仍按 `url`**,新增 `kind ∈ {switched-away, open-failed}` **只决定豁免优先级**(把键换成"原因"会让同一 url 存在多条冷却 ⇒ 抖动抑制失效 = **净退化 R11**;且 `reason` 是自由文本 ⇒ 字符串耦合)③ 🔴 **E5 改判为「幕 4」** —— 本单**已证明**(命题 P-③)在 D5 生产值下"杀 106 时 47 未被冷却"这个窗口**不会被自然产生**(当前在 106 ⟹ 47 必曾进冷却 ⟹ 若未满 300 s 则仍在冷却)⇒ 上单 §8.8-3 的回头条件**指向一条走不通的路**;正解 = `停 47 → 切 106 → 恢复 47 → 停 106(预期 D6,记 SKIP)→ 等冷却过期 → 断言 ≤ deadline 切回 47`(副产品 = §8.8-4 的正面复现)。**另加一条判据级事实**:**构 C(`--url` / `DSHS_RELAY_URL` 钉 106)已判不可用** —— `directory.ts:642-651` 明证 env 显式会让**候选链退化成单点**,杀 106 后仍无候选。**S0–S9 + E1–E13 + 回滚 + §8 回报格式均已就位**;**§4.3 待拍板 = 空**;**§4.5 R5 评估 = 未命中,暴露面零变化**。⛔ 不要重做规划。
>
> ✅ **上一轮已完成(2026-09-17 12:40–13:2x,执行棒)**:**序 ⑧(切流冷却语义)已收官** —— S1–S5 全落:`src/net/relay/switcher.ts` 冷却表结构化(键仍按 `url` + 新增 `kind ∈ {switched-away, open-failed}`)+ `replace(targetUrl, reason, origin)` 闸门**只对 directory 收口**(health 可**一跳豁免**)+ `tick()` 的 **D6 现场**加豁免(新增单点判据 `pickExemptTarget`)+ 豁免有界(每 url 每冷却周期一次,`exemptedAtMs`;豁免也失败 ⇒ 重置冷却 + 本周期不再豁免);`src/web/server.ts` **仅一处**(传 `'directory'`);`scripts/overlay-failover-drill.cjs` 新增 `--scene 4|4b|4c|ctrl`;`test/relay-failover.test.mjs` +**F12–F17**。**全部证据 = `交接单/交接单_切流冷却语义_20260917.md` §8**(1–8.9 全节;**§8 前缀指纹 `aa3a6ec0d66dd81f465cea2a3a08ad27`,回填后未变**)。**真机核心成果**:**幕 4(构 A)= 4 PASS / 0 FAIL** —— 豁免在 **19218 ms** 内切回(原文 `|豁免 kind=switched-away 剩 269991ms` = "47 当时确在冷却"的**直接证据**,原因 = 当前通道不健康/health 路径)⇒ **对序⑦ §8.8-4 缺陷正面闭环**(序⑦ 下同场景最长 ~300 s 不切流);**幕 4b = 4 PASS** —— D6 判别器原文(`候选 3 条,排除 3 条`)+ 冷却未过期 **0 行**切换 + 冷却过期后**自然**切回(25125 ms,**无豁免标记**)⇒ 归因收敛到冷却语义;幕 1/2/3 未退化(幕1-A 29586 ms PASS);`npm test` **155/154/0/1**(+F12–F17);部署 47/106 四处 lib,`grep -c RELAY_FAILOVER_EXEMPT <lib>/net/relay/switcher.js` = **2** 自证。⚠️ **遗留六条见该单 §8.8**(🔴 **§8.8-2 = 下一棒主题**:S0 基线样本 **32550 ms > deadline 30000**,回头条件已命中)。⛔ 不要重做序 ⑧。
>
> 🔴 **本单一条判据级新发现(§8.8-4,留档)**:**`RELAY_FAILOVER_COOLDOWN_MS=0` 是"看起来合法、实际会自锁"的配置** —— `num()` 的 `/^\d+$/` 放行 `'0'`,但归零会让**序⑦ F10 的"失败候选必须被排除"**一起失效 ⇒ 候选链卡在第一个失败候选上(实测 **121–123 s 无切换**)。构 B(原定归因构造)因此判**不可用**,已由 **幕 4b** 替代并拿到更强证据。⛔ **任何一棒都不许把 `COOLDOWN_MS=0` 写进回滚路径**。
>
> ✅ **上一轮已完成(2026-09-17 13:40–13:5x,执行棒)**:**序 ⑨(检测时延与 deadline)已收官** —— **P10 分解逐项复现成功**(两样本结构完全一致:检测 **15.085 / 15.119 s** + 首试 0.258 / 1.416 s + 白等 **12.033 / 12.029 s** + 建连 2.821 / 2.724 s)⇒ D1 解锁;**S2 修前 N=5 = 5/5 全超 deadline**(33914 / 31646 / 34078 / 35321 / 41252 ms,中位 34078);**S4 落点 = 抽公共 `waitUpOnStatus`(`src/net/relay/client.ts`)+ 三处装配点全部委托**(C1 `web/server.ts` / C2 `worker/relay-tunnel.ts` / C3 `net/relay/main.ts`,D7 收口),落点自证 47/106 四处 `lib` 各 3 命中;**S5 先红后绿**(改完先对旧 lib 跑 ⇒ `SyntaxError: … does not provide an export named 'openedChannelFailedTerminally'`;build 后 22/22 全绿);**S7 修后 N=5 = 5/5 进 deadline 内侧**(25465 / 25342 / 21985 / 27389 / 23318 ms,中位 25342);**白等 12.03 s → 0.09 s**、总 19.81–23.93 s,早退日志原文 `[relay-failover] ⛔ 新通道终态失败(state=backoff attempts=1 burst=false lastError="transport error")⇒ 提前放弃,不等满 12000ms`;**S8 不退化**:`npm test` **160/159/0/1**(基线 155 +新增 F18–F22)、`--scene all` 11 PASS / 1 FAIL(幕 2-B 已归因)、幕 4-A/B/C 全绿、`overlay-probe` 10/12 与 S0 逐项一致、`ss -lntp|wc -l` = 77、`nft` = 72、门户 200、演练 env 残留 0;**收口归零**(`restart dshs` 把 Manager 归位回 47,probe 回到 10/12)。**全部证据 = `交接单/交接单_检测时延与deadline_20260917.md` §8**(1–8.9 全节;**§8 前缀指纹 `d903b4eeabf25ef381379cdbaac77e8a`,回填后未变**;全文件 md5 `ccc28dafd10004d11740834004b02154`,529 行)。参数表指纹 `e6b669c257d8e8964273b3b400238351` → **`99e9e17b0c1ce0550e4bc7626a5a0494`**(新增 `DRILL_SAMPLE_N`=5 / `RELAY_GRACEFUL_BURST_MS`=15000,`DRILL_POLL_MS` 2000→500,§9 新增第 9 行「换址墙钟的四段分解」)。⚠️ **遗留三条见该单 §8.8**(= 下一棒主题)。⛔ 不要重做序 ⑨。
>
> ✅ **序 ⑩ 已收官(2026-09-17 14:23–14:5x)** |🆕 **下一棒已登记自动接续** = automation `3d4dffc0-356e-4bc6-9628-b7d664da7db9`「覆盖网络线-序11规划棒(观测口径重构+在册小缺陷清算)」(**一次性** · `scheduledAt` = **2026-09-17 14:50** = 收口 +5 min · `nextRunAt` = 1789627800000)⇒ 三件技术债全清 —— 幕 2 状态依赖**已修**(幕 2 起手现场重读权威通道归属后**两台都停** ⇒ 与上一幕解耦;`--scene all` **12 PASS / 0 FAIL**)|`COOLDOWN_MS=0` **0 命中**(`4c`/`ctrl` 整体移除并**显式拒绝**,⛔ 不静默空跑)|OBS-11 差额**有名字 = `20000`**(47 实例档、无活跃实例)。证据 = `交接单/交接单_检测时延与deadline_20260917.md` **§8.8-4**。
>
> ✅ **序 ⑪ 已收官(2026-09-17 15:0x,规划棒)** —— 出单 = `交接单/交接单_观测口径与在册缺陷_20260917.md`(**§8 前缀指纹 `3ece0f870cba67d0113a4c5f9de9d812`**)⇒ **OBS-11 判据 计数 → 白名单集合**(三集包含式 + `nft` 入站 accept 集合)+ 6 条在册小缺陷排序(§5.9);只改观测面,⛔ `src/**` 零改动。⛔ 不要重做规划。
>
> ⏹️ **(存档)序 ⑭ 本轮动作口径(已收官 · 结果见 `交接单/交接单_观测口径与在册缺陷_20260917.md` **§10**)**:**序 ⑭ · 执行棒 —— 修掉「relay 流上的 HTTP keep-alive 复用」这条数据面缺陷**(口径 = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§9.3**:现象 + **1 条命令的最小复现** + 完整取证链 + 回头条件;⚠️ 不必再出规划单)。**背景(上一棒结论)**:Q1 ✅(`mksess` 改 PG)、Q3 ✅(探针 **12/12**)、**Q2 🔴 未达成** —— 单内记的 `landModels → writeHomeFile` 本地路径问题**不是** `enter` 500 的真因;真因是**同一条连接上的第 2 条 agent 请求必回 `400`(Fastify `clientError`)**,抓包实证 = **worker 侧把 agent 上一份响应回灌给了 agent**。**开工顺序**:① 先按 §9.3 复现;② **补帧级取证**(relay `workerStream`/`dialStream` 路由表、`net/relay/server.ts` 的 stream 表、`dialer.ts` 的 `tcp.pipe(duplex).pipe(tcp)` 收尾、`client.ts#onOpenRequest/onRemoteData`)**定位到代码行再改**;③ 先红后绿;④ 端到端:guest `enter` **200**、同连接连发两次都 **200**、`npm test` 不退化(160/159/0/1)、`--scene all` 不退化、探针保持 **12/12**。**三条硬门**:**D1**(复现类前提未复现前 ⛔ 不许改任何生产值;⛔ 不动 `RELAY_FAILOVER_*`/`HB_SEC`/burst)|**R7**(Q4 `src/net/relay/**` untracked 缺口卡在**提交授权** ⇒ ⛔ 只报告、⛔ 不 commit/push;Q5 `.bak-seq7-*` 残留未动)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ **若改动必须超出 `src/net/relay/**` + 其测试 ⇒ 停下报告、别扩大**。⛔ 不 commit / 不 push。**收口必须**:释放锁 + 陈述句告知 + 登记下一棒 + 推进本入口 + 写工作区日志。
>
> ✅ **序 ⑮ 已收官(2026-09-17 16:14–16:3x,执行棒)**:**缺陷 B(拨号池未分配槽位自毁)已修并端到端验收** —— 判据 a/b/c 全绿;**先故意对未分配池口 25000 发一条连接**,随后 guest `enter` 仍 **200/200**、该口同连接连发 3 次 **200/200/200**、打后池口仍 **64**;`npm test` **162/161/0/1**、`--scene all` **12 PASS / 0 SKIP / 0 FAIL**、`overlay-probe` **12/12**。改法 = `onConn` ⛔ 不再 `close()` 服务器(只丢连接 + `stray` 计数 + 点名日志)+ `localPortFor`/`lruIdle` 只认 `server.listening` + `status().pool` 改报"实际在听"并新增 `stray`;⛔ 不取"把槽位从 `slots` 摘掉"那条(= 让任意本地连接**永久**蚕食池容量,R11)。**全部证据 = `交接单/交接单_观测口径与在册缺陷_20260917.md` §11**(含 47 上 16:00:31/35/40 三条 500 的时间线归因)。⚠️ 顺带确认一条**环境口径**:对 47/106 的 ssh **必须显式 `-p 22`**(别名 `bt-server` 里的 `32022` 是失效残留口,见该单 §11.10)。
>
> ⏹️ **(存档)序 ⑰ 本轮动作口径(已收官 · 结果见 `交接单/交接单_在册收尾_20260917.md` §9)**:**序 ⑰ · 执行棒 —— 在册收尾(S1 → S2 → S3 → S4)**(⚠️ **执行棒:按单开工,无须再出规划单**)。**开工依据 = 工作区根 `交接单/交接单_在册收尾_20260917.md`**(**§8 前缀指纹 `bab83b7219b2669d5a6e9f1acf782e1f`**,全文 md5 `ca13b9ded3d71268f8b0e56755d7aea4`)⇒ 按该单 §5 顺序:**S1** mksess 文档口径校正(「DB 直插」→「PG 直插」;只改操作性载体 = `规范/02-运维手册.md` + `skills/**` + 本机技能,⛔ **不改 `调整方案/**` 档案正文**)|**S2** 技能 `dsh-auto-handoff-chain` **三处同步建立**(本机 ← 文档库新建副本 ← 47 镜像 `/opt/dsh/docs/skills/`;**与 S1 共用一次 scp** ⇒ 故 S1 必先)|**S3** 清理代码仓 `.bak-seq7-*`(🔴 **范围修正 = 5 个**,全 untracked、均为过期快照 ⇒ 非有效回滚点)|**S4** 幕 4-A 余量判据化(三档:`p95 ≤ 24 s` 健康 / `24–27 s` 临界记录不判 FAIL / `> 27 s` 停下报告)+ `--scene 4` × `DRILL_SAMPLE_N`=5 样本。**验收** = 单内 §6 的 E1–E9(其中 E6 三件套 = `npm test` 162/161/0/1、`--scene all` 12 PASS、探针 12/12)。**两条硬门**:**D1**(不改任何生产值)|**R7**(Q4 ⛔ 只报告、⛔ 不 commit/push)。🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ 不改 `调整方案/**` 档案正文、⛔ 不重做已收官序 ①–⑮、⛔ 不做 presence / 房间层 / 内容分发。**收口必须**:释放锁 + 陈述句告知 + 登记下一棒 + 推进本入口 + 写工作区日志 + 回填该单 §8。
>
> ⏹️ **(存档)序 ⑯ 本轮动作口径(已收官 · 结果见 `交接单/交接单_观测口径与在册缺陷_20260917.md` **§12**)**:**序 ⑯ · 规划棒 —— 复核「会合 / 中继从 Manager 拆分」是否仍需要 + 给剩余在册项定序、出执行单**(⚠️ **只出规划、⛔ 不改码、⛔ 不动服务器**)。依据 = 工作区根 `docs/覆盖网络/会合中继拆分_取证与改造方案_20260916.md`(S0–S4)+ 事实「**R5 已解掉『Manager 必须与 relay 同机』**(Manager 改为只拨出一条 wss、落点搬到本机回环池 `127.0.0.1:25000+`)」。**只读取证 ≤3 条命令**,结论落成二选一:① 已被 R5 覆盖 ⇒ 判「不做」+ 写清证据;② 仍有未覆盖部分 ⇒ 写成含**逐步验收 / 回滚**的 S 步骤。**同一张单**里给剩余在册项定序:`Q5`(`src/net/relay/*.bak-*` 3 个残留)|`seq13 文档口径`(文档库 / 技能对 `mksess.cjs` 的「DB 直插」描述已过期)|`长期在册`(技能 `dsh-auto-handoff-chain` 在文档库无副本 ⇒ 三处同步从未建立)|`§8.8-2`(幕 4-A 19.5–20.8 s 的临界项)。⛔ **Q4(`src/net/relay/**` untracked 的提交 / 推送授权)不写进执行范围**(待你拍板,只登记一行);⛔ 不得自行为 presence / 房间层 / 内容分发定序(需拍板)。**收口必须**:释锁 + 陈述句告知 + 登记下一棒 + 推进入口 + 写工作区日志 + 追加回报。
>
> ⏹️ **(存档)序 ⑮ 本轮动作口径(已收官 · 结果见 `交接单/交接单_观测口径与在册缺陷_20260917.md` §11)**:**序 ⑮ · 执行棒 —— 修掉「拨号池未分配槽位被任意一条连接永久杀死」(缺陷 B)**(口径 = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§10.8**:现象 + 出处代码行 `src/net/relay/dialer.ts#onConn` + 三个候选修法 + 判据;⚠️ 不必再出规划单)。**背景(上一棒结论)**:序 ⑭ 已修好 relay keep-alive 复用缺陷(guest `enter` 200、探针 12/12),但**从旁路发现了缺陷 B** —— `onConn` 撞到 `key === undefined`(未分配槽位)时只 `slot.server.close()` + `tcp.destroy()`,**不把槽位从 `slots` 里摘掉** ⇒ 该槽位永久死亡,而 `localPortFor()` 的 `slots.find(s => s.key === undefined)` **下次还会选中它** ⇒ `ECONNREFUSED`(实测:池报"64 个口"而 `ss` 只见 63,缺口正是死掉的 `25000`)。**开工顺序**:① 先**不改代码**复现 + 帧级取证(谁/何时连了未分配槽位;`status().pool` 与实际在听口号数何时起不相等);② **定位到代码行**再改;③ 先红后绿(往 `test/relay.test.mjs` 追加用例,⛔ 不许改 `package.json`);④ 端到端:guest `enter` **200**、同连接连发两次 **200**、`npm test` 不退化(现基线 **160/0/1 skip**)、`--scene all` 不退化(现 **12 PASS**)、`overlay-probe` **12/12**(须带 `--table`)。🔴 **本棒专属陷阱**:⛔ **绝不要对「未分配」的池口发连接**(那正是缺陷 B 的触发器)—— 要打池口,**先用一次真实 `enter` 把落点分配出来**,再从日志 `[relay-dialer] 落点 127.0.0.1:<口> -> <逻辑名>:<端口>` 取**已分配**的那个口号。**三条硬门**:**D1**|**R7**(Q4 untracked 缺口卡在**提交授权** ⇒ ⛔ 只报告、⛔ 不 commit/push)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ **若改动必须超出 `src/net/relay/**` + 其测试 ⇒ 停下报告、别扩大**。⛔ 不 commit / 不 push。**收口必须**:释放锁 + 陈述句告知 + 登记下一棒 + 推进本入口 + 写工作区日志 + 追加本单 §11。
> ✅ **序 ⑮ 已完成**(automation `1933b18a-0c2a-46a2-829c-440a900fed08` 已执行完毕、入口 §0/§2 已推进)。
> 🏁 **序 ⑰ 已收官(2026-09-17 16:44–17:3x,执行棒)—— 本线「在册收尾四条」全部清干**:**S1 ✅** mksess 文档口径校正(「DB 直插」→「PG 直插」,5 处操作性载体;E1 = 0 行)|**S2 ✅** 技能 `dsh-auto-handoff-chain` **三处同步首次建立**(本机 ↔ 文档库 ↔ 47 镜像,`diff -r` = 0 行、md5 三处同值;S1 的两个技能文件同批上镜像)|**S3 ✅** 代码仓 `.bak-seq7-*` 清理(**5 个 → 0**;untracked、非有效回滚点;`npm run build` RC=0 + lib 产物 md5 零差异)|**S4 ⚠️ 临界档**(`--scene 4` × 5 样本 18772/20121/20246/21223/**24477** ms;p95 保守口径 = **24477 ms** ⇒ 记录入册、⛔ 不判 FAIL、⛔ 未调任何生产值;⛔ 回头条件未触发)。**零回归三件套全绿**:`npm test` **162/161/0/1**、`--scene all` **12 PASS / 0 SKIP / 0 FAIL**、`overlay-probe` **12/12**;收口归零 = 三服务 active + 池口 **64**。**全部证据 = `交接单/交接单_在册收尾_20260917.md` §9**(§8 前缀指纹 `bab83b72…` 回填后**未变**;参数表 `8f08e74b…` **未变** ⇒ D1 自证)。
> 🗃 **Q4 已解除**(用户本轮明确授权「执行完毕后 同步到仓库」)⇒ 两个 commit 已推送:**`146c3d2`**(代码/测试面 53 文件)+ **`bc0dd2c`**(文档库面 10 文件);远端 `master` = **`bc0dd2c`**,`git ls-files src/net/relay | wc -l` **0 → 15**(untracked 缺口闭合)。
> 🛑 **本线已无自动接续**:四条在册项全部清干后,**剩余项全部落在「需拍板」区**(presence / 房间层 / 内容分发**定序** = 业务优先级;骨干节点服务范围 = §4 的 A/B 既有待拍板项)⇒ 按登记门禁(`dsh-auto-handoff-chain §3.3`)**不登记下一棒**,等你拍板后再建。
> ⏹️ **(存档)序 ⑱ 本轮动作口径(已收官 · 产物 = 工作区根 `交接单/交接单_presence在线态_20260917.md`,§8 前缀指纹 `f612858344077420cff5f1f9ef1c942f`)**:**序 ⑱ · 规划棒 —— presence(在线状态)改造的方案规划**(⚠️ **只出规划**:⛔ 不改任何代码、⛔ 不动 47/106 配置、⛔ 不 commit / 不 push、⛔ 不改任何生产值)。**依据** = `docs/覆盖网络/覆盖网络_应用场景与待完善清单_20260916.md` **§五 第 7 步** + `docs/覆盖网络/覆盖网络_千台全场景推演_20260916.md` + `docs/覆盖网络/覆盖网络_瓶颈落地方案_20260916.md`。**用户拍板** = 「**a 要做**」(2026-09-17 17:1x)⇒ presence 先做。**产出** = 按项目 8 段模板的**执行交接单**。⚠️ **B(内容分发 / 块级内容寻址)仍待拍板 ⇒ ⛔ 本棒不规划、只登记**。✅ **已收官(17:2x)** —— 落点判为**节点 / 端点在线态**(零应用层自证),S0–S7 + E1–E11 + §9 九条回头条件 + 三层回滚已就位;**§4.2 真取舍 = 空、§4.3 待拍板 = 空、§4.4 R5 = 未命中**。⛔ **不要重做规划**。
>
> 🎯 **本轮动作(2026-09-17 17:28 起,唯一一件)**:**序 ⑲ · 执行棒 —— presence(节点在线态)改造落地**(⚠️ **按单开工,⛔ 无须再出规划单**)。**开工依据 = 工作区根 `交接单/交接单_presence在线态_20260917.md`**(**§8 前缀指纹 `f612858344077420cff5f1f9ef1c942f`**)⇒ 按该单 §5 顺序:**S0** 只读前置 + 基线采样(§2 的 P1–P5,**零改动**)|**S1** relay 侧 presence 权威表(连接生命周期驱动 + **TTL 安全网** + 同 hostId 设备聚合;**判别器必须落计数**,⛔ 不许只写日志)|**S2+S3** 线协议帧(`SUB/UNSUB/PRESENCE/SNAP`,帧号**末尾追加**)+ **1 s 窗口批合并**|**S4** 消费侧接线(C1 `web/server.ts` / C2 worker,**`/status` 降级为兜底、⛔ 不删**)|**S5** 观测(参数表 `PRESENCE_*` + `OBS-13/14/15` + 探针新项,⛔ 无 `待测` 残留)|**S6** 本机多实例真机验收(N ≥ 4,实测 **稳态 0 帧 / 一次变化 ≤1 帧 / 降幅 ≥ 10×**)|**S7** 收口(部署属 lane 内,**直接做**)。**验收** = 单内 **E1–E11**(零回归三件套 = `npm test` **162/161/0/1**、`--scene all` **12 PASS**、`overlay-probe` **12/12 + 新项**,均**必须带 `--table`**)。**三条硬门**:**D1**(⛔ 不改任何生产值 —— `RELAY_FAILOVER_*` / `HB_SEC` / burst)|**R5**(⛔ 不新增公网监听口 / 不改 nft·nginx;新增监听口·凭据·入站必须仍为 **0**)|**R7**(⛔ 不改 `调整方案/**` 档案正文、⛔ 不 commit / 不 push)。🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⚠️ **命中该单 §9 的任一条回头条件**(要动生产值 / 要扩大暴露面 / 要超出该单 §3.1 文件集 / 批合并失效 / 观测跑不出单值 / 出现静默放行 / 要求"先有房间层" / 零回归退化)⇒ **立刻停下报告,别扩大**。⛔ 不做内容分发、⛔ 不做房间层、⛔ 不做打洞实现、⛔ 不重做已收官序 ①–⑰。**收口必须**:释放锁 + 陈述句告知 + 登记下一棒 + 推进本入口 + 写工作区日志 + 回填该单 §8。
>
> 📌 **自动接续登记(2026-09-17 17:2x)**:**下一棒 = automation id `107b8e38-ccbd-4dcf-8b49-25dad7c89be9`**(名称「覆盖网络线-序19执行棒-presence节点在线态」,**一次性**,`scheduledAt` = **2026-09-17 17:28** = 收口 +4 min,`nextRunAt` = 1789637280000)⇒ **已登记自动接续,约 4 分钟后自动开新会话;接续点 = 本文件 §2「🎯 本轮动作」**。(已完成的一次性棒:序 ⑱ 规划棒 = `50882a38-07cd-494c-ae73-cbbf27f3604d`;序 ⑰ 执行棒 = `067b0892-964e-4deb-bf84-4f1c37bebea8`。)
>
> 📌 **(历史)自动接续登记(2026-09-17 16:4x)**:**下一棒 = automation id `067b0892-964e-4deb-bf84-4f1c37bebea8`**(名称「覆盖网络线-序17执行棒-在册收尾(mksess口径/技能三处同步/Q5清理/幕4A临界项)」,**一次性**,`scheduledAt` = **2026-09-17 16:44**,`nextRunAt` = 1789634640000)⇒ **已登记自动接续,约 5 分钟后自动开新会话;接续点 = 本文件 §2「🎯 本轮动作」**。(已完成的一次性棒:序 ⑯ 规划棒 = `91c53ef8-c3f0-4bb3-9f0a-943790178176`。)
>
> 📌 **(历史)自动接续登记(2026-09-17 16:3x)**:**下一棒 = automation id `91c53ef8-c3f0-4bb3-9f0a-943790178176`**(名称「覆盖网络线-序16规划棒-会合中继拆分复核与在册收尾定序」,**一次性**,`scheduledAt` = **2026-09-17 16:36**,`nextRunAt` = 1789634160000)⇒ **已登记,约 5 分钟后自动开新会话接续,接续点 = 本文件 §2「🎯 本轮动作」**。
>
> 📌 **(历史)自动接续登记(2026-09-17 16:1x)**:**下一棒 = automation id `1933b18a-0c2a-46a2-829c-440a900fed08`**(名称「覆盖网络线-序15执行棒-拨号池槽位自毁缺陷B修复」,**一次性**,`scheduledAt` = **2026-09-17 16:14** = 收口 +4 min,`nextRunAt` = 1789632840000)⇒ 已登记,会自动开新会话接续。(已完成的一次性棒:序 ⑭ 执行棒 = `3e0a7b01-9257-4b76-b82f-4998c9f7eab0`;序 ⑬ 执行棒 = `a513b25c-9399-4fd5-9a00-a19a04c36d74`。)
>
> ⏹️ **(存档)序 ⑬ 本轮动作口径(已收官 · 结果见 `交接单/交接单_观测口径与在册缺陷_20260917.md` §9)**:**序 ⑬ · 执行棒 —— 在册小缺陷清算 `Q1 → Q2 → Q3`**(口径 = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§5.9 表** + 本棒 §8.8 转办;**该单已给每条的最小验收与回滚 ⇒ 直接执行、无须再出规划单**)。按序三条:**Q1** `/opt/dshs/mksess*.cjs` 仍写 **SQLite 旧库** ⇒ **已失效**(判据 = 用它开一次临时 session ⇒ 实例面 `curl -w '%{http_code}'` 回 **200/401**,⛔ 非 `000`;用完即删。**它是 R4 规定的唯一实例面验收手段 ⇒ 不修则 Q2/Q3 连"做完了没有"都判不了**)|**Q2** guest(**w-106**) 实例页 **502**(真因 = 平台 `landModels → writeHomeFile` 用**本地路径**写**远端**实例 home;判据 = 同 Q1 的临时 session ⇒ w-106 实例页 **200**)|**Q3** `OBS-09` 实例面 `000`(**环境态非缺陷**:47 无活跃实例 ⇒ 起一个 ⇒ `OBS-09` 绿 **且** 新 `OBS-11` 在"有实例态"下仍绿 = `20000` 落在允许区间)。⚠️ **Q3 与 Q2 同批做最省**(同一临时 session 一次验两件)。**三条硬门**:**D1**(分解类前提未复现前 ⛔ 不许改任何生产值)|**R7**(范围外先报告、不动手 ⇒ **Q4 `src/net/relay/**` untracked 缺口卡在"用户授权"、⛔ 本棒只报告;Q5 `client.ts.bak-*` 残留 = 清理类,待 Q1–Q3 后办**)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**(该值看似合法、实际自锁)。⛔ **不 commit / 不 push**(Q4 要授权)。**收口必须**:释放锁 + 陈述句告知 + 登记下一棒 + 推进本入口 + 写工作区日志。
>
> 📌 **自动接续登记(2026-09-17 15:2x)**:**下一棒 = automation id `a513b25c-9399-4fd5-9a00-a19a04c36d74`**(名称「覆盖网络线-序13执行棒-在册小缺陷清算Q1-Q3」,**一次性**,`scheduledAt` = **2026-09-17 15:24** = 收口 +3 min,`nextRunAt` = 1789629840000)⇒ 已登记,会自动开新会话接续。(已完成的一次性棒:序 ⑫ 执行棒 = `52645861-6895-459c-a07e-a5d686787d9c`。)
>
> ~~(存档)序 ⑫ 执行棒口径:**序 ⑫ · 执行棒 —— 观测口径重构(`OBS-11` 计数 → 白名单集合)**。✅ **已收官(2026-09-17 15:3x)**:见上 §0 最新刷新行;产物 = 代码仓 `scripts/overlay-probe.cjs`(新增夹具模式)+ 参数表 §6 四键;`overlay-probe` **11/12**;参数表指纹 `8f08e74b026e6e5b5e1b3db813f031ae`。⛔ 不要重做。~~
>
> ~~(存档)序 ⑪ 规划棒口径:**序 ⑪ · 规划棒 —— 观测口径重构 + 在册小缺陷清算排序**。⚠️ **只出规划、不改码**(规划与执行分离):产出交接单(8 段模板)+ 为下一棒定序。范围**仅限边界内技术项**:① **OBS-11 判据从「计数相等」改为「白名单集合」**(现口径两处结构缺陷:对实例/端点在线态**敏感 ⇒ 假红**;对"一进一出"**替换式变化不敏感 ⇒ 假绿**),连带处理 `LISTEN_COUNT` 的"有/无实例态"两值与 `scripts/overlay-probe.cjs` 改造;② **在册小缺陷清算排序**(`OBS-09` 实例面 000|guest(w-106) 实例页 502|`mksess*.cjs` 失效|`src/net/relay/**` untracked 留档缺口|`client.ts.bak-seq7-*` 残留|参数表 `LISTEN_COUNT`=79 与现态差的 1 条无名口)。⛔ **不得自行为"大方向 / 业务优先级"定序**(presence / 房间层 / 内容分发 = **需用户拍板**,只列候选与优缺点、不决)。➕ **顺手办(同一棒内)**:`.workbuddy/memory/MEMORY.md` 的**真瘦身** —— 现 **8 121 字符 > 注入上限(实测 ≈7 78x)** ⇒ 每轮尾部被截断;把 §二 里"已有 PLAYBOOK 指针"的规则**下沉为一行指针**(体积只减不增)。**✅ 已办(15:0x)= `MEMORY.md` 8 121 → 7 712 字符**。⛔ 不 commit / 不 push。~~
>
> ~~**序 ⑩ · 执行棒(已收官 · 内容留档)**~~:**序 ⑩ · 执行棒 —— 覆盖网络线技术债清算(3 件)**。**直接出执行棒、无须规划棒**:三件均已定位、均属 §1 边界内技术项(实现路径 / 排查方法 / 脚本自洽),**无可上抛项**。三步:**① 演练脚本自洽 —— 幕 2 的状态依赖**(`scripts/overlay-failover-drill.cjs`:注释写"两台全杀"、实现只停 106,而幕 1 已把 Manager 通道切到 47 ⇒ 停的是当前**不用**的那台 ⇒ 120 s 窗口 0 行 `[relay-skip]`;修法 = 幕 2 先判定当前活跃通道再停它,并复验正确前置下 3 PASS);**② 清掉 `COOLDOWN_MS=0` 的 5 处命中**(全部序⑧ 遗留 ⇒ 该值已判「看似合法、实际自锁」⇒ 从演练 / 回滚路径彻底移除,改用合法构造);**③ OBS-11 的 `78 → 77` 那 1 口定位**(两次连采同值、差 1 < 2 未命中回头条件 ⇒ 需把 78 与 77 逐口对账,定位是哪一条消失)。**验收**:`--scene all` 一键全绿(含幕 2)+ `grep -c 'COOLDOWN_MS=0' scripts/` = **0** + OBS-11 差值**有名字**(否则写明"已排查 N 条、卡在哪、回头条件")。**三条硬门**:**D1**(分解类前提未复现前 ⛔ 不许改任何生产值)|**R7**(范围外缺陷先报告、不动手)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练路径**。⛔ 不 commit / 不 push;⛔ 不做 presence / 房间层 / 内容分发。**收口必须**:释放锁 + 登记下一棒 + 推进本入口 + 写工作区日志。
>
> 📌 **自动接续登记(2026-09-17 14:1x)**:**下一棒 = automation id `be7242dd-ac3e-43d0-b52c-a465683cf972`**(名称「覆盖网络线-序10执行棒-技术债清算」,一次性,`scheduledAt` = **2026-09-17 14:23**)⇒ 已登记,会自动开新会话接续。(已完成的一次性棒:序 ⑨ 执行棒 = `2ca4048b-ab74-4845-8964-47a88910c679`。)
>
> ~~(存档)序 ⑨ 规划棒口径:~~ **序 ⑨ · 执行棒 —— 按 `交接单/交接单_检测时延与deadline_20260917.md` 开工**(工作区根;8 段模板;**出单前缀指纹 = `d903b4eeabf25ef381379cdbaac77e8a`**)。**核心结论(规划棒已用现有日志分解完成,执行棒须先复现)**:30 s ≈ **检测 15.0–15.1 s**(= `gracefulBurstMs` 的 15 s 地板,⛔ **不是** 2.5×`HB_SEC`=37.5 s,上单 §8.8-2 的口径提示已在单内勘误)+ **白等 12.0 s**(`waitUpOn` 只轮询 `state==='up'`、**不对终态失败早退** ⇒ 对一个必然失败的同机候选吃满 `upTimeoutMs`)+ **建连 2.7–2.8 s**;两个逐行复核样本(`unhealthyForMs=30563` / `29376`)结构完全一致。**首选修法 = `waitUpOn` 死候选早退**(三处装配点 `server.ts` / `relay-tunnel.ts` / `relay/main.ts` 逐处验收),⛔ **不调 `RELAY_FAILOVER_DEADLINE_MS`、⛔ 不动 `HB_SEC`、⛔ 不动 burst 语义**。**开工第一件事 = 单内 §2-P10 分解复现**(复现不出,或 S2 采到任一 < 27 s 的样本 ⇒ 停下报告)。**OBS-11 已复取 = `77`**(47 无活跃实例档,口径 78;差 1 < 2 ⇒ 未命中 §8.8-3 回头条件;两次连采同值)。**三条硬门**:**D1**(⛔ 分解复现成功前不许改任何 `RELAY_FAILOVER_*` 生产值)|**R7**(范围外缺陷先报告、不动手)|**§8.8-4**(🔴 ⛔ 不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练路径)。⛔ 不 commit / 不 push;⛔ 不做 presence / 房间层 / 内容分发(清单第 7 步)。**收口必须**:释放锁 + 登记下一棒 + 推进本入口 + 写工作区日志。
>
> ~~(存档)序 ⑥ 规划棒口径:**序 ⑤ · 执行棒已收官** —— 证据 = `交接单/交接单_参数表与观测_20260917.md` **§8 执行回报**(可复现指纹见该单 **§8.9**;E1–E9 = **8 绿 + 1 部分绿**;唯一部分绿 = E5 的"在 47 上受控制造一次真实拨号",卡点 / 已做到哪一步 / 回头条件见该单 **8.7-①**)⇒ **下一棒 = 序 ⑥ · 3–5 台最小形态**:按 `docs/覆盖网络/覆盖网络_应用场景与待完善清单_20260916.md` **§五 第 6 行**开工 —— **先把 `docs/覆盖网络/参数表_覆盖网络_20260917.md` §7 的 4 个 `待测` 项 + 1 个待校准推导项换成实机实测**(打洞率 / 每玩家带宽 / 跨云稳态吞吐 / 中继 jitter / `MEM_PER_HOST_MB`),并**合批**落地 **L3 第二中继机**(参数表 §5.2 校验③ 已算出:千台 L3 需求 450 > 单台 `--max-hosts` 225 ⇒ **需 ≥2 台中继**)。⚠️ **回头条件已写死**:`MEM_PER_HOST_MB` 或 `WAN_STEADY_THROUGHPUT` 一换成实测 ⇒ **必须重算 `RELAY_MAX_HOSTS` 并重下发 47 的 `capacity.conf`**。⚠️ 两条待办随本轮带过来:① guest(w-106) 实例页 **502**(`landModels → writeHomeFile` 用**本地路径**写远端实例 home;且 `/opt/dshs/mksess*.cjs` 仍写 SQLite 旧库、**已失效**);② 🔴 **106 agent 面不吃引导链**(`worker/agent.ts` 把 `DSHS_RENDEZVOUS_URL` 直接当 relay URL 用;按字面撤掉 = `tunnel===undefined` 生产回归,**已判不执行**)。⛔ 不重做序 ②/③/④/⑤;⛔ 不做 presence(清单第 7 步);⛔ 不 commit / 不 push。
>
> ~~(存档)原规划棒口径:**序 ⑤ · 规划棒 —— 给「参数表 · 观测 · 权限评估」出一份可执行交接单**(落盘工作区根,命名 `交接单/交接单_参数表与观测_20260917.md`,按 8 段模板:目标 / 只读前置 / 范围 / 决策点 / 步骤 S0–Sn / 逐条验收判据 / 回滚 / §8 回报格式)。**必带输入** = `交接单/交接单_443兜底_20260917.md` **§8.7 的四条遗留** + 该单 **§8.8 的 45% 口径待填参数位**(relay `--max-hosts` / `/status` 的 `capacity{max,used}` / `retryAfterMs`)+ **L3 跨机真容灾**(命中 **R5**,须先出权限影响评估)。⛔ 本轮**只出单、不改服务器**(规划与执行分离);**不 commit / 不 push / 不做 presence**;收口必须释放锁 + **登记下一棒**。~~
>
> ~~(存档)原规划棒口径:**序 ④ · 规划棒 —— 给「443/TCP 兜底」出一份可执行交接单**(落盘到工作区根,命名 `交接单/交接单_443兜底_20260917.md`,按 8 段模板:目标 / 只读前置 / 范围 / 决策点 / 步骤 S0–Sn / 逐条验收判据 / 回滚 / §8 回报格式)。**背景**:现役只有 `wss://alotbuy.com/dshs-relay` 一条路且经 nginx + CF(单点);序 ④ 要补的是**CF / nginx 不可用时的 443/TCP 直连兜底**(异构设计纪律:relay 不按同构 15%,而是 **45% 设计、55% 留余量**)。**取证入口** = `覆盖网络_应用场景与待完善清单 §五`(主线第 ④ 项)+ `docs/覆盖网络/覆盖网络_补遗与参考方案_20260916.md` + `docs/覆盖网络/覆盖网络_全球架构复盘_20260916.md`。⛔ 本轮**只出单、不改服务器**(规划与执行分离);**不 commit / 不 push / 不做序 ⑤ / 不碰 presence**;收口必须释放锁 + **登记下一棒**。
> 🟢 **最新口径覆盖本节历史内容(23:0x)**:**R2 / R3 / R4 / R5 全部已完成并端到端验收**(→ 交接单 **§9 / §10.4 / §10.5 / §11**)⇒ **机制层 R0–R5 已齐**(**R5 已解掉"Manager 必须与 relay 同机"这条前提**)。
> 🔴 **下一动作已勘误**:⛔ **不是** "presence 改造"。按 `覆盖网络_应用场景与待完善清单 §五` 的主线,presence/房间层是**第 7 步**,前置为 **② 网抽象 + 地址规划 + 引导(P0-1/2/3) → ③ 一机一钥 + 信任根 → ④ 443/TCP 兜底 → ⑤ 参数表 → ⑥ 3–5 台最小形态**。(另:仓库里目前**没有任何应用层代码** —— 全仓唯一含 "presence" 字样的文件是 `src/net/relay/placement.ts` ⇒ "presence 改造"根本无从下手,这条旧指示是上一轮的笔误。)
> ✅ **2026-09-17 07:4x:序 ② 已收官(①②③ 全绿,其执行进度见 `交接单/交接单_网抽象与地址规划R6_20260916.md`)** ⇒ 🟢 **2026-09-17 07:5x 已定序:下一棒 = 序 ③(一机一钥 + 信任根)**,之后 ④ / ⑤(理由见 §0)。
> ⛔ **不要再做 R2 / R3 / R4 / R5、不要再开 `32023`、不要再做 SSH 版中继**(隧道凭据与 `32022` 都已收回,那条路已不可能重建)。
> (按顺序 · **2026-09-16 11:5x 刷新**)
1. **先抢锁**:`bash dsh-server-docs/scripts/handoff-guard.sh --claim-exec "<会话名>"` —— 锁已释放,抢到即可开工。
2. **【第一优先 · 真活】会合 / 中继从 Manager 拆分的落地**(方案:工作区根 `docs/覆盖网络/会合中继拆分_取证与改造方案_20260916.md`,S0–S4 分步 + 每步验收 / 回滚)
- ✅ **P1 / P2 / P3 已完成并验收(2026-09-16 15:5x–16:2x)** —— 全部实测证据在 **交接单 §8**(含命令原文级输出)。摘要:
· **P1** 47 对齐到 `640813e`(Manager 侧真补上 S0+S1)|多用户验收:`admin`(w-47) 与 `guest`(w-106) 实例页均 200、跨机文件面落盘已核实
· **P2** `dsh_hosts.via` 列(迁移 v8)|回填 `w-47=local` / `w-106=manager-ssh`|`hostsProvider` 走 `RendezvousRegistry`|`GET /api/admin/hosts` 已可见 `via`
· **P3** **实例端口区间隔离**(`w-47` 20000+ / `w-106` 21000+,避开 OS 临时段)⇒ 修掉「跨 worker 同号 ⇒ 47 的 `127.0.0.1` 撞号 ⇒ `tunnel.forward()` 返回值被忽略 ⇒ **静默拨到别人实例**」这条真 bug;两实例实测落 20000 / 21000 且互不重叠
- ✅ **P4(SSH 版中继 / 新开 32023)已判「不做」**(17:2x)—— SSH 反向隧道**不是"不安全"**(专用非特权账号 + `PermitOpen` + 限速是业界标准做法),但**不该长期做数据面**;它想要的两样(与宝塔 sshd 解耦、甩掉 root 凭据)在 relay 方案里**同样拿到** ⇒ 两步合一。⛔ **不要新开 32023、不要再做 SSH 版中继**。
- ✅ **R0/R1/R1.5/R2 已完成**(R0 判据表+链路画像、R1 relay 最小闭环、R1.5 韧性+准入选点、**R2 常驻+nginx 443 暴露**)⇒ 全部证据在方案 **§9–§14**。
- ✅ **R3 + R4 已完成并端到端验收(2026-09-16 21:37–22:2x)** —— R3=`RendezvousRegistry` 已接线 `RelayRendezvous`(含 relay 实时快照 + 15 s 陈旧回退)+ 106 常驻 + `w-106 via='relay'`;R4=实例面经 relay(`PORT_ADD/DEL/ACK` + `RelayTunnel` + 端点翻译)+ **sshd 反向隧道下线且不可能重建**(47 收回隧道公钥、`32022` 回收;106 摘 `DSHS_TUNNEL_*`、私钥移走)⇒ 47 公网暴露面**净减 1 口**。证据 = 交接单 **§10.5**(含一份"静默失效"缺陷的定位与修复 + 先红后绿回归测试)。
- ✅ **R5 = 会合可换机 已完成并端到端验收(2026-09-16 22:3x–23:0x)** —— Manager 改为 `dialer: true` **只拨出**一条 wss,落点在**自己本机**预绑池(`127.0.0.1:25000..26099`,64 口);新增 `DIAL(0x0e)/DIAL_ACK(0x0f)` 帧、`StreamPeer` 抽象(数据面同形)、relay 侧 `DSHS_RELAY_DIALERS=manager` 白名单 + 每机独立密钥(权限只收窄)。证据 = 交接单 **§11**:① 单测 **38/38**;② E2E `endpoints: [(19000, 41233, 0)]`(**relay 回环口 streams=0**)+ `DIAL manager -> w-106:21000 ok`(实例面)+ 门户 200/62451 B;③ 🔴 **换机等价实验**(清掉 `DSHS_RELAY_STATUS_URL` ⇒ Manager 对 relay 回环口一无所知)**仍全通**,两个回环端点 `streams` **全为 0**;④ 新增 64 口**全部仅回环**,公网零新增。
- ⏳ **下一步 = 主线第 ② 项「网抽象 + 地址规划 + 引导」**(`覆盖网络_应用场景与待完善清单 §五`)—— ⛔ **不是 presence**(那是第 7 步)。⛔ 不要再做 R0/R2/R3/R4/R5。
🟢 **阶段 ①(S0–S4 + R5)已完工;`清单 §11.6` 记下的两条缺陷(A1 假 404 / A2 锁信号)也已修完并端到端验收**(→ R2-R4 单子 **§12**)。
🟢 **2026-09-17 07:4x:② 的 Step 3(P0-3 名字解析与授权)也已完成并端到端验收 ⇒ ② 全单关闭(①②③ 全绿)**(证据 = ② 单的「执行进度」段)。⇒ **下一棒不再看 ② 的单子**,按 `清单 §五` 主线往下走(序 ③ 一机一钥 + 信任根 / 序 ④ 443/TCP 兜底 / 序 ⑤ 参数表·观测·权限评估 —— **开工顺序已于 07:5x 定为 ③ → ④ → ⑤**,理由见 §0)。⛔ 不要再重做 Step 1 / Step 2 / Step 3。
- ✅ **A1 已修并端到端验收(2026-09-16 23:2x–23:4x)** —— `RemoteUserFs.target()` 原在 `agentFor(hostId)` 查不到时**静默回退** `DSHS_CLUSTER_AGENT_URL`(= w-47 本地 agent)⇒ 每次 `restart dshs` 的窗口期内 w-106 用户回**假 `404 not_found`**(与“文件夹不存在”同形,误导排查)。**真因** = 文件面 `server.ts:262` 的 `hostDirectory` 是惰性 Map、此前**只被 spawner** 刷新 ⇒ 启动时表里只有本机。**修法** = `ensureHost` **按需补齐**(治本)+新增码 `host_unresolved` → **503 且零请求发默认机**(治安全)。**证据** = R2-R4 单子 **§12**(先红后绿 + 冷启动 `launch 200` + relay 有 `DIAL` + `not_found=0`)。判别器仍是:**relay 有没有 `DIAL`**。
- ~~原 R0 描述~~(已过期,仅存档):只看 `交接单/接续包_覆盖网络线_20260916.md`(它 17:29 已同步):**R0-a** 把六条判据(认证模型 / 默认姿态 / 零入站 / 爆炸半径 / 可观测 / 生态)补成**可打分表**;**R0-b** 测链路画像(本机↔47↔106 的 RTT / jitter / 带宽)。**R1 起才选 relay 实现**(候选 OpenZiti / Nebula 身份型优先 > rathole > frp)。⛔ **本轮不引入任何第三方 relay**。
- 🔴 **本 §2 的口径截至 2026-09-16 17:29**(17:2x 起 P4 改判、17:3x 撤销"首选 frp")。⚠️ **接续包每次更新后,必须回来同步本入口** —— 16:43–17:29 期间本入口曾滞后 41 分钟,导致 17:04 那位自动接续会话按旧口径得出「P4 **并入自研 relay**」的结论,与最新定案(**实现未定、先做 R0**)**表述不一致**(方向一致、粒度不同)。⛔ 别再让"下一棒的第一信息源"比接续包旧。
- ⏳ **未做**:git commit(未授权)、档案占号建档(建议与 P4 合并做,届时才有 commit hash 可写)。
3. **平台那批待办** ✅ **已清**:`BRIEF.md` 刷新至 09-16|T08 单子已归档 `交接单/archive/交接单-已完成/`|`.doing-T08` 已随 T08 归档(内容保留为 `T08-执行标记-已释放.md`)|`调整方案/.lock-*` 16 个空占号残留已清|未提交改动已按 5 个定向 commit 提交(HEAD `59f1a89`,**已 push**,远端 `master` 一致)。
⏳ **仍未动**:`INDEX.md §二` 的既有失真(`04-90~04-102` 共 13 行物理落在表格外 ⇒ `docs-index-stats.py` 统计不到)—— 搬别人的行有风险,留待专项。
4. **10 份文档转正式档案** ✅ **已完成**(档案 103–112,`4e3a1a4`;正文行覆盖率 98.5–99.0%)。
5. **`MEMORY.md` 精简** ✅ **已完成**(工作区 -26%;**真被截断的是用户级那份**,已按「分层重排、零删除」修好)。
6. **技术侧开工**:按 `docs/覆盖网络/覆盖网络_瓶颈落地方案_20260916.md` 的「只做三件事」(presence 改造 + 游戏服放 L1 + 块级内容寻址)开工;**前置仍是第 2 条**。
7. **代码分层 / 依赖方向**(与覆盖网络并行的一条线)—— ✅ **P0 已完成**(2026-09-16 13:2x,本机):新增 `docs/architecture.md`(四层 `①入口 → ②领域 → ③能力 → ④基础` + **R1–R4 判据** + 三条工程纪律)+ `README.md` 文档表登记。
- 📄 评估文档 = 工作区根 `docs/集群与实例/项目代码_分层范式与迭代风险评估_20260916.md`(**§8 已勘误**)。
- 🔴 **勘误(勿再复用旧结论)**:所谓「**3 处基础层反向依赖**」**不成立** —— 那几处是**入口层 `cli.ts`** 的合法依赖(`①→③`);实测 `src/*.ts` 里从子目录 import 的**只有 `cli.ts`**,基础层四文件**零 import** ⇒ **真实违规 0 处**。
- ✅ **可执行判据已补(同日)**:`scripts/check-layering.mjs`(`npm run check:layering`,已挂进 `npm run verify`)—— 静态扫描四层 + **ratchet 基线**(`scripts/layering-baseline.json`,新增违规 ⇒ 退出码 1;只许减)。**首跑实测 60 个 .ts**:`①24 / ②0 / ③32 / ④4`,**现存违规 5 条**(全是 `③能力→①入口`:`supervisor/proxy.ts`→`web/auth.ts`+`web/middleware/authn.ts`;`fs/{local,remote}-user-fs.ts`+`fs/workspace.ts`→`web/middleware/fs-guard.ts`)。
- ⏳ **剩三件(均命中 R7,动工前先出受影响清单)**:① **整改上面那 5 条**(修法已写在 `docs/architecture.md §5.1`)② 补 `src/domain/*`(把 `web/routes` 的业务规则抽出来 —— **行为敏感重构**,非纯类型)③ 给模块入口补「职责 / 依赖谁 / 被谁依赖」。
- **顺序建议**:**P0 ✅ → 覆盖网络 S1–S4 → P1**(P1 不阻塞覆盖网络)。
8. ✅ **两条「已定位未修」缺陷 —— 均已于 2026-09-16 23:4x 修完并端到端验收**(证据 = R2-R4 单子 **§12**):
- **① `state.py` 锁误报(安全信号)**:`state.py:39` 原把 `交接单/.exec-lock` 当**文件**读,而 `--claim-exec` 建的是**目录**(内含 `OWNER`)⇒ 永远报「[锁] 空闲 ✅ 可以动手」⇒ **每个新会话读到的第一个信号是错的**。**已修**:是目录就读 `LOCK/OWNER`(兼容遗留的普通文件形态);复验 = 持锁时正确报「🔴 被占用」。
- **② 假 404 / 静默回退到错 agent**:见上方第 2 条末段(`src/fs/remote-user-fs.ts` 的 `target()`) —— **已修**。
> ✅ **上一轮已完成(2026-09-17 17:28–18:16,执行棒)**:**序 ⑲(presence 节点在线态)已收官并上线** —— 详见 §0 最新那条刷新的全部数据;**产物 = `交接单/交接单_presence在线态_20260917.md` §8★ 回报(8.0–8.9 已回填)**。一句话:**在线态从"每 5 s 拉 `/status`"改为"连接生命周期 + 订阅推送 + 1 s 批合并 + TTL 安全网"**,真机 `counters={subs 1, pushed 3, snaps 2}`、单测 **169/0/1**、`--scene all` **12 PASS / 0 FAIL**、S6 本机多实例 **8/8**。⛔ 不要重做序 ⑲。
>
> 🎯 **序 ⑳ 的动作已定(本棒登记)**:① **修 `OBS-09` 口径** —— 「实例不在册 ⇒ **SKIP**(⛔ 不是 PASS、也不是假红);在册 ⇒ 必须可达 `PROBE_CODE_SET`」+ 两侧夹具实证;② **量化 presence 真机收益**(`counters.statusHits` 增速 ⇒ `/status` 轮询降幅,给算式与实测);③ presence 线**收口复验**(`npm test` / `--scene all --table` / `overlay-probe --table`);④ 处置 `web/server.ts` `translateEndpoint` 的**键口径既存缺陷**(`hostVia` 表键 = 逻辑名、传入裸 `hostId` ⇒ 恒 `undefined`)。
> ➡️ **下一棒 = 序 ⑳(执行棒)**,automation **`51cfd12f-918d-4069-81d8-c148fc174282`**(一次性 · **2026-09-17 18:20** = 收口 +4 min)。⛔ 未登记更后一棒:**`OBS-09` 的判据口径修正属技术实现 ⇒ 本棒自决**,但「**平台是否要在 Manager 重启后自动拉起既有实例**」是**业务取向**(可用性 vs 资源/复杂度)⇒ **待拍板,⛔ 不作为任何一棒的前置**(详见本棒回报的最后一节)。
> ✅ **上一轮已完成(2026-09-17 18:26–18:5x,执行棒)**:**序 ⑳(OBS-09 口径 + presence 收益量化 + 收口复验 + `translateEndpoint` 处置)已收官** —— 详见 §0 最新那条。一句话:**OBS-09 改为「在册 ⇒ 必须可达、不在册 ⇒ SKIP」**(真机转 SKIP、rc=0;两侧夹具四段实证 A/B/C/D)|🔴 **presence 真机收益实测仅 1.10×**(`/status` 轮询几乎照旧;根因 = 订阅新鲜度 TTL 与稳态零帧打架)⇒ **P-1**|三件套零回归(**170/169/0/1** · **14P/0F/1S** · **12P/0S/0F**)|`translateEndpoint` 键口径 = **另立单 P-2**(无活跃实例 ⇒ 本棒无 E2E 条件)。⛔ 不要重做序 ⑳。
>
> ✅ **上一轮已完成(2026-09-17 18:54–19:2x,执行棒)**:**序 ㉑(P-1 + P-2)已收官** —— **P-1 判据改为「订阅已建立 ∧ 链路活着」**(选 A;B 撞 R11、C 不治本),真机门窗口内 Manager 侧 `ΔstatusHits` **13 → 0**、门开关 **0 次翻转**;**P-2** 抽纯函数 + 键口径修正(单测面;E2E 无活跃实例 ⇒ 判据已写入回报);零回归 **174/173/0/1** · **12P/0S/0F** · **15P/0F/1S**;新登记 **P-2b**。⛔ 不要重做序 ㉑。
>
> ⏪ **(存档)原本轮动作口径**:**序 ㉑ · 执行棒 —— 修 P-1(presence 新鲜度判据)+ P-2(`translateEndpoint` 键口径)**(⚠️ **按单开工,⛔ 无须再出规划单**)。**开工依据** = `交接单/交接单_观测口径与在册缺陷_20260917.md` **§13**(两条缺陷的证据 / 候选修法 / 判据全在那里)+ `交接单/交接单_presence在线态_20260917.md` **§8.10**(序⑳ 全部取证与原文输出)。**P-1(主)**:病根 = `src/net/relay/client.ts#presenceFresh()` 取 `now − max(lastSnapAt, lastPushAt) ≤ PRESENCE_TTL_MS(45 s)`,稳态 `Δpushed = 0` ⇒ 必然过期 ⇒ 轮询恢复(实测 10.9 次/分钟 vs 基准 12)⇒ 候选 **A(任何入站帧含心跳即算新鲜)/ B(relay 定期重推 `SNAP`)/ C(拉长 TTL)** 属**技术项,自己拍**;**验收** = 单测先红后绿 + 夹具能判 PASS 也能判 FAIL + 真机门开关**不再翻转**且 Manager 侧 `ΔstatusHits − 探针自身读数 → 0`(给算式与实测)+ 零回归三件套。**P-2(次)**:`hostVia` 键 = 逻辑名 vs 传入裸 `hostId` ⇒ 闭包死分支;⚠️ **必须先抽出纯函数才谈得上先红后绿**;E2E 需起 `w-106` 实例(当前无 reconciler)⇒ **起不起来就只做到单测并把 E2E 判据写进报告**,⛔ 不许为凑 E2E 去改平台重拉逻辑。**零回归基线**:`npm test` **170 tests/169 pass/0 fail/1 skip**、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **14 PASS/0 FAIL/1 SKIP**(三者都必须带 `--table`)。**硬门**:**D1**(⛔ 不改生产值)|**R5**(⛔ 不扩大暴露面;106 ssh 限流只报告)|**R7**(⛔ 不 commit/push;范围外先报告)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ **不删 `/status` 兜底路径**、⛔ 不改 `switcher.ts` 冷却语义、⛔ 不做内容分发 / 房间层 / 打洞、⛔ 不重做已收官序 ①–⑳。**收口必须**:释锁 + 陈述句告知 + 登记下一棒(id 取自工具返回值)+ 推进入口 §0/§2 + 写工作区日志 + 回填对应交接单 §8。
> ⏹️ **(已收官 · 结果见 `交接单/交接单_presence在线态_20260917.md` **§8.13** + `交接单/交接单_观测口径与在册缺陷_20260917.md` **§16**)序 ㉓ 本轮动作口径(存档)**:**序 ㉓ · 执行棒 —— P-2/P-2b 的 E2E 验收(主)+ presence 线收口复核(次)**(⚠️ **按单开工,⛔ 无须再出规划单**)。**开工依据** = `交接单/交接单_presence在线态_20260917.md` **§8.11-⑤ / §8.12**(E2E 判据全在那里)+ `交接单/交接单_观测口径与在册缺陷_20260917.md` **§14 / §15**(在册缺陷表)。**主:E2E(序㉑/序㉒ 都只做到单测)** —— 用 `mksess-guest.cjs` 开**临时 session**(**R4**:用完即删,⛔ 不用真实账号)⇒ `POST /api/dsh/enter` ⇒ 四条判据:ⓐ `enter` **200**;ⓑ 47(Manager)上 `ss -lntp | grep -c ':21000'` = **0**(翻译生效 ⇒ 拨的是 relay 回环落点,⛔ 不是 Worker 侧口号);ⓒ `journalctl -u dshs | grep -c overlay-endpoint` = **0**(失败关闭未被触发);ⓓ 判别器证据:relay `/status` 的 `counters.dial` **有增量**(请求确实出去了,⛔ 不是"没出去"被当成功)。⚠️ 若实例**起不来**(平台按需拉起失败 / 无 reconciler)⇒ **只报告、⛔ 不许为凑 E2E 去改平台重拉逻辑**。**次:presence 线收口复核** —— 核对在册缺陷表(P-1 / P-2 / P-2b 是否**全部关闭**)+ 确认剩余项是否**全部落在「需拍板」区**;若是 ⇒ 明确写出「**线内可停**」。⛔ **不自行给 `B`(内容分发)/「Manager 重启后自动拉起实例」定序或开工**(两者均待拍板)。**零回归基线**:`npm test` **176 tests/175 pass/0 fail/1 skip**、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **15 PASS/0 FAIL/1 SKIP**(三者都必须带 `--table "docs/覆盖网络/参数表_覆盖网络_20260917.md"`)。**硬门**:**D1**(⛔ 不改生产值)|**R5**(⛔ 不扩大暴露面)|**R7**(⛔ 不 commit/push;范围外先报告)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ **不删 `/status` 兜底路径**、⛔ 不改 `switcher.ts` 冷却语义、⛔ 不做内容分发 / 房间层 / 打洞、⛔ 不重做已收官序 ①–㉒。🔴 **ssh 勘误(序㉒ 实测)**:对 **106 必须用别名 `test106`**(专用密钥)—— 裸 `ssh [email protected]` ⇒ `Permission denied (publickey)`,⛔ 别再误判成 MaxStartups 限流;47 一律显式 `-p 22`。⚠️ **两项仍待拍板** —— `B`(内容分发 / 块级内容寻址)与「**Manager 重启后是否自动拉起既有实例**」⇒ ⛔ **不作为任何一棒的前置**。
> ✅ **(已执行收官 · 序 ㉓)** 原登记:**下一棒 = 序 ㉓(执行棒)**,automation **`238e99eb-f173-4fe1-8c4a-0b07a6bba2fe`**(一次性 · **2026-09-17 20:08** = 收口 +5 min)。⛔ 未登记更后一棒。
> 🛑 **序 ㉓ 收口后:本线未登记更后一棒**(**线内可停** —— 在册缺陷表已清空、E2E 已补齐;剩余项**全部为待拍板**)⇒ 按用户 2026-09-17 明令「待拍板未定 ⇒ 不登记下一棒」,拍板任一即建。
> ✅ **拍板已到(2026-09-17 20:2x)** ⇒ 见下方 🎯 本轮动作(三项已全部落成可执行交接单)。
> ⏹️ **(存档)序 ㉔ 本轮动作口径(已收官 · 结果见 §0 最新刷新行 + `交接单/交接单_内容分发块级寻址_20260917.md` §8.1)**:**序 ㉔ · 执行棒 —— 首屏包冷启动的「块级内容寻址 + 同网段 peer 优先」改造**(⚠️ **按单开工,⛔ 无须再出规划单**)。**开工依据** = 工作区根 **`交接单/交接单_内容分发块级寻址_20260917.md`**(§7 前缀 `49d0f405e08c909e18ba6825d1442b9d`,全文 `3198288c8b0b102d43c87ca9a3a31cd2`,166 行)⇒ 按该单 **§4 顺序 S0 → S7** 开工。**用户拍板** = 「**B 内容分发(块级内容寻址)是否立项:做**」(2026-09-17 20:2x)。**落地做法** = 照抄上游 `docs/覆盖网络/覆盖网络_瓶颈落地方案_20260916.md` **§3**(内容源优先级 **本地 → 同局域网 peer → 同区域边缘缓存 → 区域分发点 → 公网源**;**块级 + 内容寻址**;客户端**校验哈希**;按用户/团队/局域网**分组**;同网段**广播发现**;已加载走 **304**)。**主判据** = **`E1`:版本发布时回源字节数 ≈ 1 份 × 组数**(局域网内多台设备**只回源一次**,而不是 1000 份);其余 `E2`(只拿到一部分也能共享)/ `E3`(只传变化块)/ `E4`(篡改块被丢弃)/ `E5`(跨组不穿透)/ `E6`(来源档位点名)/ `E7`(零回归)。🔴 **必须"块级 + 内容寻址",⛔ 绝不做"包级"** —— 包级必须完整下完才能当 peer 源、**版本一变全部 peer 源同时失效** ⇒ 客户端集体回源 = **本线已实证过的"版本一发就全量重拉"风暴成因**(命中该单 §9-1 回头条件 ⇒ 立刻停下报告)。**零回归基线**:`npm test` **176 tests/175 pass/0 fail/1 skip**(Node 22)、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **16 PASS/0 FAIL/0 SKIP**(三者都必须带 `--table "docs/覆盖网络/参数表_覆盖网络_20260917.md"`)。⚠️ 本棒**会新增单测** ⇒ 报「实测值 vs 基线值 + 新增用例数」,⛔ 不许拿放宽判据凑绿。**硬门**:**D1**(⛔ 不改生产值 —— `RELAY_FAILOVER_*` / `HB_SEC` / burst / `PRESENCE_*`)|**R5**(⛔ 不新增公网监听口 / 不改 nft·nginx)|**R7**(⛔ 不 commit / 不 push;**超出该单 §3.1 在册文件集 ⇒ 停下报告,别扩大**)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ 不做房间层 / 打洞实现 / 端到端加密、⛔ 不重做已收官序 ①–㉓。⚠️ **命中该单 §9 任一条回头条件 ⇒ 立刻停下报告,别扩大**。**收口必须**:释锁 + 陈述句告知 + 登记下一棒(**序 ㉕ · 实例逐步拉起**,依据 `交接单/交接单_实例逐步拉起_20260917.md`;id 取自工具返回值)+ 推进入口 §0/§2 + 写工作区日志 + 回填该单 §8。
>
> 📌 **本线三单执行顺序(已定,⛔ 勿再上抛)**:**㉔ 内容分发 → ㉕ 实例逐步拉起 → ㉖ 骨干稳定选路**。理由:㉔ 是用户明确"做"的最大瓶颈项且自成闭环;㉕ 依赖"真实多实例"条件、**与 ㉔ 的 S6 真机验收共用同一批本机多实例**(省一次搭环境);㉖ 收口时要**复用 ㉕ 的接管语义**验"骨干不受重启影响"。
> 📌 **自动接续登记(2026-09-17 20:3x)**:**下一棒 = automation id `91251b14-9ee8-42a9-9d89-8559b7af75ed`**(名称「覆盖网络线-序24执行棒-内容分发块级寻址」,**一次性**,`scheduledAt` = **2026-09-17 20:42** = 收口 +3 min,`nextRunAt` = 1789648920000)⇒ **已登记自动接续,约 3 分钟后自动开新会话;接续点 = 本文件 §2「🎯 本轮动作」**。(已完成的一次性棒:序 ㉓ 执行棒 = `238e99eb-f173-4fe1-8c4a-0b07a6bba2fe`。)
> ✅ **上一轮已完成(2026-09-17 20:42–21:5x,执行棒)**:**序 ㉔(首屏包「块级内容寻址 + 同网段 peer 优先」)已收官并落地生产** —— 详见 §0 最新那条 + `交接单/交接单_内容分发块级寻址_20260917.md` **§8.1**。一句话:**五个模块**(`chunker` / `store` / `source` / `peer` / `runtime`)+ **27 条新单测**全绿;**主判据 `E1` 放大比 = 1.0000×(对照组 Before = 4.00×)**,`E2`–`E6` 全绿;**先红后绿 4 例全部命中预期**;零回归 `npm test` **176/175/0/1** / `--scene all` **12P/0S/0F** / `overlay-probe` **17P/0F/0S**(= 基线 16 + 本棒新增 `OBS-17`);已部署 4 处并重启 `dshs-relay`/`dshs`。⛔ 不要重做序 ㉔。
> ⏹️ **(存档)序 ㉕ 本轮动作口径(已收官 · ⚠️ 半程 · 结果见 §0 最新刷新行 + `交接单/交接单_实例逐步拉起_20260917.md` §11)**:**序 ㉕ · 执行棒 —— 「Manager 重启后逐步拉起既有实例」**(⚠️ **按单开工,⛔ 无须再出规划单**)。**开工依据** = 工作区根 **`交接单/交接单_实例逐步拉起_20260917.md`**(§7 前缀 `d9d48121e68faa00e1da17ad8fea36ad`,全文 `2c53a018c2d9bfc2c422d0758413a485`,161 行)⇒ 按该单 §4 顺序开工。**用户拍板** = 「**Manager 重启后是否自动拉起既有实例:逐步拉起**」(2026-09-17 20:2x)。🔑 **本单最关键的一条反直觉事实(规划棒读源码得出,执行棒必须先复现)**:**现在不是"缺 reconciler",而是"启动时主动清空"** —— `src/supervisor/orchestrator.ts:208` 构造函数里 `cleanAllStaleScopes()` 让 **portal 启动即清掉全部实例 scope**(档案 30 的"防孤儿"修法)⇒ 重启后 **N=0、没有任何可接管的实例**。故 **"逐步拉起" = 把"清空"换成"接管"**(扫描 OS 层既有 scope ⇒ 回填 map ⇒ 按节流 probe)。⚠️ **三条硬约束**:⛔ 不许删 `cleanStaleScopes(uid)`(spawn 前清同 uid,是**档案 30 本体**)/⛔ 不许把启动流程改成"什么都不做"(孤儿会失控)/⛔ 不许"重启后重新 spawn 一遍"(换端口换名字 + 瞬间齐起 = **启动风暴**)。**验收** = 该单 §6 的 E 系列判据(⚠️ 含 **逐步**语义 = 有节流、⛔ 不是一次性齐起)+ **零回归三件套**:`npm test` **176 tests/175 pass/0 fail/1 skip**(Node 22)、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **17 PASS/0 FAIL/0 SKIP**(三者都必须带 `--table "docs/覆盖网络/参数表_覆盖网络_20260917.md"`;⚠️ `overlay-probe` 基线**已随序 ㉔ 由 16 升到 17**)。**硬门**:**D1**(⛔ 不改生产值 —— `RELAY_FAILOVER_*` / `HB_SEC` / burst / `PRESENCE_*`)|**R5**(⛔ 不新增公网监听口 / 不改 nft·nginx)|**R7**(⛔ 不 commit / 不 push;**超出该单在册文件集 ⇒ 停下报告,别扩大**)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ 不做房间层 / 打洞实现 / 端到端加密、⛔ 不重做已收官序 ①–㉔。⚠️ **命中该单回头条件 ⇒ 立刻停下报告,别扩大**。**收口必须**:释锁 + 陈述句告知 + 登记下一棒(**序 ㉖ · 骨干稳定选路与加密**,依据 `交接单/交接单_骨干稳定选路与加密_20260917.md`;id 取自工具返回值)+ 推进入口 §0/§2 + 写工作区日志 + 回填该单 §8。
> ✅ **(已执行收官 · 序 ㉕ · 半程)** 原登记:**下一棒 = automation id `16f0a3e7-4ef8-497b-aaa8-ce4d15d9353a`**(名称「覆盖网络线-序25执行棒-实例逐步拉起」,**一次性**,`scheduledAt` = **2026-09-17 21:52** = 收口 +4 min)⇒ **已于 21:5x–22:3x 跑完**;结果见 §0 最新刷新行。(已完成的一次性棒:序 ㉔ 执行棒 = `91251b14-9ee8-42a9-9d89-8559b7af75ed`。)
>
> 🎯 **本轮动作(2026-09-17 22:34 起,唯一一件)**:**序 ㉖ · 执行棒 —— 骨干稳定选路与加密**(⚠️ **按单开工,⛔ 无须再出规划单**)。**开工依据 = 工作区根 `交接单/交接单_骨干稳定选路与加密_20260917.md`**(**§8 前前缀指纹 `dbcbe633aa1aef92f4c35c77fad3ec11`**,全文 `f85b86234c2ecfaef5b2e43aa40d86a3`,176 行)⇒ 按该单 **§4 顺序 S0 → S6** 开工。**用户拍板** = 「入口 §4 骨干节点的服务范围:**按照连接稳定高效的方式 数据安全可加密传输**」(2026-09-17 20:2x)。**我的解读(已定项,可推翻)**:**按"A 起步、口径按 B 的质量标准建设"落地** —— 可见范围取 **A**(元数据暴露面最小 ⇒ 直接满足"数据安全")、质量与冗余按 **B** 标准(**jitter 选路** + 30%+ 余量 ⇒ 直接满足"稳定高效")。🔑 **主判据 = 两候选路径中 jitter 更低者被选中、即使其 RTT 更高**(⛔ 现行为是按**健康度 / 冷却**排序、**不是 jitter** ⇒ **这是主要缺口**)。🔑 **"可加密" = 能力就位**(TLS + 验签 + 内容哈希)+ **元数据最小化**,⛔ **不是**现在就上端到端加密 —— ⚠️ **E2E 属真取舍**(加密 ⇒ 每个接收者密文不同 ⇒ **与按哈希共享块直接冲突**),**已登记待评估、⛔ 本单不做**。**验收** = 该单 §5 的 **E1–E7** + **零回归三件套**:`npm test` **176 tests/175 pass/0 fail/1 skip**(Node 22)、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **17 PASS/0 FAIL/1 SKIP**(三者都必须带 `--table "docs/覆盖网络/参数表_覆盖网络_20260917.md"`;`OBS-09` 在 47 无活跃实例时为 SKIP = 正常态)。⚠️ 本棒**大概率新增单测** ⇒ 报「实测值 vs 基线值 + 新增用例数」,⛔ 不许拿放宽判据凑绿。**三条硬门**:**D1**(⛔ 不改生产值 —— `RELAY_FAILOVER_*` / `HB_SEC` / burst / `PRESENCE_*` / `DSHS_REHYDRATE_*`)|**R5**(⛔ 不新增公网监听口 / 不改 nft·nginx)|**R7**(⛔ 不 commit / 不 push;**超出该单 §3.1 在册文件集 ⇒ 停下报告、别扩大**)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ 不做房间层 / 打洞实现 / 端到端加密、⛔ 不重做已收官序 ①–㉕。⚠️ **上一棒(序 ㉕)只做到半程**(认领逻辑已落地并部署、夹具已实证;**真机 E1 被 `orchestrator.ts#teardown()` 挡住**,打通需改两个**超在册文件集**的文件 ⇒ 已按 R7 停下)⇒ **本序 ⛔ 不许替 ㉕ 打通该缺口、⛔ 不许改 `remote-spawner.ts` / `leased-spawner.ts`**;若 ㉖ 需要复用 ㉕ 的接管语义(验"骨干不受重启影响"),**只用已落地的认领路径**,并在回报里写明"㉕ 半程对本序判据的影响"。⚠️ **命中该单 §9 回头条件 ⇒ 立刻停下报告,别扩大**。**收口必须**:释锁 + 陈述句告知 + 登记下一棒(本线三单 **㉔→㉕→㉖ 已走完** ⇒ 若无可自决项就明确写出「**本线可停 + 剩余项全部落在待拍板区**」并**不登记**)+ 推进入口 §0/§2 + 写工作区日志 + 回填该单 §8。
>
> 📌 **自动接续登记(2026-09-17 22:3x)**:**下一棒 = automation id `77b4d0f1-8663-4d08-bb79-1784f67d6999`**(名称「覆盖网络线-序26执行棒-骨干稳定选路与加密」,**一次性**,`scheduledAt` = **2026-09-17 22:34** = 收口 +4 min,`nextRunAt` = 1789655640000)⇒ **已登记自动接续,约 4 分钟后自动开新会话;接续点 = 本文件 §2「🎯 本轮动作」**。(已完成的一次性棒:序 ㉕ 执行棒 = `16f0a3e7-4ef8-497b-aaa8-ce4d15d9353a`。)
>
> 🔴 **待你拍板(序 ㉕ 半程遗留 · 逐条编号 · 候选竖排)** —— E1(**真机实例**重启后存活)要打通,必须先让**两处非 `LocalSpawner`** 的退出路径停止杀实例:
> **A** 只改 `LocalSpawner.teardown()`:**优点** = 文件集最小(仅本序在册文件,零授权成本);**缺点** = **Manager 跨机重启仍会收掉 Worker 实例** ⇒ **诉求不成立**。
> **B** 三处同改(`LocalSpawner` + `RemoteSpawner` + `LeasedSpawner`):**优点** = **唯一真正达成诉求**(跨机重启也不杀);**缺点** = **超出该单 §3.1 在册文件集、需你授权**,且实例**不再随进程退出回收**(孤儿治理改由认领路径承担)。
> **C** env 开关灰度:**优点** = 可灰度、可回退;**缺点** = **跨机那处照样要改**(默认开 = 等于 B;默认关 = 等于不生效)⇒ **无增量价值**。
> **我的倾向 = B**(A 不达成目标、C 无增量价值)。⛔ 拍板前不动 `LocalSpawner` / `remote-spawner.ts` / `leased-spawner.ts`,也⛔ 不让 ㉖ 顺手做掉。
> ✅ **上一轮已完成(2026-09-17 19:33–20:0x,执行棒)**:**序 ㉒(P-2b + P-1 长窗复测)已收官** —— 详见 §0 最新那条。一句话:**P-2b 修好**(候选链**两级 → 三级**,补 ②' 级订阅推送落点,与 `addressOf` 逐级对齐;先红后绿原文级;`T37/T38` 新增;⛔ 未越出 3 个在册文件)|✅ **P-1 长窗 706 s 复测通过**(Manager 侧 `ΔstatusHits = 0`、门 **0 次翻转**、raw 降幅 **141.2×**)|三件套零回归(**176/175/0/1** · **12P/0S/0F** · **15P/0F/1S**)|已部署 4 处 lib + 回滚点 `/opt/dsh/backups/seq22-20260917-195602/`。⚠️ **E2E 仍未做** ⇒ 交序 ㉓。
> ⏪ **(存档)原本轮动作口径**:**序 ㉒ · 执行棒 —— 修 P-2b(主)+ P-1 的长窗真机复测(次)**(⚠️ **按单开工,⛔ 无须再出规划单**)。**开工依据** = `交接单/交接单_观测口径与在册缺陷_20260917.md` 在册缺陷表的 **P-2b** 行 + `交接单/交接单_presence在线态_20260917.md` **§8.11**(序㉑ 全部取证)。**P-2b(主)**:`src/net/relay/endpoint-target.ts#relayEndpointTarget` 的候选链只有「① 拨号落点 → ② relay `/status` 快照」**两级**;序㉑ 修好 P-1 后 `/status` 快照路径**趋冷** ⇒ 若拨号池分不出槽位而**订阅推送里有落点**,仍会判"实例不可达(失败关闭)"⇒ 候选 = 把 `presenceLocalPort` 插成 **②' 级**(与 `addressOf` 三级链对齐)。**验收** = 单测先红后绿 + 三级优先顺序**逐支可断言** + 零回归三件套。⚠️ 属**行为面新增** ⇒ 若发现要超出 `endpoint-target.ts` / `web/server.ts` / 测试这三个在册文件集 ⇒ 停下报告(R7)。**P-1 长窗复测(次)**:序㉑ 只用 **67 s 短窗**验证过「门 0 次翻转」⇒ 本轮做 **≥ 10 min** 长窗,给出算式 `Manager 侧 = 窗口内 ΔstatusHits − 探针自身读数` 与相对基准 `60 000 / RELAY_STATUS_POLL_MS` 的**倍数**;⚠️ 长窗内门**仍翻转** ⇒ P-1 未真正解决 ⇒ **立刻停下报告**,⛔ 不许改生产值凑数。**零回归基线**:`npm test` **174 tests/173 pass/0 fail/1 skip**、`--scene all --table` **12 PASS/0 SKIP/0 FAIL**、`overlay-probe --table` **15 PASS/0 FAIL/1 SKIP**(三者都必须带 `--table "docs/覆盖网络/参数表_覆盖网络_20260917.md"`)。**硬门**:**D1**(⛔ 不改生产值)|**R5**(⛔ 不扩大暴露面;106 ssh 限流只报告)|**R7**(⛔ 不 commit/push;范围外先报告)|🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。⛔ **不删 `/status` 兜底路径**、⛔ 不改 `switcher.ts` 冷却语义、⛔ 不做内容分发 / 房间层 / 打洞、⛔ 不重做已收官序 ①–㉑。⚠️ **两项仍待拍板** —— `B`(内容分发 / 块级内容寻址)与「**Manager 重启后是否自动拉起既有实例**」⇒ ⛔ **不作为任何一棒的前置**。
---
## 3. 关键决定(**已定,勿再上抛**)
1. **方案只做技术实现;跨境数据合规由使用者自行考虑**(用户原话)⇒ 选型不为合规让路、跨境不设限、⛔ 不再把合规当前置条件。
2. **单机自用 ≠ 不需要互联**(用户原话:「单机用也要互联,这正是建立覆盖网络的目的」)⇒ **租户维度收窄 ≠ 网络维度收窄**。
3. **覆盖网络按异构设计**:中继按 **45% 设计 / 55% 留余量**(不是同构假设的 15%);**必须补 443/TCP 兜底**;有公网 IP 的节点升格为中继候选。
4. **权威状态单点**:归属/租约/骨干资格只能控制面写;会合/中继可多实例。
5. **形态已拍板**:单机自用为默认;"当服务器给他人用"的多人维度已放弃。
6. **游戏重点是 MMORPG(2D/2.5D)/ MUD / 传奇类** ⇒ 判定上修为"最匹配",非 3D 强实时竞技。
## 4. 待你处理(**在册挂起项见下首条**;历史待拍板项均已拍板 ⇒ 已清空)
> ⏸ **在册挂起项(唯一)= D8 云安全组乙-1** —— 2026-09-18 16:1x 用户明令:「**这个测试先记下来后续在处理**」。状态 = **已获批准(09-18 15:4x)· 待人工落地 · ⛔ 不进排棒队列**。
> - **要做的事(原文级)**:两朵云各加一条**入方向**规则 —— **阿里云**(47 · **美国硅谷 `us-west-1`** · 实例 `i-rj99af19cibck1ge93tq`):`UDP` 端口 `21100/21115` ← 源 **`106.54.21.172/32`**;**腾讯云**(106 · **上海 `ap-shanghai`** · 实例 `ins-3q6k1p8t`):`UDP` 端口 `21100-21115` ← 源 **`47.77.182.89/32`**。🔴 **⛔ 零个 `0.0.0.0/0`**(含任何拆分 / 等价写法);⛔ 不放 TCP 段;⛔ 不动 `nft` / `nginx`。**保存即生效,⛔ 无需重启实例。** 逐步操作 + 定位信息 ⇒ `交接单/交接单_覆盖网络直连与P2P_20260918.md` **§8.11-④-补**。
> - **为什么 🛑 不能代做 / 不能自动化**:本机 + 47 + 106 **均无云 API 凭据**(47 `aliyun` CLI 在但 `~/.aliyun/config.json` **不存在**、metadata `ram/security-credentials` = **404**;106 **无** `tccli`、metadata `cam/security-credentials` = **404**)+ 连接器市场内**无**相关 Connector ⇒ ⛔ 按本线纪律**不索取 AK/SK**。
> - **落地后第一动作(谁先恢复本线会话谁做)**:**双向实测复测**(当前基线 **47→106 发 21 收 0** / **106→47 发 28 收 0**)⇒ 探针 `OBS-27/28` 复跑 ⇒ 参数表 §11 补记(含 §10 指纹现算)。⚠️ **⛔ 不要为它登记接续棒**(阻塞项需人操作,无人值守重试无意义)。
> ✅ **三项均已拍板并各落成可执行交接单**(2026-09-17 20:2x 用户原话):
> ① **「B 内容分发(块级内容寻址)是否立项:做」** ⇒ `交接单/交接单_内容分发块级寻址_20260917.md`(序 ㉔)
> ② **「Manager 重启后是否自动拉起既有实例:逐步拉起」** ⇒ `交接单/交接单_实例逐步拉起_20260917.md`(序 ㉕)
> ③ **「入口 §4 骨干节点的服务范围:按照连接稳定高效的方式 数据安全可加密传输」** ⇒ `交接单/交接单_骨干稳定选路与加密_20260917.md`(序 ㉖)
>
> ⚠️ ③ 用户**未按 A/B 二元选**,而是给了**目标口径** ⇒ 我的解读(**已定项,可推翻**):**按"A 起步、口径按 B 的质量标准建设"** —— 可见范围取 **A**(元数据暴露面最小 ⇒ 满足"数据安全")、质量与冗余按 **B 标准**(jitter 选路 + 30%+ 余量 ⇒ 满足"稳定高效")。**⛔ 后续任何一棒不许再把这三项当"待拍板"上抛。**
>
> ✅ **2026-09-17 23:1x / 23:3x 又一轮三问 ⇒ 亦已全部答复**(**不在本区**,登记在 §2 顶部 🎯 行):**① 序㉕ E1 缺口 ⇒ 最终执行 `B`(三处 `teardown()` 同改)+ `C` 登记为架构目标**(⇒ 序 ㉘ 单 A;⚠️ 用户 23:2x 曾答「选 C」、23:3x 更正为「选 B」)|**② 序㉖ E3 范围 ⇒ 选 B**(允许改 `relay-tunnel.ts`/`web/server.ts` ⇒ 序 ㉗)|**③ E2E 加密档位 ⇒ 选 C 组密钥加密**(⇒ 序 ㉘ 单 B)。⇒ **本区(含本轮)没有任何未决项**。
> 🗃 **原登记(存档 · 已被上述拍板取代)**:**骨干节点的服务范围**:A 只服务自己名下设备(优点:无资源/计费纠纷、权限面不变;缺点:骨干少、冗余低)| B 服务全网(优点:骨干多、可用性高、中继容量易满足;缺点:他人流量跑在你的机器上、元数据暴露、被攻破影响面大)。
> **倾向 A→B 渐进**。详见 `docs/覆盖网络/覆盖网络_骨干层方案_20260916.md` §7。
---
## 5. 回滚点
- **R5(本轮)三层回滚,均秒级**(详见交接单 §11.7):
① **Manager 拨号通道** = 删 manager drop-in 里 `DSHS_RELAY_DIAL_*` 5 行 → `daemon-reload` → `restart dshs`(`addressOf` 自动回退到 R3 的 `/status` 快照路径,"relay 同机"假设回来);
② **relay 侧白名单** = 删 `dshs-relay.service.d/dialers.conf`(不删也行:无拨号方接入 ⇒ 行为同 R3);
③ **代码级** = revert `src/net/relay/*` + `src/config.ts` + `src/web/server.ts` → `npm run build` → scp `lib/` → `restart dshs`。
⚠️ 备份:`/etc/dshs/relay-keys.json.bak-r5-20260916-224838`、`/etc/systemd/system/dshs.service.d/cluster.conf.bak-r5-20260916-224838`(及 `.bak-r5swap-20260916-225546`)。
- **缺陷 A1/A2(本轮)回滚**(详见交接单 §12.5):A1 = `cp -a /opt/dshs/lib-bak-a1-20260916-232914/lib/. /opt/dshs/lib/` → `systemctl restart dshs`(回到"假 404"复现);A2 = 还原 `state.py` 第 1 节为"按文件读"(**不建议**)。
⚠️ **A1 的备份目录只有这一份**(推送过程中滚动过两次,同名文件以后者为准,两次都在同一个目录里)。
- **有意保留、⛔ 别当"没做完"**:R5 新增的 `127.0.0.1:25000..25063` **仅回环**(公网零新增);relay 仍为端口绑动态回环口(`exposeLoopback` **有意未关**,理由见交接单 §11.5)。
- 文档侧:10 份为**新增**;被修改的 3 份(客户端化部署方案 v3 / 桌面客户端方案 v1 / 可行性评估)改动均为**追加或标注**,可反向还原。
- 服务器侧待复核事实:控制面机规格(1.8 GB / 2 核 是 09-08 旧记录);47↔106 跨云实测 **~22 KB/s**。
> 📌 交接单指纹(2026-09-16 23:4x):`tail -n +4 交接单/交接单_relay落地R2-R4_20260916.md | md5sum` = `b110b5c4e3eb8afcac08af537d333c99`(**本单已执行完毕**:R2→§9、R3 Step 0→§10.4、R3 本体+R4→§10.5、**R5→§11**、**缺陷 A1/A2→§12**)
> 📌 **② 的交接单**(**已执行完毕**):`交接单/交接单_网抽象与地址规划R6_20260916.md`,指纹 `0d3f1f305e9e6219afa97cdfecff05ba`。
> 🟢 **2026-09-17 07:4x 更新(② 收官)**:**Step 1(P0-1 网抽象)/ Step 2(P0-2 引导三级链)/ Step 3(P0-3 名字解析与授权)全部落地并端到端验收** ——
> 证据见该单的「**执行进度**」段(含判据命令与实测输出)。**② 单关闭 ⇒ 它不再是下一棒的开工依据**(指纹留着只用于"文档有没有被改过")。
> ⛔ **不要重做 Step 1 / Step 2 / Step 3**。下一棒按 `清单 §五` 往下:序 ③ 一机一钥 + 信任根(P0-4)/ 序 ④ 443/TCP 兜底 / 序 ⑤ 参数表·观测·权限评估
> —— **开工顺序已于 2026-09-17 07:5x 定为 序③ → 序④ → 序⑤**(理由见 §0)。