# Bug: VarTree block cache returns stale data

**Status**: исправлен
**Severity**: высокий — ~58% corrupted values в однопоточном тесте
**Затронуты**: `VarTree`, `VarMap` (любой тип, использующий block cache)
**Не затронуты**: `ConstTree`, `ConstMap`, `ZeroTree`, `ZeroMap`, `TypedTree`, `TypedMap` — значения inline в SkipList/HashMap, block cache не используется

## Причина

`BlockKey` не содержал `shard_id`. Каждый шард назначает `file_id` независимо
(все начинают с 1), поэтому `BlockKey { file_id: 1, block_offset: 0 }` у
shard 0 и shard 3 был одинаковым — при cache lookup возвращался блок чужого шарда.

Без ротации баг не проявлялся: все файлы — active, а active file blocks
никогда не кэшируются (`is_full_block = false`).

## Фикс

Добавлено поле `shard_id: u8` в `BlockKey`:

```rust
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct BlockKey {
    pub shard_id: u8,
    pub file_id: u32,
    pub block_offset: u64,
}
```

Обновлены все места создания `BlockKey` в `var_tree.rs`, `var_map.rs`, `cache.rs`
и сигнатура `CompactionIndex::invalidate_blocks`.
