Files
healthlog/docs/tasks/items/entity-without-parsed-label.md
av 3d24248075 docs: документация приведена к канону av-dev-pm 4
- каждая запись каталога задач получила тип вместо тега kind: и префикса
  заголовка; секция роадмапа «Разработка» стала «Сопровождением», порядок
  секций канонический
- поправлены протухшие факты: нереализованные маршруты Read API, MCP и
  `healthlog import`, словарь слоёв в инварианте, семантика гейта по покрытию
  диффа, периметр перестал дублировать security.md
- замер слияния переведён с находки 49 на находку 54, заполнены Purpose спек
  storage и parsing
2026-08-05 19:09:35 +03:00

4.1 KiB

🐞 Не терять сущность с id и неразобранной меткой

  • Тип: fix
  • Категория: Ядро
  • Зачем: Тренировка с меткой в неизвестном формате пропадает целиком, а после включения ретеншена окно становится необратимым
  • Теги: goal:parsing-completeness

Решение принято владельцем 2026-08-03: вариант (1) — хранить с NULL-меткой. start_utc/ts_utc становятся NULLABLE, содержимое (включая маршрут) хранится, метку восстановит пересборка, когда разбор научится читать формат. Вариант (3) отвергнут при постановке: подстановка метки доставки — выдуманное измерение в колонке, по которой идёт выборка.

Берётся после тренировок и записей наружу. Правило чтения — что выборка «за период» делает со строками без метки — обязано проектироваться вместе с читателем, иначе такие строки молча исчезнут из любого ответа. Порядок тот же, что у journal-order-on-ingest после /stats: решение принято, момент взятия назван.

Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change dozakryt-nahodki-sushchnostej). Та задача сделала мягким чтение заголовка: поле не той формы стоит одного поля, а не сущности. Но метка исключение — разбор кладёт сущность в ts_utc/start_utc, колонки NOT NULL, и сущность с неразбираемой меткой по-прежнему пропускается целиком.

Двигает строку «Завершения» цели: «Сущность с id и неразобранной меткой не пропадает целиком».

Что известно

  • Оракул: internal/hae/entity_test.go, случаи «метка в ином формате», «метка Unix-эпохой», «метки нет вовсе» — сущность в результат разбора не попадает, счётчик SkippedEntityNoTime растёт.
  • После той задачи пропуск виден в базе: у доставки есть skipped_entities, и ретеншен получает честный ответ «терять есть что». То есть событие больше не молчит — но содержимое всё ещё не хранится.
  • Достижимость из реального потока: замер на 118 доставках дал ноль пропусков всех трёх классов. Дрейф формата дат у HAE при этом задокументирован (docs/research/apple-health.md), то есть вход не выдуман.

Чем платим за отсрочку

Вариант «не хранить» — то, чем живём сегодня: тело лежит в архиве, доставку вернёт reindex. Отсрочка безопасна ровно до включения ретеншена: после него окно становится необратимым. Значит эти две задачи связаны порядком — ретеншен не включается раньше, чем сущность без метки начнёт храниться, либо включается с явной записью о том, что этот класс теряется.