refactor(sdk)!: 废除自定协议号,版本身份只由版本号本身承载

兼容性判据原有三处自造版本号,全部删除:
  - procProtocolVersion(模板侧握手常量)
  - shmVersion / shmOffVersion(共享段 header)
  - unifiedVersion(SuperBlock)

为什么废除:语义版本变动频繁(修 bug、加字段),再要求人去升一个额外的号,
那个号必然漏升而腐烂。实证:ProtocolVersion 常量在多次布局变更里只升过一次,
而对应的守卫测试(TestProcTemplate_ShmLayoutMatchesKernel)长期处于失败状态
无人察觉 —— 它当时期望 shmStageFieldCount=18/shmVersion=1,实际已是 19/2。

取而代之的两个判据都是**结构的派生事实**,不需要谁记得去同步:
  1. 主版本号:内核 meta.Version ↔ 插件 sdk.SDKVersion 的主版本段比对。
     主版本跃迁正是破坏性变更的定义(1.0.0 从 C ABI 改子进程即属此列),
     所以它天然是正确分界。
  2. field_count:StageContext 描述符个数,决定标志位基址。

顺带修正了 shmFlagsOff:原实现用本插件的编译期常量推算标志位基址,
内核加字段时会静默错位。现改为从 header 读取内核下发的描述符个数。
SuperBlock 的 version 槽位保留(不动其余偏移),值不再写入也不再校验。

判据:TestProcTemplate_RejectsIncompatiblePeer(含 banned 列表,
防这些号被重新引入)。
This commit is contained in:
JianFeeeee
2026-10-13 09:39:15 +08:00
parent bd26c2a402
commit b2872f3702
6 changed files with 144 additions and 67 deletions

View File

@ -32,17 +32,33 @@
想用新字段的重编即可。
!!! tip "什么时候必须重编"
只有两种情况:① 内核跨了中版本(如 1.1 → 1.2)且你用了新 API;
② 内核的 RPC 协议版本变了(`.hmap` 里的 `protocol` 字段与内核不匹配)。
后者的错配**不会静默失效** —— 握手时会显式拦下。
只有一种情况:**内核跨了主版本**(如 1.x → 2.x)。
主版本跃迁是破坏性变更的定义,此后的帧格式与共享段布局都不兼容,
必须用配套 `hmapdev` 重编。
## RPC 协议版本
**中版本跃迁(如 1.1 → 1.2)不需要重编**:1.x 内的新增全部是
「插件调用、内核实现」,不调新面就不受影响。
插件包里带 `protocol` 字段,必须等于内核的 `ProtocolVersion`(当前 **2**)。
## 协议兼容性:只认主版本号
协议 v2 引入了调用帧(tool / cleaner / output)与 `blocks_ref` 媒体块。
v1 插件遇上 v2 内核会拿到空参数,反过来 v2 插件发 `blocks_ref` 会被 v1 内核静默忽略 ——
**两边错配都不报错、只是静默失效**,所以协议版本在握手上显式校验。
**没有独立的协议版本号。** 兼容性由双方版本号的**主版本段**表态:
内核的 `meta.Version` 与插件的 `sdk_version`(插件包里的 `sdk_version` 字段,
即编译时链接的 SDK 版本)。
| 内核 | 插件 SDK | 结果 |
|---|---|---|
| 1.4.0 | 1.0.0 / 1.1.0 / 1.3.0 | ✅ 建链(同主版本) |
| 1.4.0 | 2.0.0 | ❌ 拒绝(跨主版本) |
**为什么不设独立的协议号**:语义版本变动频繁(修 bug、加字段),如果每个
这类改动都要人去升一个额外的号,那个号必然会被漏升而腐烂(历史实证:
曾有一个 `ProtocolVersion` 常量,多次布局变更里只升过一次,而对应的守卫
测试长期处于失败状态、无人察觉)。让兼容性只挂在**始终会被发的那个号**上,
就没有「忘同步」这个失效模式。
跨主版本错配**不会静默失效**——握手时会显式拦下,并提示用配套 `hmapdev` 重编。
此外握手还会比对 `field_count`(StageContext 描述符个数):它决定标志位基址,
不一致会让插件读到错位字段,因此也在握手上显式拒绝。
## 怎么确认自己在用什么