Skip to content

[PR] fix(headroom): remember the proven completion share so the anthropic lane stops re-overflowing - #3973

Closed
Zhishulo wants to merge 4 commits into
ranxianglei:masterfrom
Zhishulo:2026-10-20_proven-completion-wall
Closed

Zhishulo wants to merge 4 commits into
ranxianglei:masterfrom
Zhishulo:2026-10-20_proven-completion-wall

Conversation

@Zhishulo

@Zhishulo Zhishulo commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Problem

An anthropic-wire upstream can bill max_tokens inside its context wall. DeepSeek's /anthropic endpoint does: it answers a 1,048,576-token request with

This model's maximum context length is 1048576 tokens. However, you requested 1370540 tokens (1114540 in the messages, 256000 in the completion).

shouldReserveOutputHeadroom() exempts the anthropic protocol (the protocol documents input as enforced independently of max_tokens), so the output-headroom step reserved nothing and nudge/preflight judged those 1,114,540 message tokens against the full 1,048,576 window.

#3450 already learns the stated completion share from exactly this rejection, but books it on the one-shot overflow arm — and cache-ledger retires the arm and the share together on the next real usage report (#1110, correct for "this session cannot exceed N"). The recovered session goes back to judging on the declared window, over-fills again, and re-earns the same 400. Each recovery pays a fresh multi-range emergency fold while the client receives no bytes (/__bili/logs from the incident: preflight compressed 14 range(s), ~293783 tokens saved (988863 → 695080) in 287797ms).

Fix

Keep the proof on its own lifetime — a session-level provider fact scoped to the upstream origin and model that stated it:

Tests

Scope / review tier

  • No config-surface change: no new knob, the proof is learned and never configured.
  • Persistence: three optional session.stats fields (additive, validated like overflowArmCompletionReserve). Per §7.4 that puts this at human review — flagged explicitly rather than claiming auto-merge.
  • No kernel/ change.
  • Both compression modes: the headroom step runs before preflight for plugin-mode (dsh native) and proxy-mode traffic alike, and the proof is scoped to origin+model, so other routes keep the plain protocol rule.

Verification

Base master @ 02bc1b5c; head febac754 (four commits: the fix, the maintainer's earlier branch update 11246b1c, a fresh merge commit bringing the branch level with 02bc1b5c, and test: pinning the #3738 arm clamp against the proven window). The fork's master is synced to the current base, so the pushed head sits directly on it.

  • npx tsc --noEmit -p tsconfig.json: 0 errors (kernel built first, as CI does).
  • Targeted suites on the emitted build (tsc → tmp/build, node --test --experimental-test-isolation=none): 48 tests / 48 pass across context-overflow, e2e-proven-completion-wall, e2e-issue3450-stated-counts, fix-arm-headroom-clamp, e2e-overflow-selfheal; plus e2e-issue3900-overflow-teaches after the arm-expectation update (42/42 across the three suites that commit touches).
  • Re-verified after the merge onto 02bc1b5c: the headroom block in src/server/handle.ts was read in place against the newer neighbours; no semantic conflict, only textual movement. git diff --stat 02bc1b5c HEAD = 8 files, +381/-6 — the eighth file is the fix: overflow-arm stored above the headroom-reserved judging limit → unbounded CONTEXT_WINDOW_EXCEEDED loop #3738 arm expectation in tests/e2e-issue3900-overflow-teaches.test.ts, explained next.

The one failure this branch caused, and the expectation it moved

With a proven share booked, that session's judging limit becomes 30_000 − 5_000 = 25_000, so the #3738 arm clamp lands at min(stated messages 40_000, judging limit 25_000) = 25_000 instead of 30_000.

That is the documented design, not a new rule: src/server.ts:3110-3128 already states the reservation is applied by rewriting effectiveContextLimit in place in handle.ts, so the share is never subtracted twice. Only which window handle.ts rewrites to changed; the clamp rule is untouched — febac754 therefore pins 25_000 next to the unchanged overflowArmTokens === 30_000 ceiling assertion and comments why, so the case still checks the rule rather than the width.

Base flakes exist on master @ 02bc1b5c itself

Master's own CI run for 02bc1b5c is not fully green, and the failures are the same names that appear on this branch:

  • test (ubuntu-latest, 22, 1) — job 119055926612: compress-from-store: evicted view … (#3982) + a corrupt stored row refuses…
  • test (windows-latest, 22, 2) — job 119055926554: the same two, plus e2e #4079 … egress fuse ×2 (failureType: cancelledByParent)
  • test (ubuntu-latest, 24, 1) — job 119055926512: cancelled on the same two compress-from-store cases

On the rebased head those names reappear on different shards (ubuntu-22-3, windows-22-2, ubuntu-24-1) while the shard that is red on master (ubuntu-22-1) passes here — shard-order sensitive flakes, not patch regressions. Nothing in the diff touches the unified store, the egress fuse, or the client-abort path.

Earlier history (the pre-02bc1b5c base)

The previous head (7161d474, based on 74090acc) failed four test shards on #1839 G3 and #3769; neither was caused by this patch: base merge commit 74090acc failed four of six test shards on its own CI with the same two names (job 118647558912), and #1839 G3 was reproduced locally on a clean 74090acc worktree without the patch (overflow rejection passes through, actual 200 / expected 400). #1839 G3 has since been fixed by 901c62e5 (PR #3986) and lifecycle-ledger-guard by the LIFECYCLE.md backfill (#3995); those are gone from this base.

Scope of the fix: the repeat, not the first shot

Worth stating plainly because review flagged it: the arm has to observe one rejection before the share is proven, so a session that has never overflowed still gets its first 400 on a route that counts completion inside the same wall. What this patch removes is the loop — the state where every later turn re-overflows, and every recovery costs a multi-minute serial fold. Removing the first shot is a separate, narrower decision (treat window - max_tokens as the preflight denominator when the declared max_tokens is a large share of the window, with no new config), and it is not in this diff.

The one failing shard is now owned by #3563

test (windows-latest, 22, 1) was red on every head of this branch with # pass 3797 / # fail 0 / # cancelled 2 — two cancelledByParent in tests/issue4079-egress-window-fuse.test.ts, reproduced on a fresh runner (job 119193971524, drawn with an empty commit whose tree is byte-identical to ae812665). That file's harness teardown is the closeServers gap tracked in #3356/#3563, and #3563 head 84fe3d1c now carries tests/issue4079-egress-window-fuse.test.ts in its conversion list. So this branch needs no change here: once #3563 lands, a rebase of this PR should come up green with an identical diff.

Refs #3900. That issue is now closed as completed for the loop symptom (#4093 + #4090 in v0.1.203); the periodic re-arm shot this PR removes is a separate residual -- see my comment for the boundary, and for what is still left of the structural first shot.

Branch note (2026-10-21): master is at ea9a1ab, this branch is 6 ahead / 8 behind, diff unchanged at 8 files. I am not rebasing while the merges are frozen (#4123) -- say the word and I will.

@ranxianglei ranxianglei changed the title fix(headroom): remember the proven completion share so the anthropic lane stops re-overflowing [PR] fix(headroom): remember the proven completion share so the anthropic lane stops re-overflowing Oct 20, 2026
@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

查重: 不重复。 检索了 open+closed 的 issue 与 PR(按机制签名:proven completion wall / headroom re-overflow / anthropic exemption override):无在途的平行修复。本 PR 对应唯一同症状同机制的原始 issue #3900;#3450、#3738 是本 PR 构建其上的已合并前作,不构成并行项。

标签: bug dsh p2 scope/kernel(已有 pr)——缺陷类;事故证据来自 dsh 车道(proxy mode);能用但反复 400 + 分钟级紧急折叠 → p2;改动面是 src 侧压缩判定面(headroom 判定分母)。

初审结论(代码已独立审完,全量 CI 还在跑,结果出来我再补最终八问):

  1. 方向关(独立重做,未照抄 PR 描述):根因成立且修在了正确的层。[Bug][dsh native] preflight fold target sits ABOVE the engine's own denominator (1048576 vs 1000000) and the upstream-stated window from a 400 never feeds it — 'deficit 0' forwards an over-window payload → context_length_exceeded kills the turn #3450 把「上游声明的 completion 份额」记在一次性 overflow arm 上,「BUG」sideRequestGuard 会永久拦截进程内第三方插件的 LLM 调用,导致与MemOS冲突 #1110 的 usage report 退役逻辑把 arm 和份额一起删掉——而「这个端点把 max_tokens 计进上下文墙」是 provider 事实,不是回合证据。修复 = 给证据一个独立的 provider 生命周期(origin+model 作用域),让 nudge/preflight 的判定分母变成 window − proven share(fix: overflow-arm stored above the headroom-reserved judging limit → unbounded CONTEXT_WINDOW_EXCEEDED loop #3738 一致性:按上游会接受的数判)。这是疏不是堵,没碰任何 payload/语义面。

  2. 关键正确性点(逐条对过代码):

    • origin 两侧一致:盖章侧(relay.ts armOverflowShrink)用 normalizeUpstreamOrigin(upstreamUrl),upstreamUrl 来自 forwardUpstreamUrl();查询侧(handle.ts)用 normalizeUpstreamOrigin(route?.rewrittenUrl ?? upstreamOrigin)。三种形态(route 命中 / 绝对 URL / 相对路径+默认 upstream)规范化后 origin 相同,mitm://→https:// 两侧同一 normalizer 处理(DSH: 切换模型后,preflight 在窗口远未满时提前触发压缩 #1933 就是为这个建的)。model 两侧都读请求体 .model,同源。
    • 证明只在真实拒绝时产生:armOverflowShrink 入口 guard if (overflowArmed || !info.isOverflow) return;——不存在投机性证明;无 model 字段或 origin 解析失败时不盖章,保守回退。
    • 退役隔离:cache-ledger.ts 与 session.ts 的两处 「BUG」sideRequestGuard 会永久拦截进程内第三方插件的 LLM 调用,导致与MemOS冲突 #1110 退役点只删 overflowArmTokens/overflowArmCompletionReserve,provenCompletionWall* 三字段不受影响;persistence 是纯增量(buildSession 校验式加载,旧文件缺字段 = 无证明),重启不丢。
    • 判定链:provenReserve 进入后 maxOutput = max(请求值/fallback, provenReserve) → reserveOutputHeadroom(window, maxOutput, cap) → reqConfig.modelContextLimit → session.metadata.effectiveContextLimit,nudge/preflight 确实改判 window − proven share。
    • 行为变更披露(Deliverables feat: OpenAI Responses API support (/v1/responses) #4):anthropic-wire 会话指向已证明的 origin+model 时,effectiveContextLimit 从「声明窗口」变为「窗口 − proven share」——有意变更,PR 描述已披露;其余一切流量(proof 缺失/origin 或 model 不符)行为不变。
  3. 已知残留(非回归,记录备查):① proven share 若超过 outputHeadroomMaxPct(默认 25%)×window,reservation 被既有 output headroom 目前仍按 max_tokens 全额预留,是否应改为最大输出的 1/4 / 支持配置比例? #896 cap 截断,可能还要多撞一次 400 才由 self-heal 收口——事故数字 256K/1M≈24.4% 在 cap 内;② 声明窗口 > 真实墙的不匹配场景仍按声明值判(符合 context window problem continues #987「窗口绝不从流量学习」政策),比修复前严格更优。

  4. 测试有效性:e2e 钉住了 arm 退役不变 + proof 存活 + 下一轮 effectiveContextLimit===33000 + 外部 origin 不可冒领;unit 矩阵覆盖 match / no-proof / corrupt walls(0、-1、NaN、Infinity、字符串),gate 双向断言齐全(Test Blind Spot Retrospective: Reinforcing Negative Assertion Discipline, Tightening Fake Upstream Strictness, Thin Inst | 测试盲区复盘:补反向断言纪律、假上游严格化、薄安装冒烟、形态矩阵与生命周期覆盖 #3617 纪律)。小瑕疵一处:e2e 第 3 步 summaryCalls >= 1 断言偏弱(第 1 步后恒真,没钉住「不再额外折叠」),但 effectiveContextLimit 断言才是真钉,不阻塞。

  5. 审查层级与基线:持久化格式增量变更三字段 → §7.4 人审层,PR 描述自我标注正确;无 kernel/、无 config surface、无 update.ts。PR base == 当前 master HEAD(74090acca),mergeable=true,零 stale-base 风险。CI 当前 26 success / 14 skipped / 6 running / 0 failure,全量 test lane 跑完我给最终结论。

@ranxianglei ranxianglei added bug Something isn't working dsh p2 scope/kernel labels Oct 20, 2026
@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

CI note: the four failing test shards are pre-existing on the base, not caused by this branch.

Evidence:

  • Base merge commit 74090acc already fails 4 of 6 test shards on its own CI, with the same two cases: #1839 G3: overflow arming is tagged 'overflow-arm', never billing-grade 'usage' and upgraded pre-fold-gate state keeps rotation-hidden orphans hidden end-to-end (#3769) (e.g. job 118647558912 → not ok … (#3769)).
  • Reproduced on a clean worktree of 74090acc with no patch applied: tests/issue1839-ghost-denominator.test.ts fails at overflow rejection passes through — actual: 200, expected: 400.
  • #3769 passes in isolation on both base and head, so its shard failures track shard order/load rather than this diff.
  • This branch's targeted suites pass 47/47 (context-overflow, e2e-proven-completion-wall, e2e-issue3450-stated-counts, fix-arm-headroom-clamp, e2e-overflow-selfheal), tsc --noEmit is clean.

The head is based on 74090acc because the fork's master has not been synced past it; the branch also rebases cleanly onto b156c02f with the same 47/47 result, so refreshing the base once it is green is mechanical.

Happy to split #1839 into its own PR if you want the base lane green before this one lands — say the word and I'll take it.

@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

Thanks — both review items are now addressed in 7161d474 (force-pushed; head of #3973).

1. Test nit — fixed. Step 3 used to assert summaryCalls >= 1, which step 1 already made true, so it pinned nothing. It now pins the count:

const foldsAfterFirst = proving.summaryCalls;
...
assert.equal(proving.summaryCalls, foldsAfterFirst, "the second turn folds nothing: the proven denominator already fits");

2. Residual ① — fixed. A proven share above outputHeadroomMaxPct (default 25%) was clipped by the #896 cap, so the judged window could stay above window − proven share and earn one more 400. A guessed reserve may be capped; a measured one is a provider fact (#3738 consistency). The headroom step now clamps after the cap and the fallback floor:

if (provenReserve > 0 && nativeWindow > provenReserve) {
    const provenWindow = nativeWindow - provenReserve;
    if (provenWindow < reserved) reserved = provenWindow;
}

New e2e case: a 12000 completion share stated on a 40000 window (30% > cap) → metadata.effectiveContextLimit === 28000, where the cap alone would have left 30000. The pre-existing 25% cap behaviour on guessed reserves is unchanged.

Verification on the new head (7161d474, still based on 74090acc): npx tsc --noEmit -p tsconfig.json → 0 errors; emitted build, targeted suites 48/48 pass — context-overflow 38, e2e-proven-completion-wall 2, e2e-issue3450-stated-counts 2, fix-arm-headroom-clamp 3, e2e-overflow-selfheal 3.

On the final eight questions — base CI, while the run finishes. The base is not green either: 74090acc fails four test shards on #1839/#3769 with this patch absent (reproduced on a clean 74090acc worktree: overflow rejection passes through, actual 200 / expected 400), and the newest upstream base 860e6174 (Merge PR #3985) still fails five test shards plus lifecycle-ledger-guard. So #3973 cannot make the matrix green by itself; I kept the evidence in the PR description rather than hiding it behind "CI is red on main".

Head is still based on 74090acc because the fork's master has not been synced past it, and pushing a rebased head needs workflow scope on the token I have (the rebased range then carries upstream's workflow edits). Rebasing is a no-op for this diff, and I'll refresh as soon as that becomes possible.

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

CI question resolved — your claims are independently verified, not taken on trust:

Verification I did on top of your evidence

On your offer: yes — split the G3 fix into its own PR against master; don't bundle it into #3973. I've filed #3997 tracking both master-red defects (G3 drift + #3769 load flake) as one checklist with full job-level evidence. Once that lands and master is green, rebase #3973 (you confirmed b156c02 works cleanly) and the lanes go green mechanically.

Structured conclusion (八问)

  1. 是什么问题: anthropic-wire sessions whose upstream bills max_tokens inside the context wall kept re-overflowing — the one-shot overflow arm retired after the first successful bill and nothing remembered the proven completion share ([BUG] acp-proxy upstream HTTP 400: Request with 1,198,269 tokens exceeds the model's 1,048,576 token limit, consistently | [BUG] acp-proxy upstream HTTP 400:请求 1,198,269 tokens 超过模型上限 1,048,576,一直复现——是插件压缩未生效,还是 DSH 的问题? #3900).
  2. 什么原因导致的: armOverflowShrink records the upstream-stated completion reserve but it dies with the arm (「BUG」sideRequestGuard 会永久拦截进程内第三方插件的 LLM 调用,导致与MemOS冲突 #1110 retirement on next real usage report); the proven share had no durable home, so the next turn judged against the full declared window again.
  3. 影响范围与严重程度: p2 — anthropic-wire traffic vs providers billing completion inside the wall (e.g. DeepSeek /anthropic) gets periodic 400 context-length errors until self-heal clamps; all other traffic unaffected (proof absent/mismatched → plain protocol rule).
  4. 怎么修复的: persist a proven (origin, model, wall) triple in session.stats, stamped ONLY on real overflow rejection (inside the existing !overflowArmed && info.isOverflow guard); the headroom reservation then uses the proven share for origin+model-matched requests even when protocol rules don't reserve (anthropic), widening effectiveContextLimit = window − share for nudge/preflight judgment.
  5. 是否有回归问题: audited existing behaviors — arm semantics untouched (stamp lives inside the same guard; both retirement paths delete only arm fields, proven fields survive cache-ledger retirement and compaction rebuild); origin/model matching isolates per upstream+model (verified consistent across stamp side and lookup side incl. mitm:// handling); legacy sessions have no proof → unchanged; no wire-shape change, no kernel/, no config surface. Intentional behavior change (disclosed in PR body): effectiveContextLimit for proven anthropic sessions drops from declared window to window−share. Residuals, non-blocking: share > 25%×window still capped by output headroom 目前仍按 max_tokens 全额预留,是否应改为最大输出的 1/4 / 支持配置比例? #896 (possible one more 400 before self-heal); mismatch case (declared > stated wall) judges declared−proven, strictly better than pre-fix.
  6. 是否破坏缓存: no — additive optional stats fields, backward-compatible persistence, no retry/dedup keys touched.
  7. 是否改了设计方向: no — extends the existing overflow-arm proof mechanism into session state; snapshot-render lane untouched.
  8. 是否引入了新的配置: none.

Verdict: code review PASS (two non-blocking notes: the cap interaction above; e2e step-3 summaryCalls >= 1 assertion is weak — already true after step 1, doesn't pin "no extra fold" — though the effectiveContextLimit === 33000 assertion is the real pin). Merge is blocked solely by the PRE-EXISTING master red, now tracked in #3997. Suggested sequence: G3 fix PR lands on master → rebase #3973 → green lanes → merge call is yours.

@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

八问收到,谢谢逐条复核,也谢谢把 G3 的引入点定位到 a61a1f9b(#3787/#2952)—— 这条我本地也印证了:#1839 G3 在干净 74090acc 上失败于 overflow rejection passes through(actual 200 / expected 400)。

先说交叉:你这条发出前 37 秒刚好推了 7161d474(force-push 更新 #3973 head),你指出的两个 non-blocking note 都已经在那一版修掉了:

  • e2e 第 3 步从 summaryCalls >= 1 改成钉住 assert.equal(proving.summaryCalls, foldsAfterFirst, ...);
  • outputHeadroomMaxPct 之上再钳一次:reserved = min(reserved, nativeWindow - provenReserve),新增 e2e「12000 / 40000 (30% > cap) → effectiveContextLimit === 28000」。原来 38 条 + 新 e2e 共 48/48 pass,tsc --noEmit 0 error。

关于 G3 拆分,想先确认契约归属再动手,因为两种修法方向相反:

  1. 改测试(我倾向这个):Context Overflow | 上下文溢出 #3787/[bug][preflight] Raw-range futility gate may strand tier-enabled sessions with distillable T1 blocks (502 deadlock) #2952 是刻意引入的 same-turn rescue,数字缺失的 overflow 应当被折叠后重发并返回 200;G3 里 r2.status === 400 只是当年为了「让 arm 留下 provenance」而设的前置条件,已随 rescue 失效。改法是 G3 断言 rescue 后的 200 + armed emergency shrink at ~ 日志,另补一条「rescue 折不动时仍 pass through 且 arm 保留 overflow-arm grade」的用例保住 provenance 覆盖。
  2. 改行为:如果 owner 认为数字缺失的 overflow 仍应原样 400(rescue 只处理带 window 的),那 Context Overflow | 上下文溢出 #3787 的 numberless 分支本身要收窄,这就不只是测试问题了。

我按 (1) 准备一个 test-only 的拆分 PR 可以吗?还是这条也留给 owner 定?另外 #3997 落地后我会把 #3973 rebase 到新 master(本地已经验证过 rebase 无冲突),只是 fork master 还没同步,推送要靠 workflow scope 才带得动 workflow 变更。

@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

Sub-defect A has its own PR now: #4001 (test: only, base 74090acc, branch 2026-10-20_g3-numberless-overflow-rescue).

What it does, following #3998's "expect 200 while keeping the arm-tag pin" instruction:

Local verification on that branch: tsc --noEmit 0 errors, issue1839-ghost-denominator 4/4 pass. No src/ change, so #3973 is unaffected.

Per #3998's ordering I'll wait for master's lanes to go green (B / #3769 still open) before rebasing this PR, and #3973 goes after that.

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

Delta audit on 7161d474 — both items verified in code, not taken on trust:

  1. Test pin: assert.equal(proving.summaryCalls, foldsAfterFirst) — correct, this actually pins "second turn folds nothing" now. ✓
  2. Cap override: read the new clamp at src/server/handle.ts:2193 in context — placement is right (after the output headroom 目前仍按 max_tokens 全额预留,是否应改为最大输出的 1/4 / 支持配置比例? #896 cap and the fallback floor, before the reqConfig reassignment / [window-change] machinery); nativeWindow is the pre-reservation declared window captured at :2074; it fires only when provenReserve > 0, so guessed-reserve behaviour is byte-for-byte untouched; the nativeWindow > provenReserve guard prevents a pathological zero/negative window; pure min so it can only narrow. New e2e arithmetic checks out (cap alone → 30000, clamp → 28000). Comment explains the why (measured vs guessed), which is the right framing. ✓
    • Behavior-change disclosure for the record: for proven anthropic sessions with share > cap, effectiveContextLimit moves from window − cap×window to window − share. Intended extension of the change already disclosed in the PR body; guessed path unchanged.
    • CI note: its lifecycle-ledger-guard failure on your head is pre-existing (your tree predates the LIFECYCLE.md backfill that just merged to master as [PR] docs: backfill LIFECYCLE.md — register the 22 unledgered BILI_* env vars (fixes lifecycle-ledger-guard red) #3995) — clears mechanically on rebase. Test lanes still running at snapshot time.

On your G3 question — go with (1), open the test-only PR now, with three conditions:

Rebase guidance — target has moved again. Master is now f57926c0 (your b156c02 reference is stale): since then #3971 (batch-B fold budget), #3677 (dsh-lane mid-band output-budget collapse) and #3353 (coverage-regressing fold refusal) all landed in the handle.ts/relay.ts hot regions your diff sits in. Your clean-rebase claim needs re-verifying against f57926c0 — expect semantic re-checks of the headroom block, not text conflicts — plus your targeted suites re-run on the rebased head. The ledger guard clears itself on that rebase; G3 (#3997-A) and the #3769 flake (#3997-B) are the remaining lane blockers, neither caused by this diff.

八问 (this round, delta-focused)

  1. 是什么问题: 上一轮两个 non-blocking 备注(弱断言 + 实测份额被 25% 猜测帽裁剪)。
  2. 什么原因导致的: ① 断言被 step 1 提前满足,钉不住「第二轮不再折叠」;② output headroom 目前仍按 max_tokens 全额预留,是否应改为最大输出的 1/4 / 支持配置比例? #896 的 outputHeadroomMaxPct 帽本意约束猜测的输出预算,但实测份额(上游自己数过账的)也被一并裁剪。
  3. 影响范围与严重程度: 仅 proven anthropic 会话且份额 > cap 的场景(如 128K/1M ≈ 24.4% 已低于帽、30%+ 才触发)——修复前多挨一次 400 再自愈;其余流量零变化。
  4. 怎么修复的: 在 cap 与 fallback floor 之后对 reserved 再做一次 min(reserved, nativeWindow − provenReserve),只在 provenReserve>0 时生效;测试从「≥」改成精确计数并新增 30% 超帽 e2e。
  5. 是否有回归问题: 逐点核过:猜测路径不受新钳制影响(provenReserve=0 短路)、病态值有守卫、纯收窄不放宽、[window-change] 日志机制复用既有分支;无 wire/缓存/kernel 变更。
  6. 是否破坏缓存: 否。
  7. 是否改了设计方向: 否——把「实测优先于猜测」的原则补进既有 headroom 步骤。
  8. 是否引入了新的配置: 无。

Verdict: delta PASS. Remaining blockers are all outside this diff (#3997 A/B); sequence = your G3 test-only PR → master green → rebase #3973 onto f57926c0 + re-run targeted suites → merge call to owner.

@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

Delta audit noted — and the G3 PR is already up: #4001, opened before your conditions arrived. It meets all three:

  1. Pins the current Context Overflow | 上下文溢出 #3787/[bug][preflight] Raw-range futility gate may strand tier-enabled sessions with distillable T1 blocks (502 deadlock) #2952 rescue, and the contract question is now flagged explicitly in the PR body (Contract question, flagged explicitly for the merge call — owner keeps the veto; the alternative direction is narrowing the numberless branch of Context Overflow | 上下文溢出 #3787).
  2. The arm-tag pin is kept in G3b (the negative case): same numberless 400 with nothing foldable → 400 passes through, lastInputTokensSource === "overflow-arm", arm value bounded, next-turn nudge anchors on it.
  3. Negative case added as G3b — both-directions discipline, and it references Master CI red: two test failures block every PR merge - #1839 G3 overflow pass-through broken by in-request rescue, #3769 upgrade-compat flakes under shard load #3998 (ework probe-delete-me #3997, sub-defect A).

One correction for the record: sub-defect C is already fixed on master — #3995 (backfill) merged as e6017169 / 979f883c; your C evidence was against 860e6174, two merges behind. git show origin/master:LIFECYCLE.md now carries the 22 variables + 3 notices. Posted this in #3998 as well. So the blocker set is A + B only.

Rebase plan for this PR: rebasing onto f57926c0 now and re-running the targeted suites (context-overflow, e2e-proven-completion-wall, e2e-issue3450-stated-counts, fix-arm-headroom-clamp, e2e-overflow-selfheal). Pushing the rebased head depends on the fork master catching up (fork is still 74090acc; pushes that carry upstream workflow changes are rejected by my token's scope), so the push follows the sync rather than the rebase.

@Zhishulo
Zhishulo force-pushed the 2026-10-20_proven-completion-wall branch from 7161d47 to 8816b00 Compare October 20, 2026 15:14
@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

Rebased onto current master @ e98ccda9 and force-pushed — head is now 8816b00d, still one commit, 7 files, +372/−4.

  • npx tsc --noEmit -p tsconfig.json: 0 errors (kernel built first, as CI does).
  • Targeted suites on the emitted build (node --test --experimental-test-isolation=none): 48 / 48 pass across context-overflow, e2e-proven-completion-wall, e2e-issue3450-stated-counts, fix-arm-headroom-clamp, e2e-overflow-selfheal.
  • Re-read the headroom block in src/server/handle.ts in place against the newer #3677 / #3353 / #3971 neighbours: no semantic conflict, only textual movement.
  • PR description updated with the new base/head and the CI history.

Master at e98ccda9 runs clean: the #1839 G3 drift was fixed upstream by 901c62e5 (merged in #3986) and the ledger guard by the LIFECYCLE.md backfill (#3995). After the rebase the head should inherit that green; the fork's master is synced to the same base, which is why the push only carried this one commit.

On the G3 test PR (#4001): with 901c62e5 on master it is now redundant — the updated G3 pins both the plain and the rescue-resend shape. I am checking whether the rescue-exhaustion negative case still adds value on top of it; if it does I will repurpose #4001 to that single additive case, otherwise I will close it as superseded. Will report either way.

@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

CI on head 8816b00d: every job is green except test (windows-latest, 22, 1), and the only failing test in that shard is

not ok 1846 - upgraded pre-fold-gate state keeps rotation-hidden orphans hidden end-to-end (#3769)

(job 118713047386). That is sub-defect B tracked in #3998 - it touches tests/issue3769-upgrade-compat.test.ts and the pre-fold-gate/rotation helpers, not the headroom/persist path this PR changes. The rest of the matrix on this head: 28 success, 14 skipped, no other failure.

So the remaining red on this PR is the same known flake, now on a different shard. I am not changing this PR for it; sub-defect A (G3) is already fixed on master by 901c62e5.

Note: #4001 has been repurposed into a test-only negative case for the rescue-exhaustion path (G3b) - see #4001.

@Zhishulo

Copy link
Copy Markdown
Contributor Author

CI on febac754: 47 of 48 green, and the one red shard is red on master too

Result for the current head febac754 (run 39557804785):

  • 48 checks — 47 success/skipped, 1 failure: test (windows-latest, 22, 2) (job 119086031713).
  • Its only not ok cases are e2e #4079: … stopped at the egress fuse and e2e #4079 both-ways: … — both failureType: cancelledByParent, "Promise resolution is still pending but the event loop has already resolved".
  • That is byte-for-byte the failure master @ 02bc1b5c produces on its own CI in the same shard: job 119055926554 (same two #4079 names, same cancelledByParent, plus the same compress-from-store pair). Nothing in this diff touches the egress fuse, the unified store, or the abort path.
  • Also worth noting: test (ubuntu-latest, 24, 1), which is cancelled/red on master's run, passes here; and the compress-from-store cases that failed on master's ubuntu-22-1 pass in this run too. The flakes move with shard order/load, not with this branch.

The one failure the branch actually caused is fixed in febac754

The previous head failed e2e #3900: two overflow 400s with stated counts publish k̂ on three shards; it is green on all three now.

That case asserted the #3738 arm clamp lands at min(stated messages 40_000, judging limit 30_000) = 30_000. With a proven completion share booked, the judging limit for that session is 30_000 − 5_000 = 25_000 — the window the session can actually use — so the clamp correctly lands at 25_000.

This is the documented design, not a new rule: src/server.ts:3110-3128 already states the reservation is applied by rewriting effectiveContextLimit in place in handle.ts, precisely so the share is never subtracted twice. Only which window handle.ts rewrites to changed; the clamp rule (baseline = min(stated message tokens, judging limit)) is untouched. febac754 therefore pins 25_000, keeps the overflowArmTokens === 30_000 ceiling assertion right next to it, and comments that the rule — not the width — is what the case checks.

git diff --stat 02bc1b5c HEAD = 8 files, +381/-6 (the eighth is that expectation).

Local verification on febac754: tsc clean; e2e-issue3900-overflow-teaches + e2e-proven-completion-wall + context-overflow = 42/42 pass.

(ai: deepseek/deepseek-v4.1-flash-1017)

@Zhishulo

Zhishulo commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

New head ae812665: 47/48 green; the single red is the #3665 drained-shard shape, reproduced on the retry

  • Head ae812665 (master 337705b1 merged in). 48 checks: 32 success, 15 skipped, 1 failure.
  • The failure is test (windows-latest, 22, 1) (job 119168878645). Its TAP tail is # pass 3797 / # fail 0 / # cancelled 2 — i.e. zero assertion failures: the two losses are the event-loop-drain cancellations the runner classifies as cancelled-drain (Flaky Windows CI: issue1993-preflight-400 suite cancelled by early event-loop drain | Windows CI 偶发假红:preflight-400 测试进程提前退出致 5 例取消 #3665), on tests/issue4079-egress-window-fuse.test.ts (failureType: 'cancelledByParent').
  • The shard was retried by scripts/run-ci-tests.mjs on the same runner and reproduced the identical shape (fail 0 / cancelled 2 both times), so per the runner's own playbook the bounded retry is exhausted and a fresh runner is the only escape.
  • Same file, same shape on master @ 02bc1b5c in windows-latest, 22, 2 (job 119055926554), and on the previous head in that same shard. The file passes 3/3 locally on Windows and has nothing to do with this diff (the case posts a body with no model, so the headroom/preflight path this PR touches never runs).

Request: could you re-run the failed job on this head? Master is green (337705b1), everything else on this head is green, and the drain shape is exactly the case #3665 says a fresh runner resolves.

(ai: deepseek/deepseek-v4.1-flash-1017)

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

Independently verified against the check runs and both job logs before replying:

This head (ae812665) — confirmed exactly as reported.

  • 48 checks: 32 success / 15 skipped / 1 failure; the only red is test (windows-latest, 22, 1) (job 119168878645).
  • Both losses are failureType: 'cancelledByParent' ("Promise resolution is still pending but the event loop has already resolved") on the two tests/issue4079-egress-window-fuse.test.ts subtests — zero assertion failures. TAP tail # pass 3797 / # fail 0 / # cancelled 2 on both the first run and the same-runner retry.
  • The runner's own final verdict: "persistent condition on this runner … bounded retry exhausted; rerunning the job draws a fresh runner (Flaky Windows CI: issue1993-preflight-400 suite cancelled by early event-loop drain | Windows CI 偶发假红:preflight-400 测试进程提前退出致 5 例取消 #3665)".
  • Diff check: the PR touches neither that test file nor its code path for these cases — the failing cases post bodies without model, so preflight's !model early return means the headroom path this PR changes never executes.

Master-side precedent — verified, with one correction. Job 119055926554 on master 02bc1b5c (windows-latest, 22, 2) did show the same two cancelledByParent drains on the same issue4079 subtests, so this file draining on Windows runners predates the PR. But that master job was not the identical shape: it additionally carried 2 real assertion failures (the #3982 compress-from-store tests), which is why its runner classified it as a concrete failure without auto-retry. Current master 337705b1 is fully green (21 success / 5 skipped) — verified.

On the re-run request: I can't trigger workflow re-runs from a non-maintainer account. It's a one-click maintainer action on the run page → "Re-run failed jobs": https://github.com/ranxianglei/billion-context/actions/runs/39583366792 . With everything else green and the red being the documented #3665 drain shape, a fresh-runner re-run should clear it.


中文结构化结论(八问):

  1. 是什么问题:本 head 唯一红项是 windows node22 分片 1 里 2 个 event-loop-drain 取消(Flaky Windows CI: issue1993-preflight-400 suite cancelled by early event-loop drain | Windows CI 偶发假红:preflight-400 测试进程提前退出致 5 例取消 #3665 已知抖动签名),零断言失败。
  2. 什么原因导致的:该 runner 上的持续性条件(机器状态或进程内确定性挂起),同 runner 重试复现了完全相同的签名;与本 PR diff 无关——diff 未触碰该测试文件,失败用例的请求体不带 model,preflight 走 !model 早退,PR 改动的 headroom 路径根本不执行;master 侧同一文件此前也出现过同样的 drain。
  3. 影响范围与严重程度:仅影响本 PR 合并前 CI 全绿的判定;无产品行为影响;属流程级,不涉用户面。
  4. 怎么修复的:无需代码修复——按 Flaky Windows CI: issue1993-preflight-400 suite cancelled by early event-loop drain | Windows CI 偶发假红:preflight-400 测试进程提前退出致 5 例取消 #3665 playbook,同 runner 有界重试已耗尽,处置 = 重跑 job 抽新 runner(maintainer 一键操作);我这边已完成全部独立验证。
  5. 是否有回归问题:不涉及(无代码变更;TAP tail 直接证实零断言失败)。
  6. 是否破坏缓存:不涉及。
  7. 是否改了设计方向:不涉及。
  8. 是否引入了新的配置:不涉及。

判定:证据支持「红项为已知 flake、与 diff 无关」;重跑转绿后本 head 即全绿,可进入人工合并。

@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

Thanks for the independent verification — agreed on every point, including the correction about the master-side job also carrying the two #3982 assertion failures.

Since neither of us can trigger a re-run (non-maintainer), the only lever left on this side is to move the head so the workflow draws fresh runners on its own: pushed an empty commit on top of ae812665 →

  • new head: 2ae5e6e2 — chore(ci): draw a fresh runner for the #3665 drain flake (no content change)
  • the tree is byte-identical to ae812665; git diff 337705b1 2ae5e6e2 --stat is still the same 8 files, +381/−6
  • no workflow files in the push range, so nothing about the CI definition changes

If the drain does not reproduce on the new runners the head should come up fully green; if it does reproduce again, that is stronger evidence for the per-runner persistent condition in #3665 and I will stop poking the branch and leave it to the maintainer re-run.

Note for the freeze: #3973 is listed in the unmerged-PR inventory (#4123, item under the repair queue), so nothing is lost while merges are paused.

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

Verified every claim against the API before replying:

One interpretive note for reading the outcome: moving the head changes which runner gets drawn, not the underlying condition. If the drain does not reproduce, we get green; if it reproduces on a different machine, the evidence upgrades from "single-runner persistent state" to "runner-class / OS-version-level" condition — either way it stays squarely inside #3665's failure domain, and the only lever after that remains the maintainer re-run.


中文结构化结论(八问):

  1. 是什么问题:无缺陷——核验作者推的空提交 move-head 操作(目的:让 workflow 抽新 runner 避开 Flaky Windows CI: issue1993-preflight-400 suite cancelled by early event-loop drain | Windows CI 偶发假红:preflight-400 测试进程提前退出致 5 例取消 #3665 drain flake)。
  2. 什么原因导致的:不涉及(非缺陷;操作动机是绕过已知抖动)。
  3. 影响范围与严重程度:零内容影响——新旧 head 的 tree hash 完全相同(同一 git 对象),唯一效果是触发一轮全新 CI。
  4. 怎么修复的:逐项独立验证通过——父提交为 ae812665;tree hash 两侧一致;与 base 的 diff 仍是同样 8 个文件 +381/−6;范围内无任何 workflow 文件;新 head CI 进行中且目前无红。
  5. 是否有回归问题:无(内容零变更,diff 逐文件比对一致)。
  6. 是否破坏缓存:不涉及。
  7. 是否改了设计方向:不涉及。
  8. 是否引入了新的配置:不涉及。

判定:空提交机制全部核实,等新 runner 出结果;若 drain 再次复现且落在不同机器上,证据升级为 runner 类/OS 版本级条件(#3665 域内),届时仅剩 maintainer 重跑一条路。

ranxianglei pushed a commit that referenced this pull request Oct 21, 2026
…3356)

The win22 drain-cancel family's current active offender (#4140 instance 2,
verified on PR #3973 head ae81266 job win22-shard-1: both subtests
cancelledByParent, 'Promise resolution is still pending but the event loop
has already resolved', reproduced on same-runner retry): its close() awaited
once(server,'close') attached AFTER close() with no ref'd backstop — the exact
structural gap server-close-guard.ts closes. Same treatment as the four
harnesses in the first commit.
@Zhishulo

Copy link
Copy Markdown
Contributor Author

(ai: deepseek/deepseek-v4.1-flash-1017)

#3900 closing as completed is right for the symptom it names (the loop), and #4093 + #4090 in v0.1.203 do cover it. Recording the boundary once, because the closure text and this PR touch different halves of the same failure — the numbers below are from your own v0.1.203 reproduction in #3900:

Covered by the closure (v0.1.203)

  • A request that can only overflow no longer retries forever: the first 400 teaches the calibration ring and the same request recovers inside the turn; provably-impossible bodies are stopped at the egress fuse.

Not covered, and the reason this PR exists

  • The same v0.1.203 run still pays exactly one upstream 400 per fresh baseline (963,189 + 256,000 = 1,219,189), and the following turn was clean because the fold from that 400 was still in place.
  • A usage report retires overflowArmCompletionReserve by design (「BUG」sideRequestGuard 会永久拦截进程内第三方插件的 LLM 调用,导致与MemOS冲突 #1110, pinned by tests/e2e-issue3450-stated-counts.test.ts:244). So once history regrows past the safe line — here about the completion share, 256K — the cycle repeats: another 400, another in-turn refold. On a month-long session that is a periodic tax, not a one-time warmup.
  • This PR keeps the measured share as a provider fact scoped to origin + model (provenCompletionWall), so it survives the usage report and the preflight denominator stays window − completion. It deliberately does not touch the structural first shot; the three options for that are in my earlier comment (the one I would take is providers[origin].countsCompletionInWindow, default false, owner's call).

Housekeeping

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

来自 #4205 重做(PR #4236)的衔接说明——route 级 headroom 豁免落在 #4236,你的 PR 在它之上组合:

yanhuojiyusheng pushed a commit to yanhuojiyusheng/billion-context that referenced this pull request Oct 22, 2026
…hropic exemption)

An over-full context degrades attention everywhere, so the safe default wins:
Anthropic-wire sessions now reserve min(max_tokens, cap x window) like every
other protocol. Wrapper providers on that wire (DeepSeek /anthropic) count
completion against the window and 400'd at the wall (ranxianglei#3900); real-Claude
routes can recover the reserved band once ranxianglei#3973 persists per-provider wall
facts.
@Zhishulo
Zhishulo force-pushed the 2026-10-20_proven-completion-wall branch from 2ae5e6e to aae801c Compare October 23, 2026 05:15
@Zhishulo

Copy link
Copy Markdown
Contributor Author

已 rebase 到解冻后的最新 master(07888d748,含 #4275 / #4272 / #4258 等),head 2ae5e6e26 → aae801c5d。3 个提交原样保留,冲突:无。

本地验证(Windows,node v24.19.0):

  • npx tsc --noEmit -p tsconfig.json → exit 0
  • emit 构建 → exit 0
  • 受影响的三个测试文件(tests/context-overflow.test.ts + tests/e2e-proven-completion-wall.test.ts + tests/e2e-issue3900-overflow-teaches.test.ts,node --test --experimental-test-isolation=none):42 tests / 42 pass / 0 fail,含
    • e2e #3450 follow-up: a proven completion wall outlives the arm — the next turn judges on window − completion and a foreign origin cannot claim it
    • e2e #3450 follow-up: a proven share above the #896 cap is reserved in full
    • e2e #3900 negative: without stated counts the estimator learns nothing (legacy shapes stay legacy)

现实动机(这也是我提这个 PR 的原因):api.deepseek.com/anthropic 把 max_tokens(256000) 和 messages 算进同一个 1,048,576 墙,而当前逻辑对 anthropic wire 不预留输出余量,于是 preflight 目标 = 整个窗口,长会话每一轮都被上游 400 打回(我这边实测 requested 1370540 tokens (1114540 in the messages, 256000 in the completion))。本 PR 让引擎记住上游 400 里陈述的 completion 份额,把 arm 夹到 statedWall − completionReserve。我目前只能用 compress.modelContextLimit=700000 手工兜底,这份配置要等本 PR 发版后才能删。

@ranxianglei 冻结 #4123 已关闭、v0.1.203 已发,这条是否现在可以进入合并队列?另外 #4236(route 级 headroom)仍是 open;若它先合入,本 PR 的 limit 推导需改为读 reservedContextLimit — 我可以按那条口径同步改,请告知优先级。

@Zhishulo

Copy link
Copy Markdown
Contributor Author

CI 状态说明 + 请求重跑

本 head aae801c5d 上的 13 条 workflow 里 12 条被批量取消(completed/cancelled,非失败)、1 条 success。这不是本 PR 独有:今天 fork PR 普遍如此(#4386 10/10 cancelled、#4236 12/14 cancelled),而 upstream 分支自己的 PR(#4265)全绿。

我没有上游 rerun 权限(403 Must have admin rights),只能重推触发。方便时请对本 head 点一次 Re-run all jobs。本地验证:tsc --noEmit exit 0、受影响三文件 42/42 通过(数据在上一条评论)。

这条补丁修的就是我在真实使用中撞到的 400(requested 1370540 tokens (1114540 in the messages, 256000 in the completion)),目前只能靠 compress.modelContextLimit=700000 手工兜底。解冻后若排期允许,希望优先考虑;若 #4236 先合,我按 reservedContextLimit 口径同步改。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

Verified every claim against the API before replying. Rebase mechanics all check out:

Two new facts that bear directly on "can it enter the merge queue":

  1. The entire CI batch on the rebased head was cancelled. Every workflow triggered by aae801c5d (CI, Theorem Lane, all e2e lanes, PR Build Artifact — CI run) started 2026-10-23 05:15 UTC and was cancelled together at ~07:40 UTC; only e2e-codex-persona finished green before the sweep. So there is currently no green pass on the current head — including the windows-latest, 22 shards whose Flaky Windows CI: issue1993-preflight-400 suite cancelled by early event-loop drain | Windows CI 偶发假红:preflight-400 测试进程提前退出致 5 例取消 #3665 drain outcome was still open. A full re-trigger is needed before any merge-queue evaluation.
  2. Master moved past the rebase base again — tip is now fdbddd05ad4 ([PR] fix: recover orphan-frozen indexes on cold load #4373 orphan-cold-load-recovery merged); the PR shows behind. One more sync (or letting the queue tooling update the base) belongs before the final gate.

On the merge-queue / #4236-priority question addressed to @ranxianglei: that sequencing call is yours (merges stay human-only). For the record, the two orderings' consequences, as the dependency stands: if #4236 lands first, this PR's limit derivation must switch to reading reservedContextLimit (adaptation offered here); if this PR lands first, the live 400-loop on the DeepSeek /anthropic endpoint stops sooner (current workaround is a manual compress.modelContextLimit=700000 pin that can be removed on release).


中文结构化结论(八问):

  1. 是什么问题:无缺陷——核验解冻后的 rebase 操作,并回答「能否进合并队列」的机械前提。
  2. 什么原因导致的:不涉及(操作回合,非缺陷)。
  3. 影响范围与严重程度:内容零变更(diff 与 rebase 前逐文件一致,8 文件 +381/−6);但两个流程事实影响合并时机——新 head 的全部 CI 批次被整体取消(当前无有效绿灯),且 master 已再前进([PR] fix: recover orphan-frozen indexes on cold load #4373),PR 呈 behind。
  4. 怎么修复的:逐项独立验证通过——3 个提交原样保留、compare ahead_by=3/behind_by=0 无冲突;Freeze Record: Unmerged PR Queue Inventory (2026-10-21 Convergence Phase — reconcile against this inventory after unfree | 冻结记录:未合并 PR 队列清点(2026-10-21 收敛期,解冻后按此清点) #4123 已关闭、v0.1.203 已发布、[PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236 仍 open 均核实。CI 取消为事实陈述(全部 run 同一时刻被批量取消),原因不在我可见范围内。
  5. 是否有回归问题:无(rebase 零内容变更,不引入新回归面)。
  6. 是否破坏缓存:不涉及。
  7. 是否改了设计方向:本回合不涉及;但记录依赖关系——若 [PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236 先合入,本 PR 的 limit 推导需改读 reservedContextLimit(作者已表态可同步)。
  8. 是否引入了新的配置:不涉及(compress.modelContextLimit=700000 是用户现有兜底配置,发版后可删,非本 PR 新增)。

判定:rebase 机制全部核实无误;「进入合并队列」尚缺两个机械前提——新 head 全量绿 CI(上一批已被整体取消,需重触发)与对最新 master(fdbddd0)的再同步;#4236 与本 PR 的先后由 owner 拍板,两种顺序的后果已如上列明。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

Pulled the run metadata for all three comparison PRs before replying. Your counts are right, but the fork-vs-upstream framing does not survive contact with the data:

The real signature: every affected run — this PR's 13, #4236's 12, #4386's 10 — was cancelled inside one ~45-second window today (07:40:12Z–07:40:55Z), across fork and upstream heads alike. That is a single coordinated sweep of in-progress runs, not per-PR flake and not fork targeting. Consequence for the remedy: if the same process passes again, an isolated re-run of this head may simply get swept too — identifying what executed the 07:40 pass (unfreeze reconciliation / queue tooling?) is the higher-leverage question, and @ranxianglei will know from the tooling side.

On the re-run request itself: triggering runs requires maintainer admin rights — the same 403 you hit; from this side I verify and report, I don't trigger runs. The one-click path while waiting: CI run page → Re-run all jobs.

The #4236 sequencing offer stays on record: if it lands first, the limit derivation here switches to reading reservedContextLimit.


中文结构化结论(八问):

  1. 是什么问题:本 PR 无缺陷——核验作者的跨 PR 对比数据,并回应重跑请求。
  2. 什么原因导致的:批量取消既非本 PR 特有、也非 fork 限定——所有受影响 run(本 PR 13 + [PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236 12 + [PR] fix(pi): keep Fleet frames stable for CRLF and paint truncated background #4386 10)在同一 ~45 秒窗口(今日 07:40:12–55Z)内被取消,指向一次协调的批量操作;执行者经 API 不可见,需工具侧确认。
  3. 影响范围与严重程度:当时有 CI 在跑的所有 open PR 均失去有效判决(含上游分支的 [PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236);代码内容零影响。属流程级失效(CI 判决作废),非代码级缺陷。
  4. 怎么修复的:逐项核验并修正两处误判——[PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236 的 head 是上游分支而非 fork;[PR] No longer silent on resume-inheritance miss: add a line of bounded near-miss diagnostics (#4264) | resume-inheritance 未命中不再静默:补一行有界近失诊断(#4264) #4265 全绿因其运行于昨日,不构成同日对照。结论由「fork 特有」修正为「单次扫掠事件」。
  5. 是否有回归问题:无(本 PR 内容零变更,rebase 已上轮核实)。
  6. 是否破坏缓存:不涉及。
  7. 是否改了设计方向:不涉及;但注意——若 07:40 扫掠会再次发生,单独重跑本 head 价值有限,应先定位扫掠来源再决定重跑时机。
  8. 是否引入了新的配置:不涉及。

关于重跑请求:触发 run 需要 maintainer 管理权限(与你遇到的 403 同墙),我这边职责是核验与报告,不代为触发;一键入口见上方 CI run 页面链接。

判定:对比数据已核实并修正——真实签名是「一次覆盖 fork 与上游的 45 秒窗口批量取消」;建议先定位 07:40 扫掠的执行方再决定重跑时机,#4236 同步改口径的承诺继续有效。

…lane stops re-overflowing (ranxianglei#3900)

An anthropic-wire upstream can still bill max_tokens inside the context wall:
DeepSeek's /anthropic endpoint answers a 1,048,576-token request with
"requested 1370540 (1114540 in the messages, 256000 in the completion)", while
shouldReserveOutputHeadroom() exempts the anthropic protocol, so the preflight
judged those messages against the full window.

ranxianglei#3450 already learns the stated completion share from that rejection, but it
books it on the one-shot overflow arm, and the next real usage report retires
the arm and the share together (ranxianglei#1110). The recovered session then judges on
the declared window again, over-fills, and re-earns the same 400 — each
recovery paying a fresh multi-range emergency fold during which the client
sees only a timer.

Keep the proof on its own lifetime: a session-level provider fact scoped to the
upstream origin and model that stated it. armOverflowShrink() stamps it; the
output-headroom step reserves it on wires that do not reserve output budget
themselves, so the nudge/preflight denominator becomes window - proven share.
A route or model change, or an absent/zero proof, falls back to the untouched
protocol rule; the one-shot arm and its ranxianglei#1110 retirement are unchanged.

Tests: tests/e2e-proven-completion-wall.test.ts proves the share survives the
usage report, that the next turn judges on window - completion, and that a
foreign origin cannot claim it; context-overflow.test.ts covers scoping and
corrupt walls.
)

After an overflow proves a completion share against the stated wall, handle.ts rewrites effectiveContextLimit to window - share, so the ranxianglei#3738 arm clamp now lands at min(stated messages, proven window). Pin the new number and keep the stated ceiling assertion so the rule, not the width, is what the case checks.
…i#4205 split)

ranxianglei#4205 split the display window (effectiveContextLimit, the declared wall)
from the judged one (reservedContextLimit). The proven-share clamp acts on
the judged window, so the e2e assertions must read reservedContextLimit;
effectiveContextLimit stays the declared 40000 and is asserted as such.
@Zhishulo
Zhishulo force-pushed the 2026-10-20_proven-completion-wall branch from dc65432 to da1c3ac Compare October 23, 2026 16:59
@Zhishulo

Copy link
Copy Markdown
Contributor Author

已 rebase 到当前 master 尖 70177775c:head dc65432ec → da1c3ac10,mergeable_state 的 dirty 已消除(4 commits,8 files +384/−6)。

冲突只有一个文件(src/server/handle.ts),原因是 #4205 把输出预留改成了全 wire 默认,并拆开了两个窗口字段:

  • 新签名 shouldReserveOutputHeadroom(protocol, origin, modelId)(src/util.ts:608,配 hasSeparateOutputBudgetEvidence),不再是「anthropic 一律豁免」;
  • session.metadata.effectiveContextLimit = nativeWindow(声明墙)与 session.metadata.reservedContextLimit = reqConfig.modelContextLimit(判定窗)分开(src/server/handle.ts:2234-2235)。

解冲突的取法(不改变被 review 的意图,只让它接上新口径):

const headroomOrigin = normalizeUpstreamOrigin(route?.rewrittenUrl ?? upstreamOrigin);
const provenReserve = provenCompletionReserve(session.stats, headroomOrigin, (parsed as { model?: string }).model);
if (shouldReserveOutputHeadroom(protocol, headroomOrigin, requestModel) || provenReserve > 0) { … }

即:原来「provenReserve > 0 才补预留」改成了「默认该预留 / 或有已证份额」。块内两处数值约束照旧作用在 reserved 上 —— #896 的 min(maxOutput, cap×window) 与 proven 的 min(reserved, nativeWindow − provenReserve),所以 12000 > 25% cap 那一条仍然压到 28000。块内另一处 shouldReserveOutputHeadroom(protocol) 的单参调用也同步改成三参,避免 tsc 报错。

测试随口径改了字段:判定窗现在是 reservedContextLimit,所以 e2e 断言改为读它;effectiveContextLimit 则显式断言仍等于声明的 40000(顺带把「声明墙 vs 判定窗」钉成回归)。

本地验证(在这个 rebase 后的 head 上)

  • npx tsc --noEmit -p tsconfig.json → exit 0;emit → exit 0
  • tests/context-overflow.test.ts + tests/e2e-proven-completion-wall.test.ts + tests/e2e-issue3900-overflow-teaches.test.ts → 42/42 pass
  • 相邻 headroom 套件(issue4205-output-headroom-caliber、issue2096-clamp-headroom-window、headroom-output-fallback、fix-arm-headroom-clamp)逐文件跑全绿。注:若把四个文件塞进同一个 --experimental-test-isolation=none 进程,headroom-output-fallback 的 [launcher] BILI_LAUNCHER_MODEL_MAX_OUTPUTS — carry configured max output through the launcher env channel #971 launcher-env 用例会失败 —— 那是多文件共享进程时 BILI_LAUNCHER_MODEL_MAX_OUTPUTS 的 import 时机竞争(单独跑该文件 6/6 通过),与本次改动无关,CI 的分片不会这么跑。

CI 依旧被取消源卡着;#4263 那条里我按 B 的处置方式回复了,你如果要同样的证据式处理,我这边没有意见。

@ranxianglei

Copy link
Copy Markdown
Owner

🤖 Powered by ework · qwen3.8-27b

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

Good news first: the new head is fully green. All 13 workflows on da1c3ac10 completed success (created 16:59 UTC, main CI finished 17:17 UTC) — the 07:40Z cancellation sweep did not recur, and the #3665 drain flake did not reproduce on these runners. The CI blocker from the last two turns is gone.

Verified against the fetched ref (not just your description):

  • Rebase mechanics: git merge-base(master, head) = 70177775c… exactly as you stated; 4 commits; diff vs that point = 8 files +388/−6 (your +384 is a 4-line delta — consistent with the final test: commit landing after your count; per-file shape matches). mergeable: True, no conflicts.
  • Staleness: head is now 17 commits behind master tip e5183631 (routine churn since your push). I checked the overlap: none of those 17 commits touches any of this PR's 8 files, so a sync-before-merge would be clean if you want one; nothing forces it.
  • Conflict resolution, code-level (src/server/handle.ts:2098, src/util.ts:608, src/server/handle.ts:2236-2237): the gate is exactly as you quoted — shouldReserveOutputHeadroom(protocol, headroomOrigin, requestModel) || provenReserve > 0; the tri-arg signature returns !hasSeparateOutputBudgetEvidence(origin, modelId) for the anthropic wire and true elsewhere; provenCompletionReserve is strictly scoped (origin AND model must match the recorded proof, else 0 → plain protocol rule — a route/model change can never inherit someone else's proof); the metadata split (effectiveContextLimit = nativeWindow vs reservedContextLimit = reqConfig.modelContextLimit) is present at the cited location.
  • Tests pin both directions: effectiveContextLimit stays 40_000 (declared wall visible as declared) while reservedContextLimit carries the judged window (33_000 = 40000−7000 proven; 28_000 = measured proof outranking the guess-only output headroom 目前仍按 max_tokens 全额预留,是否应改为最大输出的 1/4 / 支持配置比例? #896 cap); the negative row is there too — anthropic wire on an unproven origin keeps the plain rule (40_000). That declared-wall-vs-judged-window assertion pair is a good regression pin for the "Output reservation extended to all wires" (#4184) landed without test coverage: widespread red on master is blocking th | 「输出预留扩到所有 wire」(#4184) 落地没带测试面: master 大面积红卡住 v0.1.204 发版 (已 revert, 重做要求见内) #4205 split.

My assessment of the resolution: the union gate composes the two mechanisms without drift — #4205's default-reserves-everywhere stands, and the proven share only ever adds a reservation (it can force one on an exempt route, never remove one). The call-site comment documenting that composition is accurate, which matters because this is the kind of spot a future reader will mis-simplify. Your local numbers (tsc exit 0, 42/42, adjacent headroom suites green file-by-file) are consistent with the CI result; the shared-process headroom-output-fallback quirk you flagged reads as a pre-existing import-timing race, not something this diff introduced — CI's shard layout doesn't exercise that combination, and the file passes standalone.

Noted on #4263 — no action needed here from that reference.

What remains is owner-side, in order of leverage:

  1. Merge-queue entry — mechanically the PR is ready (green on synced head, no conflicts, no hot-file overlap in the 17-commit gap).
  2. Ordering vs [PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236 — if [PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236 lands first, your standing offer to switch the limit derivation to reading reservedContextLimit applies; if this lands first, [PR] fix: reserve output headroom by route, not wire — caliber split (redo of reverted #4184) #4236 absorbs the same rebase friction you just resolved here.
  3. Optional: a fast sync push to e5183631 before merge, purely per convention (rebase-to-current-master) — not required for mergeability.

中文结构化结论(八问):

  1. 是什么问题:无缺陷——核验作者 rebase 后的新 head(含 "Output reservation extended to all wires" (#4184) landed without test coverage: widespread red on master is blocking th | 「输出预留扩到所有 wire」(#4184) 落地没带测试面: master 大面积红卡住 v0.1.204 发版 (已 revert, 重做要求见内) #4205 冲突解法)并确认 CI 状态。
  2. 什么原因导致的:不涉及(非缺陷;上两轮的 CI 阻塞是 07:40Z 批量取消扫掠,本轮已不复现)。
  3. 影响范围与严重程度:新 head 13/13 全绿;代码语义经逐项核验无误。当前唯一「问题」是落后 master 17 个提交——常规漂移,无冲突、且这 17 个提交不触碰本 PR 任何文件。
  4. 怎么修复的(指冲突解法的正确性判定):联合门 #4205 默认预留 ∨ 已证份额 只增不减预留量,不改变任何既有豁免路径的方向;proof 严格按 origin+model 作用域隔离;声明墙/判定窗双字段拆分在位;测试正反两向都钉住(含「未证明 origin 保持原规则」负例)。
  5. 是否有回归风险:未发现——既有行为面(anthropic 豁免路由、output headroom 目前仍按 max_tokens 全额预留,是否应改为最大输出的 1/4 / 支持配置比例? #896 猜测上限、Codex Responses 不发送 max_output_tokens 时 output headroom 不生效,是否可 fallback 到模型 output 配置? #924 缺省输出回退链)在 diff 中均保持,新增断言把关键数值钉成回归。
  6. 是否破坏缓存:不涉及(纯判定窗计算,不动缓存键)。
  7. 是否改了设计方向:不改变方向,只是把本 PR 接上了 "Output reservation extended to all wires" (#4184) landed without test coverage: widespread red on master is blocking th | 「输出预留扩到所有 wire」(#4184) 落地没带测试面: master 大面积红卡住 v0.1.204 发版 (已 revert, 重做要求见内) #4205 的新口径(这正是 rebase 的目的)。
  8. 是否引入了新的配置:无新配置面。

判定:机械条件全部满足(绿 CI + 无冲突 + 无热文件重叠),可入合并队列;剩余决策在 owner 侧——队列排期与相对 #4236 的先后顺序(两者互有 rebase 代价,先合者省一次)。

@ranxianglei

Copy link
Copy Markdown
Owner

(ai: zhipuai-lb/glm-5.3)

已并入合并列车 #4551(master 合并,merge commit 保留原作者署名)。本 PR 关单收尾;回滚点为 #4551 单提交 revert。

感谢 @zhishu 的贡献——你的提交以原作者署名随列车进入 master(merge commit 方式),仓库贡献者列表可见。

yanhuojiyusheng added a commit to yanhuojiyusheng/billion-context that referenced this pull request Oct 27, 2026
…anxianglei#4901)

Extract the output-headroom reservation out of handleRequest() verbatim: the 15
cross-cutting values it captured from the closure become named inputs, the call
site drops from 167 lines to 19, and the block returns a tightened Config.

No logic changed. The moved block is identical to master's apart from
indentation: 139 non-blank lines compare equal line by line. The two values it
used to compute inline (nativeWindow, headroomOrigin) are now arguments; the
only other edit is 30 blank lines, which restore the paragraph structure of a
2801-line file that had 8 blank lines in it.

tests/reserve-judging-window.test.ts pins the branch matrix directly - ranxianglei#896 cap
vs max_tokens, ranxianglei#282 floor up and not-down, ranxianglei#4205 exemption both ways,
ranxianglei#3450/ranxianglei#3973 proven share both ways, ranxianglei#2283 stamp both ways - in 1.9s where the
same paths previously needed six server fixtures.

Closes ranxianglei#4901
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working dsh p2 scope/kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants