Skip to content

fix(kv-unified): drop the latent-demand ranking cache; #119 follow-ups - #121

Merged
antra-tess merged 3 commits into
anima-research:mainfrom
theaspirational:fix/kv-unified-latent-demand-cache
Sep 26, 2026
Merged

antra-tess merged 3 commits into
anima-research:mainfrom
theaspirational:fix/kv-unified-latent-demand-cache

Conversation

@theaspirational

Copy link
Copy Markdown
Contributor

Follow-up to #119, from the review and benchmark in its thread and @Anarchid's post-merge review.

What changes

Latent-demand ranking cache removed. The cache from db8fb06 was keyed on the summary roots and budget only. But the what-if scores also depend on the chunks, policy, presentation and solver options. Three problems:

  • On our 60-turn replay it only hit when the summarizer stalled. Then it replayed "no merges" on 4 of 6 turns where a fresh ranking asked for L2 merges.
  • The production-budget shadow pick shares its single slot with a different budget, so it never hits there.
  • A branch switch doesn't clear it, and summary ids can repeat across branches.

The ranking is now computed on every compile. It has no candidates, and costs nothing, while fewer than mergeThreshold same-level summaries line up. The what-if certificate stays: we checked it gives the same answers as full solves.

Kept from db8fb06: the shard-metadata index. mergeAdjacentBodyGroupRaw now reuses the message listing selectAdaptive already holds (a third, optional argument, defaulting to store.getAll()), instead of listing a filtered view a second time. Overrides should forward it; the doc comment says so, and the in-repo test override does.

Certificate doc. It now says new foldable leaves are enumerated (up to 256 extensions), and certified results list every extension that fits the hard token wall as candidates.

Changelog. The unreleased compile-overhead note no longer claims the cache (no tag contains db8fb06). A new fragment states the net behaviour: latent demand keeps no ranking state between compiles.

Tests

Each new test was checked by breaking the code it guards; it fails every time.

  • The test that asserted reuse after an append is flipped. On the same roots, an appended message changes the what-if scores, and removing the over-budget price removes the demand.
  • Host guard: the live adapter passes no ranking state between compiles. It fails on a cache key or any object value in latentDemand, so new stateless knobs don't trip it.
  • Tail markers through selectAdaptive (@Anarchid's point 2): a real compile with a sharded last message. Every tail message and shard is its own layout unit, with no 'tail' fallback. The shards are one emitted entry carrying the marker, and the marker lands on the last shard's unit.

npm test: 864/864.

Review rounds

Round 1: GPT-6 Sol, high. Changes needed.

  • The changelog gate needs an added fragment when src/ changes; we had only edited one. Fixed: new fragment, and the gate condition passes locally.
  • The tail-marker test still passed if shards stopped being merged. Fixed: it now checks the merged entry.
  • It also confirmed that the stale-ranking and host-cache regressions each fail their tests, that selectAdaptive passes the same listing as before, and that the doc matches kv-unified-certificate.ts.

Round 2: Claude Opus, xhigh. Approve.

  • The doc said certified results list every extension; they list those that fit the hard token wall. Fixed.
  • The new changelog fragment described a fix for a cache no release ever had. Reworded to the net behaviour (the no-changelog label wasn't an option for us).
  • The host guard pinned the exact key set, so any new stateless setting would fail it with a confusing message. Fixed: it now rejects only a cache key or stored state, with a clear message.
  • The in-repo override of mergeAdjacentBodyGroupRaw dropped the new listing argument. Fixed: it forwards it, and the doc comment says overrides should.
  • It also confirmed: the listing passed in is the exact same snapshot as before, nothing of the cache is left, and all of @Anarchid's points are covered. It broke the code 4 ways on its own; each new test failed.
  • Not changed, noted for later: the shadow production pick doesn't restore _lastKvUnified (only _lastKvStable). This was there before this PR, and nothing in src/ reads that field.

Not covered

  • Real Sill or KR store replay with a live summarizer: the cost of ranking every turn while summaries pile up is only measured on our synthetic replay.
  • The branch-switch case is from reading the code (@Anarchid's note); removing the cache removes it either way.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UN6d9TeXZDWNMxQ3dT5uR8

theaspirational and others added 3 commits September 26, 2026 00:19
The cross-compile ranking cache from db8fb06 was keyed on the summary roots
and budget only, but the what-if scores also depend on the chunks, policy,
presentation and solver options. On a 60-turn replay it only hit when the
summarizer stalled, and then replayed "no merges" on 4 of 6 turns where a
fresh ranking demanded L2 merges. It was also shared by the production-budget
shadow pick (never hit there) and not cleared on branch switches. With fewer
than mergeThreshold same-level roots in a row the ranking has no candidates
and costs nothing, so it is recomputed on every compile. The what-if
certificate stays.

- Flip the test that asserted reuse after an append: appended messages and
  policy changes on the same roots now reach the ranking.
- Host guard: the live adapter passes no ranking state between compiles.
- selectAdaptive test: tail markers resolve to per-message tail units,
  including a sharded last message, not the opaque 'tail' fallback.
- mergeAdjacentBodyGroupRaw reuses the caller's message listing instead of a
  second store.getAll().
- Certificate doc: foldable new leaves are enumerated (up to 256 extensions)
  and certified results list every extension as candidates.
- Changelog: the unreleased compile-overhead note no longer claims the cache.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UN6d9TeXZDWNMxQ3dT5uR8
…log fragment

Review (TASK-SEGR8, GPT-6 Sol high):
- The tail-marker test passed even if mergeAdjacentBodyGroupRaw stopped
  merging shards. It now checks that the sharded message is one emitted entry
  listing every shard and carrying the marker.
- The changelog gate needs an added fragment when src/ changes; add one for
  the latent-demand change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UN6d9TeXZDWNMxQ3dT5uR8
Review round 2 (TASK-9G50H, Opus xhigh):
- Certificate doc: candidates are the enumerated extensions that fit the
  hard token wall.
- Changelog fragment states the net behaviour, with no reference to the
  unreleased cache.
- Host guard no longer pins the latentDemand key set; it rejects a `cache`
  key or any object value, with a message naming the regression.
- The test override of mergeAdjacentBodyGroupRaw forwards the caller's
  listing; the doc comment says overrides should.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UN6d9TeXZDWNMxQ3dT5uR8
@antra-tess
antra-tess merged commit 86d7349 into anima-research:main Sep 26, 2026
5 checks passed
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.

2 participants