Repository navigation
[PR] kernel: fold aged compress receipts (#4348) - #4354
Conversation
(ai: vllm-qwen/qwen3.8-27b) 查重结论(先答)查重: 不重复。 与 #4291/#4293/#4310(failed/refused 交换的豁免回退)同属「compress 交换豁免教义回退」家族,但本 PR 补的是 aged-successful 这一半——对象不同(成功回执 vs 失败/被拒交换),不重复。与我在 #4348 下落的 host 侧止血 PR #4353(重锚配对对齐)机制也不同:那条修「重锚覆盖岛落 turn 中段」的记账缺口,本条修「成功回执从设计上永不可折」;同事故族、不同失败域,两者可并存。 标签标签: 受理开始独立审核(diff 全窗通读 + 既有行为回归清点 + 定向测试)。先报两个已发现的硬情况:
我会在审核同时把 rebase 到当前 master 做掉(语义并集,不是机械取边——#4310 与本 PR 改的是同一函数的相邻语义,rebase 后以新头为准给八问结论)。 |
a4a47be to
a710d36
Compare
(ai: vllm-qwen/qwen3.8-27b) 上游冲突已解决,rebase 完成并推送(a4a47be → a710d36)。八问:
收工判定:冲突已清除,分支干净可合,等 CI 全绿后由人合并。 |
📦 Built Package ArtifactBranch: Option A — Install this exact build (recommended)npm install -g billion-context@0.0.5174-pr.4354.52f7202This exact version is immutable and reproducible. The rolling Option B — Download artifact
tar xzf billion-context-pr4354.tgz
npm install -g packageInstall instructions are refreshed on each push. |
The rebase bumped kernel/package.json 0.0.157 -> 0.0.158 without regenerating the root lockfile; lock-sync (#2704 drift guard) failed on the stale version field. Regenerated with the same command CI runs (npm install --package-lock-only); kernel/package-lock.json was already in step (idempotency verified).
(ai: vllm-qwen/qwen3.8-27b) 查重结论(先答)查重: 不重复。 这是本 PR 分支自身的锁文件漂移(rebase 时 bump 了 lock-sync 修复八问
收工判定:lock-sync 红已解,等新头 |
|
review这个pr |
ALWAYS_PROTECTED_TOOLS gave every compress exchange a permanent folding exemption, so successful compression receipts accumulated on the wire forever (148 receipts / ~170K chars measured on one session) and no range could reclaim them — attempts died with 'Range would split N turn(s)'. Only the newest COMPRESS_EXCHANGE_KEEP_RECENT=3 compress exchanges keep the exemption; older exchanges fold like ordinary tool messages with call+receipt+reasoning kept whole by the turn-integrity gate. Summaries live on in block anchors, so decompress/search lose nothing. Host protectedTools/isToolProtected patterns still win. acp_rule unchanged. kernel-change: aged-compress exemption lift in protected.ts + unit-projection fold filter, 2 kernel tests
22cfc0a to
ca05ead
Compare
- drop the keepRecent=0 early return in collectAgedCompressCallIds: it inverted the parameter semantics (keepRecent=0 should age out EVERY exchange, not none); a no-op for every caller using >= 1 - correct the unit-projection comment: the lift overrides host protection patterns for recognized compress dialects by design (the MCP lane hard-protection hook would otherwise pin mcp__bili__compress forever); the old wording claimed host patterns still win - correct the receipt-lace test header: it described apply-time turn-group snapping (pre-existing) instead of the actual fix (aged-exemption lift) - fix one mis-indented if-block left by the conflict resolution - kernel/package.json 0.0.158 -> 0.0.159 (+ both lockfiles), required by the kernel boundary for kernel/src changes
The entry said explicit host protectedTools/isToolProtected patterns still win, but isExemptFold bypasses every layer of isMessageProtected for aged compress-dialect exchanges (host message hook, protectedTools patterns, isToolProtected hook alike). The override is mechanically required: bili injects isToolProtected: isMcpBiliHardProtected into every session's kernel config (src/config.ts), so MCP-lane compress forms are pinned by the host hook and could never age out without it — the same doctrine #4289 documented for failed exchanges. Reworded to state the actual precedence; acp_rule and non-compress tools keep full host priority.
(ai: vllm-qwen/qwen3.8-27b) 查重结论(先答)查重: 不重复。 与 #4291/#4293/#4310(failed/refused 交换豁免回退)同属「compress 回执老化教义」家族,但本 PR 补的是 aged-successful 这一半——对象不同(成功回执 vs 失败/被拒交换),无重复 issue/PR。 标签标签维持受理时判定: 一、CI lock-sync 自动修复报告(本 lane)两次 lock-sync 红,同一机制:分支重写把锁文件同步丢了。
lane 状态:2 次尝试已用完。 若 二、PR Review(owner 要求,独立审核)审核基于最终树 ① 方向关:对。 修的是碎屑的生产者(无年龄豁免策略本身),不是拦截症状(turn-split fatal)。独立核过: ② 回归关:既有行为逐项清点(改前代码为基准)
③④⑤ 代码/测试/diff 审查 — 四项发现:
diff 整洁度:小范围聚焦,每行都与本 PR 目的相关;版本纪律合规(kernel 0.0.159 + 双侧锁文件 + CHANGELOG 条目齐备)。 三、结构化八问
收工判定:建议合入——等 |
📦 Merged Build PublishedThis merge to master was published as npm install -g billion-context@0.0.746-master.7681e2f # this exact build
npm install -g billion-context@master # always the newest merged build
|
|
Follow-up: the aged exemption lands on the fold filter, but not on the gates that decide what can be picked — old compress exchanges still can't be selected Context: #4354 exempts aged compress exchanges from
Net effect: compress call+receipt text still accounts for ~30% of outgoing tokens, and Suggestion: age both gates together — e.g. refs for compress exchanges older than |
What
ALWAYS_PROTECTED_TOOLS = ["compress", "acp_rule"]gave everycompressexchange a permanent, age-independent folding exemption. Successful compression receipts therefore accumulated on the wire forever — on the incident session, 148 receipts (~170K chars) rode every request with no tool able to reclaim them, and any range over them died withRange would split N turn(s)once the receipts interleaved with re-anchored coverage (the #4348 lace).This lifts the exemption for aged exchanges only:
COMPRESS_EXCHANGE_KEEP_RECENT = 3(kernel/src/protected.ts): the newest 3 compress exchanges keep the hard-coded exemption — working memory, the model still sees what it just folded.collectAgedCompressCallIds(messages, config)— host dialect recognition (config.isCompressTool, [Bug] MCP compress 历史调用未被清理,长会话累积大量旧摘要与回执 #2970 MCP names) wins over the bare-name check.filterProtectedToolMessages(kernel/src/unit-projection.ts) skips the blanket exemption for aged exchanges; both halves fold (call + receipt), with reasoning runs kept whole by the existing turn-integrity gate — no split, no stranded pairs.protectedTools/isToolProtectedpatterns still win (conservative — same philosophy as [PR] kernel: lift the permanent exemption for FAILED compress exchanges (#4289) #4293).acp_rulekeeps its blanket exemption.Root-cause correction
The issue's original framing (re-anchor misalignment) and my first framing (turn-split deadlock) were both wrong about the cause: the turn-split fatal is the symptom. The cause is that successful compress exchanges were never foldable by design — the lace is simply what that design accumulates on a long session. #4291/#4293/#4310 walk the same doctrine back for failed/refused exchanges; this completes it for aged successful ones.
kernel-change: protected.ts aged-compress exemption lift + unit-projection fold filter, 2 kernel tests
Tests
kernel/tests/issue4348-receipt-lace.test.ts(new): production-shaped fixture (reasoning + unref'd tool-call + ref'd receipt turns behind an island of coverage) — the lace range now folds with receipts AND their unref'd calls and reasoning all covered, zero withdrawals; control test pins that the newest 3 exchanges stay protected and a fold over them is refused.tscclean; straddle/prune/recommend/absorb families green.Fixes #4348