Repository navigation
fix: rotate count-triggered T2/T3 nudges with ready T1 on the growth path (#509) - #510
ranxianglei wants to merge 3 commits into
Conversation
…path (#509) The growth path short-circuited to T1 whenever t1Eff >= nudgeGrowthTokens, so an explicitly lowered tier2Trigger/tier3Trigger could never fire in a session whose raw compressible mass stayed high (billion-context-pi#628: 22 T1 blocks, t1Eff 100K-400K, zero T2 nudges). Count-ready tiers now join the slot rotation: T1 keeps first pick until it has gone (nudge.lastInjectedTier), then the count-ready tier with the oldest cadence stamp wins, and back again next cycle. lastInjectedTier is deliberately not cleared by the compression-success reset, so a compliant model draining raw ranges cannot restart every tie at T1. Default triggers (1000/2000) leave the pool empty -> byte-identical default behavior; token-mass paths and the pressure path are unchanged.
74e31ac to
bafbdfc
Compare
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)In your adapter project: npm install acp-kernel@pr-510Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf acp-kernel-pr510.tgz
npm install ./packageThis comment is automatically updated on each push. |
冲突已解决,分支已 rebase 到当前 master(v0.0.100,633b8c8)并推送: 冲突成因:PR 建在旧基线(b3f7246,v0.0.94 时代)上,期间 master 落了 ~30 个 PR,其中两处与本 PR 交叠——#478(a587c0c,nudge cadence 下移重锚,动了 src/compress.ts 的 nudgeNode + tests/nudge.test.ts)和 #438 的 prettier 全树格式化基线。唯一内容冲突在 tests/nudge.test.ts:正是本 PR 改写的那个测试(旧版单轮断言编码了 pre-#509 的「T1 永远优先」不变量,master 侧还保留旧形)——按本 PR 的意图取了新版三轮轮换断言(首轮 T1 → 轮换 T2 → 还回 T1),旧形必须被替换而非并存。src/compress.ts / types.ts / state.ts 自动合并,已逐行核对:#478 的下移重置在 nudgeNode、本 PR 的轮换在 decideNudge,互不重叠,两侧语义完整保留;README/types JSDoc(docs commit)干净落上。另补一个独立标注 style commit:PR 代码写于 prettier 基线之前,rebase 后需按 CI format gate 重排(纯换行,无语义改动)。 结构化七问(本次 rebase):
验证:typecheck 干净;定向测试(nudge/compress/pipeline/pressure-benefit/persist/packs)162/162 绿;build 成功;format:check 稳定通过。全量回归交 CI(已随 push 触发)。 判定:冲突清除,PR 恢复可合并,等 CI 绿 + owner 人工合并(§7.3 契约 8 + 状态字段增量,按规约留人)。 |
Closes #509
Root cause
decideNudge()'s growth path checkedt1Eff >= nudgeGrowthTokensFIRST and unconditionally injected T1. In any session whose raw compressible mass stayed above the threshold, the count-triggered branches (t2CountReady/t3CountReady) were therefore structurally unreachable — even whentier2Trigger/tier3Triggerwere explicitly lowered and satisfied. Production instance: billion-context-pi#628 (256K window, 22 active T1 blocks, t1Eff 100K-400K) never received a single T2 nudge across the whole session.Fix (issue option A: decouple distillation readiness from
t1Eff < threshold)nudge.lastInjectedTier(new OPTIONAL state field, defaults null), set by the nudge node on every injection. Deliberately NOT cleared by the compression-success reset: without that, a compliant model draining raw ranges would restart every tie at T1 after each compression and the explicit trigger would stay dead in exactly the #628 shape. (First-pass design keyed rotation onlastShownByTieralone; the compress->re-nudge loop test exposed that its memory is wiped on success.)Behavior change disclosure (old -> new)
nudge.lastInjectedTier; absent = null = legacy behavior, no migrationIssue face 2 (mass condition
t2Pen > t1Eff) deliberately left as-is: it is the DEFAULT-ON mass-dominance signal designed by #379; loosening it changes default behavior for everyone (product decision) and would not fix face 1 anyway. Happy to follow up separately if the owner wants it relaxed.Tests
Second commit (docs, labeled): fixes the doc drift flagged in the issue — TierConfig JSDoc said 'Default 5'/'Default 10', actual defaults have been 1000/2000 since #379; plus README note on the rotation semantics.
Touches §7.3 contract 8 (nudge invariants) + additive state field -> human-gated merge.