Skip to content

docs(eval): filesense ablation results — no measurable difference, and why - #422

Merged
ceilf6 merged 1 commit into
developfrom
docs/filesense-ablation-results
Aug 1, 2026
Merged

docs(eval): filesense ablation results — no measurable difference, and why#422
ceilf6 merged 1 commit into
developfrom
docs/filesense-ablation-results

Conversation

@ceilf6

@ceilf6 ceilf6 commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Linked Issue Or Context

Result

4/12 vs 4/12. All twelve tasks agree arm for arm; every category matches.

类别 filesense 关 filesense 开
query 0/4 0/4
create 2/3 2/3
bugfix 0/3 0/3
refactor 2/2 2/2

Cost of having it on: ~35K input / 47K output tokens, +27s per task. Zero planner degradations in either arm.

What this does and does not support

It is not "filesense is useless", and it is not evidence that it helps. Three limits travel with the numbers:

  1. Only 8 of 12 tasks can discriminate. The four query tasks fail in both arms for a reason unrelated to filesense — planner.ts:151 routes query tasks around LLM planning entirely ([Bug] query tasks never use LLM planning, so they can only read files the caller supplied #419), so nothing consumes what navigation produces.
  2. Two known defects suppress the measurable contribution, both unfixed[Bug] query tasks never use LLM planning, so they can only read files the caller supplied #419, and [Bug] trigger-policy uses bare focus-dir names as scan roots, so navigation can scan nothing #420 (a bare directory name lifted from the task text used as a scan root; measured returning 0 entries once).
  3. Single run, n=12. Too small to separate a small effect from sampling noise.

The one attributable observation

deep-refactor-route-title — the highest-precision navigation in the set, 1 entry scanned out of 430 to locate src/app/routes:

full off
result PASS PASS
steps 6 7
wall time 251s 340s
input tokens 20,421 14,921
output tokens 22,524 25,865

The off arm still passed, taking one extra step, 89 more seconds and 3.3K more output; the on arm spent 5.5K more input. A quantifiable trade, and not a favourable one at this task size.

The counter-sample is recorded too: on deep-create-checkout-hook the on arm spent more input and more output for no gain. So "navigation trades input tokens for output tokens" — which I believed after the first data point — does not hold across this run.

The zero is decomposed, not left as a shrug

类别 bottleneck
query 0/4 #419 — never reaches LLM planning, navigation output unconsumed
create 2/3 the target location was strongly hinted in the task text — a flaw in my task design
bugfix 0/3 codegen quality; localization worked (all three navigated and read the source)
refactor 2/2 the tasks were simply easy enough that one extra step of exploration sufficed

"Unmeasurable, therefore useless" would have been the easy read. Next step is to fix #419/#420 and design tasks whose target location carries no textual hint.

Impact Scope

  • benchmarks/results/2026-08-01-filesense-ablation.md — the generated report plus a hand-written conclusion section, clearly marked as not generator output.
  • benchmarks/results/2026-08-01-filesense/{full,no-filesense}-deep.jsonl — raw data for both arms, so every number is recomputable.
  • benchmarks/eval/report-filesense.mjs — a template literal was closed early by a backtick-quoted path inside it; the generator could not parse. Fixed.

GitNexus Impact Summary

  • Risk level: LOW
  • Critical skeleton changes: none — benchmarks/ matches no critical contract rule.
  • GitNexus impact: no packages/** or apps/** change, so no execution flows are affected. The report generator is invoked by hand.
  • Verification: pnpm quality:precommit exit 0.

Verification

  • pnpm quality:precommit — exit 0.
  • Both arms ran 12/12 against a real backend on fixture-deep, with all four report guards active (fixture/task-set provenance, off-arm zero-trigger, planner degradation, budget consistency). None fired, which is itself part of the result.
  • Raw JSONL committed, so the tables can be recomputed independently.

Checklist

  • I have linked an issue or explained why this PR stands alone.
  • I have kept the diff focused on the stated change.
  • I have run pnpm quality:precommit, or explained why it could not run.
  • I have run pnpm quality:local for critical skeleton changes, or explained why it could not run — there are none.
  • I have updated docs or tests when behavior, public APIs, or Harness contracts changed.
  • For critical skeleton changes, I have filled the GitNexus impact summary with concrete results — none in this diff.

🤖 Generated with Claude Code

…d why

First run with filesense as the only variable. The 2026-07-12 ablation had it
enabled in **both** arms, so that data said nothing about it.

**Result: 4/12 vs 4/12. All twelve tasks agree, arm for arm, category for
category.** The cost of having it on was ~35K input / 47K output tokens and 27s
per task.

That is not "filesense is useless", and it is not evidence that it helps. Three
limits are stated with the numbers:

1. **Only 8 of 12 tasks can discriminate.** The four query tasks fail in both
   arms for a reason unrelated to filesense — `planner.ts:151` routes query
   tasks around LLM planning entirely (#419), so nothing consumes what
   navigation produces.
2. **Two known defects suppress the measurable contribution, both unfixed**
   (#419, and #420 where a bare directory name lifted from the task text is used
   as a scan root — measured returning 0 entries once).
3. **Single run, n=12.** Too small to separate a small effect from noise.

The one attributable observation, on the highest-precision navigation in the set
(1 entry scanned out of 430 to locate `src/app/routes`): the off arm still
passed, taking one extra step, 89 more seconds and 3.3K more output tokens,
while the on arm spent 5.5K more input. A quantifiable trade, and not a
favourable one at this task size.

I also record the counter-sample: on `deep-create-checkout-hook` the on arm
spent more input *and* more output for no gain. So "navigation trades input
tokens for output tokens" — which I believed after the first data point — does
**not** hold across this run.

The zero is decomposed by category rather than left as "unmeasurable, therefore
useless": query is blocked by #419, create had strong textual hints to the target
(a flaw in my task design), bugfix is bottlenecked on codegen quality with
localization working, refactor was simply easy enough. Next step is to fix
#419/#420 and design tasks whose target location carries no textual hint.

Raw JSONL for both arms committed alongside, so every number is recomputable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 1, 2026 11:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ceilf6
ceilf6 merged commit e07256a into develop Aug 1, 2026
7 checks passed
@ceilf6
ceilf6 deleted the docs/filesense-ablation-results branch August 1, 2026 11:59

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ ceilf6/repo-guard

代码评审报告: docs(eval): filesense ablation results — no measurable difference, and why

风险等级:
处理建议: 请求修改
决策摘要: 数据与统计全部复算通过(4/12 vs 4/12、422 条目、各项均值逐个吻合),但结论表里 bugfix 类的瓶颈归因与本 PR 自己提交的 JSONL 记录相矛盾,且失败清单存在被静默截断成不可执行的命令;改这两处即可合并。

级联分析

  • 变更符号: 无导出符号。benchmarks/eval/report-filesense.mjs 是独立脚本(顶层 console.log,无 export),仅改了模板字面量内的两行文案。
  • 受影响流程: 手工运行的报告生成流程。packages/**apps/** 未触及,运行时无影响。
  • 变更集外调用方: README.md:1333 记录调用方式;scripts/tests/workflow-rules.test.mjs:617 只断言 README 提到该文件名,不加载脚本(text search)。无其他引用。
  • 置信度: medium(无代码图谱;调用方由 grep 确认,harness/夹具生成器已直接阅读复核;未能在本次评审中执行 node 复跑生成器)

问题发现

  1. [中] bugfix 类的瓶颈归因与提交的原始记录相反

    • 证据: 结论表写「代码生成质量,与定位无关(三条都触发了导航、也读到了源文件)」。但 full-deep.jsonl 三条 bugfix 的 agentError 都是 apply_patch 指向不存在的文件:src/features/billing/lib/calculateAmount.ts(任务目标是 src/features/checkout/lib/computeTotal.ts,见 benchmarks/eval/tasks-deep.json:149,即跑错了 feature)、src/features/cart/lib/merge.ts(真实文件 mergeLines.ts)、src/features/shipping/lib/estimateDeliveryTime.ts(真实文件 estimateEta.ts)。JSONL 的 eventDetails 只含 filesense/validationFailed/rollback,没有任何 read_file 记录,因此「也读到了源文件」既不能按 PR 承诺从提交数据复算,方向上也与记录相反。同族证据:deep-create-entity-guard 开臂导航已明确 warnings: ["Path does not exist: src/entities/coupon/lib"],agent 仍去 patch 该路径。
    • 受影响调用方/流程: 该行是「零差异可拆解」这一核心主张的四分之一;后续「修 #419/#420 后重测」的优先级直接建立在它之上。
    • 最小可行修复: 把瓶颈改为记录能支持的表述(如「apply_patch 目标文件名/所属 feature 判断错误,pre-execution 校验拦下」),或注明「读到源文件」的证据来自未提交的运行日志而非本 PR 的 JSONL。
  2. [中] 失败清单里的命令被静默截断成不可执行路径

    • 证据: 报告中两处写作 cmd(npx vitest run src/features/checkout/lib/computeTotal.test.t),末尾 s 丢失。成因是 report-filesense.mjs:208String(c.detail).slice(0, 60):该命令恰为 61 字符,而 shipping 的 60 字符命令完整显示。截断没有省略号标记,读者无法察觉,照抄即得到不存在的测试路径。
    • 受影响调用方/流程: 所有以该报告为复盘素材的后续排查;未来任何更长的 cmd detail 都会同样静默变形。
    • 最小可行修复: 截断时追加 标记,或对 cmd 类 detail 放宽上限。(208 行不在本次 diff,但失真产物由本 PR 提交。)
  3. [中] pnpm quality:precommit 不覆盖本次修复的文件,不能作为该修复的验证证据

    • 证据: biome.json:61includes"!!**/benchmarks"pnpm lintbiome check .)不解析 benchmarks/eval/*.mjstypecheck/test 也不加载该脚本(grep 全仓仅 README 与 workflow-rules 的文本断言)。这正是一个模板字面量语法错误能存活至今的原因,也意味着 exit 0 与本次修复无关。
    • 受影响调用方/流程: 该生成器的任何后续改动同样无自动化验证。
    • 最小可行修复: 在 precommit 增加 node --check benchmarks/eval/*.mjs(或把 benchmarks/** 纳入 biome),并在 PR 验证栏说明本轮报告确由修复后的生成器手工跑出。
  4. [低] report-filesense.mjs:187 的改动不是修复所必需,且降低产物质量

    • 证据: 176 行的反引号在模板字面量正文里,确实会提前闭合模板——该修复必要且正确。187 行的反引号位于 ${...} 内的单引号字符串中,是普通字符,不参与模板闭合;去掉后降级分支输出的 plannerFallbackReason 失去代码格式。
    • 受影响调用方/流程: 仅降级分支文案(本轮未触发)。
    • 最小可行修复: 恢复为 \`plannerFallbackReason\`
  5. [低] 报告自述的两项校验在产物里不可见

    • 证据: 开头写「filesense 的全部预算参数……已从 JSONL 校验」,但 JSONL 只记录 enabled/filesenseOutput/filesenseWriteModerun-eval.mjs:288,其注释明说是请求值而非生效值);数值预算靠 run-eval.mjs:84 的环境变量断言,不在 JSONL 里。同段又称「下面的关臂零触发守卫会验证这一点」,而该守卫(report-filesense.mjs:90-98)只向 stderr 输出并 exit,报告正文没有任何一行显示它跑过——读者无法区分「守卫通过」与「守卫未跑/产物被手改」。属既有生成器文案,非本 PR 引入,但本 PR 将其作为证据提交。
    • 最小可行修复: 措辞降级为「output/writeMode 已从 JSONL 校验,数值预算由 harness 启动断言保证」,并在报告里物化守卫结果(例如「关臂触发导航任务数:0/12」)。

行级发现

  • [benchmarks/results/2026-08-01-filesense-ablation.md:140] 「与定位无关……也读到了源文件」与三条 bugfix 的 agentError(patch 指向 billing/calculateAmount.ts、cart/merge.ts、shipping/estimateDeliveryTime.ts,均不存在)相矛盾,且 JSONL 无 read_file 记录;改为记录支持的「目标文件定位错误」表述,或标注证据来自未提交的日志。
  • [benchmarks/results/2026-08-01-filesense-ablation.md:92] computeTotal.test.treport-filesense.mjs:208slice(0, 60) 截掉了末位 s,命令不可执行;截断处补省略号或放宽 cmd detail 上限后重新生成(第 100 行同因)。
  • [benchmarks/eval/report-filesense.mjs:187] 此处反引号在 ${} 内的单引号字符串中,不会提前闭合模板,本次解析错误只来自 176 行;恢复 \`plannerFallbackReason\` 以保留降级分支的代码格式。

Karpathy 评审

  • 假设: 「触发导航」被隐含当作「导航起作用」——deep-create-checkout-hook 触发但 entries: 0,这点结论里已用 #420 明确披露,处理得当;未披露的假设是「bugfix 三条读到了源文件」。
  • 简洁性: 生成器改动 2 行,无新增抽象;报告结构与既有 report.mjs 分工在文件头注释里已说明。
  • 结构质量: 无退化。新增文件为数据与文档,生成器仍 223 行、单一职责,未见薄 wrapper、重复 helper 或边界泄漏。
  • 变更范围: 聚焦。唯一越界是 187 行的非必要改动(见发现 4)。
  • 验证: 我按提交的 JSONL 逐条复算:通过率 4/12 vs 4/12 且逐任务一致、触发 10/12、累计条目 422、均值 42、截断 1、四类通过率与触发数、两臂 input/output/延迟均值(15086/25442/251s 与 12172/21496/224s)、总量差 ~35K/47K、+27s、deep-refactor-route-title 的 6/7 步与全部 token 数,以及「430 条目」(由 fixture-deep/generate.mjs 的 24×8+12×3+14 锚点文件推算:242 files + 187 dirs + src = 430)——全部吻合。未能在本次评审中执行 node 复跑生成器,语法修复系静态判读。

缺失覆盖

  • benchmarks/eval/*.mjs 无任何 lint/解析/执行覆盖(biome 显式排除),本次这类语法错误无自动化手段可发现——建议 precommit 增加 node --check
  • 报告生成器无快照或单测:60 字符截断、零触发/泄漏守卫、降级分支文案均未被任何测试触达。
  • 「430 条目」来自夹具生成器而非 JSONL,与 PR 所称「每个数字都可从提交的 JSONL 复算」不符;建议在报告中标出该数的出处。

|---|---|---|
| query 0/4 | 相同 | #419——不走 LLM 规划,导航结果无人消费 |
| create 2/3 | 相同 | 目标位置在任务描述里线索较强,不导航也能猜对 |
| bugfix 0/3 | 相同 | 代码生成质量,与定位无关(三条都触发了导航、也读到了源文件) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「与定位无关……也读到了源文件」与三条 bugfix 的 agentError(patch 指向 billing/calculateAmount.ts、cart/merge.ts、shipping/estimateDeliveryTime.ts,均不存在)相矛盾,且 JSONL 无 read_file 记录;改为记录支持的「目标文件定位错误」表述,或标注证据来自未提交的日志。

- **[filesense 开] deep-query-format-convention**:result_contains(checkout:), result_contains(toFixed)
- **[filesense 开] deep-query-shared-lib**:result_contains(clamp), result_contains(formatDate), result_contains(pluralize)
- **[filesense 开] deep-create-entity-guard**:file_contains(isExpired)
- **[filesense 开] deep-bugfix-checkout-total**:cmd(npx vitest run src/features/checkout/lib/computeTotal.test.t)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

computeTotal.test.treport-filesense.mjs:208slice(0, 60) 截掉了末位 s,命令不可执行;截断处补省略号或放宽 cmd detail 上限后重新生成(第 100 行同因)。

arms.full.filter((r) => r.plannerFallbackReason).length > 0 ||
arms.off.filter((r) => r.plannerFallbackReason).length > 0
? '**本轮存在降级任务,通过率不可直接引用**——降级把路径覆盖成硬编码值,与 filesense 是否定位成功无关。降级原因见各条记录的 `plannerFallbackReason`。'
? '**本轮存在降级任务,通过率不可直接引用**——降级把路径覆盖成硬编码值,与 filesense 是否定位成功无关。降级原因见各条记录的 plannerFallbackReason。'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此处反引号在 ${} 内的单引号字符串中,不会提前闭合模板,本次解析错误只来自 176 行;恢复 \`plannerFallbackReason\` 以保留降级分支的代码格式。

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.

[Bug] query tasks never use LLM planning, so they can only read files the caller supplied

2 participants