Files
dsh_ai1net_server/归档/文档整理/交接单-20260924-归档/交接单_最小形态真机批次_20260917.md
T
admin c1b5e4d966 chore(工作区): 全量入库 + 补齐 .gitignore(以工作区为准)
- 变更规模:新增 514 / 修改 62 / 重命名 155 / 删除 4(归档重组与文档轮次)
- .gitignore 修:`归档/**/db-cwd归一-备份-*/` —— 原规则写绝对层级(归档/db-cwd归一-…),
  目录搬进 归档/配置与备份/ 后**静默失效**,43 MB 的 DB 备份又变成未跟踪
- .gitignore 补:嵌套 git 内部数据(归档/内嵌git-20261008/、归档/skills-git-旧线-20261007/dotgit-原样移出/)
- .gitignore 补:运行态与部署副本(.workbuddy/collab/、.workbuddy/tools/、.workbuddy/.load-pending、.workbuddy/tmp-*)
- .gitignore 补:备份件(*.bak-*)
- 未跟踪文件从 2190 降到 890(其余为 归档/ 归档件与 .workbuddy/memory/ 知识文件,按口径入库)
2026-10-10 23:13:22 +08:00

44 KiB
Raw Blame History

交接单 · 3–5 台最小形态真机批次(覆盖网络线 · 序 ⑥)

线:覆盖网络线 | 序:⑥(3–5 台最小形态跑通)| 产出:规划棒 2026-09-17 09:5x 唯一来源:覆盖网络_应用场景与待完善清单_20260916.md §五 第 6 行("3–5 台最小形态跑通,把 3 个关键估值换成实测,依赖 2/3/4")+ 参数表_覆盖网络_20260917.md §7 待测项汇总 + 同表 §5.2 校验③(需 ≥2 台中继) 本单要做的事:把参数表 §7 的 4 个 待测 项 + 1 个待校准推导项设计成可执行实测步骤(每项:怎么测 / 样本多大 / 判据 / 写回哪一行),并合批落地 L3 第二中继机。 🔴 本单不改架构、不新增传输能力:性质是「把估值换成实测」,不是"做打洞"(理由见 §4.1-1,这是本单最重要的一个已定项)。


§1 目标

一句话:让 参数表_覆盖网络_20260917.md 里 5 个空值单元格全部有实测值或"如实标注取不到"的记录,并让 relay 从 1 台变 2 台(跨机真容灾成立),同时按回头条件把 RELAY_MAX_HOSTS 重算并重下发到两台中继。

判定"做完了没有":

  1. 参数表 中 HOLE_PUNCH_RATE_LOCAL / PER_PLAYER_BW_LOCAL / WAN_STEADY_THROUGHPUT / JITTER_LINK_MEASURED / MEM_PER_HOST_MB 五行的"等级"列都不再是 待测(改成 实测,或写成 取不到 + 原因——⛔ 但不许编数);
  2. 两台中继机各自的 /status 都能看到在册会话,且杀掉任一台后客户端能自动切到另一台;
  3. §5 S7 的回头条件已执行或已写明"本轮未触发、因为哪个数没换成实测"。

§2 只读前置(⛔ 只读,不改;P1–P8 逐条核实后才允许进 S 段)

# 命令 期望输出 / 判据
P1 bash "D:/github/dsh_shenxian/dsh-server-docs/scripts/handoff-guard.sh" --claim-exec "<你的会话名>" ✓ 已持全局执行锁。抢不到 = 有会话在跑 ⇒ 只报告并立刻停
P2 "E:/ProgramData/.workbuddy/binaries/python/versions/3.13.12/python.exe" "E:/ProgramData/AI技能/aliyun-dsh-server/state.py" [锁] 🔴 被占用(owner = 你)|HEAD = 640813e|[入口] 接续入口_覆盖网络线_20260916.md
P3 cd "E:/ProgramData/AI技能/aliyun-dsh-server" && sed '/^## §10 指纹/,$d' 参数表_覆盖网络_20260917.md | md5sum f3e68012698abb352549e2560746d992。⚠️ 不等 ⇒ 参数表已被改过,先去 §7 确认 待测 计数,再按实际情况调整本单行号
P4 ssh -p 22 bt-server 'systemctl cat dshs-relay | head -25; echo ---; cat /etc/systemd/system/dshs-relay.service.d/capacity.conf 2>&1' 期望看到 --max-hosts 225(序⑤ 已下发;⚠️ 记忆铁律:主单元 ExecStart 已有显式 --max-hosts 0,CLI 优先于 Environment= ⇒ 只设 env 会被静默忽略)。⛔ 若未下发 ⇒ 停下报告,不要边补边测
P5 ssh -p 22 test106 'hostname; nproc; free -m | head -2; systemctl is-active nginx dshs-relay 2>&1; ss -lntp | grep -E ":(443|80|20080)\b"; ls -d /opt/dsh-relay /opt/dshs-cluster 2>&1' 记录:106 有无 nginx / 443 是否被占 / 是否已有 /opt/dsh-relay。这是 S8 的唯一分叉判据(有 nginx ⇒ 复用 443,零新增口;无 ⇒ 按 §4.2-2 自决)
P6 "E:/ProgramData/.workbuddy/binaries/node/versions/22.22.2-3/node.exe" -v && ls "D:/github/dsh_shenxian/lib/net/relay/" | head Node 22.x + lib/net/relay/*.js 已 build。缺 ⇒ 先在代码仓 npm run build(Node 22)再继续
P7 ssh -p 22 bt-server 'ss -lntp | wc -l; nft list ruleset | wc -l; curl -s -o /dev/null -w "%{http_code}\n" --http1.1 -H "Host: alotbuy.com" 127.0.0.1:3080/; curl -s 127.0.0.1:20080/status | head -c 400' 不退化对照基线:79 / 72 / 200 / capacity:{max:225,used:N}。⛔ 数与本单不一致 ⇒ 先报告差异,别当成 bug 顺手修
P8 cd "E:/ProgramData/AI技能/aliyun-dsh-server" && "E:/ProgramData/.workbuddy/binaries/node/versions/22.22.2-3/node.exe" "D:/github/dsh_shenxian/scripts/overlay-probe.cjs" 12 行 + 退出码 0/1/2。FAIL 清单原样记下(S9 要与它逐项对照)

🔑 P1–P8 全部只读。任何一条需要写动作 ⇒ 说明你走错了,停下回看 §3。


§3 范围

3.1 要改的(且只有这些)

# 对象 性质
1 工作区根 参数表_覆盖网络_20260917.md 只改值 + 等级 + 指纹(§3.2/§3.3/§3.5/§5.1/§5.2/§7/§10),⛔ 不改结构、不新增键
2 代码仓 scripts/ 新增一次性脚本(nat-probe / loadgen / bw-probe) 不进 src/、不进产品路径;判据 = git status 里 src/** 零改动
3 47 上 dshs-relay.service.d/capacity.conf 仅在 S7 触发时重写(drop-in 重写 ExecStart)
4 106 上新增 dshs-relay 单元 + /opt/dsh-relay/(build 后 scp) + 节点密钥 S8(L3 第二中继机)
5 47 / 106 的 seeds 广播(DSHS_OVERLAY_BOOTSTRAP_SEEDS 或签名目录 relays[]) 加入第二中继项
6 本单自身 §8 执行回报 + 工作区日志 收口

3.2 ⛔ 不动什么(防顺手扩大)

  • ⛔ 不做打洞实现(不在 src/net/relay/ 加 UDP/dgram/STUN)—— 见 §4.1-1;
  • ⛔ 不做 presence / 房间层 / 内容分发 / 游戏服(清单 §五 第 7 步,本单毫不触碰);
  • ⛔ 不引入第三方 relay 或把 STUN 库写进产品依赖(探测脚本可用公网 STUN 作降级手段,但不得进 package.json);
  • ⛔ 不重做序 ②/③/④/⑤ 的任何一步;
  • ⛔ 不改 dshs / dshs-relay 主单元的既有参数(只经 drop-in);
  • ⛔ 不在 106 上开非 443 的新公网口(安全组不动);
  • ⛔ 不 commit / 不 push(本线纪律;本单只改工作区与服务器运行态)。

§4 决策点

4.1 已定项(规划棒已拍 —— 执行棒不得自行更改;要改必须回写 §8 并说明理由)

  1. 🔴 本单只做「把估值换成实测」,不做打洞实现 —— 依据:① 清单 §五 第 6 行原文是"把 3 个关键估值换成实测",不是"新增传输能力";② 实测确认:src/ 全仓零 UDP/NAT 穿透代码(grep -iE "dgram|createSocket|stun|punch|udp" src/ 的命中全部是 signature / native 假阳性),directory.ts:404-421 只有 CGNAT 地址判定;③ 引入打洞 = 净新增 UDP 入站面(命中 R5)+需要 STUN/信令设计,属独立方案,不是本序的交付物。 ⇒ 因此 HOLE_PUNCH_RATE_LOCAL 的口径定为:测「这台设备所在网络能不能打洞(NAT 映射/过滤行为)」,⛔ 不是"我系统打洞成功率"(后者需要先有实现)。测到的数仍然可用:它决定"打洞实现值不值得做"(若可打洞比例低 ⇒ 这项能力可以直接不做)。
  2. --max-hosts 的分母 = 单台中继(参数表 §5.3 已写死);FLEET_RELAY_DEMAND(450)只作校验上界。
  3. L3 第二中继机 = 106 升格(依据:清单 §3 关键决定已定"有公网 IP 的节点自动升格为中继候选"+参数表 §5.2 校验③"需 ≥2 台")。⛔ 不新建机器、不启用"另开一台云主机"这条路(花钱属边界外,且 §4.3 列着)。
  4. 2 台就落地 2 台:225 × 2 = 450 = FLEET_RELAY_DEMAND ⇒ 恰好达标、零余量。⚠️ 必须把"零余量"这个事实写进参数表,并登记第三台的触发条件(方案里不得出现"余量充足"这类不实表述)。
  5. 打洞探测的观察面必须是我们自己的机器(首选:47 上一次性 UDP 观察器,测完即停),⛔ 不优先依赖公网 STUN(降级手段,且须在 §8 标注"经第三方")。
  6. 五项的判定口径一律"实测优先、取不到如实记":⛔ 任何一项都不许用估值顶替;取不到就写"取不到 + 卡在哪 + 什么条件一出现必须回头"。

4.2 交给执行棒自决(⛔ 不上升为提问)

  1. WAN_STEADY_THROUGHPUT 怎么造可控载荷(本单给判定顺序:① 复用既有端点声明机制新增一个临时端口 → ② 复用已声明但空闲的端口 → ③ 降级为"经 relay 的实例面链路吞吐"并如实标注口径);
  2. 106 上 relay 的绑定方式(P5 探明后按序:有 nginx ⇒ 复用 443,零新增口 → 无 nginx ⇒ 装 nginx 复用 443(标准组件、不新增监听)→ 都不可行 ⇒ 停下报告,⛔ 不许开新口);
  3. 合成节点的工程实现(脚本落 scripts/,用 Node 22 内置能力,不引依赖);
  4. 样本点的具体分布(⚠️ 本单给的是下限,允许加密);
  5. 所有输出文件落在 _中间产物_待清理/ 下的临时目录,收口时只保留正式产物(任务收尾纪律)。

4.3 真需要用户拍板的(命中才问,且一轮只问这一句)

第 4/5 台真机的来源 —— 本单能用现有资源跑满 3 台(47 / 106 / 本机),打洞分层样本需要"家宽 / CGNAT / 移动 / 企业网"四类环境,云主机给不出。候选(各有优有劣 ⇒ 才上抛):

A · 只用现有 3 台先跑满能跑的部分 —— 优点:零成本、零等待、今天就能开工;缺点:打洞率的样本偏差大(3 台里 2 台是云),该项大概率只能拿"环境可打洞性"的定性结论,写不回一个可信的百分数。

B · 由用户自备设备(手机热点 / 家里的宽带上的一台机器)跑一次性探测脚本 —— 优点:样本最贴近真实目标场景("同一人的几台设备")、零花费、脚本是一次性的(跑完给 JSON 即可);缺点:需要用户动手,且会占用用户设备一小段时间。

C · 新开 1–2 台轻量云主机(跨运营商 / 跨地域) —— 优点:样本可控可复现、随时可扩到 5 台;缺点:要花钱,且云主机的 NAT 行为与家宽/CGNAT 仍不同构(花了钱也解决不了分层问题)。

我的倾向:A 立即开工 + B 并行补样本,C 不动(理由:C 花了钱还解决不了主要的样本偏差;A+B 组合零成本且能覆盖真实场景)。⇒ 执行棒按 A 开工,不必等这一刻(B 是"什么时候给什么时候补")。

4.4 技术实现裁决顺序(⚠️ 与 dsh-decision-method §4.4 一致)

先取"不改结构的方案"→ 再取"改一处、可回滚的" → 最后才考虑"新增面/新增依赖的"。⛔ 不允许用"新引入一个组件"来绕过取证。


§5 步骤(S0–S9;每步自带一次可执行的验证)

S0 · 只读取证(= §2 P1–P8)

验证:P1–P8 全部有原文输出,且 P3 指纹、P7 基线、P8 的 FAIL 清单已落 §8.1。


S1 · 组起 3 台节点(最小形态第一步)

做:47(Manager+relay+w-47)/106(Worker w-106)/本机(第三节点)。 本机节点 = 一个一次性进程(脚本,只拨出,不声明端口或只声明 1 个 echo 口),用于提供"非云的第 3 个网络视角"。 验证:47 上 curl -s 127.0.0.1:20080/status 的 online[] / sessions[] 长度从 2 变 3(新增本机节点),且本机节点 via 非空。 判据:3 台全部在册 ⇒ S2 起可测;若本机节点起不来(Windows 侧限制)⇒ 如实记"3 台降为 2 台",S2/S3 照常跑(照 2 台口径标注),⛔ 不编第 3 台的数。


S2 · WAN_STEADY_THROUGHPUT 实测(写回参数表 §3.5)

为什么这步第一优先:它是 §5.4 明确"当前取不到、必须回来重算"的那个数,且是 §5.2 的潜在绑定约束。

怎么测:两端可控载荷。判定顺序(§4.2-1):

  1. 首选:在 106 上把一次性 HTTP 大响应服务绑在 127.0.0.1:<PORT>,经既有端点声明机制(relay PORT_ADD)把它纳入 relay 映射;在 47 上经 relay 拉取。
  2. 次选:复用已声明但空闲的端口(P4 的 /status.endpoints[] 里挑一个不在用的)。
  3. 兜底:直接测"经 relay 的实例面链路"的稳态速率,口径如实写成"经 relay 转发的实例面吞吐",⛔ 不得冒充裸链路吞吐。

样本:≥ 5 次,每次 ≥ 30 s 稳态段(去掉前 3 s 建连/爬升),载荷 ≥ 8 MB;记录 bytes / sec / 速率。 判据:报中位数(⛔ 不用峰值、不用单次最好值);同时报 min/max 说明离散度。 写回:参数表 §3.5 → WAN_STEADY_THROUGHPUT,等级改 实测,来源定位写"本单 §8.x + 完整命令",并在同一行的备注里写清口径(谁到谁 / 是否经 relay / 稳态段长度)。


做两件事(不要只做第一件):

(a) 链路 jitter 实测

  • 命令形态:ssh -p 22 bt-server 'ping -c 300 -i 0.2 -W 1 <106 公网 IP>'(反向再做一次)。
  • 样本:≥ 200 包(300 包余量更稳)。
  • 取数:rtt min/avg/max/mdev + 自算 p95(|ΔRTT|)(相邻包 RTT 差的 95 分位)——⛔ 只用 mdev 会低估抖动。
  • 判据:与参数表 JITTER_LIMIT_MS(20 ms,估值口径)对照给出达标/不达标二元结论。⚠️ 预期不达标(同链路 relay 路径 RTT 已实测 336 ms)——如实写"不达标",并按 §5(a) 的下一条处理。

(b) 🔴 relay rttMs 口径校验(本单新增的关键验证)

  • 参数表把 RELAY_RTT_W106 = 336 ms 标成"实测",但它是 relay 心跳往返(server.ts:810 注释:①②③ = 测 RTT / 察觉半开 / 保 NAT 表项),可能含应用层处理与验签耗时,不一定等于网络 RTT。
  • ⇒ 三方对比:ICMP RTT(ping)|TCP 握手 RTT(ssh -p 22或到 443 的 curl -w %{time_connect})|relay 心跳 rttMs。
  • 判据:若 relay rttMs 与 ICMP RTT 差距 > 2× ⇒ 在 参数表 §3.5 给 RELAY_RTT_W106 加一条口径备注("心跳往返,含应用层,⛔ 不等于网络 RTT"),并在 OBS 侧登记"relay rttMs 不得当链路 RTT 用"。
  • ⚠️ 这条不是可选项 —— 336 ms 目前是"跨云链路很差"的唯一证据,若它其实是口径问题,后面所有关于"跨云不可玩"的结论都要重判。

写回:参数表 §3.5 → JITTER_LINK_MEASURED(等级改 实测;值 = 中位数 + p95 两个数,注明取哪个作为判定值);RELAY_RTT_W106 加口径备注。


S4 · HOLE_PUNCH_RATE_LOCAL 实测(写回参数表 §3.2)

🔴 口径见 §4.1-1:测的是「该网络能不能打洞」,⛔ 不是"本系统打洞成功率"。

首选路径(不依赖第三方):

  1. 47 上起一次性 UDP 观察器(脚本,绑定一个高位口,仅测期监听、测完立即停):收到包即回显 {from: <对端源 ip:port>, mapping: <看到的源地址>}。
  2. 各节点向它发 5 包 ⇒ 拿到本节点的 UDP 公网映射。
  3. 节点两两互发:双方各自向对方映射每 200 ms 发 1 包、共 10 包,同时收包。
  4. 判定:任一方收到对方 ≥ 1 包 ⇒ 该对"可打洞"。
  5. 逐对记录,并标注两侧网络类型(家宽 / CGNAT / 移动 / 企业网 / 云)。

降级路径:47 的 UDP 入站不可达 ⇒ 用公网 STUN 做映射/过滤行为判定(RFC 3489 简化版:同服务器不同端口 + 不同服务器对比映射是否变化);⛔ 须在 §8 注明"经第三方"。 兜底:两者都取不到 ⇒ 如实写"取不到" + 卡在哪 + 回头条件(拿到非云环境即可补测)。

样本:3 台 ⇒ 3 对;若第 4/5 台到位 ⇒ 10 对(每对 10 次尝试)。打洞率 = 成功对次 / 总尝试次,并分层分别给(⛔ 不给单一的合并百分数就完事)。 写回:参数表 §3.2 → HOLE_PUNCH_RATE_LOCAL,值列写"分层结果",等级改 实测,注明样本量("n=3 对,云节点占 2/3,不代表家宽场景"这句话必须写进去)。 权限附注:47 上的 UDP 观察口 = 临时入站面 ⇒ 在 §8 显式列出(对象 / 端口 / 开放时长 / 关闭证据),并回填 参数表 §8(新增一行,结论栏按实际)。


S5 · PER_PLAYER_BW_LOCAL 实测(写回参数表 §3.3)

为什么不能"直接测每玩家带宽":仓库里没有游戏/应用层(清单 §五 第 7 步才谈内容分发与游戏)⇒ 没有真实玩家协议可测。如实处理: 测法:合成玩家载荷 —— 参数扫描(消息率 5 / 20 / 50 msg/s × 消息 200 B × 玩家数 10 / 50),在真机间经 relay 跑 60 s。 取数:每档的端到端 p50/p95 单向时延、丢包率、实际吞吐(KB/s)。 判据:PER_PLAYER_BW_LOCAL = "在 p95 时延 ≤ 2× p50 且丢包 = 0 的前提下,每玩家可达的最大上行速率(KB/s)"。 写回:参数表 §3.3,等级改 实测,并在该行备注里明确写出边界:「本值 = 传输层上限;游戏协议的真实需求仍是估值(PER_PLAYER_BW_TEXT/BATTLE/SIEGE)」——⛔ 不得让读者误以为这是"实测出的游戏需求"。


S6 · MEM_PER_HOST_MB 校准(写回参数表 §5.1)

为什么必须放大测:现网 used = 2,RSS 只反映 Node 基座(参数表 §5.1 已注明)⇒ 2 MB/台 是推导值,不是实测。

怎么测(干净方案,⛔ 不污染生产):

  1. 本机起一个独立 relay 实例(高位回环口,独立于生产的 20080);
  2. 起 N 个合成 client(一次性脚本)连它,每个声明 1–2 个端口;
  3. 量 relay 进程 RSS。 样本点:N = 2 / 10 / 25 / 50 / 100(⚠️ 这是下限,允许加密)。 判据:① 各点记录 RSS;② 线性回归 RSS(N) = a + b·N,R² ≥ 0.9 方为有效(否则说明有非线性跳跃,须找出跳点并在 §8 如实报告,⛔ 不许硬套斜率);③ MEM_PER_HOST_MB = b(KB/台 → MB/台,向上取整 + 20% 余量)。 写回:参数表 §6 → RELAY_RSS_MAX_KB 哨兵重新核算(若新斜率与 2 MB 差异 > 50% ⇒ 哨兵必须跟着改);参数表 §5.1 → MEM_PER_HOST_MB 等级改 实测,来源定位写"本单 §8.x(N=2..100 斜率)"。 权限附注:纯本机回环、零公网面 ⇒ ⛔ 不动 47 的任何配置。 顺带(同机合批,不额外开步):参数表 §9 第 4 行(relay 无 MemoryMax)——只测量、只登记,⛔ 本单不改单元语义(加 cgroup 上限会引入 OOM-kill 新失败模式,属 R11 的"净变差"风险)。

S7 · 🔴 回头条件强制执行(本单写死的硬门)

在 S2 / S6 出数之后立即执行(⛔ 不允许"下次再说"):

触发条件:MEM_PER_HOST_MB 或 WAN_STEADY_THROUGHPUT 从"推导/待测"换成"实测"。

必做七件(逐条落到 §8):

  1. 重算 C_MEM = floor(MEM_BUDGET_MB / MEM_PER_HOST_MB_new);
  2. 重算 C_RELAY = min(C_MEM, C_FD);并重新判断带宽是否仍不参与 min(若新实测吞吐使 225 台的控制面+实例面流量逼近实测吞吐 ⇒ 带宽进 min,这是 §5.4 预留的口子);
  3. 重算 RELAY_MAX_HOSTS = floor(C_RELAY × DESIGN_MARGIN);
  4. 重跑 §5.2 三条校验(防自锁 > used×4 / 余量自洽 / 千台需求 ≤ 225 × 2 = 450);
  5. 重下发:47 上重写 drop-in capacity.conf(⚠️ 必须重写 ExecStart 而不是只加 Environment= —— 主单元已有显式 --max-hosts 0,CLI 优先于 env,只设 env 会被静默忽略)→ daemon-reload → restart dshs-relay;106 上的第二中继同值同步;
  6. 复验:overlay-probe.cjs 的 OBS-02(max = RELAY_MAX_HOSTS 且 free = max - used)必须 PASS;
  7. 回写:参数表 §5.2(含变更前后对照:旧值 → 新值 → 为什么变)+ §10 指纹+工作区日志记一笔"哪个键从什么换成什么"。

若未触发(某项确实没换成实测)⇒ 在 §8 明写"未触发,因为 X 没换成实测,卡点是 Y,回头条件是 Z" —— ⛔ 不许默认跳过。


S8 · L3 第二中继机落地(106 升格,与上面合批)

依据:清单 §3 关键决定(有公网 IP 的节点自动升格中继候选)+ 参数表 §5.2 校验③(需 ≥2 台)。

顺序:

  1. 权限影响评估更新(先做,R5):把 参数表 §8 第 ④ 行从"只评估不实施"改为实施态,逐项写明:新增监听口(几个、哪个、公网还是回环) / 新增凭据(节点密钥签发) / 是否改变 106 "入站 = 0" 这条已收窄成果。⛔ 只能用「收窄 / 维持」二选一作结论;确有扩大 ⇒ 在 §8 逐条列出(陈述式,不是征询)。
  2. 铺 relay 到 106:本机 npm run build(Node 22)→ scp 到 106 的 /opt/dsh-relay/(⚠️ 与本线既定纪律一致:本机 build 后 scp;relay 代码真身在 /opt/dsh-relay/lib/,⛔ 不是 /opt/dshs/lib/)。
  3. 签发 106 的 relay 身份:用既有密钥仪式 CLI scripts/overlay-keyring.cjs(序③ 产物);relay 侧 keys 表用逻辑名 <net>/<hostId> 索引。
  4. 绑定方式:按 §4.2-2 判定顺序(首选复用既有 443,零新增口)。
  5. 加入 seeds 广播:把第二中继项写进 DSHS_OVERLAY_BOOTSTRAP_SEEDS 或 签名目录 relays[](⚠️「改一次 seeds 全网刷新」是既定机制;注意 relays[] 顺序语义 = 主入口首位,⛔ 第二中继不得插到首位)。
  6. 两台各自设 --max-hosts(值 = S7 重算结果;若 S7 未触发则沿用 225)。
  7. 端到端验收(见 §6 E9)。

硬约束:⛔ 不新开非 443 公网口;⛔ 不改安全组;⛔ 不动 47 的角色。


S9 · 回填 + 不退化 + 收口

  1. 参数表回填:§3.2 / §3.3 / §3.5 / §5.1 / §5.2 / §7(待测 行清空或写明取不到)/ §8 / §10 指纹。
  2. 不退化检查(逐条对照 S0 的 P7/P8):ss -lntp | wc -l、nft list ruleset | wc -l、门户 200、双实例面、npm test(Node 22)。
  3. 临时产物清理:探测/压测脚本与中间输出按 §4.2-5 处理,只保留正式产物。
  4. 收口三件(⛔ 缺一即算本条未完成): ① --release-exec 释放锁; ② 登记下一棒(序 ⑥ 执行棒的后续 / 或按实际收口点到的一棒)并用陈述句在回复里告知用户("已登记自动接续,约 N 分钟后自动开新会话,不用你操作;接续点 = X"); ③ 写工作区日志 .workbuddy/memory/2026-09-17.md。

§6 验收(判据清单;命令 + 期望输出,可被第三方复现)

# 判据 期望
E1 参数表 待测 单元格数量 4 → 0(全部换成实测 或 "取不到 + 原因 + 回头条件");MEM_PER_HOST_MB 等级 推导 → 实测
E2 每个新填值的"来源等级" 全部为 实测,且每行都有一条能跑的命令(复现入口)
E3 参数表 §10 指纹 已更新,且新值 + 旧值都记在 §8
E4 WAN_STEADY_THROUGHPUT ≥ 5 样本 + 中位数 + 口径三要素(谁到谁 / 是否经 relay / 稳态段长度)
E5 JITTER_LINK_MEASURED ≥ 200 包 + `p95(
E6 打洞探测 逐对结果 + 分层标注 + 样本量 + "不代表家宽场景"这句在表内
E7 MEM_PER_HOST_MB N = 2/10/25/50/100 五点 + 斜率 + R²;非线性则如实报告跳点
E8 🔴 回头条件已执行 §5.2 三条校验重跑记录 + 两台 capacity.conf 重下发证据 + OBS-02 PASS(或明写"未触发 + 卡点 + 回头条件")
E9 第二中继可用 两台 relay 各自 /status 有在册会话;杀掉任一台 ⇒ 客户端在 DIRECTORY_REFRESH_SECONDS(300 s)内、实测应在 15 s 心跳级切到另一台(附日志片段)
E10 暴露面 ss -lntp / nft 行数与 S0 一致(或新增项逐条列出 + 参数表 §8 已回填)
E11 不退化 npm test 全绿(Node 22)|双实例面 200/401(∈ PROBE_CODE_SET)|门户 200
E12 收口三件 锁已释放 + 下一棒已登记并已陈述句告知 + 日志已写

§7 回滚

对象 回滚动作 粒度
47 的 --max-hosts 删 drop-in capacity.conf → daemon-reload → restart dshs-relay(回 --max-hosts 0 = 不设限) 秒级
106 第二中继 systemctl stop/disable dshs-relay(106)+ 从 seeds / relays[] 移除该项(改一次全网刷新)+ keyring CLI 吊销该节点密钥 分钟级
打洞/压测脚本 全在 scripts/,删文件即可(src/** 零改动 ⇒ 产品路径零回滚需求) 秒级
本机独立 relay 进程退出即消失(无持久化、无开机自启) 秒级
参数表 保留改动前后的值对照表(§8 内),可反向还原;⛔ 不做整文件覆盖式还原(指纹自指,易错) —

备份要求(动手前):47 /opt/dsh-relay/ 铺前打包;/etc/systemd/system/dshs-relay.service.d/*.bak-<step>-<ts>;/etc/dshs/relay-keys.json.bak-<ts>;106 侧同理(首铺无旧件 ⇒ 记录"无旧件")。


§8 回报格式(执行棒按此格式收口;沿用序⑤ 单的分节)

## §8 执行回报(执行棒 · 2026-09-17 10:12 → 11:05)

> **证据等级标记(本单统一口径)**:`【实测】`= 本轮现场跑出来的;`【留档缺口】`= 当时未单独留存、只有结论(**不补造**)。

### 8.1 S0 快照(P1–P8:命令原文 + 原文输出 + 判定)

| # | 命令(原文) | 记录 | 判定 |
|---|---|---|---|
| **P1** | `bash …/handoff-guard.sh --claim-exec "覆盖网络线-序6执行棒"` | `✓ 已持全局执行锁`;收口前复核 OWNER = `覆盖网络线-序6执行棒`,起始 `09-17 10:12` | ✅ |
| **P2** | `python state.py` | 锁被占用(owner = 我)|HEAD = `640813e`|入口 = `接续入口_覆盖网络线_20260916.md` | ✅ |
| **P3** | `sed '/^## §10 指纹/,$d' 参数表_覆盖网络_20260917.md \| md5sum` | **`f3e68012698abb352549e2560746d992`** —— 与单内期望**逐字一致** ⇒ 单内行号/§7 计数有效,未偏航 | ✅ |
| **P4** | `ssh bt-server 'systemctl cat dshs-relay …; cat …/capacity.conf'` | 47 relay drop-in 已带 **`--max-hosts 225`**(序⑤ 下发);主单元 ExecStart 确有显式 `--max-hosts 0` | ✅ |
| **P5** | `ssh test106 'hostname; nproc; free; systemctl is-active nginx dshs-relay; ss; ls -d /opt/dsh-relay /opt/dshs-cluster'` | 106 有 nginx —— **但由宝塔托管**(master = `/www/server/nginx/sbin/nginx`,属 `bt.service`)⇒ `systemctl is-active nginx` = `inactive` **是正常态、不是故障**(收口时复核同值);443 已被占 ⇒ **S8 走"复用 443"分支,零新增公网口**;`/opt/dsh-relay` **不存在** ⇒ 首铺 | ✅ |
| **P6** | `node -v && ls lib/net/relay/` | `v22.22.2` + `lib/net/relay/*.js` 已 build(未触发补 build) | ✅ |
| **P7** | `ssh bt-server 'ss -lntp\|wc -l; nft list ruleset\|wc -l; curl …3080; curl …20080/status'` | 基线 **`79` / `72` / `200` / `capacity{max:225,used:2}`** —— 与单内期望**完全一致** | ✅ |
| **P8** | `node scripts/overlay-probe.cjs` | 12 行 + 退出码 `1`(有红项)。⚠️ **【留档缺口】S0 时刻的原始 FAIL 清单未单独留存**(首次运行已发生在 S 段推进中)⇒ 见 §8.8-3 | ⚠️ |

### 8.2 五项的实测值(怎么测 / 样本量 / 值 / 等级 / 写回位置)

| 项 | 怎么测(复现入口) | 样本量 | 值 / 等级 | 写回 |
|---|---|---|---|---|
| `HOLE_PUNCH_RATE_LOCAL` | `overlay-holepunch.cjs --stun`(首选"47 双 UDP 观察器"路径**失败**,按 S4 降级走公网 STUN) | **n = 3 对** | **2/2 可打洞**;映射 `125.83.247.110:33742`(两次 STUN 一致 ⇒ **cone 型**)/云机 `:21200`;⛔ 表内已写"云节点占 2/3,**不代表家宽场景**" + **方向性限制**(本机→云机被安全组拦,真打洞须成功后回摆)。等级 = **实测(分层)** | 参数表 §3.2 |
| `PER_PLAYER_BW_LOCAL` | `overlay-wan.cjs --players`(7 档扫描) | 10 / 50 玩家 × 5/20/50/200 msg/s | **9.8 KB/s(10 玩家)|3.9 KB/s(50 玩家)**;聚合天花板 **200–350 KB/s**;崩坏点:50 玩家 @50 msg/s(丢包 91%)、10 玩家 @200 msg/s(丢包 85.6%)。等级 = **实测**(边界写明"传输层上限,游戏需求仍是估值") | 参数表 §3.3 |
| `JITTER_LINK_MEASURED` | `overlay-jitter.cjs --icmp … --count 300 --interval 0.2` + `--tcp …` | ICMP 各 300 包 × 双向 + TCP 30 次握手 | **`p95(|ΔRTT|)` = 3 ms ⇒ 达标**(对 `JITTER_LIMIT_MS = 20`,且 20 是业界估值口径、已标明)。**三方对比**:ICMP 148.29 / TCP 153 / **relay 344–376** ⇒ relay 是真 RTT 的 **2.3×**(故 `RELAY_RTT_W106` 已加口径备注:**心跳往返,含应用层+验签,≠ 网络 RTT**)。等级 = 实测 | 参数表 §3.5 |
| `WAN_STEADY_THROUGHPUT` | `overlay-wan.cjs --serve/--download/--upload`(**尊重反压**:`write()` 返 false 必等 `drain`) | 每向 5 样本取中位数 | **下行 352 KB/s(106→47)|上行 12213 KB/s(47→106)**;口径三要素齐全。**决定性校验**:relay `/status` 计数 `in=1905328505B` 与 106 侧 `rchar=1905380725` 吻合 ⇒ 12 MB/s 确实跨了 WAN;106 公网出带宽封顶 ≈2.8 Mbps 正是下行 352 的成因。`WAN_UP_BOUND_KBPS` **192 → 作废**(下界偏低 64×) | 参数表 §3.5 |
| `MEM_PER_HOST_MB` | `relay-mem-calibrate.mjs`(本机独立 relay 子进程 + 同进程内 N 个 `RelayClient`;RSS 取 7 次采样中位数) | 6 点(N=2/10/25/50/100/150) | **0.06 MB/台**(斜率 46.7 KB/台,**R² = 0.9424**)⇒ `2 → 实测`;原"2 MB/台"**高估 36×**(把 per-stream 256 KB 当成了 per-host)。**首跑 R²=0.487 已作废**(单次采样噪声),修正过程记在 8.5。等级 = 实测 | 参数表 §5.1 |

### 8.3 参数表 diff 摘要(旧值 → 新值)

| 键 | 旧 | 新 |
|---|---|---|
| `HOLE_PUNCH_RATE_LOCAL` | 待测 | 分层实测(2/2,n=3 对,云节点 2/3) |
| `PER_PLAYER_BW_LOCAL` | 待测 | 9.8 / 3.9 KB/s(10/50 玩家) |
| `JITTER_LINK_MEASURED` | 待测 | `p95(|ΔRTT|)` = 3 ms(达标) |
| `WAN_STEADY_THROUGHPUT` | 待测 | 352(106→47)/ 12213(47→106)KB/s |
| `WAN_UP_BOUND_KBPS` | 192 | **作废**(下界偏低 64×) |
| `MEM_PER_HOST_MB` | 推导 2 | **实测 0.06** |
| `C_MEM` / `C_RELAY` | 501 | **16700** |
| `RELAY_MAX_HOSTS` | **225** | **7515** |
| §5.2 校验③ 结论 | `450 > 225` ⇒ 容量上必须 ≥2 台 | **结论变更**:容量上单台即够;2 台依据改为"公网节点升格"+"跨机真容灾" |
| §5.4 带宽判定 | 旧 | 用实测重判"带宽不进 `min`",登记实例面单次 46.3 MB ≈ **135 s 时延上界** |
| §7 待测项计数 | 4 + 1 待校准 | **0 + 0**(回头条件标记"已执行") |
| §8 权限影响 | ④ 单条 | ④ 改**实施态**(新增监听口 0 / 新增凭据 0 / 106 入站仍为 0,**结论维持**)+ 新增 ⑧(临时 UDP 观察口,已关闭)⑨(106 的 443 `location /dshs-relay`)—— 两条**结论均维持** |
| §9 已知边界 | 4 行 | **8 行**(新增:无失败切流 / per-stream 内存未测 / 106 无 bootstrap / 宝塔管 vhost) |
| §10 指纹 | `f3e68012698abb352549e2560746d992` | **`db1317c2f7aaef7b47785c1f4fc9de03`** |

### 8.4 E1–E12 逐条

| # | 现场证据 | 判定 |
|---|---|---|
| **E1** | `grep -c 待测` = 8,**逐条核对全部落在**:§7 标题/计数口径说明/图例行 `\| **待测** \|` —— **数据单元格 0 个**(4 → 0);`MEM_PER_HOST_MB` 等级 `推导 → 实测` | ✅ |
| **E2** | 五个新值全部标 `实测`/`实测(分层)`,每行带一条可跑命令(见 8.2 第 2 列) | ✅ |
| **E3** | 新指纹 `db1317c2…`、旧指纹 `f3e68012…` 均已记(本节 8.3 + 8.9) | ✅ |
| **E4** | 5 样本中位数 + 口径三要素(谁到谁/是否经 relay/稳态段长度)+ relay 侧与 106 侧字节数交叉校验 | ✅ |
| **E5** | ICMP 300 包 × 双向(≥200)+ `p95(\|ΔRTT\|)` + **ICMP/TCP/relay 三方对比表**(并在表内标明 20 ms 是估值口径) | ✅ |
| **E6** | 逐对结果 + **分层标注** + n=3 对 + 表内明写"不代表家宽场景" + 方向性限制 | ✅ |
| **E7** | 六点 `N = 2/10/25/50/100/150` + 斜率 46.7 KB/台 + `R²=0.9424`(非线性/跳点不适用;首跑 R²=0.487 已作废并记因) | ✅ |
| **E8** | 回头条件**已触发**:§5.2 三条校验**全部重跑**(① 防自锁 `7515 > 4×4` ✅ ② 见参数表 ③ `450 ≤ 7515` 结论变更)+ **两台** `capacity.conf` 重下发(47/106 `"max":7515`)+ **`OBS-02` 复验 PASS**(`max=7515 used=2 free=7513`) | ✅ |
| **E9** | 两台 relay 各自 `/status` 可见在册会话(47:`manager`/`w-106`;106:`max=7515` 就绪,443 入口 **WS 101**)。**前半绿**:杀掉 106 后 w-dev 断连并 **1.2 s 内**自动重连回同一台。**后半红**:**不会切到另一台** —— ⇒ 见 §8.8-1 | ⚠️ **半绿** |
| **E10** | 收口后 `ss -lntp \| wc -l` = **79**(= S0 基线)、`nft` = **72**(= 基线);106 = 14 个监听(基线 14 + relay 的 `127.0.0.1:20080`);参数表 §8 已逐条回填(新增 ⑧⑨) | ✅ |
| **E11** | `npm test`(Node 22)= **138 tests / 137 pass / 0 fail / 1 skipped**;双实例面 `本机:20000=401`/`w-106=401`(∈ `PROBE_CODE_SET`);门户 = **200** | ✅ |
| **E12** | 锁 `--release-exec` 已释放;下一棒已登记 automation **并已陈述句告知**;工作区日志已写 | ✅ |

### 8.5 🔴 S7 回头条件(触发与否 + 重算过程 + 重下发 + `OBS-02` 复验)

1. **触发**:`MEM_PER_HOST_MB` 2 → 0.06、`WAN_STEADY_THROUGHPUT` 待测 → 352/12213 ⇒ 命中"实测值替换后必须重算容量"。
2. **重算**:`C_MEM = floor(1002 / 0.06) = 16700` → `C_RELAY = min(16700, 65536) = 16700` → `RELAY_MAX_HOSTS = floor(16700 × 0.45) = 7515`。三条校验重跑,**结论③ 变更**(单台容量即足够)。
3. **重下发(关键坑位)**:主单元 ExecStart **已有显式 `--max-hosts 0`**,**CLI 优先于 `Environment=`** ⇒ 只设 env 会被**静默忽略** ⇒ 两台一律用 **drop-in 重写 ExecStart**:`47-capacity.conf` / (106 同款) → `daemon-reload` → `restart dshs-relay`。
4. **复验**:47 `/status` `"max":7515,"used":2,"free":7513`;106 `/status` `"max":7515`;**`OBS-02` PASS**。
5. **校准方法自纠**:首跑 `R² = 0.4871` 不合格 ⇒ 定性为**单次 RSS 采样噪声** ⇒ 每点改 **7 次采样取中位数** 并补第 6 点(N=150)⇒ `R² = 0.9424`。**首跑结论已作废、未写进参数表**。

### 8.6 第二中继(106)落地 + 切流验证 + 权限影响评估更新版

| 项 | 结果 |
|---|---|
| 落地 | `/opt/dsh-relay/`(build 后 scp)+ 新单元 `dshs-relay`(**只绑 `127.0.0.1:20080`**)+ 节点密钥 `ops/w-106`;**首铺,无旧件** ⇒ §7"记录无旧件"已满足 |
| 443 暴露 | 走 §4.2-2 自决:**复用既有 443**(`location /dshs-relay` 挂在 `include …/extension/106.54.21.172/*.conf` 里 ⇒ 落在既有 server 块**内部**)。实测 **WS 升级握手 = 101**、`/nope` = **404**。**零新增公网口**(安全组未动) |
| seeds 广播 | 47 的 `…-443fb.conf` 把 `https://106.54.21.172/dshs-relay` 追加到 `relays[]` **末位**(不动首位主入口) |
| 切流验证 | **前半绿 / 后半红** —— 详见 §8.8-1(**单外发现,只报告不动手**) |
| 权限影响(§8④ 更新版) | **新增监听口 = 0**(复用 443)|**新增凭据 = 0**(节点密钥落在既有 `/etc/dshs/relay-keys.json`,按 `<net>/<hostId>` 逻辑名索引)|**106 入站 = 0**(worker 永远只拨出)⇒ **R5 结论维持**:暴露面未扩大 |
| 收口清理(S9-3) | 两个临时节点密钥 **已吊销**(`ops/w-dev`、`ops/w-106p`;两台 keys 表 5 → **3 条**,回到基线 `manager`/`w-106`/`w-47`,先备份后原子写、`loadKeysFile` 自校验);探针目录 `/opt/seq6-probe`(47/106)、`/tmp/seq6-*`、106 的 `node-w-106p.*` **均已删**;复核 `pgrep` 零命中 |

### 8.7 不退化(S0 对照 / 双实例面 / 门户 / `npm test`)

| 项 | S0 基线 | 收口 | 判定 |
|---|---|---|---|
| 47 `ss -lntp \| wc -l` | 79 | **79** | ✅ 完全一致 |
| 47 `nft list ruleset \| wc -l` | 72 | **72** | ✅ |
| 门户 | 200 | **200** | ✅ |
| 双实例面 | 200/401 | `本机:20000=401`、`w-106:41775=401` | ✅ ∈ 码集 |
| `npm test`(Node 22) | — | 138 / 137 pass / 0 fail / 1 skip | ✅ |
| `overlay-probe` | 12 行(见 8.1-P8) | **12/12 PASS**(`OBS-02` `OBS-08` `OBS-11` 三红**全部转绿**) | ✅ |
| 47 relay 会话 | `manager` / `w-106` | 同(重启后自动重连,`identityOk=2`) | ✅ |

> **三红转绿的根因(诚实记录)**:`OBS-11`/`OBS-08` 的红**不是泄漏**,是 S1/S8 期间**临时探针会话在 relay 内存里留下的 2 条离线端点**(relay 每个 endpoint 会占 1 个本地监听 ⇒ 79 → 81)。S9 清理 + relay 重启后端点表回到 2 条、监听口回到 79。`OBS-02` 的红是**探针解析坑**(见 8.8-2),修的是**参数表书写**,不是改脚本。

### 8.8 未过项 / 遗留

1. 🔴 **E9 后半(无"失败切流")—— 本单唯一未过项,根因已定位**:客户端把 relay url **在首次解析后钉死** —— `main.js --client` 无重解析;worker 走 `DSHS_RENDEZVOUS_URL` 同样不吃引导链;只有 Manager 的**拨号通道**有周期重解析(`web/server.ts#refreshOverlay`),而它的换址条件是"**目录里的地址变了**",与"当前 relay 挂了"**无关**。⇒ **已做到哪一步**:第二中继本身可用(101 + 容量就绪 + seeds 已广播)、断连自动重连成立(1.2 s)。**什么条件一出现必须回头解决**:要做**多中继负载分担**或**真容灾切换**时,必须先补"连接失败后重解析 + 排除已失败 relay"这段**新功能**。已登记参数表 §9 第 5 行。
2. ⚠️ **`OBS-02` 假红的解析坑(已修,须防复发)**:探针 `KEY_RE` 取参数表**行内整格**并 `cleanValue`(只剥 `*` / 反引号)⇒ 值格里写 `**7515**(原 225)` 会被当成 `7515(原 225)` ⇒ `NaN` ⇒ 假红。**已把夹注挪出值格**,并在参数表该行写明"值格必须是纯数字"。**回头条件**:以后任何键改值,⛔ 别往值格塞夹注。
3. ⚠️ **【留档缺口】P8 的 S0 原始 FAIL 清单未单独留存**(详见 8.1-P8)。已做到哪一步:收口状态 12/12 PASS 有据可查。**回头条件**:下一棒若仍以探针作对照,**开跑即先存一份原始输出**(`> /tmp/xxx.txt`)。
4. ⚠️ **per-stream 内存开销仍未测**(`MEM_PER_HOST_MB` = 0.06 只是空闲会话斜率):已登记参数表 §9 第 6 行。**回头条件**:`--max-hosts` 若重新收紧,必须先有本数。
5. ⚠️ **106 的 `127.0.0.1:40179` 在收口时已不在监听**(P5 快照里有):非本单所留(本单在 106 只碰 `19777/19778/20080`)⇒ 如实登记,未追查,**亦未顺手修**(R7)。
6. ⚠️ **106 的 `systemctl is-active nginx` = `inactive`**:由宝塔(`bt.service`)托管 nginx,**不是退化**;但**任何"用 systemctl 判 106 nginx 死活"的脚本都会误判** ⇒ 记入运维注意。

### 8.9 指纹(本单收口后的可复现核对口径)

- **参数表**(§10 不计入):
  `cd "E:/ProgramData/AI技能/aliyun-dsh-server" && sed '/^## §10 指纹/,$d' 参数表_覆盖网络_20260917.md | md5sum`
  ⇒ **`db1317c2f7aaef7b47785c1f4fc9de03`**(S0 = `f3e68012698abb352549e2560746d992`)
- **本交接单**(**§8 及其后不计入** —— 本值就在 §8 内,含进去即刻失效):
  `cd "E:/ProgramData/AI技能/aliyun-dsh-server" && sed '/^## §8 执行回报(执行棒/,$d' 交接单_最小形态真机批次_20260917.md | md5sum`
  ⇒ **`1edde731eba5034c5f6f3a43864e5a8e`**
- ⚠️ §10 原口径(整文件不计 §10)**无法内嵌数值**(自指),故本单改用上面这条**前缀口径**。

附 A · 规划棒已核实的事实(执行棒不必重复探索)

  1. 🔴 src/ 全仓零 UDP / NAT 穿透代码 —— grep -iE "dgram|createSocket|stun|punch|udp" src/ 的命中全部是 signature / native / alternative 之类假阳性;src/net/relay/directory.ts:404-421 只有 CGNAT 地址判定函数(100.64.0.0/10)。⇒ 本单不测"系统打洞成功率"(§4.1-1)。
  2. 参数表 §7 计数已核:待测 4 个(HOLE_PUNCH_RATE_LOCAL / PER_PLAYER_BW_LOCAL / WAN_STEADY_THROUGHPUT / JITTER_LINK_MEASURED)+ 待校准推导 1 个(MEM_PER_HOST_MB)。
  3. 参数表 §5.2 校验③ 已算出:FLEET_RELAY_DEMAND = 450 > RELAY_MAX_HOSTS = 225 ⇒ ≥2 台中继;225 × 2 = 450 ⇒ 恰好达标、零余量(§4.1-4 要求把这个事实写进表)。
  4. --max-hosts 的落点陷阱:主单元 ExecStart 已有显式 --max-hosts 0,CLI 优先于 Environment= ⇒ 只设 env 会被静默忽略,必须 drop-in 重写 ExecStart(S7-5 已写死)。
  5. 现役只有 1 台中继(47);relay 只绑 127.0.0.1:20080,经 nginx 443 暴露(origin + CF 双路 101)。
  6. relay 的 rttMs 是心跳往返(server.ts:810 注释写明三个作用)⇒ 不一定等于网络 RTT(S3(b) 要求做三方校验)。
  7. JITTER_LIMIT_MS = 20 ms 是估值口径(业界),不是实测 ⇒ 与实测对比时必须标明这一点。
  8. PER_PLAYER_BW_* 三行全部是估值(0.5 / 2–5 / 10–20 KB/s,来源为同一份调研文档)⇒ 本单测的是传输层上限,不是游戏协议需求(S5 已写死边界)。

附 B · 硬约束复述(防走偏)

  • 提问判据:技术实现(怎么造载荷 / 怎么绑 443 / 脚本怎么写 / 样本怎么分布)一律自决;只有 §4.3 一项属真取舍,且执行棒不必等(按倾向 A 开工)。
  • 只做被明确要求的事:执行中发现的其他缺陷(如既有 502 / 引导链问题)先报告,不顺手改。
  • 成本纪律:批量活先写脚本再让脚本跑,⛔ 不把"大范围取证"派给无人值守会话。
  • 红线:R5(权限只准收窄;扩大必须出评估)|R7(不做未授权批量写入;本机是生产的前身)|R11(任一维度净变差即停)。
  • 收口:锁必须释放;下一棒必须登记并用陈述句告知;日志必须写。

§10 指纹

  • 本节口径(推荐核对用,可复现):整个 §10 不计入 ⇒ cd "E:/ProgramData/AI技能/aliyun-dsh-server" && sed '/^## §10 指纹/,$d' 交接单_最小形态真机批次_20260917.md | md5sum ⇒ 见 §8.9 回填。
  • 全文件 md5:请现取(⛔ 本行故意不内嵌数值 —— 包含本节自身,写进去即刻失效)。

§11 补记(2026-09-17 11:1x,在指纹口径之外)

  • ✅ §4.3 的唯一待拍板项已闭环:用户原话「1 本机内存大 可以模拟多台」⇒ 选 D · 本机模拟多台,放弃候选 B(自备设备)与 C(新开云主机)。⭐ 本条覆盖 §4.3 里"才上抛 / 倾向 A+B / 执行棒按 A 开工"的表述。
  • 本机实测:总内存 47.6 GB / 空闲 27.4 GB / 32 核;relay 单实例 ≈ 48 MB ⇒ 可模拟数十台。⚠️ 局限:多实例共用同一出口 IP ⇒ 对"切流逻辑"够用,对"家宽 / 运营商 NAT 差异"无增量(§4.3 里"云主机给不出分层样本"的判断同样适用于本机多实例)。
  • 落到本单:"第 4/5 台"改由本机多实例承担(不再等新真机);§5 样本口径里"若第 4/5 台到位 ⇒ 10 对"按此理解执行。
  • 🔒 本补记位于 §10 之后 ⇒ §8.9 回填的前缀指纹与 §10 口径均不变。