Skip to content

fix(report): fold payback verdict uses the full post-fold window (#2044) - #507

Open
ranxianglei wants to merge 1 commit into
masterfrom
2026-10-05_fold-economics-window
Open

ranxianglei wants to merge 1 commit into
masterfrom
2026-10-05_fold-economics-window

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

Fixes the verdict-window mismatch reported in billion-context#2044 (owner approved: 全窗口口径 + cadenceOk 字段).

Problem

computeFoldEconomics judged payback with turnsToNextFold >= breakevenTurns (requests until the next fold) while savedSoFar on the same row counts every post-fold request. A fold that paid back long ago read NOT PAID BACK purely because the next fold arrived in the same batch (k=0 — 73% of NPB rows in the field sample; counterfactual ~38% of NPB flips to PB). The last fold was forever unobserved. Git archaeology: the short window was an intentional cadence design from #800, mislabeled with payback vocabulary.

Change

field before after
paidBack turnsToNextFold >= n* (cadence window) requestsAfter >= n* (full post-fold window, same as savedSoFar)
cadenceOk (new) — the original short-window verdict, kept as an explicit interleave-cadence signal (guard-signal candidate for billion-context#1280)
  • summary explainer: "post-fold requests so far have not reached n* (early fold or session ended before payback — one-time cost, not data loss)"
  • n* print precision 1→2 decimals (verdict recomputable from the printed value; the rounding display quirk flagged in the issue)
  • text labels unchanged; JSON adds one backward-compatible field

Unchanged: savedSoFar / grossSaved / repayCost / netTokens / GRAND LEDGER (already full-window). Zero cache/wire/config impact — report math only.

Tests (22/22 in tests/cache-report.test.ts; full suite 1236/1236)

  • incident regression: back-to-back fold — paidBack: true + cadenceOk: false with requestsAfter=9 ≫ n*≈3.6, k=1
  • last fold with enough post-fold requests flips unobserved → PAID BACK
  • last fold with requestsAfter < n* → NOT PAID BACK (previously null)
  • zero one-time cost (n*=0) → instantly paid back; cadence stays null
  • S ≤ σ → both verdicts null (unobserved)
  • #359 formula test extended with the k=0 variant

Follow-up (billion-context side, after this releases)

pin bump + tests/cache-ledger.test.ts expectation flips for the new verdict distribution.

paidBack compared turnsToNextFold (requests until the NEXT fold) against
the breakeven horizon n*, while savedSoFar on the same row counts every
post-fold request — a fold that paid back long ago read NOT PAID BACK
purely because the next fold arrived in the same batch (k=0; 73% of NPB
rows in the field sample, ~38% flip under the corrected window).

- paidBack now evaluates requestsAfter >= n* (same window as savedSoFar;
  the last fold becomes evaluable instead of forever unobserved)
- the original short-window verdict survives as cadenceOk (explicit
  interleave-cadence signal; guard-signal candidate for #1280)
- summary explainer line updated to the full-window semantics
- n* print precision 1→2 decimals so verdicts are recomputable from the
  printed value (rounding display quirk flagged in the issue)
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-10-05_fold-economics-window (6fa4eb1)

Option A — Install from npm PR tag (recommended)

In your adapter project:

npm install acp-kernel@pr-507

Each push to this PR publishes a new version under the pr-507 npm tag.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf acp-kernel-pr507.tgz
npm install ./package

This comment is automatically updated on each push.

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

Review 完成:实现与批准的设计逐点吻合,本地定向验证通过,CI 全绿,可合并。本轮只审查与验证,未改任何代码。

任务识别:这是 [PR] 唤醒——PR 已存在(分支 2026-10-05_fold-economics-window,单 commit 6fa4eb1,base = 当前 master tip 4d38906 / v0.0.101 发布点,mergeable_state=clean)。按规范不重做工作,改为拉分支核对代码、测试、CI。

方向关(原 issue billion-context#2044):问题属实、方向正确——判定表达式 turnsToNextFold >= breakevenTurns 本身是问题字节出处(当时已用真实内核导出独立复现);git 考古证明短窗口自模块诞生(#800)起就是刻意的 cadence 设计,缺陷在于用盈亏词汇命名节奏指标并与全窗口数字并排。本 PR 正是落地你拍板的方案(全窗口 verdict + 短窗口降级 cadenceOk + 顺手修 n* 显示精度),逐点核对:

  • paidBack = breakevenTurns !== null ? f.requestsAfter >= breakevenTurns : null(与 savedSoFar 同窗口;S≤σ 时 null 约定不变)
  • cadenceOk = 原短窗口表达式逐字保留,doc 注释明确「interleave-cadence signal, NOT a payback verdict」
  • n* .toFixed(1)→.toFixed(2):full/summary 两个渲染点都改了,全仓 grep 确认无第三个渲染路径;paidBack/cadenceOk/breakevenTurns 消费方仅 src/cache-report.ts 一个文件
  • summary 解释行更新为全窗口措辞;文本标签(PAID BACK / NOT PAID BACK / ?)不变
  • savedSoFar/grossSaved/repayCost/netTokens/GRAND LEDGER:diff 零触碰 ✓

回归审查(diff 触碰路径的既有行为逐项):

既有行为 结论
per-fold verdict 分布 有意变更(本 PR 目的):NPB→PB 大面积翻转(issue 反事实 ~38%)、末次折叠从恒 unobserved 变为可评估——PR 正文已披露旧值→新值 ✓
unobservedCount 语义随之收窄:旧口径数「末次折叠 ∪ S≤σ」,新口径仅数 S≤σ——上一条的必然派生,已披露 ✓
savedSoFar/grossSaved/repayCost/netTokens/GRAND LEDGER 不变(diff 零触碰)✓
JSON wire shape 纯增字段 cadenceOk,无改名/删除/重排,向后兼容 ✓
双路径一致性(内核批量 vs 宿主增量) 同一 computeFoldEconomics,结构性一致;billion-context 侧未 bump pin 前仍跑 0.0.101 旧语义,过渡期其测试不会红 ✓
fail-fast / 阈值 / 时序 / 缓存 / wire 字节 不涉及(纯报告计算,零依赖不变)✓

测试有效性:PR 承诺的 6 个 case 全部以精确断言钉住(paidBack/cadenceOk 的 true/false/null 逐一验证 + economics 聚合计数);事故形态回归(k=1 且 requestsAfter=9 → paidBack:true + cadenceOk:false)在 buildCacheReport 端到端和 computeFoldEconomics 公式层(k=0 变体)两级都有;旧的「末次折叠必为 null」断言被正确重锚而非遗留失真。唯一一处较松的断言(paidBackCount >= 1)在旧行为下可为 0,仍抓得住回归,无需修。

本地定向验证(head 6fa4eb1):typecheck clean · tests/cache-report.test.ts 22/22 通过(与 PR 描述一致)· format:check 绿。全量套件按纪律交给 CI。

CI:head commit 最新一轮全绿(test(22) / test(24) / build-artifact / pr-validation)。注:首次推送时 pr-validation 失败过一次,同 SHA 四分钟后的重跑即绿——瞬态,与代码无关。

结构化七问

  1. 是什么问题:逐 fold 的「PAID BACK」判定拿「到下次折叠的请求数 k」比盈亏平衡轮数 n*,而同行的节省额按「折叠后全部请求」累计——早已回本的折叠只因紧接着又来一次折叠就判 NOT PAID BACK,报告自相矛盾。
  2. 什么原因导致的:内核判定表达式本身取了短窗口。git 考古:短窗口自 #800 起是刻意的节奏(cadence)设计,但被贴上盈亏标签并与全窗口数字并排呈现——命名/呈现实义缺陷,非后续回归,与 #1286(k 钉死 ≤1)正交。
  3. 怎么修复的:头条 verdict 对齐全 post-fold 窗口(requestsAfter ≥ n*,名字与语义归位),原短窗口判定降级为新增显式字段 cadenceOk 供节奏诊断/#1280 护栏消费;顺手把 n* 打印精度 1→2 位小数使判决可从打印值重推。
  4. 是否有回归问题:见上表——受影响面仅 verdict 分布与 unobserved 计数(产品决策本身,已披露);GRAND LEDGER 等数值全部不变;未发现 fail-fast 变吞错、阈值漂移等其他高危模式。
  5. 是否破坏缓存:不涉及。纯报告计算,不触碰前缀缓存/重试/去重键/wire 字节。
  6. 是否改了设计方向:无架构转向;报告模块判定口径归位 + 一个向后兼容增字段,cadence 信号保留而非删除。
  7. 是否引入新配置:无(无 env/config/默认值变化)。

行为变更披露(均有意、均在 PR 正文列明):① paidBack 旧「到下次折叠未达 n*」→ 新「post-fold 已观测全部请求未达 n*」;② 末次折叠 verdict 从恒 ? 变为可评估;③ n* 打印 1 位小数 → 2 位;④ summary 的 NOT PAID BACK 解释行措辞变化;⑤ JSON 增加 cadenceOk 字段。只读 token 数字的消费者零感知。

后续(本轮不做,待发布后按跨仓顺序执行):此 PR 合入、release 发版且 npm live 后,billion-context 侧做 pin 精确版本 bump + tests/cache-ledger.test.ts 期望翻转(部分 paidBack 断言按新口径翻面,双路径一致性结构不变)。

收工判定:可合并——方向正确、实现与批准设计一致、测试有牙、diff 干净(单 commit、2 文件、每行都与本 PR 目的相关)、CI 绿、与 master 无冲突。按 §7.4 这属产品决策(verdict 口径变更),需你人工合并:#507

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant