Repository navigation
[PR] fix: bound the failed-compress orphan sweep window at the commit-time ref frontier - #6142
ranxianglei wants to merge 7 commits into
Conversation
…ef frontier (#6116) The #3769 fold-gated orphan sweep removed failed compress calls at/after the pending fold's earliest start ref with no upper bound, so a failure issued in the SAME assistant turn AFTER the successful compress call (mixed multi-tool turns) was wiped on the next pass too — destroying fresh error feedback the model needs to react correctly (the exact pathology #3769 exists to prevent). applyCompression now also records pendingOrphanSweepMaxRef = highestUsedIndex of the ref map at commit time: the successful call and any later same-turn calls only get refs strictly above that frontier on the next assignRefs pass, so they stay out of the sweep. Across folds committing before one consuming turn the markers accumulate (running MIN / running MAX). The hide node consumes both one-shot; sync-blocks, cloneState and hydration carry the new field. States written before this change lack the max bound and keep the pre-fix unbounded behavior (upgrade compat, pinned by test). kernel-change: issue #6116 requests exactly this behavior; owner filed the issue, in-thread decision B confirmed (mechanism fix only, no prompt change).
mergeState() is the single source of truth for persisted CompressionState fields (#4192); add pendingOrphanSweepMaxRef to its literal so the transient window bound survives the unified round-trip like its min counterpart, and pin the round-trip in the storage field test.
📦 Built Package ArtifactBranch: Latest build — install this exact versionnpm install -g billion-context@0.0.9309-pr.6142.72283f8This exact version is immutable and reproducible. The rolling Recent builds (commit → version)
Download artifact
tar xzf billion-context-pr6142.tgz
npm install -g packageInstall instructions are refreshed on each push. |
[bot] 🏷 Review pass started on this PR (independent of the author-side report above). 查重: 不重复 — searched open+closed issues/PRs for the sweep-window mechanism: closest items are #5607 (failed-compress recovery re-request shape), #5987 (failure accounting on rebase), #5336 (orphan-sweep CLI surface) and the closed orphan-ACK family #4293/#4307/#4310 — all different mechanisms, none bounds the sweep window. This is the only open PR targeting #6116; no parallel second fix PR exists. 标签: bug + scope/kernel + p2(内核清理窗口语义修正:特定条件——同轮混合工具调用中成功压缩后又出现新失败——下丢新鲜错误反馈,非不可用、非缓存泄露,p2)。 Live state verified just now: PR open, head Next: pulling the branch, reading the full diff against master, regression-walking the touched paths, and running the targeted kernel suites locally. Full structured conclusion (八问) to follow in a second comment. |
kernel/package.json was bumped 0.0.192 -> 0.0.193 but its own package-lock.json was left at 0.0.192, and the version line in both lockfiles lost its indentation. npm install --package-lock-only re-normalizes all of it, so git diff --exit-code went red. - kernel/package-lock.json: 0.0.192 -> 0.0.193 (top-level + packages.""), matching the already-declared kernel bump in this PR. - package-lock.json: restore canonical 6-space indent on the acp-kernel version line (content unchanged).
Resolve the kernel-version conflict introduced by master advancing 0.0.192 -> 0.0.195 while this PR carried its own 0.0.193 bump: - kernel/package.json, root package-lock.json, kernel/package-lock.json: the merged tree now holds master's 0.0.195 kernel PLUS this PR's sweep-window change, so the version moves to 0.0.196 (one bump past master's tip) rather than reusing either side's stale number. - Restores canonical indentation on the acp-kernel version line that the original sed-style bump had stripped (the root cause of the lock-sync red: npm install --package-lock-only re-normalizes it, so git diff --exit-code went non-zero). Kernel source (compress.ts / sync.ts / types.ts / hide-consumed.ts) auto-merged clean against master; only the version/lockfile lines conflicted.
…und key #6116 adds pendingOrphanSweepMaxRef to the persisted CompressionState (kernel/src/compress.ts, sync.ts, types.ts; hydrated in src/state-hydration.ts). The four storage-render goldens pre-date that key, so the per-top-level-state-key digest pin (stateKeyDigests) now sees one new entry. In the scripted golden scenario the value is undefined (the one-shot window bound is consumed together with its fold marker), so the entry carries the shared "null" digest 74234e98afe7498f and no other field changes — stateDigest, section digests, per-turn wire digests and state shape are all byte-identical. Net diff: one added line per wire. Regen: node --import tsx scripts/update-storage-render-goldens.ts
[bot] 🏷 Re-verified live, root-caused, fixed, and pushed. The What was red (live, head Root cause: this PR (#6116) adds Fix: regenerated the four goldens with the sanctioned script ( Verification:
CI now (live, single GitHub API read — the mirror cache is stale, 八问(中文,供人工 reviewer):
收工判定:修复已推送( |
[bot] 🏷 Re-verified live — everything is already green; no work needed this run. This event reported Live state on the current head
Nothing to fix. Stopping without further work. |
[bot] 🏷 Final confirmation — PR #6142 is green and ready for human merge. Re-verified live this run on the current head No further work from the CI lane. Ready for you to merge: #6142 |
[ework] CI fix verified green ✓ |
kernel-change: issue #6116 requests exactly this behavior (owner-filed feature request; in-thread decision B confirmed — mechanism fix only, no prompt change).
What & why
The #3769 fold-gated orphan sweep removes failed compress calls at/after the pending fold's earliest start ref (
pendingOrphanSweepMinRef) with no upper bound. A failure issued in the same assistant turn AFTER the successful compress call (mixed multi-tool turns — compress mixed with other tools, exactly the scenario raised in #6116) therefore gets wiped on the next pass too, destroying fresh error feedback the model needs to react correctly — the exact pathology #3769 exists to prevent ("failures must remain observable or a deterministic model re-issues the same no-op compress forever").Fix:
applyCompressionnow also recordspendingOrphanSweepMaxRef = highestUsedIndex(state.messageRefs)at commit time. The successful call and any later same-turn calls only receive refs strictly above that frontier on the nextassignRefspass, so they stay out of the sweep window[minRef, maxRef]. Across multiple folds committing before one consuming turn the markers accumulate (running MIN / running MAX). The hide node consumes both one-shot; sync-blocks, cloneState and host hydration carry the new field.Behavior change (old -> new)
Cache impact: none — the sweep still runs in the same post-fold rewrite pass where the cached breakpoint already moved past foldMinRef.
Duplicate screening
查重: 不重复 — closest open work is #5607 (failed-compress recovery re-request shape), #5987 (failure accounting on rebase), #5336 (orphan-sweep CLI surface); all different mechanisms, none bounds the sweep window.
Tests
kernel/tests/issue6116-sweep-window.test.ts(7 tests): inclusive window both ends + single-ref windows; legacy min-only -> unbounded (upgrade pin); max-without-min inert; realcore.applyCompressionwrites both markers; THE issue scenario (same-turn failure after the success call survives); two folds accumulate the union window; fullprocessTurnpipeline carries the bound through sync-blocks and consumes both one-shot.Closes #6116