Files
dsh_shenxian/dsh-server-docs/ops/接续入口_覆盖网络线_20260916.md
T
admin 04776af4b1 docs: 工作区根项目文档批量入仓(04-调整方案 113–128 / 交接单 T09–T21 / ops / archive)
起因:用户 2026-09-17 明确「所有文档都要同步,都放在开发仓库 docs 对应文件夹下」。
判据:工作区根 *.md 中在仓库(git ls-files --quotepath=false)搜不到的那些。

入仓 33 份(一律复制,工作区根原件保留不动,避免引用断链):
- 04-调整方案/113–128(16 份 · 原子占号后落盘):覆盖网络 传输方案取舍 / 应用场景与待完善清单 /
  插件化vs改内核 / 问题逐条推演 / 参数表与观测口径;会合中继拆分取证与改造方案;
  集群化改造方案 Manager-Worker;跨节点迁移与节点自举;项目代码分层范式与迭代风险评估;
  搬运与共享重建方案 guest w47→w106;方案规划方法提炼;文档无效信息审计报告;
  会话接续机制复盘与修复;会话接续规范;dsh 客户端化部署方案;dsh 桌面客户端开发方案
- 交接单/archive/交接单-已完成/T09–T21(13 份 · 覆盖网络线已完成单归档)
- ops/(2 份运行态指针:接续入口 / 接续包 · 覆盖网络线)
- archive/(2 份临时与内部简报)

已排除(无需重复入仓):覆盖网络线 10 份方案正文已入档案 103–112(文件名不同)。

登记:INDEX.md §二 新增 04-113–128 共 16 行 + §四 追加 T09–T21 说明 + 机器摘要行刷新
(⛔ 未跑 docs-index-stats.py --write:该脚本会按 \r\n 归一化全文件行尾,故改为字节级单行替换);
README.md 追加 1 条入仓指针;docs-manifest.json 复跑 scripts/docs-manifest.py 刷新。

验收:工作区根 47 份 .md —— 同名已入仓 8 / 本次内容一致 29 / 已知改名映射 10 / 未入仓 0;
git status 待提交清单只含本次新增与登记 3 件(未涉 src/ 与 relay 代码面)。
2026-09-17 18:24:19 +08:00

93 KiB
Raw Blame History

接续入口 · 覆盖网络线(2026-09-16)

这是本工作线的唯一入口。 新会话先读这一份(约 3 KB),再按需打开下面的文档。 详细过程记录在 .workbuddy/memory/2026-09-16.md 末尾的「会话接续包」——不必先读那个 60 KB 日志。


0. 当前状态(一句话)

🆕 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 行原文自证)= 正是要替换的"轮询"路径。做法 = 照抄 覆盖网络_瓶颈落地方案_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 的可执行交接单(依据 = 覆盖网络_应用场景与待完善清单_20260916.md §五 第 7 步 + 覆盖网络_千台全场景推演_20260916.md + 覆盖网络_瓶颈落地方案_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 行 + 本机技能同内容;⛔ 04-调整方案/** 档案正文未动;判据 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 拆分「不做」 —— 原方案 会合中继拆分_取证与改造方案_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、均为过期快照 ⇒ 无回滚价值)② 04-调整方案/** 档案的 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 + _中间产物_待清理/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 可行性评估_客户端安装与覆盖网络互联_20260916.md 判定可做;列出现有架构已给出的 80% 形状(soft 隔离 = 裸子进程 / Worker 四条协议纪律 / 拨出式反向隧道 / 全仓仅一处平台分支);§六 = 与另两份客户端文档的对账
2 覆盖网络_全球架构复盘_20260916.md 五层架构 + 12 条内建特性 + 选型对照 + 10 类风暴类型学 + 流量组织五原则 + 7 步落地顺序
3 覆盖网络_瓶颈落地方案_20260916.md 九大瓶颈逐个给可执行做法(含 Slack / SCCM 官方做法照抄点 + 验收判据);"只做三件事"= presence + 游戏服放 L1 + 块级内容寻址
4 覆盖网络_骨干层方案_20260916.md 多中心骨干(≤10–20 成员)+ 选择性加入;三条硬约束(接入/成员/可见三分离、资格只能控制面签发、骨干不得被默认征用)
5 覆盖网络_百台规模推演_20260916.md(v2) 100 台异构画像;L1 10 / L2 30 / L3 需中继 40–55;全互联 4,950 vs 星型 100
6 覆盖网络_千台全场景推演_20260916.md 1000 台 × 11 场景;瓶颈排序(presence 第一)+ 流量预算总表
7 覆盖网络_游戏专项_MMORPG与MUD_20260916.md MMORPG/MUD/传奇 = 最匹配;核心简化:玩家之间不需要互联,中继按"服数"算
8 覆盖网络_调研_游戏网络特征与群聊上限_20260916.md 游戏网络参数(每玩家 2–20 KB/s、jitter<20 ms)+ 群聊上限按扇出预算定义的分档
9 覆盖网络_答疑_群聊备份迁移保密_20260916.md 四问:群聊+agent / 备份(主备份用对象存储)/ 迁移提速 / 三层加密与元数据保护
10 覆盖网络_补遗与参考方案_20260916.md 补遗 24 条 + 参考方案对照 + 反模式 12 条
11 参数表_覆盖网络_20260917.md 序⑤ 产物 · 唯一一张参数表(155 行):输入参数 + 代码固化常量 + 45% 口径填值(--max-hosts = 225)+ 观测阈值 OBS-01..12 + 权限影响评估 + 待测汇总。观测探针 = 代码仓 scripts/overlay-probe.cjs(一条命令 / 12 行 / 退出码 0-1-2;cwd = 本工作区根即可跑)

另有两份他人产出(已按最佳方案收口,勿重复改):dsh客户端化部署方案_20260916.md(v3,平台侧单一来源)|dsh桌面客户端_开发方案_20260916.md(v1,交付载体层)。

🧭 方法论(2026-09-16 16:4x 新增):方案规划方法_覆盖网络线提炼_20260916.md —— 把本线「信息收集 → 方案调研 → 场景梳理 → 逻辑验证 → 应用推演」五段作业法反推成可复用方法(含每段骨架/出口判据、出口闸门三件事、8 次真实纠错自证、可抄模板)。下次做新方案规划时先读它。


2. 下一步

✅ 上一轮已完成(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 差异无增量。已落三处:参数表_覆盖网络_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/** + 本机技能,⛔ 不改 04-调整方案/** 档案正文)|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 写进任何回滚 / 演练 / 夹具路径。⛔ 不改 04-调整方案/** 档案正文、⛔ 不重做已收官序 ①–⑮、⛔ 不做 presence / 房间层 / 内容分发。收口必须:释放锁 + 陈述句告知 + 登记下一棒 + 推进本入口 + 写工作区日志 + 回填该单 §8。

⏹️ (存档)序 ⑯ 本轮动作口径(已收官 · 结果见 交接单_观测口径与在册缺陷_20260917.md §12):序 ⑯ · 规划棒 —— 复核「会合 / 中继从 Manager 拆分」是否仍需要 + 给剩余在册项定序、出执行单(⚠️ 只出规划、⛔ 不改码、⛔ 不动服务器)。依据 = 工作区根 会合中继拆分_取证与改造方案_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、⛔ 不改任何生产值)。依据 = 覆盖网络_应用场景与待完善清单_20260916.md §五 第 7 步 + 覆盖网络_千台全场景推演_20260916.md + 覆盖网络_瓶颈落地方案_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(⛔ 不改 04-调整方案/** 档案正文、⛔ 不 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 台最小形态:按 覆盖网络_应用场景与待完善清单_20260916.md §五 第 6 行开工 —— 先把 参数表_覆盖网络_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% 留余量)。取证入口 = 覆盖网络_应用场景与待完善清单 §五(主线第 ④ 项)+ 覆盖网络_补遗与参考方案_20260916.md + 覆盖网络_全球架构复盘_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 拆分的落地(方案:工作区根 会合中继拆分_取证与改造方案_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)|04-调整方案/.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. 技术侧开工:按 覆盖网络_瓶颈落地方案_20260916.md 的「只做三件事」(presence 改造 + 游戏服放 L1 + 块级内容寻址)开工;前置仍是第 2 条。
  7. 代码分层 / 依赖方向(与覆盖网络并行的一条线)—— ✅ P0 已完成(2026-09-16 13:2x,本机):新增 docs/architecture.md(四层 ①入口 → ②领域 → ③能力 → ④基础 + R1–R4 判据 + 三条工程纪律)+ README.md 文档表登记。
    • 📄 评估文档 = 工作区根 项目代码_分层范式与迭代风险评估_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 资源/复杂度)⇒ 待拍板,⛔ 不作为任何一棒的前置(详见本棒回报的最后一节)。


3. 关键决定(已定,勿再上抛)

  1. 方案只做技术实现;跨境数据合规由使用者自行考虑(用户原话)⇒ 选型不为合规让路、跨境不设限、⛔ 不再把合规当前置条件。
  2. 单机自用 ≠ 不需要互联(用户原话:「单机用也要互联,这正是建立覆盖网络的目的」)⇒ 租户维度收窄 ≠ 网络维度收窄。
  3. 覆盖网络按异构设计:中继按 45% 设计 / 55% 留余量(不是同构假设的 15%);必须补 443/TCP 兜底;有公网 IP 的节点升格为中继候选。
  4. 权威状态单点:归属/租约/骨干资格只能控制面写;会合/中继可多实例。
  5. 形态已拍板:单机自用为默认;"当服务器给他人用"的多人维度已放弃。
  6. 游戏重点是 MMORPG(2D/2.5D)/ MUD / 传奇类 ⇒ 判定上修为"最匹配",非 3D 强实时竞技。

4. 待拍板(唯一一项,真取舍)

骨干节点的服务范围:A 只服务自己名下设备(优点:无资源/计费纠纷、权限面不变;缺点:骨干少、冗余低)| B 服务全网(优点:骨干多、可用性高、中继容量易满足;缺点:他人流量跑在你的机器上、元数据暴露、被攻破影响面大)。 倾向 A→B 渐进。详见 覆盖网络_骨干层方案_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)。