fix(proc)!: shm 桥 v2 —— fExtraBag 透传插件自建 Extra 键,修复绑桁权限门失效

根因(2026-10-12 生产实证):shm 桥此前只透传 4 个具名 Extra 键
(media_blocks/media_type/input_source/output_channel),插件自建键
(qq 的 qq_auth 绑帧身份)在 WriteDirty/captureLocal 处被静默丢弃,
下一 stage ReadInto 重建的 Extra 永远没有它 → authOnFrame 恒 miss →
before_toolcall 回落到可变全局身份。owner 轮被并发的非 owner 中断
合并降权后,自己的 memory_commit 被硬私名单误拒(日志 22:20:58
「改写了 1 个字段」);反向时序则可能把非 owner 误放为 owner。

- shm.go:stageField 加 fExtraBag(19 字段),shmVersion 1→2
  (AttachSegment 与插件握手对旧版失败即拒,不静默错读新布局)
- shmcodec.go:captureLocal/WriteAll/ReadInto/newSnapshotFromLocal
  全链接入 bag;写侧过滤具名键(bag 不偷具名键槽位);读侧 bag 先
  打平、具名键后覆盖(具名键永远赢);不可序列化值显式报错——
  宁失败不静默丢键(丢键对 qq 是权限失效)
- extra_bag_test.go:判据 8 条(往返无损/具名键语义不变/不可序列化
  报错/WriteDirty 零写与脏写/跨 stage 帧存活/袋污染具名键必输/
  raw-JSON 写侧过滤/快照脏检),变异 M1-M3 全杀

配套:SDK 仓 777c3a0(模板 v2 同步 + qq 身份可序列化 + 插件侧判据)。
部署注意:shmVersion 2 后全部 23 个 proc 插件须用新 hmapdev 重编。
This commit is contained in:
JianFeeeee
2026-10-12 08:30:14 +08:00
parent b15994d964
commit 6abf03bd78
3 changed files with 397 additions and 2 deletions

View File

@ -18,9 +18,13 @@ import (
)
// 共享段魔数与版本,用于挂载时校验对端布局一致。
//
// v2(2026-10-12):新增 fExtraBag —— Extra 具名 4 键之外的插件自建键
// (如 qq 的 qq_auth 绑帧身份)跨进程/跨 stage 透传。加字段必升版:
// AttachSegment 与插件握手对版本失败即拒,旧插件不会静默错读新布局。
const (
shmMagic uint32 = 0x48415348 // "HASH" — HomeAgent SHared
shmVersion uint32 = 1
shmVersion uint32 = 2
)
// 段布局(所有偏移均相对**段起始**,arena 内偏移相对 arenaBase):
@ -84,10 +88,22 @@ const (
fMemory // JSON
fTokenUsage // JSON
fErrors // JSON
fExtraMediaBlocks // JSON —— Extra 的 4 个键提升为具名字段(§3.3 已核实使用点)
fExtraMediaBlocks // JSON —— Extra 的 4 个键提升为具名字段
fExtraMediaType
fExtraInputSource
fExtraOutputChannel
// fExtraBag 承载 Extra 里**具名 4 键之外的全部插件自建键**(JSON)。
//
// 背景(2026-10-12 权限失效修复):qq 插件靠 ctx.Extra["qq_auth"] 把
// 身份绑到推理帧上(中断抢占/并发合并场景下全局身份不可靠,见该插件
// README「身份必须绑帧」)。但此前的桥只透传 4 个具名键,插件自建键
// 在 stage 之间静默丢失 → before_toolcall 永远回落到可变全局身份 →
// 绑帧(以及建立在它之上的权限门)在 proc 插件下整体失效。
//
// bag 把 Extra 恢复成「任意键跨进程/跨 stage 存活」的原语义。值以 JSON
// 往返:插件侧拿到 map[string]interface{}(数字统一 float64),不能
// 类型断言回私有 struct —— 插件侧解码约定见 sdk example/qq。
fExtraBag
stageFieldCount
)