回收 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)、记忆修复前备份。
465 lines
342 KiB
Markdown
465 lines
342 KiB
Markdown
# 接续入口 · 覆盖网络线(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)。
|