- каждая запись каталога задач получила тип вместо тега kind: и префикса заголовка; секция роадмапа «Разработка» стала «Сопровождением», порядок секций канонический - поправлены протухшие факты: нереализованные маршруты Read API, MCP и `healthlog import`, словарь слоёв в инварианте, семантика гейта по покрытию диффа, периметр перестал дублировать security.md - замер слияния переведён с находки 49 на находку 54, заполнены Purpose спек storage и parsing
7.1 KiB
✨ Подчищать сырой архив до последнего проверенного экспорта
- Тип: feature
- Категория: Инфра
- Зачем: Архив не подчищается вовсе, а резать его раньше даты проверенного экспорта нельзя — в журнале останется дыра, которую нечем пересобрать
- Теги: goal:journal-and-rebuild
Срок жизни сырого архива объявлен (14 дней, storage.raw_retention), но
удаления нет: архив растёт бесконечно. Пока это 16 МБ и проблемой не является.
Само правило изменилось. Экспорт Apple — снапшот всей истории, доставки после его даты — события поверх снапшота, и состояние всегда пересобираемо свёрткой. Значит доставки должны жить до следующего проверенного экспорта, а не фиксированные две недели: иначе между концом ретеншена и датой снапшота образуется дыра в журнале, и пересобрать этот отрезок будет нечем.
Цена измерена: ~23 МБ архива в сутки, то есть ~2 ГБ за квартал между экспортами. Дёшево за возможность пересобрать что угодно.
Отдельное исключение: stateOfMind в экспорт не попадает вовсе (проверено на
свежем архиве). Для него доставки — не хвост журнала, а единственный источник,
и под общее правило удаления он не подпадает.
Включать после того, как разбор устоится и пересборка докажет, что хранилище действительно восстанавливается: иначе страховка исчезнет раньше, чем перестанет быть нужна.
Готово, когда удаляются только доставки старше последнего проверенного
экспорта, записи stateOfMind не трогаются вовсе, а /stats показывает
глубину архива и дату снапшота, до которой он подрезан.
Двигает строку «Завершения» цели: «Сырой архив подчищается до последнего проверенного экспорта».
Предусловие снова открыто
Признак «доставка с непокрытой секцией» появился в change
2026-08-01-nerazobrannye-sekcii-dostavki и работал заодно защитой
stateOfMind: такие доставки числились partial, и ретеншен их не тронул бы.
Change 2026-08-02-trenirovki-i-zapisi покрыл stateOfMind разбором, и защита
исчезла: доставка из одного состояния разума теперь получает parsed с пустым
списком непокрытых, то есть побайтово неотличима от доставки из метрик — а
метрики восстановимы из экспорта Apple, состояние разума нет (находка 46).
Ретеншен, написанный по правилу «удаляем всё, что не partial», сотрёт ровно те
тела, которых в экспорте не существует, и первая же пересборка потеряет историю
состояния разума навсегда.
Значит признак невосстановимости нужен не производный от «непокрытости». Варианты:
- Перечень покрытых секций, которых нет в экспорте Apple рядом с доставкой
(сегодня — ровно
stateOfMind). Цена: колонка и строка в свёртке; читается так же, какuncovered_sections, и одним запросом. - Признак у доставки «тело — единственный источник», выставляемый разбором. Цена та же, но смысл шире и требует решения, что считать единственным источником для будущих секций.
- Никогда не подрезать тела доставок, у которых есть строки в
record. Цена нулевая по схеме, но неточная: провенанс записи указывает на доставку её текущей версии, а копий у записи бывает по 26.
Рекомендация — первый вариант: он прямо отвечает на вопрос «что останется
потерянным», как это уже делает uncovered_sections, и не требует додумывать
семантику.
Вместе с этим действует правило: задача, которая начинает разбирать секцию, тем
же изменением переводит partial-строки с этим ключом в pending (так сделала
миграция 00007). Ретеншену позволено смотреть на partial только пока правило
соблюдается.
Что читать перед удалением тела
Две колонки учётной записи, и обе обязательны:
uncovered_sections— непустой список означает, что в теле есть секции, которых разбор не покрывает; удалять нельзя;skipped_entities— число сущностей с собственнымid, которые разбор не понял.NULLозначает «не измерялось» и нулю не равен: так выглядят доставки, свёрнутые разбором, который пропусков не считал, и те, чей разбор не досчитал.NULL— «не удалять». Прочитать его как ноль значит удалить тело тренировки, маршрута которой нет больше нигде: в экспорте Apple его не существует.
Правило пришло из задачи «Дозакрыть находки ревью по слиянию сущностей»
(миграция 00008), где колонка и заведена — без DEFAULT именно ради этого
различия.