- Правило покрытия получило второй разряд (условный, как у точек), запрет вырождения формы и счёт содержательных элементов ряда: скелет из скаляров и ряд из null больше не затирают маршрут. Победитель внутри доставки стал функцией множества версий — общим помощником с точками, — а провенанс поднимается и при совпавшем хеше, иначе отложенная доставка возвращала витрину к прежнему содержимому. - Одно поле не того типа больше не уносит сущность, а пропуски видны в учётной записи доставки (миграция 00008, NULL = «не измерялось»); каноническая форма считается один раз и вне транзакции; откат бинаря поверх новой схемы отказывает на старте; текст ошибки разбора не несёт значений из тела. - Ревью кода профилем deep (девять проходов) нашло две регрессии и обе закрыты: безусловный второй разряд запирал законный досчёт навсегда, а выбор победителя был квадратичен по числу присланных версий одного ключа.
82 lines
6.4 KiB
Markdown
82 lines
6.4 KiB
Markdown
## MODIFIED Requirements
|
|
|
|
### Requirement: База назначения пригодна к подмене
|
|
|
|
База назначения SHALL нести полноценный учёт доставок, а не только объекты
|
|
витрины: подменяется файл базы **целиком**, а не одна таблица.
|
|
|
|
Состав переноса нормируется явно, потому что колонки `delivery` двух разных
|
|
родов:
|
|
|
|
```
|
|
факты журнала id, received_at, automation_name, automation_id, aggregation,
|
|
period, session_id, bytes, sha256, raw_path, headers
|
|
← переносятся дословно
|
|
производные parse_status, points, derived_layer, uncovered_sections,
|
|
skipped_entities ← начинаются пустыми
|
|
```
|
|
|
|
Перечень производных полей SHALL пополняться **тем же изменением**, которое
|
|
заводит новое поле: он единственное место, где сказано, чему нельзя пережить
|
|
пересборку, и следующий автор решает по нему. Поле, не внесённое в перечень,
|
|
однажды перенесут «для полноты учёта».
|
|
|
|
Факты журнала SHALL переноситься дословно, включая записи, тела которых в
|
|
архиве уже нет. Заголовки восстановлению не подлежат ничем — в архиве их нет, —
|
|
и неполный перенос уничтожил бы их первой же подменой, а с ними и вывод слоя
|
|
для **всех** доставок, не только подобранных. Запись без тела при этом не
|
|
сворачивается и в наследовании слоя не участвует: выведенного слоя у неё нет.
|
|
|
|
Производные от разбора поля MUST начинаться пустыми. Перенос `derived_layer`
|
|
особенно опасен и незаметен: доставка, чей повторный разбор отказал (штатный
|
|
исход, когда слой не выводится), сохранила бы слой **прежнего** разбора, и
|
|
следующая доставка той же автоматизации унаследовала бы его. Витрина снова стала
|
|
бы функцией предыдущего прогона, а не журнала, причём оба прогона были бы
|
|
самосогласованы — проверка «повторная пересборка ничего не меняет» этого не
|
|
ловит. Для числа пропущенных сущностей цена та же и хуже: пустота у него значит
|
|
«не измерялось», и перенесённое число выдавало бы измерение прежнего разбора за
|
|
измерение текущего — а по нему принимается необратимое решение об удалении тела.
|
|
|
|
#### Scenario: Учёт переносится полностью
|
|
|
|
- **WHEN** пересборка завершилась
|
|
- **THEN** число строк учёта в базе назначения равно числу строк рабочей базы
|
|
плюс число подобранных тел
|
|
- **AND** заголовки перенесённых доставок совпадают с рабочей базой дословно
|
|
|
|
#### Scenario: Слой прошлого разбора в наследование не попадает
|
|
|
|
- **WHEN** в рабочей базе у доставок проставлен `derived_layer`
|
|
- **THEN** отпечаток пересобранной витрины совпадает с отпечатком пересборки
|
|
того же журнала из учёта без проставленных слоёв
|
|
|
|
#### Scenario: Число пропущенных сущностей не переносится из журнала
|
|
|
|
- **WHEN** в рабочей базе у доставки проставлено число пропущенных сущностей, а
|
|
тела этой доставки в архиве уже нет
|
|
- **THEN** в базе назначения её число пропущенных сущностей отсутствует
|
|
|
|
## ADDED Requirements
|
|
|
|
### Requirement: Отчёт пересборки показывает удержанные версии сущностей
|
|
|
|
Отчёт пересборки SHALL называть число версий сущностей, удержанных правилом «не
|
|
теряем содержания», — тем же счётчиком, что ведёт свёртка.
|
|
|
|
Без него правило слияния сущностей проверить нечем. Сходимость отпечатка его не
|
|
проверяет **по построению**: живой приём и пересборка пользуются одним правилом
|
|
и одинаково сойдутся на одинаково удержанной версии. То есть слишком строгое
|
|
правило — например, замораживающее тренировку на старой версии из-за исчезнувшего
|
|
ключа с пустым значением — выглядело бы как идеальная сходимость. Счётчик
|
|
несравнимых наборов точек выведен в отчёт по ровно той же причине и тем же
|
|
рассуждением.
|
|
|
|
Число SHALL печататься всегда, а не только при ненулевом значении: ноль здесь
|
|
утверждение, а не отсутствие новостей.
|
|
|
|
#### Scenario: Удержанная версия видна в отчёте пересборки
|
|
|
|
- **WHEN** журнал содержит доставку, приехавшая версия сущности в которой
|
|
теряет содержание сохранённой
|
|
- **THEN** отчёт пересборки называет число удержанных версий больше нуля
|