fix(cache): make the SSD budget real end-to-end and stop v17 corrupting migration fingerprints
The 10% disk default shipped inert and the new SSD-only default could not
start DSV4 at all. Both were found by running the thing rather than reading it.
Engine
- normalize_block_disk_cache_budget() collapses the GB/percent flags to one
number at the single parse_args point, and both scheduler config builders
call it. The GB flag defaults to None so a percent can size the cache, but
the resolver only ran inside the paged-default helper; every other path read
the raw attribute and got None. BlockDiskStore then raises on
"'>' not supported between NoneType and float", the generic path swallows it
("Continuing without disk cache"), and the disk-ONLY path -- the new shipping
default -- refuses to start. Observed live on DeepSeek-V4-Flash-0731:
startup printed max=NoneGB and the engine exited during lifespan startup.
Note getattr(args, 'x', 10.0) did not save it: the default does not fire when
the attribute exists and is None.
- percent 0 now means unlimited, matching --block-disk-cache-max-gb 0 and the
Session Settings slider. It previously returned a flat 10GB, inventing a cap
for a user who explicitly asked for none.
- The fatal disk-only error now carries the cause it used to hide 40 lines
above it in a swallowed except Exception.
Panel
- buildArgs emits --block-disk-cache-max-percent, and fresh configs seed 0 GB
instead of 10. The engine resolves explicit-GB-wins, so seeding the flat GB
meant the percent could never take effect and the slider was decorative.
- The v17 SSD-first default is now a POST-pass. Every legacy cache migration is
an exact-tuple fingerprint that includes usePagedCache, so flipping it first
rewrote near-miss tuples into exact matches and re-fired migrations users had
deliberately escaped. It also skips any pass where the version stamp declined
because the bundle is unreachable -- otherwise it rewrites the fingerprint
the retry depends on and the retry never fires.
- ZAYA CCA and openPangu v2 are exempt: both carry runtime policies that
contradict SSD-only, and a persisted value the launcher overrules would show
the checkbox Off while the engine ran the RAM tier.
- Per-session "Clear SSD cache" button in Session Settings, reporting which
tiers were cleared and which were skipped. paged_prefix:blocks_in_use means
nothing was freed there, so a flat "Cleared." would be a lie.
- One definition of the percent default in src/shared/cacheDefaults.ts.
- The percent tooltip carries the semantics the GB tooltip used to: one
aggregate root shared across namespaces and typed companions, with the
smallest finite limit enforced across live sessions. All five locales.
Verified live on the box, SSD-only, TQ off (stored quantization=none):
DSV4-Flash-0731, Gemma-4-26B (rotating SWA) and Qwen3.8-27B-4D (SSM companion)
answer correctly across changed prefixes, reasoning-effort changes, tools
toggled per turn, JSON and XML tool dialects, malformed and truncated tool
calls, and reasoning blocks in history. RAM tracks model size: gemma4 16.2GB
after load with a 2.9GB on-disk block cache. J
Jinho Jang committed
9200e6ef34f382cf36c229b040d06fcafd69031b
Parent: ae47fcf