Skip to content

[design/bug] DSH auto-review 与主会话共用 session 持续制造 CACHE SEAM;建议拆分为可压缩的 derived review lane #2203

Closed

Description

@kettly1260

Description *

main-agent traffic 和 auxiliary-review traffic 被错误地建模成了同一条 session/cache lineage。

本 issue 建议不要再次采用 “识别 auto-review 后直接 side-passthrough” 的方案,而是将 auto-review 建模为:

main session 的 derived child/review lane:状态隔离,但仍然经过 bili,并保留独立压缩能力。


Environment

  • billion-context: 0.1.185
  • DSH: 0.2.0-rc.2
  • DSH Web profile
  • @deepseek-ai/dsh-experimental-auto-review enabled
  • billion-context native DSH plugin
  • Windows
  • reproduced session:
session-a215f0cf-648a-4134-ab96-0b4aa8691429

Observed behavior
在该 session 中,bili dashboard 当时显示大约:
requests:          19
input:             ~641K
cached:            ~315K
cumulative hit:    ~49%

CACHE SEAM:        ~189K × 10

compressionCount:  0
active blocks:     0

这里最关键的是:
compressionCount = 0
active blocks = 0

也就是说:
这些 CACHE SEAM 在 bili 做任何 compression 之前就已经出现了。

因此这次现象不能解释为 fold 修改历史造成的 cache invalidation。
Request sequence
实际请求呈现出非常规律的两种形态。
Main-agent requests
主 Agent 的 history 持续正常增长,例如:
13 msgs
16 msgs
19 msgs
22 msgs
25 msgs
28 msgs
31 msgs
...

其 system prompt 大约:
~13.9K chars

主 Agent 请求在稳定阶段通常具有较好的 cache hit,例如:
~77–94%+

Auto-review requests
但每次工具调用附近都会插入一个完全不同形态的请求:
2 wire messages

即:
system: REVIEW_POLICY
user:   reviewUserText(snapshot)

在 bili processTurn 侧基本表现为:
1 core message

system prompt 大约:
~3.9K chars

这些 review request 经常出现:
cache hit = 0%

What bili sees
因为 main agent 和 reviewer 共用同一个 session id,bili 实际看到的是类似:
13 msgs
  ↓
2 msgs      <- auto-review
  ↓
16 msgs
  ↓
2 msgs      <- auto-review
  ↓
19 msgs
  ↓
2 msgs
  ↓
22 msgs
  ↓
2 msgs
...

即:
13 -> 2 -> 16 -> 2 -> 19 -> 2 -> 22 -> 2 -> ...

从 byte-level prefix/cache lineage 的角度,这并不是:
old history + new turn

而是不断在两个完全不同的 request families 之间切换。
因此 seam detector 合理地观察到:
main lineage
   ↓
review lineage
   ↓
main lineage

并持续记录 CACHE SEAM。
问题在于:
这些 seam 被记在了 main conversation 的 session trajectory 中。

Why this matters
这不仅仅是 dashboard 的统计不好看。
当两种 traffic 共用同一 session 时,理论上或已经在既有问题中观察到的受影响状态包括:
- cache ledger
- CACHE SEAM trajectory
- usage baseline
- lastInputTokens
- nudge baseline
- refs
- remembered snapshot
- lastMessages
- orphan-GC visibility
- compression state bookkeeping
即使其中一些状态现在已经有局部 guard,session identity 本身仍然没有被正确拆分。
对于 cache accounting 来说尤其明显:
main-agent request

和:
auto-review request

根本不是同一条 prefix chain,却被当成同一个 session 的相邻调用进行 cache continuity 分析。
This is NOT a compression-configuration problem
我测试时使用的 compression 配置包括较高的 nudge interval / context threshold,但当前 reproduction 中:
compressionCount = 0

因此修改下面这些参数都不能解决根因:
compress.maxContextLimit
compress.nudgeGrowthTokens
compress.tiers
preserveRecentTokens
preserveRecentMessages

因为问题发生在第一次 fold 之前。
Relation to existing issues
这个问题与以下 issue 同属一个问题族:
#1307
#1307 已经证明:
- DSH auto-review 使用主 session id;
- review 请求表现为 request: 2 msgs / processTurn: 1 msgs;
- review request 可以破坏 remembered snapshot;
- 随后的 plugin-path compress 可能无法 anchor。
当前 0.1.185 reproduction 的 request shape 与 #1307 一致。
#1309 / #1314
这两个 issue 已经讨论:
- auxiliary request isolation
- auto-review
- side-request semantics
- reviewer 自身的上下文成本
- host-side structured review input
所以本 issue 不是重新报告 “review request exists”。
本 issue 聚焦的是一个当前仍然可观察的残留:
review traffic 和 main traffic 仍然共享同一个 bili cache/session lineage,因此会持续污染 main session 的 CACHE SEAM 和 cache accounting。

Why #1431 / #1861 are not the desired final design
曾经有两个相关 PR:
- #1431
- #1861
它们的方向基本是:
detect auto-review
        ↓
side-passthrough
        ↓
do not touch bili kernel state

这种方案确实可以防止 reviewer 污染 main session。
但它的代价是:
reviewer no longer participates in bili compression

这也是后来这些 PR 被关闭时指出的问题:
让 auto-review 直接穿过、不压缩,不是最终设计目标。

我同意这个判断。
因此这里建议的不是重新引入 side-passthrough,而是把请求身份拆成两个 lane。
Proposed design
1. Treat auto-review as a derived child session
逻辑上:
main conversation
       |
       +-- derived auxiliary/review session

例如:
session-main-123
    └── review:dsh-auto-review

二者可以保留 parent-child relation,但必须分别维护:
cache ledger
cache seam trajectory
refs
nudge
usage baseline
snapshot
lastMessages
orphan-GC state
compression blocks

也就是说:
main lane != review lane

2. Reviewer must still go through bili
这里与 side-passthrough 的关键区别是:
NOT:

auto-review
   ↓
detect
   ↓
bypass bili

而应该是:
auto-review
   ↓
detect / classify
   ↓
derived review session
   ↓
normal bili pipeline

这样 reviewer 未来仍然可以拥有:
- independent compression
- independent cache accounting
- search_context
- decompress
- CCR / retrieval
- observability
同时不会破坏 main conversation。
3. Preferred host signal
最干净的方案是 DSH 明确告诉 bili:
this request is auxiliary review traffic.

例如:
x-bili-request-class: auxiliary-review
x-bili-parent-conversation: <main-session-id>
x-bili-plugin-agent: dsh-auto-review

bili 可以据此创建或解析:
parent session:
  session-main

child lane:
  session-main / dsh-auto-review

而不是继续使用完全相同的 session state object。
4. Temporary bili-side compatibility
在 DSH 还没有实现显式 header 之前,bili 已经有足够稳定的信息识别 auto-review,例如:
- fixed REVIEW_POLICY
- one synthetic review user message
- no normal main-agent tool surface
- stable DSH review persona/signature
短期可以:
detect DSH auto-review
        ↓
route to derived review lane

但不要:
detect DSH auto-review
        ↓
side-passthrough

这可以先解决 session/cache lineage 污染,同时不给 reviewer compression 这条路线封死。
Reviewer compression itself
还有第二层问题。
当前 DSH auto-review 基本构造为:
system:
  REVIEW_POLICY

user:
  ENVIRONMENT
  PROJECT_INSTRUCTIONS
  FILTERED_HISTORY
  PENDING_ACTION

其中 FILTERED_HISTORY 被重新序列化进一个巨大的单条 user message。
从 bili 的角度看,review request 实际只有一个巨大的 message。
因此即使把 reviewer 独立成 child session,当前形态仍然不利于 ACP compression:
one huge synthetic message

没有正常的 message-level ranges 可以 fold。
5. Keep FILTERED_HISTORY structured
更理想的是 DSH 将 reviewer 输入保持为结构化 history,例如:
system:
  REVIEW_POLICY

history item 1
history item 2
history item 3
...
history item N

user:
  PENDING_ACTION

或者:
REVIEW_POLICY
+ filtered structured projection of main session
+ PENDING_ACTION

而不是把全部历史重新 stringify 成一条字符串。
这样 review lane 才能真正获得:
- stable prefix caching
- message-level compression ranges
- recent-history preservation
- old-history folding
- search/decompress
- incremental growth
6. Filtering semantics can remain host-owned
这并不要求 reviewer 必须看到 main Agent 的全部原始历史。
DSH 仍然可以继续决定:
- 哪些 assistant messages 保留;
- 哪些 tool calls 保留;
- 是否排除 tool results;
- 哪些 project instructions 可见;
- 哪些 source attribution 可见。
关键区别只是:
filtered history as structured messages

而不是:
filtered history as one giant serialized blob

这样不会要求 bili 重新实现 DSH 的 review policy。
Expected behavior after fix
修复后:
Main session
应该只看到:
13 -> 16 -> 19 -> 22 -> 25 -> ...

而不再看到:
13 -> 2 -> 16 -> 2 -> 19 -> 2 ...

auto-review 不应再增加 main session 的:
CACHE SEAM
cache miss accounting
usage baseline
nudge state
refs
snapshot changes

Review session
应该单独看到:
review 1
review 2
review 3
...

并拥有自己的:
cache hit rate
CACHE SEAM
compression count
blocks
usage
nudge

如果 DSH 后续采用结构化 history,那么 review lane 自己应该能逐渐形成稳定 prefix,并在需要时独立压缩。
Suggested acceptance criteria
修复可以用下面这些条件验收:
1. 开启 DSH Auto Review 后,main bili session 不再出现:
N msgs -> 2 msgs -> N+... msgs

2. auto-review request 不再增加 main session 的 CACHE SEAM。
3. reviewer 有自己的 derived session / lane identity。
4. main conversation cache hit 恢复为正常 append-only conversation 的水平。
5. reviewer 仍通过 bili,而不是 raw passthrough。
6. main lane 与 review lane 的:
refs
nudge
usage
snapshot
orphan-GC
compression blocks

相互独立。
7. 如果 reviewer history 已结构化,review lane 可以正常:
compress
search_context
decompress

8. Web UI 最好能显示类似:
Main session
└── DSH auto-review

方便诊断 parent/child relation。
Why I think this is the correct abstraction
现在的问题本质并不是:
"How do we detect a side request?"

而是:
"How do we represent multiple LLM request lineages
that belong to one user-facing conversation?"

DSH main Agent 和 DSH auto-review:
- 属于同一个高层 user session;
- 但不是同一个 prompt lineage;
- 也不应该共享一套 compression/cache state。
因此更自然的模型应该是:
user conversation
    |
    +-- main-agent lane
    |
    +-- auto-review lane

而不是:
one session id
    |
    +-- every LLM request mixed together

Related
- #1307
- #1309
- #1314
- #1431 (closed)
- #1861 (closed)

---

这版我认为维护者是能直接看懂的,而且它有一个重要优势:**没有只报“缓存低”这种症状,而是把现象、证据、与旧 issue 的区别、为什么旧修法不合适、建议的新抽象和验收标准都给出来了。**

尤其一定要保留这一组证据:

```text
CACHE SEAM ×10
compressionCount = 0
active blocks = 0

### bili version *

0.1.185

### Usage mode *

Plugin native (bili plugin install …, runs inside the host process)

### Client and version *

dsh 0.2.0-rc.2

### Operating system *

 Windows 11

### Upstream and model *

gemini-3.8-flash

### Compression-related config (optional)

```yaml

Log excerpt (strongly recommended)


/acp or acp_status output (optional)


Activity

  1. ranxianglei commented on Oct 5, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 已收到。先给审核结论(对照 master e5a0066de 源码与测试逐条核过),再列需要你补的证据。

    1. 查重与机制现状:你提的核心抽象已经在 master 上(v0.1.181 起)

    本 issue 不是 #1307/#1309/#1314 的重复——那一条线(快照护栏 #1312 → 根治讨论 #1309/#1314 → 两个 passthrough PR #1431/#1861 均关闭未合并,master 上已确认无 #1861 marker 代码残留)最终落地的方案正是你描述的抽象:「拆身份,不绕管线」——persona fingerprint 拆分(PR #1956,#1916 lineage),v0.1.181 起已发版:

    • dsh 请求带 x-bili-plugin: dsh 时,session key 从纯 conversation id 变为「id + system 提示词指纹」:主 agent 的 system 锚定原 key(kernel anchor 语义),auto-review 的固定 REVIEW_POLICY system 落到自己的会话 <id>|sub:<fp>(src/server.ts:2189-2213、src/session-id.ts 的 dshPersonaFingerprintApplies)。
    • 拆分后两会话各自独立维护 refs / nudge 基线 / usage baseline / snapshot / orphan-GC / cache ledger / CACHE SEAM 轨迹 / compression blocks——与你列的受影响状态逐项对应;review 请求走完整管线(非 passthrough),保留独立压缩/search/decompress 能力。你的验收标准 1–6 在「有文档化的流量形状」下按设计成立。
    • 已被 tests/dsh-persona-fingerprint.test.ts 钉死(真实 proxy e2e:主轮锚定 raw key → review 形状 fork 到 |sub:<fp> → 连续 review 复用同一 fork 会话 → 主会话计数/快照不变 → conversations map 单值纪律),并经 feat: side-lane regression hardening — pure lane gates, truth tables, canaries, CI lane guard (#2170) #2175 加固(泳道判定真值表 + runtime canary + CI lane guard)。

    所以「passthrough 不是终态」的判断与仓库最终走向一致;本 issue 的真正增量是 (a) 你在 0.1.185 上仍观察到未拆分,(b) 验收标准 8(UI 树形)。

    2. 关键判断:你的复现说明 fork 在你的环境里没触发——这才是待查的根因

    你的 dashboard 显示 19 个请求全在同一 session(13→2→16→2 交错、seams×10 记在 main 上)。若拆分生效,dashboard 会是两行:main(约 9 请求、无 seam)+ 一行 |sub:<fp>(web 列表是平铺的,|sub: 行会独立出现,不会合并进主行)。而 fork 代码确认包含在 v0.1.185 内(git tag --contains 核过),因此你的环境里必有某个条件让谓词漏掉。候选按可能性排序:

    1. 陈旧内嵌运行时(最可能):plugin 模式跑在 dsh 进程里——bili 自更新只换磁盘文件,进程内驻留的还是启动时的旧码,重启宿主才生效(auto-update installs but never activates on long-lived plugin hosts; unwritable install dir retries every 3-min cycle for 11+ days #1603)。拆分 10-03(v0.1.181)才落地;若你的 dsh 在那之前启动且一直没重启,磁盘 0.1.185 ≠ 进程内 0.1.185。
    2. review 请求没带 x-bili-plugin: dsh:拆分谓词要求这个 marker(KDD#9 白名单纪律)。若你 dsh 版本/profile 里 classifyRisk 走另一条 LLM 调用路径、不打插件头,fork 不发生。
    3. google native wire 缺口(代码层面确认存在):拆分分支目前只覆盖 openai/anthropic wire;protocol === "google" 时 keying 是 verbatim 的(src/server.ts:2195-2196,personaSystemText 对 google 也取空串)。如果你的 gemini-3.8-flash 端点说的是 Google 原生协议而非 OpenAI 兼容,拆分完全不会触发。

    3. 需要你补的证据(任一组即可定位)

    1. GET /__bili/status 的 JSON——看 version vs diskVersion/stale(直接裁决候选 1);或 /acp 面板的 staleness 行。
    2. ~/.local/state/billion-context/bili.log 里任一 2-msg 请求附近的日志行(processTurn: 1 msgs / request: 2 msgs)——[session-…] 前缀里有没有 |sub:?
    3. /__bili/sessions(或 web sessions 页)清单里有没有 id 以 |sub: 结尾的行?
    4. dsh 访问 gemini-3.8-flash 用的上游端点/wire:OpenAI 兼容 relay(/v1/chat/completions)还是 google-native?

    4. 方案评估(逐项)

    • 条目 1–2、4(derived lane / 仍走 bili / detect→lane 而非 bypass):同意,且即已实现方案,无需新设计。
    • 条目 3(显式 host header,如 x-bili-request-class):长期方向成立(与 [跟进] 辅助请求(auto-review/classifier)需统一隔离策略——与 #1075 冲突,需 owner 拍板 #1309/[design] 辅助请求的会话身份判定与审查请求自身的压缩 —— #1312 止血后的根治方向 #1314 讨论过的 host-marker 方向同族),但建议暂缓:① 属新增协议/config surface,按仓库配置面纪律需 owner 拍板并映射到既有机制;② 需 DSH 侧配合(跨仓工作);③ 一个具体陷阱——现有 x-bili-plugin-agent + SIDE_REQUEST_AGENTS 集合的语义是「side request = passthrough」,把 "auxiliary-review" 塞进去正好走到本 issue 反对的路径上;要做,语义必须是「命名子 lane」而不是「side request」。先弄清指纹为何在你环境失手,再看它是否真的必要——指纹路线今天零宿主改动即可工作。
    • 条目 5–6(结构化 FILTERED_HISTORY / 过滤语义留宿主):分析完全同意(单条巨型消息 = 无可折区间 + 零前缀复用,这层成本可能比快照问题更大)。但这是纯 DSH 侧改动(deepseek-harness 仓库),超出 bili 范围;要推进需在该仓库立项,跨仓动作我会先报 owner 批准。
    • 验收标准 8(Web UI 显示 Main └── auto-review):未实现——web 会话列表平铺,|sub: 行与主行并列。这是小的 bili 侧改动,值得做(见下)。

    5. 建议的下一步(明确建议,非选择题)

    1. 先用第 3 节的证据定位你环境的失手原因。命中候选 1 的话,重启 dsh 现象即消失,无需改码;命中 2/3 则按实际形状修(补 google-wire 分支属于同一白名单内的补全,是按 KDD#9 纪律我会先看到真实流量证据再动)。
    2. 暂不引入显式 header 协议——失败模式未确认前加新面是过度设计。
    3. 两个小的 bili 侧改进可作为后续 PR(引用本 issue):① web UI 把 |sub: lane 显示为父会话的子项(+ 可选在 fork 上记录显式 derivedFrom 链接,对齐 [pi plugin] Prime RLM inline 派生子会话在代理模式下零继承:搜不到也解压不了父会话压缩块(billion-context-pi#531 同场景) #1333 derived-session 模式);② dsh e2e golden lane(tests/e2e/e2e-native-dsh.test.ts)目前没有任何 review/fork 用例,只有单元级 server 测试钉住该行为,补一个端到端形状用例。

    证据一到我就继续在这个线程推进。

  2. kettly1260 commented on Oct 6, 2026

    @kettly1260
    Author

    @ranxianglei 我按上面的 4 组证据查完了,已经能进一步定位。
    结论:不是 stale runtime,也不是 google-native;实际缺口是 DSH persona fingerprint 没有覆盖 Responses wire。
    GET /__bili/status:
    {
    "version": "0.1.185",
    "diskVersion": "0.1.185",
    "stale": false
    }
    而且发生问题时的生产日志逐行明确为 [v=0.1.185],因此可排除旧内嵌运行时。
    复现 session:
    session-a215f0cf-648a-4134-ab96-0b4aa8691429
    protocol = responses
    clientHint = dsh
    upstream = https://ai.sample.com
    实际日志:
    forward POST -> https:///v1/responses
    因此不是 google native。
    同一安装环境中 Anthropic DSH 已经存在正常 persona fork:
    session-53c1f292-0108-4957-81c8-565abfe11366
    session-53c1f292-0108-4957-81c8-565abfe11366|sub:1e893fddc811aa5b
    说明 |sub: 机制在本机确实可以工作。
    但所有 DSH Responses 会话都仍是 raw session id,没有对应 |sub:。
    直接核对 v0.1.185/src/server.ts 后,原因似乎就在当前分支逻辑:
    const personaSystemText = protocol === "openai"
    ? openaiSystemTextForPersona(...)
    : protocol === "anthropic"
    ? systemTextsForSplit.join("\n\n")
    : "";
    dshPersona && subagentNamespace(...) 也只出现在 anthropic 和 openai conversation 分支。
    Responses 分支走的是 instructionsFingerprintApplies(req.headers),而 src/session-id.ts 中这个 allowlist 只覆盖 Codex / Claude-over-Responses,并不包括 DSH。
    因此对:
    x-bili-plugin: dsh
    protocol: responses
    当前代码实际上不会执行 DSH persona split。
    这与实测完全吻合。相同 raw session 中 system 在两种 persona 之间反复切换:
    [fold-reconcile] system prompt changed (3859 -> 13927 chars)
    ...
    [fold-reconcile] system prompt changed (13927 -> 3859 chars)
    reviewer:
    processTurn: 1 msgs
    request: 2 msgs
    input ~= 18K-20K
    cached = 0
    main agent:
    processTurn: 69 msgs ...
    input ~= 70K
    cache hit ~= 90-96%
    两者都继续记录在:
    session-a215f0cf-648a-4134-ab96-0b4aa8691429
    所以我认为 #2203 现在可以从 design discussion 收敛成一个更具体的 parity bug:
    DSH persona fingerprint is implemented for OpenAI chat / Anthropic, but not for Responses wire.
    建议修复:
    Responses + dshPersona 也用 subagentNamespace(..., body.instructions);
    同步扩展 rawPersonaIdentity/personaForked;
    同步扩展 designNamespaced canary;
    给 tests/dsh-persona-fingerprint.test.ts 增加 Responses parity e2e: main raw key -> review |sub: -> repeated review same fork -> main state unchanged。
    Google-native 可以作为另一个 parity gap 处理;本次生产复现明确是 /v1/responses。
    所以当前不需要新增 host header,也不需要重新设计 derived lane;现有 persona-fingerprint 设计只需要补齐 DSH Responses wire。

  3. ranxianglei commented on Oct 6, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 四组证据非常关键——定位完全正确,已修复。PR: #2232 (Closes #2203)

    1. 是什么问题
    DSH auto-review 与主会话共用同一 conversation id,而 bili 在 Responses wire 上没有做 persona-fingerprint 分裂——review 请求(固定 REVIEW_POLICY instructions + 新拼装的扁平 blob)在主会话内部走完整管道,持续踩踏主会话的 remembered snapshot / nudge baseline,制造 CACHE SEAM、压缩永不触发。

    2. 什么原因导致的
    persona-fingerprint 机制本身(v0.1.181 起随 #1916/#1307 上线)只实现了 OpenAI-chat / Anthropic 两条 wire。Responses wire 的 identity 分支走 instructionsFingerprintApplies(),其 allowlist 只含 codex / claude-over-Responses,不含 dsh → 所有 dsh /v1/responses 流量落进 verbatim、按 raw id 键控。你的证据链依次排除了 stale runtime(status+日志版本号)、google-native(日志明确 /v1/responses)、机制失效(同机 anthropic fork 正常产生 |sub:),正好钉死这个 parity gap;根因在 host 侧身份解析,不在 kernel。

    3. 怎么修复的
    parity 补齐,不引入新机制(与你的结论一致:不需要新 host header,也不需要 derived-lane 重设计):

    修复后 review 会话拥有独立状态、可独立压缩;主会话前缀保持 byte-stable。

    4. 是否有回归问题
    逐项审过既有行为:codexTurn trusted-turn 路径未动;codex/claude-over-Responses 指纹逻辑未动(纯 OR 追加);opencode/grok 等非 allowlist 客户端仍 verbatim;side request(小预算+无 tools)仍按原样经 sideRequestLike 走 side lane;anthropic/openai lane 未动;google-native 未动(见第 6 问)。唯一有意行为变更:stableSystemAnchor 开启时,dsh-responses 旧走 anchored verbatim 路径、新走 persona split——这正是修复方向本身。定向测试 33/33 绿(dsh-persona-fingerprint 全量 + e2e-stable-system-anchor + codex-turn-isolation + side-lane truth-table/invariants + e2e-session-identity),全量回归交给 CI。

    5. 是否破坏缓存
    这正是对缓存的修复:分裂后 review 不再打断主会话前缀——你日志里 cached=0 的 review 请求从此落在自己的 fork 会话,主会话命中率回到 90%+。缓存失效策略(去重键/游标/重试)均未受影响。

    6. 是否改了设计方向
    没有。这是对现有 persona-fingerprint 设计(KDD#9)的 wire parity 补齐,不是 issue 提议的 derived-lane 重构,也没有引入显式 host header。google-native wire 是同一机制族的剩余面(identity ternary 的 google 分支同样没有 dsh case);按 allowlist 纪律(需流量证据才准入),等出现真实的 dsh-google-native 流量再补,在本 issue 跟踪(同机制同失败域,不另立项)。

    7. 是否引入了新的配置
    无。无新 env/config/默认值。

    回归测试:tests/dsh-persona-fingerprint.test.ts 新增 responses-lane e2e(真实代理管道:main 锚定 raw key → review fork 到 |sub:<fp> → 重复 review 复用同一 fork → 主会话 stats/snapshot/conversations-map 条目全部不变 → 无 instructions 辅助调用 ride raw key)。stash 验证:未修复代码上该测试失败,修复后通过。

    判定:待 CI 绿灯后合并。合并后请在生产环境复核:dashboard 应出现 <id>(主会话,前缀干净)与 <id>|sub:<fp>(review,独立压缩计数)两行独立条目。

  4. ranxianglei commented on Oct 6, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 收工状态:CI 25/25 全绿,待人工合并。

    PR #2232(分支 2026-10-06_dsh-responses-persona-fork,head 21ce73108)最终栈:

    1. 980fd4e96 核心修复:DSH persona fingerprint 补齐 Responses wire(src/server.ts 身份判定 + src/session-id.ts 文档注释 + tests/dsh-persona-fingerprint.test.ts 新增 Responses parity e2e)
    2. 7af68e4ad lane-guard 要求的 truth-table 扩展(responses 协议格 + dsh auto-review 形状不触发 side-lane 的钉死)
    3. c3661fff2 side-lane 不变量 (E)(并行会话已推入同分支的提交)
    4. 21ce73108 drive-by 小修(见下)

    Drive-by 小修(独立机制,已立项 #2236):tests/pi-subagent-registry.test.ts 的单槽 fake-Pi Map 会吞掉 #2186(wirePiSubagents,pi.ts:939)注册的第二个 session_start handler,导致 #2185 的 factory-wiring 测试自 #2209 合入起在 master 上红(pristine base bd33b11 复现,与本 PR diff 无关)。修法:fake 改为 per-event handler 数组 + fire-all,与真实 host 的多播行为对齐;本地 10/10,CI 上此前红的三个 test matrix job 由此转绿。注意:存在并行修复 PR #2237(Closes #2234,同一根因同一修法),已在 #2236 交叉引用——owner 二选一即可;若 #2237 先合,#2232 rebase 时直接丢弃该 commit,无内容损失。

    验证清单:typecheck 干净;定向套件 33/33 + pi-subagent-registry 10/10;stash 证明(新 e2e 在未修改代码上失败、修复后通过);CI 全矩阵 25/25 绿(含 lane-guard、dsh plugin lane、全部 real-client lane)。

    合并后请验证(升级下一版本后看 dashboard):① 主会话行保持 raw <id>,review 请求落到独立的 <id>|sub:<fp> 行;② 主会话不再出现 CACHE SEAM;③ 主会话 compressionCount 恢复正常累积。有异常随时回帖。

    合并判定留给 owner:#2232

  5. ranxianglei commented on Oct 6, 2026

    @ranxianglei
    Owner

    检测下master是否已经彻底修复这个问题

  6. ranxianglei commented on Oct 6, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 检测结论:master(c4ae70796)尚未彻底修复——Responses wire 缺口仍在,PR #2232 已 rebase 到最新 master 并与其后的 #2247 设计对齐。

    检测过程(全部基于当前 master,非 PR 分支):

    1. 代码核对:src/server.ts 身份判定三元组的 Responses 分支仍只查 instructionsFingerprintApplies(allowlist 仅 codex/claude)+ plain-proxy 的 stableSystemAnchor;无 dsh 条款。rawPersonaIdentity 仍只覆盖 openai/anthropic。即 x-bili-plugin: dsh 走 /v1/responses 依旧 verbatim 落在 raw session id——本 issue 的生产复现路径原样存在。
    2. 实证复现:把 [design/bug] DSH auto-review 与主会话共用 session 持续制造 CACHE SEAM;建议拆分为可压缩的 derived review lane #2203 的 responses parity e2e 直接在 pristine master 上跑 → FAIL(AssertionError: 'review request landed on its own forked session');同文件其余 7 个测试(openai/anthropic lane、[bug] dsh:side request 先到会抢走 persona 锚点,主会话被 fork 到 |sub:<fp>,原生 compress 永久失败 #2156 anchor 竞争、allowlist pin)全过——说明 anthropic/openai 的 persona fork 健康,缺的正是 responses wire。
    3. master 已有的相关进展:fix(#2241): continuity-aware dsh persona anchor — model switches migrate the anchor instead of forking the main lane #2247(dsh-persona-continuity)把 anthropic/openai 升到 continuity-aware anchor(model switch 迁移锚点而非 fork 主泳道);fix: pi-subagent-registry fake stores per-event handler arrays (#2234) #2235 修掉了 master 上红的 pi-subagent 测试;v0.1.186 已发版。这些都不覆盖 responses wire。
    4. 未修清单:① dsh-over-Responses verbatim 共会话(本 issue 主体);② google-native wire 同样没有 dsh 条款(已知 facet,按 KDD#9 证据纪律需该 host/wire 形状的流量证据后再启用,跟踪在 [design/bug] DSH auto-review 与主会话共用 session 持续制造 CACHE SEAM;建议拆分为可压缩的 derived review lane #2203 内)。

    PR #2232 现状(head 370e1493e):rebase 到 c4ae707 后把 responses lane 对齐到 #2247 同一机制(dshPersonaNamespace:review blob fork 到 |sub:<fp>、model switch 迁移锚点、无 instructions 非锚定)——原方案用的 kernel subagentNamespace 会在 responses wire 上重新引入 #2241 的 model-switch fork 问题,故弃用。drive-by commit 已丢弃(对应修复已经由 #2235 独立进 master)。本地 typecheck 干净 + 定向 48/48(含 #2247 的 continuity 套件与全部相邻身份套件)。CI 快 job 已全部绿(lane-guard、dsh plugin lane、real-client lanes、e2e、theorem),test matrix 与 windows registry 在跑。

    合并判定留给 owner:#2232

  7. ranxianglei commented on Oct 6, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 补充:PR #2232(head 370e1493e)CI 已 25/25 全绿(含 lane-guard、dsh plugin lane、real dsh headless profile lane、全部 real-client lanes、test matrix 四格、hermetic registry 双平台)。待人工合并:#2232

  8. ranxianglei commented on Oct 7, 2026

    @ranxianglei
    Owner

    现在再检查 检测下master是否已经彻底修复这个问题

  9. ranxianglei commented on Oct 7, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 重新检测完成(master 86191d6ac,v0.1.187 之后):尚未彻底修复。Responses wire 上的 dsh persona 分叉仍然缺失,修复目前只存在于未合并的 PR #2232。

    检测方法与证据(两条独立证据链)

    1. 代码审查(origin/master src/server.ts identity 三元组,Responses 分支):

      • 分支顺序仍是 codexTurn → stableSystemAnchor(plain-proxy) → instructionsFingerprintApplies → verbatim;instructionsFingerprintApplies 的 allowlist(src/session-id.ts)仍只覆盖 codex / claude-over-Responses,不含 dsh;
      • 没有 dsh 专属子句;rawPersonaIdentity 仍只有 openai/anthropic 两个 case。
      • 即:x-bili-plugin: dsh over /v1/responses 依旧按 raw id verbatim 记账 —— 与生产复现路径完全一致。
    2. 实测(pristine master worktree @ 86191d6ac,跑本 PR 的回归测试 tests/dsh-persona-fingerprint.test.ts):7/8 通过,唯一失败就是 e2e responses lane #2203,断言 AssertionError: 'review request landed on its own forked session' —— 与上一轮在 c4ae707 上的结果一致。openai/anthropic 两个 lane 的 persona fork 测试均通过,说明其他 wire 没问题,缺口只在 Responses。

    master 这段时间的相关进展(方向对,但没覆盖到本问题):

    PR #2232 状态:已按你的要求在今日重新 rebase 到当前 master(86191d6ac),并适配 #2271 的重命名——新 Responses 子句现在调用泛化后的 personaNamespace(...)(与 anthropic/openai/codex-instructions 三个 lane 同一机制),另修了 rebase 带入的一行缩进漂移。新 head 31adfb4d7:typecheck 干净、定向套件 48/48、pristine master 上该 e2e 仍失败(证明是真实回归测试)、CI 正在跑。diff 收敛为 src/server.ts 三处 hunk + session-id.ts 文档注释 + 3 个测试文件。

    结论:合并 #2232 后此问题才算彻底修复(google-native wire 的同类缺口仍按 KDD#9 evidence-per-client 纪律留在本 issue 跟踪,需该 host/wire 形状的流量证据后再启用)。CI 全绿我会再报一次。

  10. ranxianglei commented on Oct 7, 2026

    @ranxianglei
    Owner

    🤖 Powered by ework · qwen3.8-27b

    [bot] 🏷 CI 跟进:PR #2232 新 head 31adfb4d7(rebase 到 master 86191d6ac + #2271 重命名适配)全矩阵 27/27 通过,含 lane-guard、e2e、hermetic registry(ubuntu+windows)、real-client 各 lane、4 组 test matrix。

    当前状态小结:

    • master 未修复本问题(检测结论见上一条:代码审查 + pristine master 实测 e2e 失败双证据);
    • 修复完整存在于 PR fix: dsh persona fingerprint parity for the Responses wire (#2203) #2232,diff 收敛(src/server.ts 三处 hunk + session-id.ts 文档注释 + 3 个测试文件),行为变更披露在 PR 的 Behavior change 节(仅 dsh-over-Responses 流量:raw id verbatim → main/review persona 分叉 <id>|sub:<fp>,模型切换走 anchor 迁移不分叉);
    • 无配置面/持久化格式/kernel 变更;google-native wire 同类缺口按 KDD#9 留在本 issue 跟踪。

    等人工合并即可收工。

  11. added 2 commits that reference this issue on Oct 7, 2026
  12. added a commit that references this issue on Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions