Repository navigation
[PR] fix: failed-only compress rounds end the turn — ephemeral failure frames never reach upstream (#4186) - #4217
ranxianglei wants to merge 3 commits into
Conversation
📦 Built Package ArtifactBranch: Option A — Install this exact build (recommended)npm install -g billion-context@0.0.5015-pr.4217.6715fa7This exact version is immutable and reproducible. The rolling Option B — Download artifact
tar xzf billion-context-pr4217.tgz
npm install -g packageInstall instructions are refreshed on each push. |
The new breaker (a failed-only mutating round completes the turn instead of re-requesting) invalidated 24 tests across 15 files that used a failing compress as their re-request vehicle or pinned the old internal-continuation behavior. Three adaptation classes: - contract rewrites (old behavior gone by design): issue1502 salvage (no re-request after unsalvageable garbage args), issue3661 forms 1/2 (exercised on salvage-SUCCESSFUL rounds so the placeholder rides a real re-request; raw-malformed-skeleton absence pinned), issue1195 #2777 (the accepted overflow fold is now asserted to survive into the NEXT turn's rebuild), ccr-v2 unarmed opt-in (refusal receipt asserted on client SSE), loop-compress #422b (no fold refresh, no re-request). - vehicle swaps to acp_status (the test pins a re-request property, not compress itself): loop-core #5, fix-stream abort tests, loop-compress #3/#6/#10, strict-echo-model-criterion, anthropic-thinking-replay x3, upstream-truncation, loop-strict-echo (+responses), visibility-markers streaming pair. - made genuinely successful (the test needs a landed fold): e2e anthropic / responses-chat-relay / proxy-smoke round trips (unique session ids + protected-zone tail mass), subagent-namespace (positional refs + tail mass + honest usage claims — its mock had always failed via hash-boundary refs and only passed on master through retry-after-failure).
(ai: vllm-qwen/qwen3.8-27b) 查重: 独立复核——按失败签名(cache-seam fuzz / seed 1592 / unsanctioned seam / failed-only round / invariant-judge CCR/truncation 豁免 / #4186)在 open+closed issue/PR 检索,除本 PR 与源 issue #4186 外无同机制条目;作者声明的「50 个在途 PR 无一触碰本机制」与我的检索一致。查重结论:不重复。 标签: 开始审核:先独立通读两个 commit 的完整 diff 与既有行为清单,再做定向测试与回归判定,结论按结构化八问给出。审核不照抄 PR/issue 侧分析,diff 我自己读。 |
(ai: vllm-qwen/qwen3.8-27b) PR #4217 审核结论 — 报告路径的修复成立,但发现同机制一处残留(F1),需要你拍板 独立重读了全部 diff(未照抄 issue 侧结论)、本地重跑定向测试与 fuzz、核对 CI。先给判定:按现状提交的代码能解决 #4186 报告的「失败轮断缝」,diff 干净(19 个文件全部与本 PR 目的相关),typecheck clean,本地定向全绿,CI 在 d2c1086 上全绿/跳过。但审核中发现 breaker 条件只覆盖「一轮里全是失败」的形状,没覆盖「失败与其他调用混排」——泄漏机制与 #4186 完全相同,按你的政策不拆票,作为决策点列在下面。 结构化八问
F1 决策点 — 选项对比
其他发现(均不阻塞):
证据:typecheck clean;本地 loop-core+fix-stream+invariant-judge 58/58、11 个改造单测文件 61/61、5 个 hermetic e2e 文件 27/27;fuzz 种子 1592(默认 3 场景)+ 你点名的 44444/83204 独立跑绿;CI 在 d2c1086 上全部 check runs success/skipped。 判定:拍 A —— 可合(已验证的现状代码质量成立,F1/F2 记入 #4186 后续)。拍 B —— 我直接在本 PR 分支推泛化 commit、补 fuzz 场景、重跑定向套件后再交。等你拍板。 |
Closes #4186
查重: 无 — open+closed issues/PRs 按失败签名(cache-seam fuzz / seed 1592 / unsanctioned seam / mid-history divergence / I1 violation / failed-only round)检索,仅 #4186 本身命中;50 个在途 PR 无一触碰本机制(最接近的 #4139 是 marker-migrated tail append 分类、#4023 是 judge body cap,均不同机制)。
是什么
loop 内部的 compress/decompress 失败帧是临时的(#1548:只拼进当前重试请求,从不落 session、客户端从不可见)。但旧行为让这种临时帧真的到达上游一次(re-request),下一个客户端请求又不带它们 → provider 冻结前缀被中途改写 = unsanctioned cache seam。仓库自带 fuzz 在默认种子 1592 下确定性抓到它;owner 加扫确认 17 个种子里 7 个红(41%),签名全部相同。
修法(thread 里的 Option A)
commit 1 —
src/loop/core.ts(主修)finish_reason=length收尾,不再发 re-request。失败帧从此完全不出线;❌ receipt 已经流给客户端(reason 跨 turn 存活),后续 turn 可用不同 range 重试。failedSignaturesSet +canonicalArgs/sortKeys变为死代码,一并删除。commit 2 —
src/invariant-judge.ts(同族告警,诊断面)Issue 第二层证据(I1/I2 warn,5/12 场景)是同一家族的判官侧缺陷——豁免清单漏了两种合法变换:
📦 [acp-stored …]),入站还是全文。用 kernel 的严格整体解析器parseStoredPlaceholder(bug(ccr): embedded [acp-stored text is misclassified as a canonical placeholder #1456 纪律,不做子串扫描)识别,方向性豁免(只有 tool-result↔tool-result 且 b 是合法 placeholder 才放行)。na.startsWith(pre) && na.endsWith(post)、严格更短——伪造/膨胀体仍会被告警。exempt.ccr/exempt.truncate,warn/debug 日志行同步扩展)。纯诊断:零流量影响。行为变更披露(旧值 → 新值 + 原因)
finish_reason=length+ ❌ receipt)。原因:失败帧一旦到过一次上游,下一客户端请求必然断缝(41% 种子命中率);"进了就保持稳定直到 fold 顶替"(Option B)需要把临时帧写进 session 持久层,触碰 identity/persistence 边界,代价与风险都更高。这是本 PR 唯一的行为变更,按 thread 中推荐先行落地 Option A——若 owner 拍板要 B,关此 PR 即可。ccr=N truncate=N;JudgeVerdict.exempt增加两个字段(additive)。仅日志/诊断面。测试
tests/cache-seam-fuzz.test.ts(自带 rig,未改断言):11/11 种子 × 12 场景全绿(1592/20260101/424242/777/31337 + owner 点名的 44444/6666666/12345678/13579/24680/83204),0 条 invariant-judge 违规(修复前同跑 13 条)。tests/loop-core.test.ts:小模型(2B级)compress 循环空转:同参数重复失败烧满 10 轮 + 幻觉 ref + 摘要长度约束不遵守 #156 测试改写为 Bundled cache-seam fuzz deterministically fails under default seed 1592 (widened 12 scenarios): failed compression pairs | 自带 cache-seam fuzz 在默认种子 1592(加宽 12 场景)下确定性失败:失败压缩对凭空消失 + 运行时判官同族 I1 告警 #4186 回归钉——failed-only round fetchCalls===0(失败帧从未到上游)+ completion 存在 + ❌ receipt 可见;compress 执行后的 acp-loop 重放请求触发上游 400 {"code":3007,"msg":"captcha verify failed"} #189 replay-retry 五件套换成真实成功的 post-compress replay fixture(此前 harness 缺 refs/config,这五个测试历史上一直在跑 failing-compress 载体,Bundled cache-seam fuzz deterministically fails under default seed 1592 (widened 12 scenarios): failed compression pairs | 自带 cache-seam fuzz 在默认种子 1592(加宽 12 场景)下确定性失败:失败压缩对凭空消失 + 运行时判官同族 I1 告警 #4186 之后该载体不再 re-request,fixture 必须换才能继续钉住 retry 机制);limit-hit 测试同理换 acp_status 载体。tests/fix-stream.test.ts:abort-during-re-request 两件套换 acp_status 载体(abort 机制不动,避免被新 breaker 短路)。tests/invariant-judge.test.ts:+8 条(G2/G3 各正例+反例对,gate discipline Test Blind Spot Retrospective: Reinforcing Negative Assertion Discipline, Tightening Fake Upstream Strictness, Thin Inst | 测试盲区复盘:补反向断言纪律、假上游严格化、薄安装冒烟、形态矩阵与生命周期覆盖 #3617 双向)。测试套件波及(commit 3)
CI 首轮暴露 15 个文件 24 处失败——全部是把「失败的 compress」当 re-request 载体的测试,或直接钉住旧 internal-continuation 行为的断言(Option A 的合法波及)。commit 3 按三类适配:
复核:全部 19 个触碰文件本地定向跑绿(单元 107/107 + e2e 39/39);typecheck clean;fuzz 11/11 种子 × 12 场景绿、0 judge 违规。全量判定以本次 push 的 CI 为准。
另:JSON lane(
compressLoopResponsesJson)单独审过、不需要 gate——其 re-request 只重发 raw client input + append 的 tail items,失败帧结构上骑不上去,seam 不存在(该 lane 的既有测试保持原样通过)。并发热点提示
#4023(invariant judge 4MiB body cap)也改
src/invariant-judge.ts+ 其测试(纯增量 +26/+47)。若 #4023 先合,本 PR 需一次小 rebase;两处改动区域不重叠(wrapper vs stableEqual/ledger),union 即可。