Files
dsh_ai1net_server/交付物/两机lib差异面核对与106补齐-20260925.md
T
admin 318430c9e9 chore(工作区): 插件投放与分库线收口入库(第 35 棒 + 22:44 拍板落盘)
范围 = 本线(插件投放与分库线)产物 + 记忆类,共 27 件:
- 接续入口_插件投放与分库线(1 件):§0 新增 22:44 拍板行;§2 第 36 棒范围改 5 步、条件步转无条件
- 交付物(22 件):MCN 数据面接入阶段一/阶段二系列(含 B 案落地与 shadow 读数)、
  P0 修通与移动端真机验收、pnpm-EPERM、两机 lib 差异、共享层台账语义、
  基础插件身份与回滚、插件接入验收、插件数据面取数口、移动端迁包与字号扩面、跨机错误消息
- 记忆(4 件):2026-09-24 / 2026-09-25 日志、MEMORY.md、本棒 automation 执行记录

⛔ 未含他线在途改动(只报告、不代提交):机制层 CODEBUDDY.md / state.py /
.codebuddy/rules/server-ops.md、接续入口_IM线、接续入口_StoryForge验收线、
其余 29 个 automation 目录、docs/规则与载体/、归档/、接续包_*。
2026-09-25 23:06:29 +08:00

203 lines
14 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.
# 两机 `lib/` 差异面核对与 106 补齐(第 22 棒 · 执行棒)
> **线**:插件投放与分库线 | **棒**:第 22 棒(执行棒)| **日期**:2026-09-25 11:58–12:2x
> **一句话**:106 的 `lib/` 停在 **09-23 08:04 那次构建**(+此后少量零散补投)⇒ 代码面缺 **46 件**;已按 **47 生产部署面**(=本机构建产物,抽样逐字一致)补齐 ⇒ **代码面差异面归零(368 = 368,内容不同 0)**。⛔ 全程未重启 106。
---
## 一、结论(先行)
| 判据 | 结果 | 关键读数 |
|---|---|---|
| ① 完整差异清单 | ✅ | 47 **389** 件 / 106 **357** 件;逐字一致 **322**;内容不同 **23**;仅 47 有 **44**;仅 106 有 **12** |
| ② 补齐后差异面归零 | ✅ | 代码面 **368 = 368**、内容不同 **0**、单向缺失 **0**(`p22-verify.py` rc=0) |
| ③ 待重启才生效的文件 | ✅ 已列 | **46 件全部**(106 `dshs-worker` 起于 `09-25 09:52:11`,写入在其后);其中运行时 `.js` **21 件** |
**判据口径(本棒立 · 后棒沿用)**:两侧 `lib` 树里各自留有历史部署快照(`.s3bak-*` / `.s0bak-*` / `*.bak-*`),
它们**不是代码面**、两机时间戳本就不同 ⇒ 判据**只在代码面**(368 件)上要求归零。
---
## 二、判据① · 完整差异清单
### 2.1 方法(3 条命令,第三方可复现)
```bash
# 1) 两机各出一份「路径|md5|大小|mtime」全量清单(relpath 相对各自 lib 根)
ssh bt-server 'cd /opt/dshs/lib && find . -type f | sort | while read -r f; do m=$(md5sum "$f"); m=${m%% *}; printf "%s|%s|%s|%s\n" "$f" "$m" "$(stat -c%s "$f")" "$(stat -c%Y "$f")"; done' > tmp/p22-lib47.tsv
ssh test106 'cd /opt/dshs-cluster/lib && find . -type f | sort | while read -r f; do m=$(md5sum "$f"); m=${m%% *}; printf "%s|%s|%s|%s\n" "$f" "$m" "$(stat -c%s "$f")" "$(stat -c%Y "$f")"; done' > tmp/p22-lib106.tsv
# 2) 对比出清单
python tmp/p22-diff.py tmp/p22-lib47.tsv tmp/p22-lib106.tsv tmp/p22-diff-pre.tsv
# 3) 复核(排除备份残留,rc=0 即归零)
python tmp/p22-verify.py
```
- 两机代码根:47 = `/opt/dshs`(Manager);106 = `/opt/dshs-cluster`(Worker)。**⛔ 两机根目录名不同是既定事实**,不影响本判据(比的是各自 `lib/` 内相对路径)。
- 原始差异面 **79 条** → 其中**代码面 46 条** + **部署备份残留 33 条**(47 侧 21 条、106 侧 12 条)。
### 2.2 差异面构成
| 类别 | 条数 | 说明 |
|---|---|---|
| `DIFF`(两机都有、md5 不同) | **23** | 全部是 106 停在 09-23 版;含 `business-plugins.js`、`db/*.js`、`im/hub.js`、`web/server.js` 等 |
| `ONLY_47` 中**代码件**(106 缺) | **23** | `db/plugin-data/*`、`im/backends|connection-backend|keepalive|presence-ingest`、`web/routes/plugin-data.js`、`web/essential-plugins.js` |
| `ONLY_47` 中**备份残留** | 21 | `.s3bak-20260920-174307/`、`.s0bak-20260920-165634/`、`net/relay/*.bak-*`、`web/server.js.bak-seq19-*` |
| `ONLY_106`(47 无) | 12 | **全部是 106 自己的备份残留**(`.bak-20260917-155841` / `.bak-seq19-…-180218`)⇒ 代码面多出 **0** |
⇒ **代码面差异面 = 23 + 23 = 46 件**(21 件运行时 `.js` + 25 件 `.d.ts`/`.js.map`)。
### 2.3 关于 33 条备份残留(⛔ 本棒未投、未删)
- **不投**:它们是 47 侧**改前快照**(时间戳 09-17 / 09-20),投到 106 只会让 106 多出一批**过时代码副本**,属净变差(可维护性)。判据不是"字节级全等",而是**代码面全等**。
- **不删**:删除属**不可逆**、且是**别处部署面的历史留档**,超出"两机差异核对"范围 ⇒ 只报告。
### 2.4 本次补齐的 46 件(清单 + 两侧指纹)
| 路径 | 类型 | 47 md5 | 106 改前 md5 | 说明 |
|---|---|---|---|---|
| `./db/pg.js` | 运行时 .js | `8f7923fb0414` | 38375 | `b79bf5ce6af8` | 37989 |
| `./db/plugin-data/registry.d.ts` | 声明/映射 | `adef48d3ffbf` | 5414 | `—` | — |
| `./db/plugin-data/registry.js` | 运行时 .js | `44d3b5c424f7` | 9333 | `—` | — |
| `./db/plugin-data/registry.js.map` | 声明/映射 | `e83f9b4c0504` | 6615 | `—` | — |
| `./db/plugin-data/runtime.d.ts` | 声明/映射 | `31cc1acdad96` | 8561 | `—` | — |
| `./db/plugin-data/runtime.js` | 运行时 .js | `45daf7c5b2b6` | 20309 | `—` | — |
| `./db/plugin-data/runtime.js.map` | 声明/映射 | `d8f91115fcaf` | 15637 | `—` | — |
| `./db/repo.js` | 运行时 .js | `fe8bc9a698ab` | 40132 | `47f82e9617ba` | 39384 |
| `./db/schema.js` | 运行时 .js | `cf62c2b43cac` | 41287 | `1cb43ade2db8` | 40487 |
| `./db/sqlite.js` | 运行时 .js | `f05eb1a8e816` | 14478 | `62ae95ce50a5` | 14285 |
| `./db/types.js` | 运行时 .js | `20bd54a22f6c` | 7766 | `c1caff6f1ed4` | 7601 |
| `./im/backends/gateway.d.ts` | 声明/映射 | `693cea8cf738` | 7131 | `—` | — |
| `./im/backends/gateway.js` | 运行时 .js | `7f0638c89d48` | 12077 | `—` | — |
| `./im/backends/gateway.js.map` | 声明/映射 | `61950bd7abf7` | 6470 | `—` | — |
| `./im/backends/native.d.ts` | 声明/映射 | `c2ca6034ae13` | 2323 | `—` | — |
| `./im/backends/native.js` | 运行时 .js | `2d14f373325c` | 3168 | `—` | — |
| `./im/backends/native.js.map` | 声明/映射 | `8b652f7acfa9` | 1165 | `—` | — |
| `./im/connection-backend.d.ts` | 声明/映射 | `505e22d66ff5` | 8241 | `—` | — |
| `./im/connection-backend.js` | 运行时 .js | `19ddbb402dd9` | 3342 | `—` | — |
| `./im/connection-backend.js.map` | 声明/映射 | `2525a78e9dcc` | 2150 | `—` | — |
| `./im/hub.d.ts` | 声明/映射 | `9f1c235ec084` | 12414 | `b6ec9ae149d8` | 10871 |
| `./im/hub.js` | 运行时 .js | `cf405a4b5a10` | 13468 | `f36638808680` | 11868 |
| `./im/hub.js.map` | 声明/映射 | `1afee241b41d` | 9325 | `8361b2e081ae` | 8538 |
| `./im/keepalive.d.ts` | 声明/映射 | `042ca5b4943c` | 5015 | `—` | — |
| `./im/keepalive.js` | 运行时 .js | `efb3963f4e40` | 6462 | `—` | — |
| `./im/keepalive.js.map` | 声明/映射 | `31d8cc60d92e` | 4269 | `—` | — |
| `./im/presence-ingest.d.ts` | 声明/映射 | `7ed47172720d` | 6641 | `—` | — |
| `./im/presence-ingest.js` | 运行时 .js | `bb9e599f0b84` | 6607 | `—` | — |
| `./im/presence-ingest.js.map` | 声明/映射 | `8eef921f5597` | 4701 | `—` | — |
| `./supervisor/plugin-assembly.d.ts` | 声明/映射 | `e896c0c53bfb` | 13955 | `e0d3a15b8751` | 8762 |
| `./supervisor/plugin-assembly.js.map` | 声明/映射 | `f3eb2523919c` | 13104 | `dc9aad3f62a4` | 10274 |
| `./supervisor/remote-spawner.d.ts` | 声明/映射 | `589b9bca7a53` | 11968 | `85ed46970499` | 10372 |
| `./supervisor/remote-spawner.js` | 运行时 .js | `269d3d20ffce` | 20564 | `bea5d38cdc3f` | 18525 |
| `./supervisor/remote-spawner.js.map` | 声明/映射 | `218758f06bb5` | 11105 | `6ced34702565` | 10963 |
| `./web/dsh-install.js` | 运行时 .js | `ce82eef48c4c` | 6628 | `f707c77e505f` | 8504 |
| `./web/essential-plugins.js` | 运行时 .js | `9e79a5fd5665` | 6606 | `—` | — |
| `./web/routes/admin.js` | 运行时 .js | `3c5a64cb1c4d` | 19066 | `e794cad96c90` | 18184 |
| `./web/routes/business-plugins.d.ts` | 声明/映射 | `72fee3739477` | 5640 | `d50990983ad6` | 2944 |
| `./web/routes/business-plugins.js` | 运行时 .js | `3a752e01e4f1` | 135308 | `70d5c0f2085a` | 114041 |
| `./web/routes/business-plugins.js.map` | 声明/映射 | `d919d78e8a53` | 73109 | `545ed8c21cf2` | 59079 |
| `./web/routes/im.js` | 运行时 .js | `14dd9a0cf7c9` | 36738 | `d6ee03187ca1` | 27355 |
| `./web/routes/im.js.map` | 声明/映射 | `62d1cb88348e` | 22653 | `576a3c7f8ad6` | 18494 |
| `./web/routes/plugin-data.js` | 运行时 .js | `fac8f4dfe0d5` | 15523 | `—` | — |
| `./web/server.js` | 运行时 .js | `fcbbb9b34764` | 75298 | `c935e916d4fe` | 74822 |
| `./worker/agent.d.ts` | 声明/映射 | `e8799f5b6d55` | 7275 | `9cd56a9a914e` | 3445 |
| `./worker/agent.js.map` | 声明/映射 | `6a09bb376d7f` | 36616 | `2cf708d046f3` | 23514 |
> 完整 79 条原始清单(含两侧 md5/大小/mtime)= `tmp/p22-diff-pre.tsv`;补齐清单 = `tmp/p22-fill-list.txt`。
---
## 三、判据② · 补齐与归零
### 3.1 动作与读数
| 步 | 动作 | 读数 |
|---|---|---|
| 1 | 106 全量备份(改前) | `/opt/dsh/backups/lib-p22/106-pre-p22-20260925-120615.tgz`(sha256 `9612e4c0f63e024db3a7aceaa3088c26474e886c67cdafd848c80a8eba739233`)+ 同目录改前指纹清单 `…-manifest-20260925-120615.tsv` |
| 2 | 47 侧按清单打包 | `/tmp/p22-fill.tgz` = **232651 B** / 46 件,md5 `1ac3922cb3a3239a3f9d4cf59f7beb4f` |
| 3 | 传输完整性 | 106 收到后 md5 **同为** `1ac3922cb3a3239a3f9d4cf59f7beb4f` ✅ |
| 4 | 解包落地 | `tar xzf` rc=0;`lib` 文件数 **357 → 380**(+23 缺件);新建目录 `db/plugin-data`、`im/backends` 属主 **root:root 755** ✅(与既有目录一致) |
| 5 | 复核 | 重采 106 全量清单 ⇒ **代码面 368 = 368、内容不同 0、单向缺失 0**,`p22-verify.py` **rc=0** |
### 3.2 基准成立性(为什么拿 47 当基准是对的)
- 47 = **Manager 现行运行单元**(`dshs.service` 起于 `09-25 11:47:33`)所加载的那份代码 ⇒ 生产口径。
- 抽样验证 47 ≡ 本机构建产物 `D:/github/dsh_shenxian/lib`:`db/pg.js` `8f7923fb…`、`supervisor/remote-spawner.js` `269d3d20…`、`web/routes/business-plugins.js` `3a752e01…` **三件逐字一致**。
- ⚠️ 但**本机构建产物 ≠ 生产部署面全等**(见 §五-2)⇒ 本棒的基准**只取 47 生产面**。
---
## 四、判据③ · 106 待重启才生效的文件
### 4.1 106 的运行形态(现场取证)
- 单元:**只有 `dshs-worker.service`**(active,`ExecMainStartTimestamp = Fri 2026-09-25 09:52:11 CST`)+ `dshs-relay.service`;**⛔ 无 `dshs.service`**。
- 入口:`ExecStart = /usr/bin/node /opt/dshs-cluster/lib/cli.js worker --port 19000 --host 127.0.0.1 --host-id w-106 …`。
- ⚠️ 关键:`cli.js` **顶层静态 import** 了 `./db/index.js`(→ `./pg.js`、`./sqlite.js`)与 `./web/server.js`(静态 import **14 条 routes**)⇒ **web/db 层同样在 106 worker 的模块图内**(不是"106 用不到的库存")。
### 4.2 待重启清单
- **全部 46 件**(写入时刻 12:06+ **晚于** 进程启动 09:52:11)⇒ 进程内仍是旧版;**下次 `dshs-worker` 重启后才生效**。
- 其中 **运行时 `.js` 21 件**(其余 25 件为 `.d.ts`/`.js.map`,不参与运行)。
- **本棒改盘对运行中进程的行为影响 = 0**:ESM 静态图在启动时已全部求值并缓存,改盘不改变已加载模块。
- ⚠️ **残留理论窗口**:`web/routes/admin.js`、`web/routes/dsh.js`、`web/plugin-compat*.js` 内存在**动态 `import()`** ⇒ 若某目标模块在重启前**首次**被动态加载,会读到新文件,与内存中旧模块并存。未观测到异常;47 上"同版本组合"已在跑 ⇒ 判**低风险**;彻底消除 = 重启(⛔ 待用户给窗口,见入口 §5-19)。
- 📌 与 §5-19 **同源但不同事**:§5-19 说的是"p20 的 `plugin-assembly.js` 待重启";本棒补的是**另外 46 件**的待重启面。
---
## 五、新发现(⛔ 本棒未动 · 已登记入口 §5)
### 5.1 106 落后面远大于第 21 棒顺带看到的那一件
第 21 棒只看到 `web/routes/business-plugins.js` 落后(`70d5c0f2…` / 114041 B / mtime `09-25 00:28`,而 47 为 `4109ba34…` 投前)。本棒全量核对:**代码面落后 46 件**,`business-plugins.js` 只是其中之一。该文件的落后 = **缺第 17 棒(可观测性 + `-w` 修)、第 19 棒(`essential` 标记)、第 21 棒(`reconcile` 口)三轮改动**。
### 5.2 🔴 本机构建产物 ≠ 生产部署面(后棒 ⛔ 别拿本机 `lib` 当基准)
`D:/github/dsh_shenxian/lib`(**09-25 11:44 新构建**)与两机部署面(09-23 20:59 的 IM 版)不同,且**两机缺的是同一批**(不是 106 独有):
| 类 | 件 | 本机 | 47 / 106 |
|---|---|---|---|
| 运行时 `.js` 内容不同 | `im/backends/gateway.js` | 16241 B | 12077 B |
| 运行时 `.js` 内容不同 | `im/connection-backend.js` | 4154 B | 3342 B |
| 运行时 `.js` 内容不同 | `web/routes/im.js` | 47262 B | 36738 B |
| 本机独有 | `im/gateway-token.{js,d.ts,js.map}` | 7280 B(`.js`) | **两机都没有** |
| 本机独有 | `web/essential-plugins.{d.ts,js.map}`、`web/routes/plugin-data.{d.ts,js.map}` | — | 两机只有 `.js` |
- 另有 31 件 `.d.ts`/`.js.map` 差异(本机构建与部署面构建不同次 ⇒ 声明/映射产物不同),**运行时 `.js` 不受影响**。
- ⇒ 定性:本机 `lib` 含 **IM 线尚未投放的改动**(本机文件更大 + 多出新件)。**⛔ 本棒未据此改任何一侧**(超出"两机差异核对"范围;且那批件属 IM 线投放决定)。**已登记为待查项。**
---
## 六、未做 / 未闭合(⛔ 不得据本文宣称"运行面验收通过")
| # | 项 | 为什么没做 |
|---|---|---|
| 1 | **106 重启以使 46 件生效** | 中断在线用户 ⇒ **待用户给窗口**(同 §5-19) |
| 2 | **运行面读数**(重启后 106 上实跑新代码) | 依赖第 1 项 ⇒ 本棒**只完成"文件面归零"**,⛔ 未验证运行面 |
| 3 | 投本机独有 7 件(`im/gateway-token.*` 等) | 超出范围 + 属 IM 线未投放件 |
| 4 | 清两侧 33 条备份残留 | 不可逆 + 别处部署面历史留档 ⇒ 只报告 |
| 5 | 46 件在 106 上的**功能影响面**核对(哪几件 106 真的会用) | 已做模块图取证(`cli.js` → `db/index.js` + `web/server.js` 14 routes ⇒ 全在图内),未逐件做行为核对 |
---
## 七、回滚
```bash
# 106 回滚(恢复改前整棵 lib)
cd /opt/dshs-cluster && tar xzf /opt/dsh/backups/lib-p22/106-pre-p22-20260925-120615.tgz
# 或按需只回滚单件:从该 tgz 内取对应路径(题录:./db/pg.js 等,相对 lib 根)
```
- 47 侧**零改动**(本棒只读 47,只写 106)。⛔ 未 commit / push;⛔ `src/web/routes/im.ts` 零改动;⛔ 未手改用户 `home` 下 profile / `.pnpm`。
---
## 八、卫生
- 47 `/tmp/p22-fill.tgz`、106 `/tmp/p22-fill.tgz`、`/tmp/p22-lib106.tsv`:本棒临时件(入口 §9 口径:`tmp/` 留 7 天)。
- 新建目录仅 `106:/opt/dsh/backups/lib-p22/`(备份)与工作区 `tmp/p22-*`。
- 锁:本棒域锁(`aliyun-dsh-server/接续入口_插件投放与分库线_20260922.md`)收口时释放。
---
*生成:`tmp/p22-report-gen.py`(表由清单现算,非手抄)。*