Skip to content

[PR] fork: msgid identity track for the plugin fork protocol (#6262) - #6293

Open
ranxianglei wants to merge 2 commits into
masterfrom
2026-11-11_fork-msgid-track
Open

ranxianglei wants to merge 2 commits into
masterfrom
2026-11-11_fork-msgid-track

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

[PR] fork: msgid identity track for the plugin fork protocol (#6262)

一句话

fork(会话分叉)协议现在用 msgid 识别"共享父会话的前缀",不再只靠逐字节比对。某条消息在 fork 后被改写过(同一 id、字节变了),子会话也能完整继承该前缀——以前这种字节漂移会让 fork 前缀在漂移点被截断(首格漂移则 fork 直接失败)。

这是四原则提案(discussion #6262)的第一条:身份(msgid) > 顺序 > hash。本 PR 只实现插件通道(dsh/omp/pi 声明式 fork);非插件通道(服务端字节猜测收养)按讨论边界不动,后续 PR 处理。

为什么

现有 fork 前缀验证是字节精确匹配(stableJson + order hash)。两个现实失败场景:

  1. 宿主在父会话看到某消息之后重渲染/改写了它(同一 msgid,字节不同)→ 字节比对在该格停住 → fork 前缀被截断,其后的压缩块不被继承;
  2. 极端:首个消息格就漂移 → no prefix match → fork 失败。

"字节变、身份不变"是常态:#3011(fork 零继承,41 评论,用户讨论最热的 bug)、#5984(dsh-live-compact 改写宿主历史)都反复出现。

怎么做的

  • snapshot / fork 请求新增两个可选字段:prefixMsgIds(前缀每格的宿主 msgid)+ driftFrom(字节验证前缀的长度,即漂移区起点)。
  • 服务端 gate:host-pinned 父会话的 snapshot rawId 就是宿主 msgid;子会话声明的每格宿主 id 与父 rawId 逐格相等 → 接受字节漂移的前缀,回执标 status: "drifted"(跨块时 "expanded+drifted"),回显已验证的 driftFrom。
  • gate 失败不报错:任一 id/长度不匹配 → 回退现有严格字节 fork(exact/expanded),附加字段被忽略;只有字段形状非法才 400。
  • 老客户端零影响:字段纯增量可选,协议版本不升(v2 manifest 不动),不发字段的客户端走字节路径,行为与现在逐字节一致。
  • 不新增 msgid 校验副本:客户端复用各车道既有 parity-pinned 采集器(dsh hostMsgIdsOf;pi/omp laneMsgIdsForWire + content-pinnable 门,与增量 pin 同条件);服务端复用既有 identifier();tests/msgid-rule-parity.test.ts 的 6 副本矩阵不变。fork-adopt 自身只做"与投影 core 等长"一条锁。
  • opencode-v2 本 PR 未接线(走字节轨,后续补)。

验证

  • npm run typecheck 干净
  • 新测试 8/8(tests/issue6262-fork-msgid-track.test.ts:客户端前缀跨漂移格扩展、字节回退各分支、全链路代理 round-trip、服务端 gate drifted/strict/400 各臂)
  • fork 面 234/234 全绿(21 个既有 fork 测试文件 + 新文件)
  • dsh/pi/plugin/msgid/incremental 回归(见下,机器负载高,分两批跑)
  • tools/check-architecture-docs.mjs 全绿
  • 环境性失败甄别:dsh-native/dsh-admin-relay 的 55 个失败(全部 15s waitFor 超时形态)在基线树(未含本 PR)与本分支上失败集逐字节一致——与 [PR] fix: clear compress-failure accounting on rebase; exempt post-rebase stale-ref from the model breaker (#5984) #5985 验证轮同型,共享机负载(VBoxHeadless + sglang + 多 pi 进程)所致,非本 PR 引入。

边界

  • 只动插件通道(m01106 用户明确边界:"先搞插件通道的 非插件通道先不管")。
  • 服务端收养路径(fork-adoption.ts:匿名/resume/derived/boot)零改动。
  • 无行为变化清单外的任何改动:8 文件,src 4 个 + 文档 3 个 + 新测试 1 个。

相关

@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-11-11_fork-msgid-track (2eb2055)

Latest build — install this exact version

npm install -g billion-context@0.0.9319-pr.6293.06b95ac

This exact version is immutable and reproducible. The rolling pr tag tracks the newest test build across all PRs.

Recent builds (commit → version)

commit version build
2eb2055 billion-context@0.0.9319-pr.6293.06b95ac build
f377a6f billion-context@0.0.9201-pr.6293.049b1cb build
8644561 billion-context@0.0.9181-pr.6293.d697090 build

Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr6293.tgz
npm install -g package

Install instructions are refreshed on each push.

ranxianglei and others added 2 commits November 12, 2026 18:21
Principle 1 of the four-principles proposal (discussion #6262): identity,
not bytes, decides which prefix a fork inherits. The plugin-protocol
channel (dsh/omp/pi declared forks) gains an optional msgid track:

- a host-pinned parent exposes the host's stable message ids AS its
  snapshot rawIds, so the child may present the host id of each matched
  prefix message (prefixMsgIds) plus the hash-run length (driftFrom);
- the server accepts a byte-drifted prefix only when every presented id
  equals the parent's rawId at its slot; the receipt is marked
  status "drifted" (or "expanded+drifted") with the verified
  driftFrom echoed;
- a gate failure never fails the fork: the byte-verified strict fork
  proceeds exactly as before (no 409); malformed shapes are 400; parents
  without host-pinned ids make the track a no-op (byte path unchanged).

Client: lanes inject their existing parity-pinned collectors (dsh
hostMsgIdsOf; pi/omp laneMsgIdsForWire on the anthropic wire with the
same content-pinnable gate the incremental pin uses); fork-adopt
performs only the core-alignment length lock — no new validator copies,
msgid-rule-parity matrix untouched. opencode-v2 is not wired in this PR
(byte track, follow-up).

Tests: tests/issue6262-fork-msgid-track.test.ts (8) — client prefix
extension across a drift cell, the byte-fallback arms, a full-chain
proxy round trip, and the server gate (drifted receipt / strict
fallback / 400 arms). Docs: msgid-infrastructure.md consumer 6,
plugin-protocol.md section 8, architecture.md.
…k row (#6262) in en+zh

The PR's count bump (five→six consumers) left the table with only five rows
and the zh twin still at 五个. Adds the missing ⑥ row in both languages and
fixes the 'other four/five' cross-references in row ①.
@ranxianglei
ranxianglei force-pushed the 2026-11-11_fork-msgid-track branch from f377a6f to 2eb2055 Compare November 12, 2026 10:21
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

[bot] 🏷 (ai: vllm-qwen/qwen3.8-27b)

查重:不重复——open [PR] 列表中指向本线程的只有本 PR 一个,无并列修复分支。

结论:审核通过。旧 head 唯一的 CI 红项是 flake(偶发),非回归;审核中发现的 2 处文档缺陷已直接修掉并推送;PR 已 rebase 到最新 master,新 head CI 绿后即可合。

(上一轮会话在等 CI 时挂起被重启,本轮改为单次检查,以下为已核实的最新状态。)

验证与处置

  1. 方向(①):msgid 身份轨与四原则(身份 > 顺序 > hash)一致;gate fail-open——任一 id/长度失配静默回退严格字节 fork(不 409),只有字段形状非法才 400;字段纯增量可选、协议版本不升,老客户端行为与现状逐字节一致;不新增 msgid 校验副本(客户端复用各车道 parity-pinned 采集器,服务端复用 identifier(),6 副本矩阵不变)✓
  2. 代码(③):dsh/pi(omp)接线复用与增量 pin 完全相同的组合(anthropic-wire 门 + laneMsgIdsForWire + lanePinnableContent,与 pi.ts:1479/:1554 既有模式一致);opencode-v2 刻意未接线(PR 正文已声明,走字节轨后续补);新测试 8 个断言有牙,gate 双向覆盖(跨漂移格扩展 / 字节回退各分支 / 全链路 round-trip / 服务端 drifted、strict、normalized、400×4 各臂)✓
  3. 回归(②):严格字节路径(字段缺省时响应对象逐字节不变)、400 条件、v2 manifest、服务端收养路径(fork-adoption.ts)零改动;本地 A/B 中 2 个 responses-wire 测试失败在 base 与 head 上逐字节一致(环境性,与本 PR 无关)✓
  4. CI 红项:旧 head 8644561 的 test (windows-latest, 22, 3) 唯一失败是 tests/fork-replica-convergence.test.ts 的 fork receipts cut pinned fork_base checkpoints...,错误 TypeError: fetch failed(传输层,无断言失配),该 shard 1881/1898 通过、相邻对照测试 3.3s 通过、日志无 crash/OOM;master 全绿;本 PR 改动不触及该测试任何代码路径;PR head 本地定向跑 4/4 绿。判定:flake(Windows runner 传输层偶发),非回归。 新 head f377a6f 的 CI 已全绿(16 success / 14 skipped / 0 failed),印证判定。
  5. 顺手修(审核发现,独立 commit):docs/msgid-infrastructure.md 的"five→six consumers"计数更新漏了表格 ⑥ 行(fork-adopt msgid 轨),中文版 msgid-infrastructure.zh-CN.md 完全未更新(仍是"五个消费方")——两语言补 ⑥ 行并修正"其余四/五方"交叉引用。
  6. rebase:master 前进 1 个 commit([PR] fix: persist ledger rows before the model call (durability-before-render) #6326,与本 PR 零文件重叠)→ 已 rebase 到 9674cfa,新 head 2eb2055,CI 重跑中。

八问

  1. 是什么问题:功能 PR——fork 协议改用 msgid 识别"共享父前缀",使"字节变、身份不变"(宿主在 fork 后重渲染/改写消息)时子会话仍能完整继承前缀;以前字节漂移会让前缀在漂移点被截断,首格漂移则 fork 直接失败。
  2. 什么原因导致的:既有 fork 前缀验证是字节精确匹配(stableJson + order hash),而"字节变、身份不变"是常态([Bug] Fork of DSH branch clone: inheritance permanently abandoned by 409 SNAPSHOT_UNAVAILABLE — zero-fold clone triggers context_length_exceeded 400 on first turn | [Bug] DSH 分支克隆的 fork 继承被 409 SNAPSHOT_UNAVAILABLE 永久放弃:克隆零折叠,首轮即 context_length_exceeded … #3011/[Bug][compress] After rebase, the ref reported by acp_status/nudge is inconsistent with the ledger used by compress for | [Bug][compress] rebase 后 acp_status/nudge 报的 ref 与 compress 校验用的台账不一致:提示的区间必然 unknown,连续三次即熔断 #5984:宿主压缩后改写历史),字节比对在漂移点停住。
  3. 影响范围与严重程度:仅插件车道(dsh/omp/pi)声明式 fork;不发字段的老客户端行为与现状逐字节一致;非插件通道(服务端字节猜测收养)不动。属功能非缺陷,解决的是 [Bug] Fork of DSH branch clone: inheritance permanently abandoned by 409 SNAPSHOT_UNAVAILABLE — zero-fold clone triggers context_length_exceeded 400 on first turn | [Bug] DSH 分支克隆的 fork 继承被 409 SNAPSHOT_UNAVAILABLE 永久放弃:克隆零折叠,首轮即 context_length_exceeded … #3011 "fork 零继承"的 p2 级用户痛点。
  4. 怎么修复的:snapshot/fork 请求加可选 prefixMsgIds + driftFrom;客户端把字节匹配前缀沿 id 稳定段延长(逐格 宿主 id == 父快照 rawId);服务端 gate 逐格验"子声明宿主 id == 子重发前缀的 rawId"(host-pinned 父的 rawId 即宿主 id)→ 接受漂移前缀,回执标 drifted/expanded+drifted 并回显 driftFrom;gate 失败静默回退严格字节 fork。
  5. 是否有回归问题:无。严格字节路径 / 400 条件 / 协议版本 / 6 副本矩阵 / 服务端收养路径均未变(逐项见上③);本地 A/B 的 2 个 responses-wire 失败 base/head 一致(环境性)。
  6. 是否破坏缓存:否。不触及缓存/重试/增量游标/去重键路径;增量车道与水位车道未动。
  7. 是否改了设计方向:无转向——四原则提案(discussion 提案:fork 继承四原则(msgid 身份轨 / lineage 编号 / 无状态账本 / 纯块拷贝) #6262)第一条的落地,只动插件通道,非插件通道明确留给后续 PR(PR 正文已声明边界)。
  8. 是否引入了新的配置:无。无新 env/config/CLI;纯协议增量可选字段(v2 manifest 不动)。

标签:pr(原有)+ dsh、pi(本 PR 接线的插件车道;omp 经 pi 同一工厂覆盖)、scope/wiring(插件协议接线)、p3(功能 PR,无用户可见缺陷)——已打。

CI 结论已同步到 #4599。合并/收工判定:代码+文档就绪、flake 已印证、PR 已 rebase 到最新 master(新 head 2eb2055),新 head CI 绿后即可合并(人工合并)。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

[bot] 🏷

(ai: vllm-qwen/qwen3.8-27b)

进度汇报:rebase 完成、新 head 全 CI 绿,合并只差 full-matrix 门。

已完成(相对上一条回复的增量)

  1. Rebase:master 前进 1 个提交(9674cfafbc78,[PR] fix: persist ledger rows before the model call (durability-before-render) #6326 durability-before-render 的 merge,与本 PR 文件零重叠),已 rebase 到其上 → 新 head 2eb2055a48(force-with-lease 推送)。
  2. 新 head 10 个 workflow 全绿:CI、e2e-local-registry、CI Windows codex overlay (E2E verify on real Windows: codex accepts CODEX_HOME overlay and registers the bili MCP server (#681 / PR #683) #686)、e2e-native-pi、e2e-pi-codex-ws、e2e-native-dsh、E2E (real codex)、e2e-dsh-plugin-lane、e2e-fake-codex、PR Build Artifact —— 全部 completed/success。
  3. core matrix 11 个 test job 全 success——含之前一次性 flake 过的 test (windows-latest, 22, 3)(已判共享机负载,见 CI Control Center: Centralized CI Failure Handling & Status Sync (Comment all CI issues here; do not open new issues) | CI 总控: CI 失败集中处理与状态同步(所有 CI 问题在此评论, 勿开新 issue) #4599 评论),本次绿。
  4. 两处文档修正(msgid-infrastructure en+zh 补第六消费方行)已包含在新 head 内。

为什么 mergeable_state 仍是 blocked(已 live 核实)

  • 上一条回复「CI 绿后即可合并」是基于 check runs 第一页(30/52)的判断,补查全量后修正:
  • master 分支保护的 required checks = 14 个 test context:ubuntu 22×3、ubuntu 24×3、windows 22×5、windows 24×3。
  • .github/workflows/ci.yml:windows node-24 legs 是 FULL-only(152-153 行注释原文「The windows node-24 legs stay FULL-only」;CORE_TEST 不含 windows-24,只有 FULL_TEST 含)。
  • 本 PR 无 ci:full 标签 → 只跑 core matrix → 那 3 个 test (windows-latest, 24, N) context 永远不会上报 → 分支保护判 blocked。
  • 这是仓库设计的 full-matrix 门(release PR 天生 full scope,普通 PR 需打标),不是 CI 失败,与本 PR 代码无关。

选项(各带代价)

  • A. 给 PR [PR] fork: msgid identity track for the plugin fork protocol (#6262) #6293 加 ci:full 标签 → 触发 full matrix(含 windows 24×5,每 shard ~13-17min,尾部可到 ~35min)→ 14 个 required checks 全绿 → 可合并。代价:一轮 full CI 负载(共享机当前负载不低)。
  • B. force-merge / 临时调分支保护(owner 判断 core matrix 覆盖已足够)。代价:本 PR 跳过 windows node-24 的测试覆盖。
  • 推荐 A——设计内流程,full matrix 是仓库对任何 PR 的合并门。需要我代加标签说一声即可。

八问

  1. 是什么问题:本 PR(插件 fork 协议的 msgid 身份轨)审查与修复已全部完成,当前唯一事项是合并被 full-matrix 门挡住。
  2. 什么原因导致的:分支保护无条件要求 windows-24×3 context,而 CI matrix 里 windows-24 legs 是 FULL-only、仅 PR 带 ci:full 标签时运行——设计内门,非缺陷。
  3. 影响范围与严重程度(按选项):A——仅本 PR,多一轮 full CI 负载,无其他影响;B——本 PR 少 windows node-24 测试覆盖,无其他影响。均无外部用户面影响。
  4. 怎么修复的:无需代码修复——打标触发 full matrix(A)或 owner force-merge(B)。
  5. 是否有回归问题(按选项):A——无,只是把既有测试套件跑全;B——无,代码不变,仅本 PR 验证覆盖减少。
  6. 是否破坏缓存:不涉及。
  7. 是否改了设计方向:不涉及。
  8. 是否引入了新的配置:不涉及。

结论:代码侧已闭环(审查 + 文档修正 + rebase),新 head 10 个 workflow 全绿;只差 ci:full 标签(或 owner force-merge)后即可人工合并。

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant