- 变更规模:新增 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/ 知识文件,按口径入库)
45 KiB
交接单 · 在册收尾(Q5 + mksess 文档口径 + 技能三处同步 + 幕 4-A 临界项)(2026-09-17)
本单来源:序 ⑯ 规划棒(automation
91c53ef8-c3f0-4bb3-9f0a-943790178176,2026-09-17 16:36 起)。 本单定位:执行单(8 段模板,可直接开工)。把「会合 / 中继拆分复核结论」+「剩余在册项定序」合并为一个执行棒 = 序 ⑰。 本棒只出规划:⛔ 未改任何代码、⛔ 未动 47 / 106、⛔ 未 commit / push;全部取证 = 只读命令(详见 §0.2)。
§0 结论先行
0.1 复核结论(二选一 ⇒ 判「不做」)
「会合 / 中继从 Manager 拆分」—— 判「不做」。原方案
会合中继拆分_取证与改造方案_20260916.mdS0–S4 的四个耦合点(C1–C4)与两个改造步骤(S3 / S4)已逐条被后续序次覆盖,未覆盖部分 = 无。
| 靶子 | 原方案描述 | 现状证据(只读取证) | 判定 |
|---|---|---|---|
| C1 | 会合地址硬编码在 Worker 的 env(DSHS_TUNNEL_TARGET 写死在 switch-C-worker.sh + /etc/dshs-worker.env) |
src/config.ts:485-490:DSHS_RENDEZVOUS_URL 优先、DSHS_TUNNEL_TARGET 降为兜底(注释原文:「覆盖网络 S1:会合地址出 env」);src/worker/agent.ts:158、src/worker/tunnel.ts:16 同口径 |
✅ 已被 序② P0-2(引导三级链) 覆盖 |
| C2 | 中继落点 = Manager 的 loopback + 两端同号 ⇒ 第三台机器无法直达、中继不可多实例 | src/config.ts:498-500:DSHS_RELAY_DIAL_PORT_BASE=25000 / SPAN=1000 / POOL=64 ⇒ 落点在 Manager 自己本机的回环池;src/net/relay/dialer.ts:11 注释「Manager 也像 worker 一样只拨出一条 wss(RelayClient 的 dialer 模式)」 |
✅ 已被 R5(会合可换机) 覆盖 —— 这就是题面给的已知事实 |
| C3 | 可达性登记把「经谁中转」磨掉了(dsh_hosts.endpoint 语义 ≠ worker 地址) |
src/net/rendezvous.ts:103-106「按 via 选实现的注册表」+ Reachability.via(:27 / :65 / :98);src/supervisor/remote-spawner.ts:21-48 取址一律走 agentBaseUrlOf() |
✅ 已被 S2 / P2(dsh_hosts.via 列) 覆盖 |
| C4 | 控制面 PG 也走同一条隧道 ⇒ 回滚面含 DB | 方案 §8.1 实测:106 与 47 的 worker env 都没有 DSHS_TUNNEL_STATIC_PORTS ⇒ C4 前提不成立 |
✅ 前提不成立,无需处理 |
| S0 | 抽 Reachability / Rendezvous 接口 |
src/net/reachability.ts(agentBaseUrlOf() = 全仓唯一取址入口,:99)+ src/net/rendezvous.ts 均在册 |
✅ 已落地 |
| S1 | 会合地址出 env | 同 C1 行 | ✅ 已落地 |
| S2 | dsh_hosts 增 via 列 |
同 C3 行 | ✅ 已落地 |
| S3 | 中继落点命名空间可配(回环别名 127.0.0.2…) |
方案 §9.1 实测 gatewayports no ⇒ 别名方案证伪;已改「实例端口区间隔离」(w-47 20000+ / w-106 21000+)⇒ 连「两端同号」这个前提都没了 |
✅ 原设计已作废且被更强做法替代 |
| S4 | 中继独立成单元 + 会合可换机 + 多实例 | dshs-relay 独立 systemd 单元已常驻两台(47 / 106,只绑回环 20080);序⑥ S8 把 106 升格为第二中继;序⑦ 切流演练「杀 47 ⇒ 切到 106」实测通过;sshd 反向隧道已下线且不可能重建 |
✅ 已被 R2 / 序⑥ S8 / 序⑦ / 序④ 覆盖 |
⇒ 处置:在 会合中继拆分_取证与改造方案_20260916.md 头部加一行状态标注(已由 R5 + 序②/②P3/④/⑥S8/⑦ 覆盖 ⇒ 仅存档,⛔ 勿再按 S0–S4 开工),正文⛔ 不改(历史档案属性)。
⚠️ 顺带登记一条观察项(⛔ 本单不处置):SSH 隧道代码路径 src/worker/tunnel.ts 现已是生产死路径(47 同机不建隧道、106 走 wss:// relay),是否删除 = 独立决策(可能保留作 ssh 兜底变体)⇒ 只登记,不定序。
0.2 本棒取证(只读,共 3 条命令族;⛔ 未连任何池口、未动 47/106 配置)
| # | 命令(cwd = 代码仓 D:/github/dsh_shenxian) |
关键输出 |
|---|---|---|
| 1 | grep -rn "DSHS_TUNNEL_TARGET|32022" --include=*.ts src + grep -rn "DSHS_RENDEZVOUS_URL" --include=*.ts src |
C1 现状(config.ts:485-490 新变量优先 / 旧变量兜底) |
| 2 | grep -rn "via" src/net/rendezvous.ts + grep -rn "25000|dialer" src/net/relay/dialer.ts + grep -rn "DSHS_RELAY_DIAL" src/config.ts |
C2 / C3 现状(拨号池 25000..26000、Manager 只拨出) |
| 3 | find src test scripts -name "*.bak-*" + git ls-files src/net/relay | wc -l + git ls-files --error-unmatch <bak> |
Q5 真实范围 5 个(非 3 个);src/net/relay tracked = 0(Q4 自证) |
0.3 剩余在册项定序(→ 本单 §5 的 S1–S4)
| 序 | 项 | 类型 | 为什么排在这个位置 |
|---|---|---|---|
| S1 | mksess 文档口径(「DB 直插」→「PG 直插」) | 文档(操作性载体) | 必须最先:它改 skills/** 正文,而 S2 的镜像同步要把 S1 的产物一起带上 ⇒ 二者共用一次 scp(硬顺序) |
| S2 | 技能 dsh-auto-handoff-chain 三处同步 |
文档 + 镜像 | 紧随 S1(同属 skills/** 面、共用一次 scp);且它是自动接续链路的载体 ⇒ 直接影响本线后续每一棒的可复现性 |
| S3 | Q5:.bak-seq7-* 残留清理(范围修正 = 5 个) |
清理(零服务副作用) | 与 S1/S2 无依赖,但同属「零服务副作用批」⇒ 合在文档批一起做,省一次抢锁 |
| S4 | §8.8-2 临界项:幕 4-A 耗时贴近 deadline | 演练采样(唯一有副作用项) | 放最后:它会把 Manager 通道挪来挪去(幕 4)⇒ 前面三条全部完成后再动,收尾 restart dshs 归零不影响已完成工作 |
排序一句话:S1 → S2(硬依赖,共用一次镜像同步)→ S3(零风险清理,同批)→ S4(唯一动服务的一项,置末)。
0.4 ⛔ 本单不写进执行范围的项(只登记)
| 项 | 登记内容 |
|---|---|
| Q4 | 代码仓 src/net/relay/** untracked(实测 git ls-files src/net/relay | wc -l = 0)⇒ 序⑭/⑮ 的修复与 test/relay.test.mjs 只存在于工作区、不在版本库。卡在「commit / push 授权」,属待用户拍板 ⇒ ⛔ 本单不执行、⛔ 执行棒也不得动,只报告。 |
| presence / 房间层 / 内容分发定序 | 属「业务优先级」(§1 边界外 ①)⇒ ⛔ 本单不定序;候选与优缺点登记见 §3.3。 |
| 骨干节点服务范围 | 入口 §4 既有待拍板项(A 只服务自己名下设备 / B 服务全网)⇒ 原样保留,本单不重复上抛。 |
§1 目标
一次执行棒把四条在册项收干,全部满足「零生产值改动 + 可秒级回滚」:
- mksess 口径对齐实现 —— 文档库 / 技能 / 镜像里对
/opt/dshs/mksess{,−guest}.cjs的「DB 直插(SQLite 旧库)」描述已过期(序⑬ Q1 实测已改 PG)⇒ 改成与实现一致的描述,避免 R4 验收手段被误述。 - 技能
dsh-auto-handoff-chain的「三处同步」从「从未建立」变为「已建立」 —— 现在文档库无副本(实测 ❌)。 - 清掉代码仓
.bak-seq7-*残留 —— 立起「.bak只在执行期存在」这条规矩(序⑫ 已以身作则、仓内.bak= 0,但代码仓仍有 5 个历史快照)。 - 给「幕 4-A 耗时贴近 deadline」这条临界项落一个判据(三档递进),并采 5 个样本自证是否仍临界。
非目标:⛔ 不 commit / 不 push(Q4 未授权);⛔ 不改任何生产值(RELAY_FAILOVER_* / HB_SEC / burst);⛔ 不做打洞、不改 worker 拨出方向、不重做任何已收官序。
§2 只读前置(S0 必须先核实;任一条不符 ⇒ 停下报告,⛔ 不硬闯)
| # | 核实项 | 命令(cwd 见括注) |
期望(本单规划时的实测值) |
|---|---|---|---|
| P1 | 锁空闲 | bash dsh-server-docs/scripts/handoff-guard.sh |
报「空闲」;抢锁后再开工(抢不到 = 有会话在跑 ⇒ 停手报告) |
| P2 | 代码仓基线未漂移 | cd D:/github/dsh_shenxian && git rev-parse --short HEAD && git status --porcelain | wc -l |
HEAD = 640813e;总数 = 43(17 M + 3 ?? + 余) |
| P3 | .bak 真实范围 |
cd D:/github/dsh_shenxian && find src test scripts -name "*.bak-*" |
5 个:src/net/relay/{client,directory,main}.ts.bak-seq7-20260917-112114 + src/web/server.ts.bak-seq7-20260917-112114 + src/worker/tunnel.ts.bak-seq7-20260917-112114(⚠️ 均 untracked,实测 git ls-files --error-unmatch 报 pathspec 不匹配) |
| P4 | Q4 自证(⛔ 只记录) | cd D:/github/dsh_shenxian && git ls-files src/net/relay | wc -l |
0(untracked 缺口仍在 ⇒ 本棒 ⛔ 不得 commit) |
| P5 | mksess 命中面 | cd D:/github/dsh_shenxian && grep -rn "mksess" dsh-server-docs/ | grep -iE "sqlite|直插|dshs\.db|旧库" |
命中 4 行:04-调整方案/77-…md:97(档案,⛔ 不改)、skills/dsh-change-workflow/SKILL.md:146/395/495、skills/dsh-env-bootstrap/references/常驻规则-快照.md:55 |
| P6 | 技能三处现状 | ls -d "E:/ProgramData/.workbuddy/skills/dsh-auto-handoff-chain" + ls -d D:/github/dsh_shenxian/dsh-server-docs/skills/dsh-auto-handoff-chain |
① 本机 ✅ 存在;② 文档库 ❌ 不存在(与在册项一致);③ 镜像(47 /opt/dsh/docs/skills/)待现取 |
| P7 | 基线回归值 | 见 §6-E6 | npm test = 162 / 161 pass / 0 fail / 1 skip;--scene all = 12 PASS / 0 SKIP / 0 FAIL;overlay-probe --table "…/参数表_覆盖网络_20260917.md" = 12/12 · rc=0 |
⚠️ ssh 一律显式 -p 22(别名 bt-server 的 32022 是失效残留口);取证落盘一律 2>/dev/null(ssh 的 PQ 告警会污染行数判据);106 的 ssh 偶发 rc=255(MaxStartups 限流)⇒ 容许单次重试,⛔ 不放宽限流(命中 R5)。
§3 范围
3.1 改哪些(三处文档面 + 一处代码仓清理)
| 面 | 具体对象 | 动作 |
|---|---|---|
| 文档库(代码仓内) | dsh-server-docs/skills/dsh-change-workflow/SKILL.md(3 行)、dsh-server-docs/skills/dsh-env-bootstrap/references/常驻规则-快照.md(1 行)、dsh-server-docs/02-运维手册.md(命中处) |
口径校正 |
| 文档库(新增) | dsh-server-docs/skills/dsh-auto-handoff-chain/(新建目录)+ skills/README.md / skills/INDEX.md 登记 |
新建 + 登记 |
| 本机技能 | E:\ProgramData\.workbuddy\skills\**(命中 10 行) |
口径校正(与文档库同内容) |
| 镜像 | 47 /opt/dsh/docs/skills/** |
scp 同步(S1 + S2 产物 一次上) |
| 代码仓 | src/{net/relay/web/worker}/*.bak-seq7-20260917-112114(5 个) |
删除 |
| 观测口径 | 参数表_覆盖网络_20260917.md §6(仅在 S4 判据落地时) |
新增余量判据(⚠️ 会改参数表指纹 ⇒ 必须在 §8.9 记录变更前后值) |
3.2 ⛔ 明确不做
- ⛔ 不 commit / 不 push(Q4 未授权 ⇒ 本棒零提交动作,含"顺手提交
.bak删除"也不行); - ⛔ 不改任何生产值:
RELAY_FAILOVER_*/HB_SEC/ burst / deadline; - 🔴 ⛔ 不许把
RELAY_FAILOVER_COOLDOWN_MS=0写进任何回滚 / 演练 / 夹具路径(看似合法、实际自锁); - ⛔ 不改
04-调整方案/**历史档案正文(D1 已定:只在操作性载体里写"档案口径已过期"的指针); - ⛔ 不动 47 / 106 的 nginx / nft / systemd 单元 / env(唯一例外 = §5 S4 的演练与收尾
restart dshs归零,与序⑩–⑮ 同口径); - ⛔ 不重做任何已收官序(①–⑮);⛔ 不做 presence / 房间层 / 内容分发;⛔ 不做打洞实现;⛔ 不改 worker 拨出方向。
3.3 范围外登记(⛔ 不定序、不决策 —— 属「业务优先级」)
| 候选 | 优点 | 缺点 |
|---|---|---|
| presence | 清单 §五 第 7 步;千台推演里第一瓶颈,做完才能谈"谁在线"类功能 | 仓库里目前零应用层代码(全仓唯一含 "presence" 字样的是 src/net/relay/placement.ts)⇒ 从零起步、工作量最大 |
| 房间层 | 是 presence 的下游、MMORPG 多人的前置 | ⛔ 无 presence 则无输入;依赖链在前 |
| 内容分发(块级内容寻址) | 与 presence 无依赖、可独立做;直接吃"跨云 ~22 KB/s"这条实测短板 | 与游戏主线收益关系较远;块级寻址会引入新的存储/校验面 |
§4 决策点
待拍板项 = 空(本单四条全部落在 §1「边界内自决清单」:实现路径 / 排查方法 / 文档技术内容 / 清理类)。以下为已定项(可推翻):
| # | 已定项 | 理由 |
|---|---|---|
| D1 | mksess 口径只改操作性载体(02-运维手册.md + skills/** + 本机技能),⛔ 不改 04-调整方案/*.md 档案正文;在 02-运维手册.md 的 R4 段写一行「档案 77 里的『DB 直插』为当时形态,现实现 = PG 直插」作勘误指针 |
档案的属性是当时事实,改写 = 销毁溯源;且档案命中面 7 个文件(R7 批量面)。B 方案(只改载体)明显更优 ⇒ 自决 |
| D2 | Q5 范围扩到 5 个(含原单未记的 src/web/server.ts.bak-seq7-* 与 src/worker/tunnel.ts.bak-seq7-*) |
同类、同批、同为 untracked 过期快照(seq7 11:21 的快照,已被序⑧/⑨/⑭/⑮ 改写作废 ⇒ 无回滚价值);只删 3 个 = 规矩只立一半,下次还要再开一单。R7 透明:本行即"先报告" |
| D3 | 幕 4-A 判据取三档递进而非单一阈值:p95 ≤ 24 s(deadline×0.8)= 健康|24–27 s = 临界(记入在册、⛔ 不判 FAIL)|> 27 s = 回头条件触发(停下报告) | 观测样本 19.5 / 20.8 / 22.2 s,单阈值 24 s 有假红风险、27 s 又预警太晚 ⇒ 三档把"假红 vs 预警提前量"这个取舍消解掉了(既不失预警、也不误判) |
| D4 | ⛔ 本单不处理 src/worker/tunnel.ts 这条生产死路径(是否删 = 独立决策) |
删代码有风险、且它可能作为 ssh 兜底变体保留 ⇒ 只登记(§0.1 末) |
| D5 | S4 若触发回头条件(p95 > 27 s),⛔ 不许自行调 RELAY_FAILOVER_DEADLINE_MS / HB_SEC / burst ⇒ 停下报告,重做四段分解(检测 / 首试 / 白等 / 建连)后定位 |
沿用序⑨ 已立的三条硬门(D1 / 生产值不可调 / 分解优先) |
§5 步骤 S0–S5
S0 · 只读前置 + 抢锁
- 跑 §2 的 P1–P7 全部核实;任一条不符 ⇒ 停下报告。
- 抢锁:
bash "D:/github/dsh_shenxian/dsh-server-docs/scripts/handoff-guard.sh" --claim-exec "覆盖网络线-序17执行棒"。 - 抢到后再跑一次信息模式,记下占用与越界改动。
S1 · mksess 文档口径校正(「DB 直插」→「PG 直插」)
- 先取准实现事实(只读,1 条命令):
ssh -p 22 bt-server 'head -40 /opt/dshs/mksess.cjs'⇒ 确认落点是 PG、连接串来源 = env /dshs.env/dshs.service.d、⛔ 不固化凭据(序⑬ §9.2 已改)。 - 改哪些行:按 §2-P5 的 grep 结果逐行改(只改断言"存储机制"的行;仅提及文件名、不涉机制的行保持原样)。
- 统一措辞(示例,⛔ 不写死凭据):
node /opt/dshs/mksess.cjs(PG 直插,连接串取自 env /dshs.env/dshs.service.d;10 分钟;user_agent=poc-curl2)
- 统一措辞(示例,⛔ 不写死凭据):
- 本机 + 文档库两副本同改(内容逐字节一致)。
- 判据:
grep -rn "mksess" dsh-server-docs/ \| grep -iE "sqlite\|旧库"= 0(⚠️ 原本 0 命中的"旧库"也一并核)grep -rniE "sqlite|旧库" <文档库 skills 与 02-运维手册> \| grep -c mksess= 0- 两副本
md5sum逐文件一致
- 回滚:
git checkout -- <改动文件>(文档库)+ 本机技能按 §7 备份还原。
S2 · 技能 dsh-auto-handoff-chain 三处同步建立
- ① 核本机副本清单:
ls -R "E:/ProgramData/.workbuddy/skills/dsh-auto-handoff-chain"⇒ 记下全部文件(SKILL.md+ 可能的references/、scripts/)。 - ② 建文档库副本:逐文件复制到
D:/github/dsh_shenxian/dsh-server-docs/skills/dsh-auto-handoff-chain/(逐文件 copy,⛔ 不用cp -r整目录覆盖;⚠️ 文档库.gitattributes=* -text⇒ 保持纯 LF)。 - ③ 登记:改
dsh-server-docs/skills/README.md与dsh-server-docs/skills/INDEX.md,加上该技能行。 ⚠️INDEX.md是混合换行 ⇒ 字节级单行插入,⛔ 不跑git checkout --、⛔ 不做批量换行符转换。 - ④ 镜像同步:scp 到 47
/opt/dsh/docs/skills/(连同 S1 的改动物一次上);同步前先抢锁(本棒已持锁)。 - 判据:
diff -r两副本 = 0 差异;逐文件md5sum一致(⚠️ 本机md5sum出hash *path、远端出hash path⇒ 先cut -d' ' -f1再比)- 镜像
/opt/dsh/docs/skills/dsh-auto-handoff-chain/SKILL.mdmd5 == 文档库 md5 grep -c "dsh-auto-handoff-chain" dsh-server-docs/skills/README.md≥ 1(INDEX.md 同)
- 回滚:删文档库新增目录 + 镜像改名还原备份(
README.md/INDEX.md用git checkout --)。 - ⚠️ 本步自证价值:这一条正是「长期在册」项 —— 此前该技能的"三处同步"从未建立,本步是第一次把它建起来;完成后在 §8.8 明确写"已建立",并在
.workbuddy/memory/MEMORY.md的对应处("该技能三处同步从未建立(在册未办)")改为已办。
S3 · Q5 清理 .bak-seq7-*(5 个)
- 前置(缺一不可):①
find src test scripts -name "*.bak-*"逐个确认属 seq7-20260917-112114 批次;② 确认对应源文件存在(client.ts/directory.ts/main.ts/web/server.ts/worker/tunnel.ts);③ 确认lib/内有等价产物;④ ⚠️ 记录一条事实:这些是 11:21 的快照,已被序⑧/⑨/⑭/⑮ 改写作废 ⇒ 他们不是有效回滚点(删除风险 = 零)。 - 怎么做:逐个
rm(5 个,逐个点名,⛔ 不用通配符rm src/net/relay/*.bak-*)。 - 判据:
find src test scripts -name "*.bak-*" \| wc -l= 0npm run buildRC=0(⛔ 未改任何源文件 ⇒ 产物指纹应与 S0 一致,可对账lib/net/relay/*.jsmd5 不变)npm test= 162 / 161 / 0 / 1(不退化)git status --porcelain \| wc -l只减不增(Δ ≤ 0;⚠️src/net/relay/整体是??一个条目 ⇒ 不能期望 −5,判据落到find结果与 md5 上)
- 回滚:
.bak不可再生 ⇒ 回滚动作 = 从当前源文件重新cp一份快照(⚠️ 语义不等价,仅作备案)。⇒ 故删除前必须完成前置 ④ 的书面记录。
S4 · §8.8-2 临界项 —— 幕 4-A 余量判据化 + 稳定性采样
- 不改任何生产值;只跑演练 + 落判据。
- ① 采样:
node scripts/overlay-failover-drill.cjs --scene 4 --table "<工作区根>/参数表_覆盖网络_20260917.md"(DRILL_SAMPLE_N= 5)。 ⛔ 只跑--scene 4(构 A);⛔ 不跑4b/4c/ctrl(4c/ctrl已被序⑩ 整体移除并显式拒绝 —— 那是COOLDOWN_MS=0的诱发面)。 - ② 算判据:对 5 个样本取 p95,按 §4-D3 三档判定:
p95 ≤ 24000 ms⇒ 健康 ⇒ 把判据写进参数表 §6(配套说明:分母 =RELAY_FAILOVER_DEADLINE_MS= 30000 ms);24000 < p95 ≤ 27000⇒ 临界(记录,⛔ 不判 FAIL) ⇒ 写进 §8.8 在册;p95 > 27000⇒ 🔴 停下报告(⛔ 不许自行调任何生产值)⇒ 按 §4-D5 重做四段分解。
- ③ 零回归:
--scene all= 12 PASS / 0 SKIP / 0 FAIL(幕 4-A / 4-C 全部 ≤ deadline);npm test不退化。 - ④ 收口归零(本步的"回滚"):演练会把 Manager 通道挪到 106 ⇒ 必须
systemctl restart dshs归零回 47,再跑overlay-probe确认 12/12、ss -lntH 'sport >= :25000 and sport <= :25063' | wc -l= 64。 ⚠️ 判"服务是否正常"要systemctl is-active dshs dshs-relay dshs-pg—— 演练进行中某台 relay 是inactive,那是幕的正常态。 - 回滚:本步不改服务配置 ⇒ 回滚 = ① 参数表备份还原(指纹回到现值
8f08e74b026e6e5b5e1b3db813f031ae)② 演练坐标/env 残留清 0(grep -r 'DRILL_' /etc/systemd/system/dshs.service.d/= 0)。
S5 · 收口(6 件,缺一即算未完成)
① 释放锁 --release-exec;② 陈述句告知用户 + 登记下一棒一次性 automation(scheduledAt = 收口时刻 +2~5 分钟;⚠️ 下一棒 id 只能来自工具返回值:先 create → 取 id → 再落盘);③ 把 接续入口_覆盖网络线_20260916.md §0 + §2 推进到再下一棒;④ 写工作区日志 .workbuddy/memory/2026-09-17.md(append-only);⑤ 在本单追加回报(§8 八小节);⑥ 输出指纹(§8.9)。
§6 验收(逐条命令 + 期望 + 退出码;可被第三方复现)
| # | 项 | 命令(cwd 见括注) |
期望 |
|---|---|---|---|
| E1 | S1 口径已对齐 | cd D:/github/dsh_shenxian && grep -rn "mksess" dsh-server-docs/ | grep -iE "sqlite|旧库" | grep -v "04-调整方案" |
0 行(⛔ 档案除外) |
| E2 | S1 双副本一致 | 逐文件 md5sum(本机技能 vs 文档库技能,cut -d' ' -f1 后比) |
全同 |
| E3 | S2 三处同步 | diff -r "E:/ProgramData/.workbuddy/skills/dsh-auto-handoff-chain" "D:/github/dsh_shenxian/dsh-server-docs/skills/dsh-auto-handoff-chain" + 镜像 md5sum |
diff 0 行;镜像 md5 == 文档库 md5 |
| E4 | S2 登记 | cd D:/github/dsh_shenxian && grep -c "dsh-auto-handoff-chain" dsh-server-docs/skills/README.md(INDEX.md 同) |
≥ 1 |
| E5 | S3 清理干净 | cd D:/github/dsh_shenxian && find src test scripts -name "*.bak-*" | wc -l |
0 |
| E6 | 零回归(三件套) | ① cd D:/github/dsh_shenxian && npm.cmd test(必须 Node 22)② node scripts/overlay-failover-drill.cjs --scene all --table "<工作区根>/参数表_覆盖网络_20260917.md" ③ node scripts/overlay-probe.cjs --table "<工作区根>/参数表_覆盖网络_20260917.md" |
① 162 / 161 / 0 / 1 ② 12 PASS / 0 SKIP / 0 FAIL ③ 12/12 · rc=0 |
| E7 | S4 余量判据 | --scene 4 × DRILL_SAMPLE_N=5 ⇒ p95 |
落 §4-D3 三档之一;> 27000 ms ⇒ 停下报告 |
| E8 | 越界自证 | cd D:/github/dsh_shenxian && grep -c 'COOLDOWN_MS=0' scripts/ + git rev-parse --short HEAD + git status --porcelain | wc -l |
0;HEAD 仍 640813e(⛔ 无 commit);总行数 ≤ 43 |
| E9 | 收口归零 | ssh -p 22 bt-server 'systemctl is-active dshs dshs-relay dshs-pg' + ssh -p 22 bt-server "ss -lntH 'sport >= :25000 and sport <= :25063' | wc -l" |
三个 active;池口 64 |
§7 回滚
| 对象 | 回滚动作 | 耗时 |
|---|---|---|
| S1 文档(文档库) | git checkout -- dsh-server-docs/skills/dsh-change-workflow/SKILL.md dsh-server-docs/skills/dsh-env-bootstrap/references/常驻规则-快照.md dsh-server-docs/02-运维手册.md |
秒级 |
| S1 文档(本机技能) | 执行前逐文件备份到 _中间产物_待清理/seq17/skills-bak/ ⇒ cp 还原 |
秒级 |
| S2 文档库新增目录 | rm -rf dsh-server-docs/skills/dsh-auto-handoff-chain(⚠️ 纯新增 ⇒ 无溯源损失)+ git checkout -- README.md INDEX.md |
秒级 |
| S2 镜像 | ssh -p 22 bt-server 把 /opt/dsh/docs/skills/ 备份目录改名还原 |
秒级 |
S3 .bak 删除 |
⚠️ 不可逆(原文件是过期快照、无回滚价值)⇒ 回滚 = 从当前源文件重建快照(仅备案)。故前置 ④ 必须先写 | 秒级 |
| S4 参数表判据 | 参数表备份还原 ⇒ 指纹回 8f08e74b026e6e5b5e1b3db813f031ae |
秒级 |
| S4 服务态 | systemctl restart dshs 归零回 47(⛔ 不删 drop-in、⛔ 不改 cluster 配置) |
秒级 |
§8 回报格式(执行会话按此回填;⛔ 缺一节即算未完成)
8.1 结论(1 行) :四条在册项逐条 ✅ / ❌(S1 / S2 / S3 / S4),+ 是否触发 S4 回头条件
8.2 只读前置 P1–P7 :逐条贴命令与输出(P3 的 5 个 .bak 逐个点名 + git ls-files 的 untracked 自证)
8.3 S1 口径校正 :命中行清单(文件:行 → 改前 / 改后)、0 命中的判据命令原文、⛔ 未动档案的自证
8.4 S2 三处同步 :本机副本文件清单(逐个 md5)+ 文档库 md5 + 镜像 md5(三处对照表)+ README/INDEX 登记原文
8.5 S3 清理 :find 前 / 后计数 + 5 个文件逐个名 + npm run build RC + npm test 计数 + "非有效回滚点"的书面记录
8.6 S4 临界项 :--scene 4 5 个样本原文 + p95 = ? ms ⇒ 落哪一档 + 判据是否落表(落表则给参数表指纹 变更前/后)
8.7 零回归 / 越界自证 :E6 三件套原文(含 --scene all 的幕 4-A / 4-C 两个毫秒值)+ E8(COOLDOWN_MS=0 计数、HEAD、git status 计数)
8.8 未过项 / 在册未办 :逐条写「现象 / 已做到哪一步 / 回头条件」;Q4 原样转下一棒(⛔ 只报告);§0.4 的三项登记原样保留
8.9 指纹(可复现核对口径)
- 本单前缀:
cd "E:/ProgramData/AI技能/aliyun-dsh-server" && sed '/^## §8 回报格式/,$d' 交接单_在册收尾_20260917.md | md5sum - 本单全文:
md5sum 交接单_在册收尾_20260917.md - 参数表(D1 自证):
sed '/^## §10 指纹/,$d' 参数表_覆盖网络_20260917.md | md5sum(⚠️ 截断口径,⛔ 不是全文件 md5;现值8f08e74b026e6e5b5e1b3db813f031ae) - 关键产物:
src/net/relay/{client,directory,main}.ts+src/web/server.ts+src/worker/tunnel.ts的 md5(清理前后应不变 ⇒ 自证未改源文件)
§9 执行回报(序 ⑰ 执行棒 · 2026-09-17 16:44–17:3x)
口径 = 按 §8 的九个小节逐条回填;本 §9 位于 §8 之后,不进 §8 前缀指纹。
9.1 结论(对应 §8.1)
四条在册项逐条:S1 ✅ | S2 ✅ | S3 ✅ | S4 ⚠️ 落「临界档」(记录在册,⛔ 不判 FAIL)。
S4 回头条件是否触发:未触发(p95 = 24477 ms < 27000 ms)⇒ ⛔ 未调任何生产值。
范围遵守:⛔ 未改任何生产值;⛔ 未改 04-调整方案/** 档案正文;⛔ 未重做已收官序 ①–⑮;⛔ 未做 presence / 房间层 / 内容分发;⛔ 未超 §3 范围。
追加授权:用户本轮明确「执行完毕后 同步到仓库」⇒ Q4(提交/推送授权)已解除并办结,见 §9.10。
9.2 只读前置 P1–P7(对应 §8.2)
| # | 核实项 | 实测 | 判定 |
|---|---|---|---|
| P1 | 锁空闲 | 报「空闲」;本棒 --claim-exec "覆盖网络线-序17执行棒" 抢到 |
✅ |
| P2 | 基线未漂移 | HEAD = 640813e;git status --porcelain | wc -l = 43 |
✅ |
| P3 | .bak 真实范围 |
5 个(逐个点名见 §9.5) | ✅ 与单一致 |
| P4 | Q4 自证 | git ls-files src/net/relay | wc -l = 0 |
✅(本轮已解除 → 见 §9.10) |
| P5 | mksess 命中面 | grep -rn "mksess" dsh-server-docs/ 筛 sqlite|直插|dshs.db|旧库 = 5 行 ⇒ 落点 = 档案 77(⛔ 不改)+ skills/dsh-change-workflow/SKILL.md:146/395/495 + skills/dsh-env-bootstrap/references/常驻规则-快照.md:55 |
✅ |
| P6 | 技能三处现状 | ① 本机 ✅ 存在(SKILL.md + scripts/chain_report.py);② 文档库 ❌ 不存在;③ 镜像 ❌ 不存在(8 个技能、无此项) |
✅ 与在册项一致 |
| P7 | 基线回归值 | 见 §9.7 | ✅ |
mksess 实现事实(只读,1 条 ssh;-p 22 显式):/opt/dshs/mksess.cjs(74 行)第 2 行即「临时会话直插(PG 版)」;第 4–6 行写明「原版直插 /var/lib/dshs/dshs.db(SQLite)… 集群化后权威库 = 47 的 PG13(DSHS_DB_URL),SQLite 只剩回滚用途」;第 9–10 行「连接串从环境读(DSHS_DB_URL env → /etc/dshs.env → dshs.service.d/*.conf),⛔ 不把凭据固化进本文件」;第 17 行 require('/opt/dshs/node_modules/pg');TTL_MS = 600 * 1000。
⇒ 文档口径必须改成「PG 直插」,与实现一致。
9.3 S1 口径校正(对应 §8.3)
命中行清单(文件 : 行 → 改前 → 改后) —— 文档库与本机技能同内容逐字节一致:
| 面 | 文件:行 | 改前 | 改后 |
|---|---|---|---|
| 文档库 + 本机 | skills/dsh-change-workflow/SKILL.md:146 |
… mksess.cjs\ 直插临时 session,或…` |
… mksess.cjs\(PG 直插)建临时 session,或…` |
| 文档库 + 本机 | skills/dsh-change-workflow/SKILL.md:395 |
改用 \mksess.cjs` 直插临时 session 或…` |
改用 \mksess.cjs` PG 直插临时 session 或…` |
| 文档库 + 本机 | skills/dsh-change-workflow/SKILL.md:495 |
(DB 直插,10 分钟,user_agent=poc-curl2) |
(**PG 直插**,连接串取自 env / \dshs.env` / `dshs.service.d`;10 分钟;`user_agent=poc-curl2`)` |
| 文档库 + 本机 | skills/dsh-env-bootstrap/references/常驻规则-快照.md:55 |
(\mksess.cjs` 直插)` |
(\mksess.cjs` PG 直插)` |
| 仅文档库 | 02-运维手册.md:211–214 |
# 测试 session 生成(门户 API 直调,10 分钟) |
注释行补「PG 直插,连接串取自 env / dshs.env / dshs.service.d;10 分钟;user_agent=poc-curl2」+ D1 勘误指针两行(说明档案 77 与更早文档的描述属当时形态、写 /var/lib/dshs/dshs.db,集群化后权威库 = 47 的 PG13、那份文件仅回滚用) |
判据原文:
- E1
cd D:/github/dsh_shenxian && grep -rn "mksess" dsh-server-docs/ | grep -iE "sqlite|旧库" | grep -v "04-调整方案" | wc -l= 0 ✅(⛔ 档案除外) - E1b
grep -rniE "sqlite|旧库" dsh-server-docs/skills/ dsh-server-docs/02-运维手册.md | grep -c "mksess"= 0 ✅ - E2 两副本逐文件 md5:
dsh-change-workflow/SKILL.md=338bf9534e5243f495e7d66f914371bf(本机 = 文档库);dsh-env-bootstrap/references/常驻规则-快照.md=e1a460b53cc4b62466107f8555946496(本机 = 文档库) → 全同 ✅ - 行尾:5 个文件 CR 计数 全 0(纯 LF)✅
⛔ 未动档案自证:04-调整方案/77-回到页面自检与就地恢复-恢复过程可见化.md:97 原文未改(该行本就不含 sqlite/旧库,属 E1 的排除项)。
⚠️ 一处判据偏差(已按实质落点执行):§3.1 / §5-S2 写的登记文件路径为 dsh-server-docs/skills/README.md 与 INDEX.md,实测 skills/ 下无这两个文件 —— 真实登记文件在文档库根 dsh-server-docs/README.md 与 dsh-server-docs/INDEX.md(内容形态与描述一致:技能表 + 「什么时候查什么」表 + 技能清单表)⇒ 按实质落点执行,判据 E4 落在根文件上。
9.4 S2 三处同步(对应 §8.4)
① 本机副本清单(E:/ProgramData/.workbuddy/skills/dsh-auto-handoff-chain/):
| 文件 | 字节 | md5 |
|---|---|---|
SKILL.md |
18926 | 0c5c4103f8ffa8071ce29434654fa2d3 |
scripts/chain_report.py |
8126 | 636c4f336864bc99c408e92577516f11 |
② 文档库副本(新建 dsh-server-docs/skills/dsh-auto-handoff-chain/,逐文件 copy、⛔ 未用 cp -r):
| 文件 | 本机 md5 | 文档库 md5 | 镜像 md5(47 /opt/dsh/docs/skills/dsh-auto-handoff-chain/) |
判定 |
|---|---|---|---|---|
SKILL.md |
0c5c4103f8ffa8071ce29434654fa2d3 |
同 | 同 | ✅ 三处同值 |
scripts/chain_report.py |
636c4f336864bc99c408e92577516f11 |
同 | 同 | ✅ 三处同值 |
- E3
diff -r "E:/…/skills/dsh-auto-handoff-chain" "D:/…/dsh-server-docs/skills/dsh-auto-handoff-chain"= 0 行 ✅ - 行尾:两处 CR = 0(纯 LF)✅(文档库
.gitattributes的dsh-server-docs/** -text完好)
③ 登记(字节级单行插入,新行行尾跟随锚点行):
| 文件:行 | 内容 |
|---|---|
dsh-server-docs/README.md:37 |
技能表新增 skills/dsh-auto-handoff-chain/ 行(v1.3.2 + 六件套骨架 + 登记门禁 + 五条实测防护 + scripts/chain_report.py;同步方向本机 → 此处) |
dsh-server-docs/INDEX.md:22 |
「什么时候查什么」新增 **跑跨会话长任务(自动接力)** 行 |
dsh-server-docs/INDEX.md:169 |
技能清单表新增 — / ✅ / skills/dsh-auto-handoff-chain/SKILL.md 行 |
- E4
grep -c "dsh-auto-handoff-chain" dsh-server-docs/README.md= 1 ✅;INDEX.md= 2 ✅(≥ 1) - ⚠️
INDEX.md是混合换行(全文件 CR 计数 = 734)⇒ 全程字节级插入、新行行尾跟随锚点(两处锚点均为 LF)、⛔ 未做任何批量换行符转换、⛔ 未跑git checkout --。
④ 镜像同步(S1 + S2 产物一次上;同步前远端备份):
- 备份 =
/opt/dsh/docs/.bak-seq17-20260917-164809(5 个文件) - 上传 7 个文件,md5 逐条与本地一致:
skills/dsh-change-workflow/SKILL.md338bf953…|skills/dsh-env-bootstrap/references/常驻规则-快照.mde1a460b5…|skills/dsh-auto-handoff-chain/SKILL.md0c5c4103…|…/scripts/chain_report.py636c4f33…|02-运维手册.mdd6627843b67c72ddfd3b62b5cfd5e29f|README.mdddfd4d5fc890af0ee86d5442d8c0d610|INDEX.md5677883fd3777a225ae85af7c5c79fb7
⇒ 该技能的「三处同步」由「从未建立」变为「已建立」(此前文档库与镜像都无副本)。
9.5 S3 清理(对应 §8.5)
前置四项(缺一不可)全部满足:
① 5 个全属 seq7-20260917-112114 批次;
② 对应源文件 5/5 存在(src/net/relay/{client,directory,main}.ts、src/web/server.ts、src/worker/tunnel.ts);
③ lib/ 内等价比产物 5/5 存在;
④ 书面记录:这 5 个是 seq7 11:21 的快照,已被序⑧/⑨/⑭/⑮ 改写作废 ⇒ 不是有效回滚点、删除风险 = 零。
删除前 → 后:find src test scripts -name "*.bak-*" | wc -l = 5 → 0 ✅(逐个点名 rm,⛔ 未用通配符)
逐个名:src/net/relay/client.ts.bak-seq7-20260917-112114 / src/net/relay/directory.ts.bak-seq7-20260917-112114 / src/net/relay/main.ts.bak-seq7-20260917-112114 / src/web/server.ts.bak-seq7-20260917-112114 / src/worker/tunnel.ts.bak-seq7-20260917-112114
判据:
npm run buildRC = 0 ✅npm test= 162 / 161 / 0 / 1 ✅(不退化)- lib 产物 md5 清理前后零差异 ✅(自证未改任何源文件):
client.js b8b29afba06ed6347cbefd29091f8c73/directory.js 3382ae677788d3bd1c026d4c71ca40ee/main.js 7531be9eeba5ced5928ff7747621d512/web/server.js b64fe76500249703e34934d274d0a151/worker/tunnel.js 5f2649b43b072812fbf5d910d91b0c22 - ⚠️
git status --porcelain | wc -l不减(这 5 个全 untracked ⇒ 本来就不体现在 git status 里;判据落在find与 md5 上,与 §5-S3 的说明一致)
⚠️ 额外兜底(超出单子、零风险):删除前把这 5 份原件复制到 E:/ProgramData/AI技能/aliyun-dsh-server/_中间产物_待清理/seq17/bak-archive/(5 个文件,保持相对路径)⇒ 即使日后需要,仍有字节级副本可查。
9.6 S4 临界项(对应 §8.6)
采样命令:node scripts/overlay-failover-drill.cjs --scene 4 --sample 5 --table "<工作区根>/参数表_覆盖网络_20260917.md"(RC = 0;原文 = _tmp_seq17_scene4.txt)
⛔ 只跑 --scene 4(构 A),⛔ 未跑 4b / 4c / ctrl。
5 个样本(切换耗时,ms):
| 轮 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| 耗时 ms | 20121 | 18772 | 21223 | 24477 | 20246 |
(5/5 全部在 deadline = 30000 ms 内侧;AUTH 就绪 4358 / 2272 / 2846 / 3652 / 2853 ms;目标恒为 wss://106.54.21.172/dshs-relay)
p95 口径(⚠️ 两种口径分档不同,必须点名):
- nearest-rank(保守,本次采用):
k = ceil(0.95 × 5) = 5⇒ 第 5 个 = 24477 ms ⇒ 落 临界档(24000 < p95 ≤ 27000) - 线性插值:
idx = 0.95 × (5−1) = 3.8⇒21223 + 0.8 × 3254= 23826.2 ms ⇒ 落 健康档
⇒ 结论(按 §4-D3):临界档 ⇒ 记录在册、⛔ 不判 FAIL、⛔ 不调任何生产值。
⚠️ 两口径均 < 27000 ms ⇒ 回头条件未触发(§4-D5 未被激活)。
⇒ 判据未落参数表 §6 —— §5-S4 ② 规定只在「健康」档落表 ⇒ 参数表指纹保持不变(8f08e74b026e6e5b5e1b3db813f031ae,见 §9.9),D1 自证成立。
阈值口径:deadline = RELAY_FAILOVER_DEADLINE_MS = 30000 ms;两档 = deadline×0.8 = 24000 / deadline×0.9 = 27000。
9.7 零回归 / 越界自证(对应 §8.7)
E6 三件套(全绿):
① npm test(Node 22)= 162 tests / 161 pass / 0 fail / 1 skipped,RC = 0 ✅
② --scene all = 12 PASS / 0 SKIP / 0 FAIL,RC = 0 ✅ —— 幕 4-A 两个毫秒值:20419 ms(停 47 ⇒ 切 106)与 18333 ms(一跳豁免切回 47);幕 4-C 实测 18333 ms / deadline 30000 ms
③ overlay-probe --table "…/参数表_覆盖网络_20260917.md" = 12/12 · rc = 0 ✅(OBS-01…OBS-12 全 PASS;OBS-11 = 必在 7 / 允许 4 / 区间 3 / 派生 2 / 实际 78,多出 0 / 缺失 0;OBS-09 本机:20000=401 w-106:45747=401)
E9 收口归零:ssh -p 22 bt-server 'systemctl is-active dshs dshs-relay dshs-pg' = active / active / active ✅;ss -lntH 'sport >= :25000 and sport <= :25063' | wc -l = 64 ✅
E8 越界自证:
COOLDOWN_MS=0精确计数 = 0 ✅(grep -rn "COOLDOWN_MS" scripts/的命中全部是「⛔ 不许置 0」的警示注释,无任何实际赋值 —— 已逐行人工核)- HEAD =
640813e(⛔ 本棒零 commit) —— ⚠️ 该判据表内值为基线快照;本节其余项全绿后才按用户追加授权单独提交(§9.10),提交发生在 E8 判据采集之后 git status --porcelain | wc -l= 49(基线 43 + 6),逐项可归因,无越界:- +4 个 M:本轮 S1/S2 把 4 个原本干净的文档改为 M ——
dsh-server-docs/02-运维手册.md、skills/dsh-change-workflow/SKILL.md、skills/dsh-env-bootstrap/references/常驻规则-快照.md、dsh-server-docs/INDEX.md - +1 个 ??:
dsh-server-docs/skills/dsh-auto-handoff-chain/(S2 计划内新建) - +1 个 ??:
_中间产物_待清理/(演练脚本落盘产物;⛔ 不在提交范围内) - ⇒ M 项逐个都在计划内 ⇒ 无越界改动
- +4 个 M:本轮 S1/S2 把 4 个原本干净的文档改为 M ——
9.8 未过项 / 在册未办(对应 §8.8)
- S4 落「临界档」(p95 = 24477 ms,nearest-rank 口径)。
- 现象:5 个样本中 1 个为 24477 ms(超
deadline×0.8 = 24000),其余 4 个 18772–21223 ms。 - 已做到哪一步:三档判据已立(§4-D3)、
--scene 4× 5 采样已做、零回归三件套全绿、收口归零完成、⛔ 未改任何生产值。 - 回头条件(一出现必须回头解决):① p95(nearest-rank)> 27000 ms;②
--scene all的幕 4-A / 幕 4-C 出现 FAIL;③ 任何RELAY_FAILOVER_*/HB_SEC/ burst 值被调整。命中任一条 ⇒ 按 §4-D5 重做四段分解(检测 / 首试 / 白等 / 建连)后定位,⛔ 不许自行调生产值。
- 现象:5 个样本中 1 个为 24477 ms(超
- Q4 —— 已解除(用户本轮授权):原「
src/net/relay/**untracked ⇒ commit/push 需授权」由用户原话「执行完毕后 同步到仓库」解除 ⇒ 已 commit + push(§9.10);git ls-files src/net/relay | wc -l0 → 15。 src/worker/tunnel.ts生产死路径(§0.1 末 / D4):⛔ 本棒未处置,原样登记(是否删 = 独立决策,可能保留作 ssh 兜底变体)。- presence / 房间层 / 内容分发(§3.3):⛔ 未定序 —— 属业务优先级(§1 边界外 ①)⇒ 需拍板,候选与优缺点登记原样保留。
- 骨干节点服务范围(入口 §4 既有待拍板项 A/B):原样保留,本棒未重复上抛。
§8.8-1106 sshd MaxStartups 限流:本轮 ssh 未遇rc=255(单次重试机制未触发);⛔ 未放宽限流(命中 R5)⇒ 仍在册。
9.9 指纹(对应 §8.9,可复现核对口径)
| 对象 | 值 | 判定 |
|---|---|---|
| 本单 §8 前缀 | bab83b7219b2669d5a6e9f1acf782e1f |
回填后未变 ✅(§9 在 §8 之后,不进前缀口径) |
| 本单全文 | 回填后见下(脚本输出) | — |
参数表(截断口径 sed '/^## §10 指纹/,$d' … | md5sum) |
8f08e74b026e6e5b5e1b3db813f031ae |
未变 ✅(S4 落临界档 ⇒ 判据未落表 ⇒ D1 自证) |
| 覆盖网络线入口 | 接续入口_覆盖网络线_20260916.md(§0 + §2 已推进,见 §9.11) |
— |
三处同步产物(本机 = 文档库 = 镜像):
skills/dsh-auto-handoff-chain/SKILL.md=0c5c4103f8ffa8071ce29434654fa2d3skills/dsh-auto-handoff-chain/scripts/chain_report.py=636c4f336864bc99c408e92577516f11skills/dsh-change-workflow/SKILL.md=338bf9534e5243f495e7d66f914371bfskills/dsh-env-bootstrap/references/常驻规则-快照.md=e1a460b53cc4b62466107f8555946496
仅文档库 + 镜像:02-运维手册.md = d6627843b67c72ddfd3b62b5cfd5e29f|README.md = ddfd4d5fc890af0ee86d5442d8c0d610|INDEX.md = 5677883fd3777a225ae85af7c5c79fb7
S3 涉及的源文件(清理前后不变,自证未改码):
src/net/relay/client.ts = 6ffb117f3f6df1c2456641e176529ce8|directory.ts = d6dfcf1f1fbf388f994582d43bbb65ec|main.ts = 7d5f915fcf0298e178e910d37863ef1d|src/web/server.ts = 12f8dadd4a2e06ffaed70bddbd719999|src/worker/tunnel.ts = e84c0baab6e96da1208d9512a000cedc
9.10 追加项 —— 同步到仓库(用户本轮明确授权 ⇒ Q4 解除)
授权原话:「执行完毕后 同步到仓库」(本棒执行期间用户明确下达)。
提交清单核对(提交前逐项确认只含本线真实改动) ⇒ 两个 commit:
| commit | 面 | 文件数 | 内容 |
|---|---|---|---|
146c3d2 |
代码 / 测试 | 53 | relay 子系统 src/net/relay/**(15 文件)+ src/worker/relay-tunnel.ts + src/web/routes/overlay.ts + 8 个 overlay 脚本 + 12 个测试 + package.json 等改动(+16187 / −63) |
bc0dd2c |
文档库 | 10 | 02-运维手册.md、INDEX.md、README.md、scripts/stop-dialog-guard.py、4 个技能文件(含 S1 的两处校正)+ 新增 skills/dsh-auto-handoff-chain/**(2 文件) |
- ⛔ 未用
git add -A:逐路径git add src/ scripts/ test/ package.json与git add dsh-server-docs/;_中间产物_待清理/未被提交(提交后仍为唯一的??)。 - 推前判定:
git ls-remote origin refs/heads/master取裸 sha =640813e84e5e48c56ca39d765d7b195884e58ebc;git merge-base --is-ancestor 640813e… HEAD⇒ 是祖先(fast-forward,无分叉);git push --dry-run显示640813e..bc0dd2c。 - 推送结果:
640813e..bc0dd2c master -> master;推送后git ls-remote=bc0dd2c96da88b1ee3a8450760b6cbb8ab92d845= 本地HEAD✅ - Q4 缺口闭合自证:
git ls-files src/net/relay | wc -l= 0 → 15 ✅(序⑭/⑮ 的修复与test/relay.test.mjs首次进入版本库) - 行尾:
.gitattributes的dsh-server-docs/** -text完好(文档库保持纯 LF)⇒ ⛔ 未做任何批量换行符转换。
9.11 收口六件核对
| # | 项 | 状态 |
|---|---|---|
| ① | 释放锁 --release-exec |
✅ 本棒收尾第一步执行 |
| ② | 陈述句告知 + 登记下一棒 | ✅ 已陈述句告知;⛔ 未登记下一棒 —— 理由见下 |
| ③ | 入口 §0 + §2 推进 | ✅ 已刷新(§2 的序⑰ 转存档 + 新增收官段) |
| ④ | 工作区日志 .workbuddy/memory/2026-09-17.md |
✅ append-only 追加 |
| ⑤ | 本单回填回报 | ✅ 本 §9(9.1–9.11) |
| ⑥ | 输出指纹 | ✅ §9.9 |
⛔ 为何未登记下一棒(登记门禁):四条在册项清干后,剩余项全部落在「需拍板」区 —— presence / 房间层 / 内容分发定序(= 业务优先级,§3.3)与骨干节点服务范围(入口 §4 的 A/B)。按用户明令的登记门禁(「要用户拍板的,等拍了再登记」,技能 dsh-auto-handoff-chain §3.3),不登记下一棒;拍板到手后再建。
⚠️ 技能的三处同步(S2)完成后,dsh-auto-handoff-chain 已同时存在于本机 / 文档库 / 镜像 ⇒ 上述门禁在三处都可读取。