fix(dots3): adopt the LOGICAL extent of a restored KV layer, not the padded buffer
Restored plain-KV layers are zero-padded up to KVCache.step (256) while
offset stays logical. _adopt_restored_caches read .keys/.values -- the
padded buffers -- and then let a padded physical length become the offset.
The latent held ceil(n/256)*256 rows while past was n, so the DSA indexer
counted pad rows as real keys, put the causal frontier (physical - logical)
tokens behind, and made zero rows legal top-k candidates. Generation never
converged: it ran to max_tokens and returned no visible content.
Trigger is cached_tokens % 256 != 0, not any particular reuse shape.
Alignment is a 1-in-256 accident -- observed restore lengths were 2176,
2232, 2245, 3438, 7043 and 10634, none aligned.
_logical_kv_extent slices to offset, _logical_offset refuses to launder a
physical length into a logical one, and an invariant check declines the
adoption loudly instead of silently attending over zeros.
Regression test sweeps {256, 320, 448, 512, 576, 2176, 2245}. The existing
dots3 restore tests only used 256 and 512 -- exact multiples of the step,
where the padded and logical extents coincide -- so this was invisible to
them by construction.
Proven on dots3-note-prev-JANG: at cached=2176 and cached=2232 the request
that previously returned an empty answer after 1500 tokens now answers in
78 and 87 tokens. J
Jinho Jang committed
9936e83ed6ced06ab673bc099add0062dfd28fe3
Parent: 1bca990