полнота точки — множество ключей, победитель — функция множества точек
- отношение победы было нетранзитивным: полнота (частичный порядок) плюс тай-брейк (тотальный) в попарной свёртке давали цикл, из-за которого одна и та же доставка меняла содержимое объекта при каждой пересборке - надмножество побеждает только при совпадении значений общих содержательных ключей: иначе точка без единого измерения вытесняла измерение - Less стал тотальным, isEmpty не материализует значение, имя метрики в координате столкновения обрезается, отпечаток витрины включает units и sealed - на живом архиве строгий no-op: 1737 объектов, содержимое совпало побайтово
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
## Why
|
||||
|
||||
Полнота точки при разрешении столкновения считается **числом** ключей с
|
||||
непустым значением. Число сравнимо всегда, а сравнивать надо содержание: точка
|
||||
с пятью полями, где значения `0`, `{}` и `[]`, выигрывает у настоящего
|
||||
измерения с двумя полями и стирает его безвозвратно.
|
||||
|
||||
```
|
||||
точка {"qty":0,"a":0,"b":0,"c":{},"d":[]} полнота 5 ← выигрывает сегодня
|
||||
точка {"date":"…","qty":123.4} полнота 2 ← стирается
|
||||
```
|
||||
|
||||
Замер по всем 99 доставкам (docs/local-research.md, находка 49) даёт основание
|
||||
для правильной формы правила: настоящих столкновений 2 897 из 444 256
|
||||
координат (0.65%), из них наборы полей сравнимы в 981 случае, равны в 1 916 и
|
||||
**несравнимы ни разу**. То есть правило сводится к «побеждает надмножество», а
|
||||
самая дорогая часть — объединение полей из двух точек — на живом потоке не
|
||||
нужна вовсе.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Полнота точки перестаёт быть числом и становится **множеством ключей с
|
||||
непустым значением**. Побеждает строгое надмножество; равные множества
|
||||
уходят на прежний тай-брейк.
|
||||
- Пустым значением считается не только `null` и `""`, но и `0`, `{}`, `[]`:
|
||||
поле, не несущее содержания, не делает точку полнее отсутствующего поля.
|
||||
Это и есть та часть, из-за которой сегодняшний счётчик даёт неверный исход
|
||||
на приведённой выше паре. `false` пустотой НЕ считается — для булева поля
|
||||
это одно из двух значений, а не отсутствие сведений.
|
||||
- Надмножество побеждает только при совпадении значений общих содержательных
|
||||
ключей: иначе точка без единого измерения вытесняла бы измерение.
|
||||
- Несравнимые множества (ни одно не является надмножеством другого) не
|
||||
объединяются, а **считаются**: счётчик в итоге слияния плюс `WARN` с
|
||||
координатами объекта (метрика, слой, час), без значений. Победителя в этом
|
||||
случае выбирает тот же тай-брейк, что и при равной полноте.
|
||||
- **Не меняется** тай-брейк при равной полноте: он зависит от рода метрики,
|
||||
а род измеряется сверкой слоёв (задача `rod-agregacii-i-katalog`). Выбирать
|
||||
его сейчас — угадывать то, что скоро станет известно точно.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
Нет.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `storage`: требование «Разрешение столкновений по полноте» переформулируется
|
||||
с числа значащих полей на множество ключей с непустым значением; добавляется
|
||||
наблюдаемость несравнимых множеств.
|
||||
|
||||
## Impact
|
||||
|
||||
- `internal/canon` — `Completeness` (число) заменяется сравнением множеств
|
||||
ключей; расширяется понятие пустого значения.
|
||||
- `internal/store/bucket.go` — `resolve` и `MergeStats` (новый счётчик и
|
||||
координаты несравнимых случаев).
|
||||
- `internal/fold` — новая ветвь `WARN` в единственном логирующем чекпоинте.
|
||||
- `openspec/specs/storage/spec.md` — дельта-спека.
|
||||
- Витрина не мигрирует: правило меняет исход только там, где сегодня он
|
||||
неверен. Проверяется прогоном `task verify:archive` на живом архиве —
|
||||
состояние обязано совпасть с прежним.
|
||||
Reference in New Issue
Block a user