Repository navigation
[PR] fix(resume): inherit timestamp ledger so resumed sessions re-render provider-cached tag bytes - #5609
Conversation
…5608) A stamp is keyed by raw id (SHA-256 of message identity) and renders into the ACP tag time= attribute — cache-relevant bytes. Two paths dropped the ledger, so the first replay after a resume/fork re-rendered every tagged message differently from what the provider had cached: - adoption (resume hit / fork receipt): refs, blocks and view latches were carried, tsStamps was never carried (#4313 landed after those carries were written) → time-less tags where the original process rendered time-stamped ones; - resume-inheritance miss: fresh state + empty ref map made the stamp node mint Date.now() for days-old history (the honesty lie its own doc warns against) → the one-generation 1–12% cache collapse reported in #5608 shapes B/C. seedTimestampsFromParent copies the parent's ledger into the child (child entries win); inherited values always denote the exact bytes the model saw, replaying the stored first-sight time verbatim = the provider-cached tag bytes. Ids absent from the parent map stay honest NULL. Applied on both paths: applyForkAdoption (hit) and the handle.ts miss branch seeding from the closest tracked chain (miss). No new config/env surface.
📦 Built Package ArtifactBranch: Latest build — install this exact versionnpm install -g billion-context@0.0.8927-pr.5609.aab6725This exact version is immutable and reproducible. The rolling Recent builds (commit → version)
Download artifact
tar xzf billion-context-pr5609.tgz
npm install -g packageInstall instructions are refreshed on each push. |
[bot] 🏷 标签: bug / dsh / scope/kernel / p1(缓存命中崩坏致成本爆炸 = p1 缓存泄露类;机制在会话核心逻辑——resume/fork 继承时丢时间戳台账) 查重: 不重复。 在途 PR 中唯一触碰 版本基线: head = master + 单 commit(无陈旧基线),base d244fff 即当前 master。diff 已拉取通读(3 文件 +164/-1)。 审核进行中:正在独立验证机制主张(tsStamps 持久化链路、 |
|
(ai: vllm-qwen/qwen3.8-27b) APPROVE(review 结论以评论形式给出——本账号即 PR 作者,GitHub 禁止自批自 PR,无法落正式 approve review 事件)。独立审过代码与行为(未照抄 issue/PR 描述)。改动最小、隔离、有测试、无 kernel/ 触碰、无新配置面。已本地定向验证。 八问
行为变更披露(旧 → new)开启 timestamps 的会话,resume/fork 首轮重放的 验证
非阻塞观察(不改,留记录)① miss 路径 handle.ts 那 ~20 行接线没有直接集成测试(被测函数本身已充分覆盖;完整 handleRequest harness 太重,不值得单开)。② 判定:可合(APPROVE)。 |
(ai: vllm-qwen/qwen3.8-27b) review-worker-r1 完成:APPROVE。完整结构化八问结论已发上游 PR #5609 评论(comment id 6603407027);本账号即 PR 作者,GitHub 禁止自批自 PR,故无法落正式 approve review 事件,结论以评论给出。要点:机制独立验证通过(内容寻址杜绝错绑、child-wins、flag-off no-op、tsStamps 经 mergeState 跨重启持久化);本地定向跑自带测试 6/6 pass;A/B 证实相邻两测试文件(resume-ref-inheritance / resume-adoption-wires) |
…5608) Review follow-up on #5609: handlePluginFork copied every sibling ledger (refs, blocks, latches) but dropped tsStamps, so the first replay after a public ACP fork re-rendered the provider-cached time= attrs from freshly minted now-times - the same one-generation prefix re-bill this PR fixes on the adoption and resume-miss paths. Same symptom, same mechanism, so it lands here rather than as a separate issue. Also completes the miss-path wiring coverage: an end-to-end two-phase test (persist chain under id A, restart, equal-depth replay under id B) pinning that the closest tracked chain donates its ledger above the MIN_RESUME_PREFIX floor.
(ai: vllm-qwen/qwen3.8-27b) 审核结论:方向正确、机制独立验证成立;审核中发现并直接修掉了第三条丢失路径(同症状同机制,按政策并入本 PR),已推送标注 commit 审核中我做了什么(不是重做,是补漏)
结构化八问
行为变更披露(old → new)
遗留事项(不在本 PR 范围)
收工判定:可合(等 |
…er-cached prefix (#5608) A resume-inheritance MISS started FRESH state: new ref numbers, minted-now (or absent) tag times, and RAW ranges where the old process sent FOLDED carriers. Every tagged byte flipped vs the provider-cached prefix, so the whole history re-billed for one generation (the 1-12% one-generation cache collapse in #5608). The miss path now adopts from the CLOSEST tracked chain instead of starting bare (maybeAdoptResume with blocksEnabled: true). Refs/blocks/latches/timestamps are all raw-id (content-hash) keyed, so every carried value denotes the exact bytes the model saw; set-semantics adoption self-defends against the deep divergence that broke the byte-exact gate (a block whose sources were mutated is simply straddled). Honest ceiling: the true common prefix. applyForkAdoption also carries the tsStamps ledger (#4313 landed after the other carries were written, so adoption dropped it): without it the first replay rendered time-less tags where the original rendered time-stamped ones. maybeAdoptResume gains an optional via phrasing so the weak path logs its relationship honestly; strong-path log output stays byte-identical (pinned by a regression test).
…nudge state, #5555 copy sweep) master d244fff is born-red on these four goldens (#5415 added persisted nudge state fields without regenerating); the sentinel converged the regen onto origin/ci-fixes 4809a83 per the CI-coordination policy (#4599). This head carried the stale copies verbatim, so every shard failed the same four assertions. Adopting the sentinel-converged files instead of regenerating keeps one source of truth. Verified under the full CI preload chain: golden-storage-render 5/5 green here (was 1/5).
Under the CI preload chain (tests/preload-test-env.mjs) the suite-wide BILI_MESSAGE_TIMESTAMPS=0 pin suppresses stamp minting entirely, so the two #5608 tests that prove ledger inheritance fail their stamp preconditions (and their ledger equality would be tautological without them). Defeat the pin per test with save/restore, mirroring tests/message-timestamps-default-on.test.ts:45. Verified under the full CI preload chain: both files green together with golden-storage-render (71/71), typecheck clean.
(ai: vllm-qwen/qwen3.8-27b) 状态更新(分支移动 + 两处残留修复): 分支状态:审核期间分支落了 owner 侧新提交 6d40dd1——miss 路径从「只 seed 时间戳」升级为从最近链做完整弱采纳(refs/blocks/latches/stamps 全部按内容寻址值继承;强路径日志保持不变并有回归钉)。评估:方向成立且严格强于 seed-only(连 ref 编号与折叠载体一并恢复),对深度分歧自防御(源被改写的块直接跳过不采纳);我此前的 b6270ab 第三路修复仍在历史中。 新 head 上的两处残留问题(本地复现并已修):
本地按完整 CI preload 链验证:golden-storage-render + resume-miss-timestamp-seed + plugin-fork 共 71/71 绿,typecheck 干净。已推 c73b1af。 更正说明:我先前在 #4599 报告的「新 head sha=d658f5b7c」现已不在分支上(GitHub API 422 No commit found);本次推送基于当前 tip 6d40dd1 重新落地了同样两个修复。 结论不变:可合,等 c73b1af 的 CI 重跑转绿。 |
# Conflicts: # tests/golden/storage-render/anthropic.json # tests/golden/storage-render/chat.json # tests/golden/storage-render/google.json # tests/golden/storage-render/responses.json
🔶 需要决策 本轮已完成(机械部分):PR 与 master 的合并冲突已解决并推送——merge 红 CI 根因(不是继承性失败,是 PR 自身提交的行为变更):本地定向复现 + 二分钉死——基座 d244fff 与 b6270ab 上涉事测试全绿,owner 提交 6d40dd1(resume-inheritance MISS 从「只 seed 时间戳」升级为「从最近链全量弱采纳 refs+blocks」)一上,同一批测试立刻红,签名与 CI 完全一致;合并 master 后失败集不变(纯该提交贡献,非 master 漂移、非负载抖动)。受影响:9 个 e2e 回归文件、13 条断言(issue1993×3、ccr-v2、fix-781-summary-images、issue1195-overflow-refold×2、issue2733、preflight-nonstream-400-probe、preflight-stream-summary-config×2、cache-friendly-plugin #3769、wire-exit-matrix error-delivery)。机理一致:弱采纳把旧进程的 blocks/refs 恢复回新会话后,原本「fresh start → 重新 fold / 触发 preflight 摘要 / fail-fast 502」的路径变成了「已覆盖 no-op / 跳过摘要直接 200」。其中多数断言像是钉死了旧行为(新行为正是 #5608 想要的缓存前缀恢复),但个别(wire-exit-matrix 期望 200 实得 429、#1993 的 fail-fast 错误契约)可能是门过宽的真实信号——逐条裁定超出机械修复范围。 选项:
在决策落地前我停手不动此 PR(自动修复车道 attempt 1/3,剩余尝试留给决策后的执行)。备注:#4599(CI 总控)的镜像线程号在本环境解析不到,按身份规则不猜编号,状态行未发,特此说明。 结构化八问(本轮)
判定:冲突已清、根因已钉、球在决策区——拍板 A/B/C 后我继续收尾。 |
(ai: vllm-qwen/qwen3.8-27b) 新 head(2d3230a)CI 重跑核查完毕:红项与上轮完全同源,无新增破坏,决策请求(floor 16)仍然有效、仍在等拍板。 本轮做了什么:
结构化七问(本轮)
|
(ai: vllm-qwen/qwen3.8-27b) 本轮为重复触发,无新动作:本次通知指向的 run(41666118938)与上一轮(floor 19 已核查)是同一 run、同一批 job、同一 head(2d3230a),失败集已在上一轮逐条比对并本地 A/B 钉死——全部同源 owner 提交 6d40dd1(resume-miss 弱采纳 vs 11 个 e2e 文件的旧语义基线)。线程里仍无 A/B/C 拍板,机械修复空间为零,未重复拉日志、未动分支。 七问(本轮)
|
(ai: vllm-qwen/qwen3.8-27b) 新 head(91be1cc,「sync master 预合并重跑」——他人推送,线程内未见 A/B/C 拍板记录)核查完毕:失败集与既有家族完全同源,master 同步未引入新破坏。决策请求(floor 16)继续有效。 本轮做了什么:
七问(本轮)
|
…5608) v2's miss path adopted the closest tracked chain unconditionally once byte-exact matching failed. Content similarity alone cannot PROVE same- conversation identity, and three measured misfire shapes ship exactly that (false-positive cross-session adoptions inside one proxy process): equal-depth two unrelated sessions resending the SAME conversation bytes under new ids — #3686 replayed a 15K-token fixture verbatim across lanes and the foreign fold block landed on the declared-pi session ('no fold may land' broke) truncated a session resending a SHORTER subview of another session's live chain head break near-duplicate boilerplate conversations diverging at cell 0-8 of short chains (#3450/#3645/preflight families saw inherited token budgets flip fail-fast paths) v3 gates the weak rung to the ONLY shape identity can be argued for: strictly-deeper prefix-break continuations whose verified common prefix reaches >= WEAK_ADOPT_MIN_PREFIX_RATIO (0.8) of the parent chain depth. The floor sits just below the lowest production telemetry reading in #5608's maintainer comments (dsh desktop restart LCP floor 632/760 = 0.83) and far above every measured CI misfire (<= 0.67). Equal-depth replays never adopt weakly again, restoring the #1486 stance v2 overrode without proof; truncated subviews likewise start fresh. Every rejection logs its shape and numbers; honest-log discipline unchanged. fork-adoption.ts and plugin.ts are untouched (bisect proved them innocent of the red CI).
…and pin the v3 adoption gate (#5608) The old e2e fixture was an equal-depth byte-exact replay — precisely the shape v3 now rejects by design, so it could not coexist with the fix. It now sends what production actually does (telemetry in #5608): the same history with recent-tail drift plus one appended turn under a new id, which defeats byte-exact matching and lands on the weak rung. Assertions now pin the actual bug contract: days-old stamp values ride over UNCHANGED (the seed copies the whole parent ledger), only the fresh/drifted turns are minted live, and the adoption stays logged, not silent. New sibling test pins the gate itself: an equal-depth replay and a truncated subview of a tracked chain must both start FRESH with their OWN ledgers and name their rejection reason — the two shapes whose adoption was red on CI.
v3: 弱收养加身份门(修上一轮全红)上一版(v2,commit 6d40dd1)把 red CI 带回来了,根因不是某个测试坏了,而是 miss 路径拿到“最近的链”就无条件收养——它没有身份判断。字节精确匹配本身没问题;问题在它失效之后没有任何兜底证明。本地探针实测出三种误伤形状(同一代理进程内、跨会话的假阳性):
生产真实形状(本 issue 维护者评论里的 dsh 桌面重启遥测)只有一种:严格更深 + 只在近期尾部漂移,已验证 LCP 下限 632/760 ≈ 0.83。这跟三种误伤形状之间有干净的间隙。 改动(2 commit:
|
CI 复跑分析:v3 已修掉全部 7 个误伤套件,剩余红全是 master 自身带的新 run
master 侧的失败家族还包括 #1993×3、#2777、cache-friendly #3769、e2e #1195 C、e2e #2133×2、e2e #781×2、planAware search、CCR v2、preflight #829、error-delivery SSE 等(老 run 各 shard 里可见)。 关键验证:本分支 run 的全部日志里,上一版(v2)带红的 7 类签名一个都不再出现(#3686 “no fold may land”、#3450 stated completion、#3645 fail-fast、fix-1001 ref 计数、preflight-hold/empty-summary)。本地矩阵:受影响 7 套件全绿(35/35)+ resume-miss-timestamp-seed 10/10 + plugin-fork 57/57 + tsc 通过。 结论:v3 的身份门把误伤清零;PR 在 GitHub 上继续显示红是基线问题——需要有人先把 master 的这波红(#2817 / dsh-lane guard / #5418 A/B 等)修绿,之后本 PR 的 CI 才能转绿。建议在单独 issue/PR 处理 master 红,不和本 PR 混。 |
(ai: vllm-qwen/qwen3.8-27b) 收到你的「结局冲突」(floor 64)。这条太简短,我不敢替你解读成某个决定——先把刚核实的几处「冲突」摆出来,请你指认指的是哪个、要我做什么: A. 本线程前后两个相反判定(若「结局」=结论):不是自相矛盾,是跟着范围变的——早期 APPROVE 针对不含内核的旧 head B. 分支现在是 C. 正文一致性:已核实当前正文已正确带 在你明确前我不动分支、不擅自下结论。请告诉我 A / B / C 哪个(或其它)、以及期望动作。 |
(ai: vllm-qwen/qwen3.8-27b) 冲突已解决并推送(4eeb781):把 master(d640d0d)merge 进 PR 分支,唯一文本冲突 = acp-kernel 版本行(三处文件),按 max+1 裁定为 0.0.185。镜像 mergeable_state 会随轮询从 dirty 自动转干净。 七问:
|
|
(ai: vllm-qwen/qwen3.8-27b) FINDINGS-ONLY REVIEW(head 本轮新增:master 同步合并的正确性(重点核过)head
八问(特性未变,答案稳定;逐机制深析见上一轮 review)
行为变更披露(旧值 → 新值,同上一轮)
测试 & CI
非阻塞观察(不改代码,留记录)① 判定master 同步合并干净正确,特性与上一轮我审的实现逐字一致、CI 无失败。但因触碰 |
|
🔶 需要决策 (ai: vllm-qwen/qwen3.8-27b) 针对新 head PR #5609 触及
独立评估见上一条 findings review:master 同步合并干净正确(union-of-intent、特性符号完整、共享内核文件零 churn)、实现正确、隔离良好、测试有牙、CI 无失败(8 shard 收尾中)。请求 owner 授权合并此内核变更。 |
(ai: vllm-qwen/qwen3.8-27b) PR #5609 复审完成(新 head |
(ai: vllm-qwen/qwen3.8-27b) PR #5609(新 head |
…ses large histories locally; log every direct send with its size
Owner ruling 2026-11-07 (items 1-3 as one PR; item 4 deferred):
(1) Calibrated estimate tier. The shared over-window predicate now
prices bodies at bytes/4 x CALIBRATED_TEXT_TOKEN_RATIO (1.14, the
measured billing bias from #5613's session ledger) on top of the
optimistic floor. The old bar is strictly nested: anything the floor
already refused is still refused (provablyOver); anything only the
calibrated estimate crosses is refused too, since direct-sending it
was a coin flip weighted toward a guaranteed upstream 4xx. Missing
data (no size / no window / undecodable stays all-core) keeps
fail-open by construction.
(2) Large-history fail-close lands on BOTH gate arms: the thrown-
attribution settle path (#2924/#3581/#5609 lineage) and the unattributed
arm (#4068). Local refusal = 422 with the token math in the durable
line; small lanes keep #1117 direct semantics byte-for-byte.
(3) Every bare DIRECT send now carries its body size (or an explicit
'size unknown - the fuse could not run' note) and logs on a bounded
cadence (first occurrence / state change / every 10th), so a leaking
agentless lane can no longer stay silent after line one. Streamed
bodies with a declared Content-Length are now priced from it instead
of being skipped, so the fuse also arms for large streaming sends.
(ai: vllm-qwen/qwen3.8-27b) Conflict resolved and pushed ( Environment note (transparency): between runs this sandbox was reset — 七问:
|
📦 Merged Build PublishedThis merge to master was published as npm install -g billion-context@0.0.1168-master.a51e11f # this exact build
npm install -g billion-context@master # always the newest merged build
|
…6150 fold-point removal) Master independently bumped the kernel to 0.0.193 for the compressAtFoldPoint removal; this PR's overlap atomic-reject changes now sit on top of that, so the version must move again (max+1, same precedent as #5609 sync). Both lockfiles regenerated; diff vs master is only the kernel version lines.
Resume-miss timestamp seeding + v3 adoption gate + fold-boundary discipline (#5608)
What this fixes
A desktop client (dsh) that restarts mints a new session id while resending its full history, optionally with a re-rendered tail line. bili saw "unknown id + full old history" and — depending on how closely the resend matched a tracked chain — either (a) started FRESH and re-minted today's date into every historical message's ledger, (b) adopted the closest chain and re-stamped, or (c) mis-adopted unrelated sessions under equal-depth/truncated shapes (the CI reds that first motivated this work: #3686-class byte-exact replays, stated-counts, preflight family). Every one of those paths changed wire bytes across the whole prefix ⇒ provider cache cliff ⇒ the 681K–760K token rebills reported in #5608 (hit rate 97.9% → single digits).
Layers (each independently pinned)
seedTimestampsFromParentcopies the parent's whole tsStamps ledger (orphaned ids included) so days-old timestamps survive an adoption instead of being re-mintednow.WEAK_ADOPT_MIN_PREFIX_RATIO); equal-depth and truncated shapes NEVER adopt (restores the Claude 上 resume 导致消息错乱 #1486 stance). Rejection logs name shape + numbers. This is what turned the 7 red e2e suites green and stays green on every CI shard.Date.now()values that would seed false timestamps into future lineage via wholesale ledger copies. Strong byte-exact resume stays un-armed: its uncovered tail is provably new work. Self-clearing; not hydrated after restart (drop = safe default).time=only once its ref seat exceeds the mark frozen from state (sync/fold/hydration carry; ledger alignment raises it). Flipping feat: Support precise timestamps for each message, allowing the model to recognize which messages are outdated and which | feat: 给每个消息支持精确时间,以让模型认识到什么消息是过期的什么是当前的新的 #4313 on mid-session, including the v0.1.209→v0.1.210 default off→on upgrade, changes zero prefix bytes until a tag's own content edit/fold remints it.Tests
New:
kernel/tests/issue5608-timestamp-tails.test.ts(4 pins); re-pinned S15 (cold load is now a no-op), HTTP fork survival, storage digests, and the miss-seed e2e now asserts the honest-NULL contract. Kernel suite 1580/1580; host battery green; tsc clean both trees; verif-subset-guard incl. negative control.kernel-change: #5608-B/C/D display-metadata fold-boundary discipline (owner-directed in session; issue #5797 closed per owner instruction 「不要立issue,原来的pr改」)
kernel/changed in commitskernel: #5608-B/C …(45027bb): types/compress/refs/sync + one new test file, version 0.0.180 → 0.0.181. Owner-directed in session (rulings quoted above); initial issue #5797 closed per instruction, this block is the standing declaration. Guarded-file duties: tests/verif-subset-guard.test.ts green (solver verif-* auto-skip without VERIF_PYTHON/cvc5).