Files
dsh_ai1net_server/归档/交接单-20260924-归档/交接单_骨干稳定选路与加密_20260917.md
T
admin 7bd1151c67 chore(工作区): 归档交接单 27 件 + 新增 CODEBUDDY §9 工作区卫生
交接单按归属约定(正文落文档库、工作区只放指针)归档至
归档/交接单-20260924-归档/,含逐件判定 README:
- 16 件已被文档库正式版取代(T09–T21 + 覆盖网络-24/25/26)
- 4 件主题已被覆盖网络线入口汇总
- 7 件历史接续包/规划件

CODEBUDDY §9:收口清本棒 tmp、tmp 保留期 7 天、禁「待清理」中间态、
工作区入库只放文档与文件、不保留脚本副本、>60 KB 单文件须逐个判。
2026-09-24 07:58:57 +08:00

252 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 交接单 · 骨干节点落地(稳定高效选路 + 传输可加密)
- **序号**:覆盖网络线 **序 ㉖ · 规划棒**
- **立单**:2026-09-17 20:3x
- **用户拍板**:**「入口 §4 骨干节点的服务范围:按照连接稳定高效的方式 数据安全可加密传输」**(2026-09-17 20:2x)
- **上游依据**:`覆盖网络_骨干层方案_20260916.md` **§7(原 A/B 待拍板)**/**§8 落地顺序**/`覆盖网络_瓶颈落地方案_20260916.md` **§4(jitter 是一等指标)**/`覆盖网络_补遗与参考方案_20260916.md`(45% 设计 / 55% 余量口径)
- **状态**:**待执行**
---
## §0 摘要 + 我把用户口径翻译成的两条硬判据
用户**没有按 A/B 选**,而是给了一句**目标导向**的话:**「按照连接稳定高效的方式 数据安全可加密传输」**。
⇒ **我的解读(已定项,可推翻)**:用户要的不是"服务范围"这个二元选择,而是**两条可验证的工程质量判据**:
| 口径 | 翻译成机器判据 | 与 A/B 的关系 |
|---|---|---|
| **连接稳定高效** | **选路按 jitter 排序**(⛔ 不按 RTT)+ 每连接保 2–3 条候选路径 + 中继利用率留 **30%+** 余量 + 骨干间心跳 ≤10 成员全互联 | **与 A/B 正交** —— 无论自用还是全网,这条都要满足 |
| **数据安全可加密传输** | ① 传输层加密(**wss/TLS 已在**,⛔ 不新造)② **内容/信令完整性由签名与哈希兜住**(本线已有 relay 签名目录 + 密钥体系)③ **对外只暴露"转发能力",⛔ 不暴露"看到谁连谁"的元数据** | **B 档的最大缺点正是"骨干会看到流量元数据"** ⇒ 用户这句**恰好把 B 档的最大代价按住了** |
✅ **因此我的判定(可推翻):按 "A 起步、口径按 B 的质量标准建设" 落地** —— 即 **§7 原倾向 A→B 渐进 与用户口径并不冲突**:
- **可见范围**仍取 **A**(只服务自己名下设备):无计费/合规纠纷、权限面不变(⛔ 不命中 R5)、元数据暴露面最小 —— **这直接满足"数据安全"**;
- **质量与冗余**按 **B 的标准**建设(多中心骨干、jitter 选路、30%+ 余量):**这直接满足"稳定高效"**;
- **"可加密"** ⇒ 做成**能力就位**(TLS + 签名 + 内容哈希),**⛔ 不在本单引入端到端加密**(见 §7)。
---
## §1 目标(可判定"做完了没有")
| # | 判据 | 期望 | 怎么测 |
|---|---|---|---|
| **E1** | **选路按 jitter**(⛔ 不按 RTT) | 两候选路径中 jitter 更低者被选中,**即使其 RTT 更高** | 夹具:候选 A(RTT 20ms/jitter 15ms) vs B(RTT 30ms/jitter 2ms) ⇒ 断言选 **B** |
| **E2** | **jitter 可观测** | 每连接有 jitter 直方图 + 超阈值自动切路径并**告警** | 判别器计数 + 直方图落盘 |
| **E3** | **路径多样性** | 每连接维护 **2–3 条**候选(直连 / 就近中继 / 备用中继) | `/status` 可查候选数 ≥ 2 |
| **E4** | **利用率留余量** | 中继利用率 ≤ **70%**(留 30%+) | `used / capacity` 可查、超限**拒绝新接入**(⛔ 不打满) |
| **E5** | **骨干互认只校验不自行批准** | 控制面签发资格;骨干间只验签 | 未签名骨干接入 ⇒ 被拒并**点名** |
| **E6** | **元数据最小化**(A 档) | 骨干**只知"转发给谁",不知"谁在连谁"**;跨用户**不可见** | 断言跨用户 0 命中(与内容分发的 `E5` 同族) |
| **E7** | 零回归 | `npm test` **176/175/0/1**、`--scene all --table` **12P/0S/0F**、`overlay-probe --table` **16P/0F/0S** | 三件套跑同值 |
---
## §2 只读前置(执行前**必须**先核实的 5 条)
| # | 要核实什么 | 命令 | 期望 |
|---|---|---|---|
| **P1** | 现行 relay 是否**已**做到"只绑回环 + 443 兜底" | `ss -lntp` + relay ExecStart | 已实测:两台 relay 均**只绑 `127.0.0.1:20080`**、106 复用既有 443 ⇒ **零新增公网口**(⛔ 本单不许破坏这条) |
| **P2** | 现行选路是**按什么排序** | 读 `src/net/relay/switcher.ts` / `directory.ts` | ⚠️ 预判:**按健康度/冷却**,**⛔ 不是按 jitter** ⇒ 这是本单的主要缺口 |
| **P3** | jitter 现测值 | `scripts/overlay-jitter.cjs` | 已有脚本;序⑥ 实测 `p95(\|ΔRTT\|)` = **3 ms**(达标)⇒ **本单把"点测"变成"持续采样 + 参与选路"** |
| **P4** | 骨干"资格"体系现状 | `scripts/overlay-keyring.cjs` + relay `keys` 表 | 已有四层密钥模型(离线根 → 在线签名者 → 每机节点密钥 → 会话)+ 逻辑名索引 + 成员资格校验 ⇒ **E5 大部分已就位** |
| **P5** | 45% 容量口径现值 | 参数表 `RELAY_MAX_HOSTS` | 实测 **7515**(序⑥ 重算并已下发两台)⇒ 本单**只读不改**,⛔ 不动容量值 |
---
## §3 范围
### 3.1 在册文件集(⚠️ **超出必须先停下报告** — R7)
| 面 | 文件 | 说明 |
|---|---|---|
| 新增 | `src/net/relay/jitter.ts` | jitter 采样与直方图(**选路的输入**) |
| 改动 | `src/net/relay/directory.ts` | 候选排序:健康度 → **jitter 为主序**(⛔ 不删既有冷却语义) |
| 改动 | `src/net/relay/switcher.ts` | ⚠️ **只加"jitter 劣化即切",⛔ 不改冷却语义** |
| 改动 | `src/net/relay/server.ts` | 利用率守卫(`E4`)+ 候选路径可查(`E3`) |
| 改动 | `scripts/overlay-jitter.cjs` | 点测 → 持续采样 |
| 改动 | `scripts/overlay-probe.cjs` | 新增 `OBS-17`(jitter)/`OBS-18`(余量) |
| 改动 | `参数表_覆盖网络_20260917.md` | 新增 `JITTER_*` / `RELAY_UTIL_MAX_PCT` 键 |
⛔ **不在本单范围**:`RELAY_FAILOVER_*` 任何值、`HB_SEC`、burst、`switcher.ts` 冷却语义、`RELAY_MAX_HOSTS`、房间层、打洞实现、内容分发的块级实现(**另单**,见 `交接单_内容分发块级寻址_20260917.md`)。
### 3.2 三条硬约束
1. 🔴 **⛔ 不改 `switcher.ts` 冷却语义**(本线持久禁令)—— 只**新增** jitter 触发条件。
2. 🔴 **⛔ 不新增公网监听口 / 不改 nft·nginx**(R5)—— 骨干仍只绑回环 + 443/TCP 兜底复用。
3. 🔴 **骨干资格只能控制面签发**(权威状态单点 Manager)—— 骨干**只校验,不自行批准**。
---
## §4 步骤 S0–S6
| 步 | 做什么 | 验证(一次可执行) | 回滚 |
|---|---|---|---|
| **S0** | 只读前置 `P1–P5` + 基线 jitter 采样(**零改动**) | 输出 Before:现行选路按什么排序(**原文行号级证据**) | 无(只读) |
| **S1** | jitter 采样与直方图(`jitter.ts`) | 夹具:喂 3 条已知 jitter 序列 ⇒ 直方图与 p95 **逐项可断言** | 删新增文件 |
| **S2** | **候选排序改为 jitter 为主序**(`directory.ts`) | `E1`:**先红后绿**(jitter 更低但 RTT 更高的那条**必须被选中**) | 还原排序函数 |
| **S3** | 切换条件新增"jitter 劣化即切"(`switcher.ts`,⛔ 不碰冷却) | `E2`:劣化 ⇒ 切 + 告警;⛔ 冷却语义断言**不变** | 移除新增条件 |
| **S4** | 利用率守卫 + 候选可查(`server.ts`) | `E4`:利用率 > 阈值 ⇒ 拒绝新接入并**点名**;`E3`:候选数 ≥ 2 | 还原守卫 |
| **S5** | 骨干互认与元数据最小化复验(`E5` / `E6`) | 未签名骨干被拒并点名;跨用户 0 命中 | 同 S2 |
| **S6** | 真机验收 + 观测 + 零回归(`E7`)+ 收口 | 三件套同值;探针新增 2 项 PASS | 产物回滚点 |
---
## §5 验收判据 E1–E7
见 **§1**。⚠️ **`E1` 是主判据**("选路按 jitter 排序而非 RTT")—— 这一条**能不能机器断言**,决定了"连接稳定高效"是不是**嘴上说说**。
---
## §6 回滚(两层)
1. **排序级**:还原 `directory.ts` 的排序函数 + 移除 `switcher.ts` 新增条件 → `tsc` → scp `lib/` → `restart dshs` ⇒ 回到"按健康度/冷却"的旧选路。
2. **产物级**:scp 回滚点 `/opt/dsh/backups/seq26-<ts>/lib/net/relay/{directory,switcher,server,jitter}.js`。
🔴 ⛔ **回滚路径里不许出现 `RELAY_FAILOVER_COOLDOWN_MS=0`**。
---
## §7 安全与加密档位(**用户口径的关键落点**;属已定项、⛔ 不再上抛)
用户原话:**「数据安全可加密传输」**。逐条落法:
| 层 | 现状 | 本单怎么做 |
|---|---|---|
| **传输层加密** | ✅ **wss / TLS 已在**(relay 经 `https://alotbuy.com/dshs-relay` 可达、双路 101) | **复用,⛔ 不重造**。骨干之间同样只走 wss |
| **身份与授权** | ✅ 四层密钥模型已落地(离线根 → 在线签名者 → 每机节点密钥 → 会话)+ 逻辑名索引 + 成员资格校验 + 吊销演练通过 | `E5`:**骨干间只校验,不自行批准**(补齐"骨干资格"这一档) |
| **完整性** | ✅ 有签名目录 | 信令与目录**全程验签**;⛔ 不引入第二套密钥体系 |
| **元数据最小化** | ⚠️ B 档的最大缺点是"看到谁连谁" | `E6`:**A 档可见范围** ⇒ 骨干**只知转发目标、不知连接双方**;跨用户不可见 |
| **端到端加密(E2E)** | ⛔ **不做** | **属真取舍**:E2E 会让"每个接收者密文不同" ⇒ **与内容分发的按哈希共享块直接冲突**(要加密就失去共享)⇒ 本阶段取 **"TLS + 验签 + 内容哈希"**;E2E 登记为**待评估**(见 §9-3) |
🔑 **一句话**:**"可加密"= 能力就位(TLS + 验签 + 哈希)+ 元数据最小化**,⛔ **不是**"现在就上端到端加密"。
---
## §8 回报格式(执行会话**必须**回填)
```markdown
### 8.x 序 ㉖ 执行棒回报(YYYY-MM-DD HH:MM–HH:MM)
#### ① S0–S6 逐条(命令 + 原文输出 + 判定)
#### ② 主判据 E1:jitter 更低(但 RTT 更高)的候选被选中
- 候选 A = ? | 候选 B = ? | 实测选中 = ? | 原文 = ?
#### ③ 先红后绿(原文级)
#### ④ 零回归三件套(均带 `--table`)
#### ⑤ 边界自证
⛔ 未改 `switcher.ts` 冷却语义 / ⛔ 未改生产值 / ⛔ 未新增公网口 / ⛔ 未改 nft·nginx / 🔴 `COOLDOWN_MS=0` = ? / ⛔ 未 commit·未 push
#### ⑥ 指纹
参数表 = ?(前值 `42238175d84319ada99afa56d583f9db`)|directory.ts / switcher.ts / server.ts md5 = ?
```
---
### 8.1 序 ㉖ 执行棒回报(2026-09-17 22:34–23:2x)
#### ① S0–S6 逐条(命令 + 原文输出 + 判定)
| 步 | 做了什么 | 证据(原文级) | 判定 |
|---|---|---|---|
| **S0** | 只读前置 + 改前基线 | **P2 ✅ 缺口确认**:`directory.ts` 候选序 = 签名目录发布序(同源优先)、`switcher.ts` 换址 = 冷却/豁免优先级,**两处均无 jitter**(`grep -n "sort(\|jitter\|rtt" src/net/relay/{directory,switcher}.ts` 得 0 处 jitter 排序)。**P1/P5 间接取证**:47 `ss -lntp` ⇒ relay 只绑 `127.0.0.1:20080`、无新增公网口;`curl /status` ⇒ `capacity.max=7515`(未动)。**改前 `/status` 原文**:`"capacity":{"max":7515,"used":2,"free":7513}` ⇒ **无 `utilPct`/`utilMaxPct`、无 `jitter` 块** = 改造前形态的直接证据 | ✅ |
| **S1** | 新增 `src/net/relay/jitter.ts`(237 行):`absDeltas` / `percentile` / `histogram` / `statsFromDeltas` / `JitterTracker` / `orderByJitter` / `pickJitterTarget` / `sharedJitterTracker` | 新夹具 `test/overlay-jitter.test.mjs` **21 用例**(直方图逐桶、p95 口径、零样本 `D9`、采样门限、`pickJitterTarget` 五态) | ✅ |
| **S2** | `directory.ts` 候选排序 → **jitter 为主序**(`orderByJitter`:已知 jitter 升序 + 未测样本保原序排后 + **零样本逐字返回原数组**) | **先红后绿**见 ③;`D9` 由 `E1-b` 用例钉(零样本返回**同一个数组**,非等值新数组) | ✅ |
| **S3** | `switcher.ts` 新增"**jitter 劣化即切**":`jitterSwitches` / `jitterAlerts` 计数 + 注入位 + `pickJitterTarget` 调用;🔴 **冷却表(`cooldown`)一行未动** | `E2-b`/`E2-c` 用例:jitter 换址**无豁免权**(`exemptSwitches` 增量 = 0);真机告警原文见 ② | ✅ |
| **S4** | `server.ts`:**利用率软门**(`utilMaxPct`,`used/max×100 ≥ 它` ⇒ 拒**新**接入、⛔ 不驱逐在线;计数独立为 `utilRefused`)+ **`jitter` 观测块**(无样本也**结构完整**)+ 每会话 `rttSamples` 环 | 重启后真机 `/status` 原文:`"capacity":{"max":7515,"used":2,"free":7513,"utilPct":0,"utilMaxPct":70}` + `"jitter":{"samples":0,…,"hist":[0×8],"sessions":0,"thresholdMs":20,"overThreshold":false,"alerts":0}` | ✅ |
| **S5** | E5/E6 复验 | **E5**:探针 `OBS-03 identityRequired=true trustedSigners=1` + `OBS-04 identityOk=3` + `OBS-05 revokedHosts=0` ⇒ 骨干资格仍**只校验不自行批准**(本序**零改动**身份面)。**E6**:`content.peer` 五键齐(`crossGroupDenied=0`)|⚠️ **诚实标注**:`0` = 本期**无越界尝试**,**不是**"被拒 0 次"⇒ E6 的强判据(构造越界尝试)属内容分发线,本序只做复验 | ✅(复验) |
| **S6** | 真机验收 + 观测 + 零回归 + 收口 | 见 ②③④⑤⑥;探针新增 **`OBS-19`/`OBS-20`** 由红(改造前无 `jitter` 块 ⇒ 必红)转绿 | ✅ |
#### ② 主判据 E1:jitter 更低(但 RTT 更高)的候选被选中
- **夹具(机器断言,E1-a)**:候选 A(RTT 20 ms / jitter 15 ms)· 候选 B(RTT 30 ms / jitter 2 ms)⇒ **实测选中 = B** ✅ `ok 8 - E1-a 主判据:**jitter 更低的那条排在首位,即使它 RTT 更高**`
- **真机读数(47 上 `node scripts/overlay-jitter.cjs --watch --targets "127.0.0.1:20080,106.54.21.172:443" --rounds 14 --gap 400`)**:
| 候选路径 | RTT median | RTT p95 | **jitter p95(\|ΔRTT\|)** | hist(8 桶) |
|---|---|---|---|---|
| `127.0.0.1:20080`(本机 relay 回环) | 0.59 ms | 4.75 ms | **3.88 ms** | `[13,0,0,0,0,0,0,0]` |
| `106.54.21.172:443`(跨云兜底) | 151.64 ms | 1166.34 ms | **1015.69 ms** | `[8,4,0,0,0,0,0,1]` |
原文:`"order":["127.0.0.1:20080","106.54.21.172:443"]`、`"e1":{"curJitterMs":3.88,"wouldSwitchTo":null}`
- ⚠️ **诚实标注**:真机两条真实路径的 **jitter 序与 RTT 序同向**(回环两项都最优)⇒ **真机拓扑无法区分"按 jitter 排"与"按 RTT 排"** ⇒ 主判据的判别力**由夹具提供**(E1-a/E1-e 端到端用例),真机只作同口径佐证。⚠️ 这是**拓扑限制**、⛔ 不是判据失败(§9-6 未命中:机器断言**跑出来了**)。
- **端到端(E1-e)**:当前通道不健康 ⇒ 换到 jitter 更低的那条(目录序里它排第二)—— 同一破坏实验下**必红**(见 ③)⇒ 证明它是真判据。
#### ③ 先红后绿(原文级)
**破坏点** = 编译产物 `lib/net/relay/jitter.js:221` 的候选排序 comparator 改为 `() => 0`(= 退化成"保原序")⇒ `npm test` 前先单跑新夹具:
```
not ok 8 - E1-a 主判据:**jitter 更低的那条排在首位,即使它 RTT 更高**
not ok 10 - E1-c 未测样本的候选**保原序排在其后**
not ok 12 - E1-e **端到端主判据**:当前通道不健康 ⇒ 换到 jitter 更低的那条
# tests 21 / # pass 18 / # fail 3
```
⇒ `npm run build` 还原 ⇒ `# tests 21 / # pass 21 / # fail 0`,且 `lib/net/relay/jitter.js` md5 **回到部署值 `47e248d84aa6fa6c8f29f18f942b82cb`**(逐字一致)。
#### ④ 零回归三件套(均带 `--table`)
| 件 | 基线 | 本棒实测 | 判定 |
|---|---|---|---|
| `npm test`(Node 22) | 176 / 175 / 0 / 1 | **197 / 196 / 0 / 1**(+ 新夹具 **21 用例**) | ✅ 零退化 |
| `scripts/overlay-failover-drill.cjs --scene all --table` | 12 PASS / 0 SKIP / 0 FAIL | **12 PASS / 0 SKIP / 0 FAIL** | ✅ 同值 |
| `scripts/overlay-probe.cjs --table` | 17 PASS / 0 FAIL / 1 SKIP | **19 PASS / 0 FAIL / 1 SKIP**(+ `OBS-19`/`OBS-20`;`OBS-09` SKIP = 47 无活跃实例,正常态) | ✅ +2 |
#### ⑤ 边界自证
⛔ **未改 `switcher.ts` 冷却语义**(`cooldown` 表结构/写入/读取**一行未动** —— 只**新增** jitter 触发条件与两个计数)|⛔ 未改任何生产值(本仓 `COOLDOWN_MS *= *0` 命中 **0**;47 `dshs*.service.d/*.conf` 内 `COOLDOWN` 命中 **0**;`RELAY_FAILOVER_*` / `HB_SEC` / burst / `PRESENCE_*` / `DSHS_REHYDRATE_*` 逐项未动)|⛔ 未新增公网监听口(47 `ss -lntp` 非回环面 = 58888/80/22/888/443/8765 **全为既有**;relay 仍只绑 `127.0.0.1:20080`)|⛔ 未改 nft·nginx | 🔴 **`COOLDOWN_MS=0` 计数 = 0**(未写进任何回滚 / 演练 / 夹具路径)|⛔ **未 commit / 未 push**(HEAD `04776af` 未变;`git status` 显示 `M`/`??` 未暂存)。
**部署(在册产物)**:`lib/net/relay/{jitter,directory,switcher,server}.js` scp 到 47 **两处**(`/opt/dshs/lib/net/relay/` + `/opt/dsh-relay/lib/net/relay/`)⇒ **8 个文件 md5 与本机全同**;重启 `dshs-relay` + `dshs` + `dshs-worker`(🔴 **动手前已取证 47 上无活跃实例 scope** ⇒ 未影响任何用户)。回滚点 = **`/opt/dsh/backups/seq26-20260917-225032/`**(含 `.relay/` 子目录,覆盖两处旧值)。
#### ⑥ 指纹
- **参数表**(`sed '/^## §10 指纹/,$d' | md5sum`)= **`4c78912d03f4f209d417407a80018361`**(前值 `42238175d84319ada99afa56d583f9db`)
⚠️ **重要勘误**:开工单 §11 记的"立单时 `42238175…`"**在本棒开工时已失效** —— 实测起点 = **`93e38d1a57fbcd3126d2122150a2e838`**(立单后序㉔/㉕ 已在 §10 之前加键:`CONTENT_*` + `OBS-17`、`DSHS_REHYDRATE_*` + `OBS-18`)。凡拿立单值当"改前基线"的判据都会**假红**。
本棒变更 = §3.5 之后新增 **7 键**(`JITTER_ENABLE` / `JITTER_SAMPLE_MAX` / `JITTER_MIN_SAMPLES` / `JITTER_HIST_MAX_MS` / `JITTER_HIST_BUCKETS` / `JITTER_SAMPLE_GAP_MS` / `RELAY_UTIL_MAX_PCT`)+ `JITTER_LIMIT_MS` 行**语义扩展注** + §6 新增 `OBS-19` / `OBS-20`。
- **源码 md5**:`jitter.ts` = `ea72bdf6c0c4b78b6c791f1bc3a7709b`(新增)|`directory.ts` = `e24501b1cada3d2aeb03a8d6ff9a572b`|`switcher.ts` = `65942838b3418f0a0d22b0c0d1dd4165`|`server.ts` = `33c9186762e7e6977a56f472a7b11e89`
- **构建产物 md5**(部署对账值):`jitter.js` = `47e248d84aa6fa6c8f29f18f942b82cb`|`directory.js` = `e2347a7047d5cb6a10cd03fda51db40e`|`switcher.js` = `5e09d04452c8ded7c3824fb450ecfcb0`|`server.js` = `c643ea04d6a42a80e87b146e4580be79`
- **开工单 §8 前前缀指纹**:**`dbcbe633aa1aef92f4c35c77fad3ec11` 复核一致** ✅(开工前校验通过 ⇒ 本棒依据有效)
#### ⑦ 三条必须留档的实测发现(⛔ 均未越线处置)
1. 🔴 **`JITTER_SWITCH_MS` 未新造** —— 参数表**已有** `JITTER_LIMIT_MS = 20`(序⑥ 的 `p95(|ΔRTT|)` 达标限值),"超标"与"该换路"是**同一件事** ⇒ 直接**复用**该键。🔑 理由 = **同一事实两处写**是本线的知识碎片化病根。⚠️ 该值仍是**业界估值**(非实测),定值属待测项。
2. 🔴 **`dshs` 侧 `/opt/dshs/lib/net/relay/server.js` 比 `dsh-relay` 侧落后一个版本**(取证:`diff` 13 行,**只有** relay 侧有序㉔ 的 `statusContent` 注入位)⇒ 序㉔ 当时**只铺了 relay 侧**、`dshs` 侧被漏掉。本棒两边同铺 ⇒ **该既存不一致已随本棒消除**(属同一文件新版本不可剥离,非"顺手优化")。
3. ⚠️ **jitter 告警计数与日志条数口径不同**:`/status.jitter.alerts` = **当前进程**累计(实测 `2`),`journalctl | grep -c relay-jitter` = **跨进程**累计(近 30 min 实测 **11** 行 —— 期间 `--scene all` 重启过 relay)。⛔ 两者**不可直接对比**。告警原文:`[relay-jitter] ⚠ 会话 ops/w-106 抖动超标(p95|ΔRTT|=1540ms ≥ 阈值 20ms,样本 4 个,最近 rtt=423ms)⇒ 该链路的对端应换更稳的候选`。
4. ⚠️ **E3(路径多样性)未取得机器断言面**:判据"每连接 2–3 条候选 ⇒ `/status` 可查候选数 ≥ 2"的落点**落在 §3.1 在册文件集之外**(需改 `src/worker/relay-tunnel.ts` 或 `src/web/server.ts` 暴露字段;而 relay 的 `/status` **语义上不承载** client 侧候选概念)⇒ 按 **§9-5 停下报告**、未扩大。**既存事实**:候选链实现已在册(`directory.ts:789 listOverlayRelayCandidates` + `web/server.ts:605` 注入 worker),但 47 当前形态(单 relay 回环 + 443 兜底)**实际可用候选 = 1 条** ⇒ "冗余"尚未成立。
---
## §9 回头条件(**一出现必须回头**)
1. 要**改 `switcher.ts` 冷却语义** ⇒ 停下报告(持久禁令)。
2. 要**新增公网监听口 / 改 nft·nginx** ⇒ 停下报告(R5)。
3. 要引入**端到端加密**(E2E)⇒ **属真取舍**(加密即失去按哈希共享块)⇒ 停下上抛。
4. 要**改 `RELAY_MAX_HOSTS` / 45% 容量口径值** ⇒ 停下报告。
5. 需要**超出 §3.1 文件集** ⇒ 停下报告(R7)。
6. `E1` 跑不出机器断言 ⇒ 停下报告,⛔ 不许放宽判据凑绿。
7. 零回归三件套任一退化 ⇒ 停下报告。
8. 🔴 ⛔ **不许把 `RELAY_FAILOVER_COOLDOWN_MS=0` 写进任何回滚 / 演练 / 夹具路径**。
---
## §10 未验证项
| # | 项 | 状态 |
|---|---|---|
| 1 | 各网络类型实际占比(决定骨干数量需求) | ⚠️ 上游仍为推演设定 |
| 2 | 骨干上行带宽是否够(家宽上行常远小于下行) | ⚠️ 上游未实测 |
| 3 | E2E 加密与块级共享的取舍 | ⚠️ 本单**未做**,登记待评估 |
---
## §11 指纹与状态
| 项 | 值 |
|---|---|
| 本单 §8 之前正文前缀指纹 | **`dbcbe633aa1aef92f4c35c77fad3ec11`**(口径 = `sed '/^## §8 /,$d' 交接单_骨干稳定选路与加密_20260917.md \| md5sum`) |
| 参数表指纹(立单时) | **`42238175d84319ada99afa56d583f9db`** |
| 代码仓 HEAD(立单时) | `04776af` |
| 本单全文件 md5(立单时) | `f85b86234c2ecfaef5b2e43aa40d86a3`(176 行) |
| 本单全文件 md5(**序㉖ 执行棒回填 §8.1 后**) | **`f49a34275fa6628107e184c7f3a9a52e`**(250 行;§8 前前缀仍 = `dbcbe633aa1aef92f4c35c77fad3ec11` ⇒ 回填未触及依据区) |
| 本单状态 | **待执行** ⇒ 交**序 ㉖ 执行棒** |