Files
healthlog/openspec/changes/archive/2026-08-04-aktivnaya-proverka-novyh-sekcij/proposal.md
T
av bd5d17b079 первая встреча непокрытой секции стала наблюдаемым событием
- свёртка спрашивает журнал, встречалось ли имя строго раньше по паре
  (received_at, id), и пишет WARN с атрибутом uncovered_new; повторные молчат.
  Признак выводится, а не хранится — реестр был бы второй копией факта
- добавлена подкоманда `healthlog uncovered`: перечень накопленного, чтение
  только на чтение, экранированные имена и названные границы носителя
- синк документации: ADR о выводе новизны из журнала, две записи в журнал
  дефектов, два правила промоутом в конвенции, терминал оператора назван
  адресатом недоверенного входа
2026-08-04 13:39:48 +03:00

69 lines
5.5 KiB
Markdown

## Why
Разбор уже перечисляет секции тела, которых он не покрывает, и пишет их в
`delivery.uncovered_sections`. Момент, ради которого колонка заводилась —
«поток принёс секцию, которой раньше не было», — **фиксируется, но ничем не
наблюдается**: узнать о нём можно только запросом в базу руками, а догадаться
заглянуть в колонку некому.
Пользователь дописывает на телефоне оставшиеся метрики (`symptoms`, `ecg`,
`heartRateNotifications`, `cycleTracking`, `medications`, вес), и данные
появятся сами. Пропущенный момент стоит дорого не сразу: тело живёт в архиве до
следующего проверенного экспорта, и разбор новой секции, написанный через
квартал, писать будет уже не по чему.
## What Changes
- Первая по журналу встреча имени непокрытой секции даёт запись уровня `WARN` в
логирующем чекпоинте свёртки, с именами отдельным атрибутом; повторные встречи
того же имени события не дают.
- Тот же признак переживает **отказ** свёртки: доставка, у которой не вывелся
слой, всё равно записывает список непокрытых секций, поэтому промолчать о
новом имени здесь значило бы потерять событие навсегда — следующая доставка
сочтёт имя уже виденным. Отложенный по обстоятельствам исход события не даёт:
учётной записи он не меняет, доставка вернётся следующим проходом.
- Новизна **выводится из журнала**, а не хранится: строгое сравнение пары
`(received_at, id)` с прежними доставками, запросом вне транзакции записи.
Схема не трогается, отдельного реестра не заводится, состояние остаётся
свёрткой по журналу — пересборка полного архива повторяет те же события.
- Появляется подкоманда `healthlog uncovered`: перечень непокрытых секций,
накопленных журналом, — имя, число доставок, первая и последняя встреча.
Без ручного SQL по рабочей базе, чтением только на чтение, с объявленным
пределом вывода и экранированием имён.
- Границы носителя названы спекой, а не замолчаны: обрезка списка на 32 имени,
обнуление производных полей пересборкой и уход имени из колонки после того,
как секцию покрыли.
Разбор самих новых секций сюда **не входит**: их формы никто не видел, и вслепую
разбор не пишется. Каждая приехавшая секция станет отдельной задачей — тогда,
когда её будет на чём проверить.
## Capabilities
### New Capabilities
- `uncovered-sections`: наблюдение за секциями, которых разбор не покрывает —
событие первой по журналу встречи имени и перечень накопленного.
### Modified Capabilities
- `storage`: перечень оснований, повышающих уровень записи чекпоинта свёртки,
дополнен первой встречей имени непокрытой секции. Перечень нормирован там и
читается как исчерпывающий — без правки следующий автор снял бы новую ветвь как
незаказанную.
Capability `parsing` не меняется: разбор непокрытых секций остаётся как есть,
новое поведение читает его результат.
## Impact
- `internal/store` — запрос «какие из этих имён встречались строго раньше в
журнале» и запрос перечня для команды; обе — чтение по существующей колонке
через `json_each`, вне транзакции записи.
- `internal/fold` — признак новизны в `Stats`, ветвь эскалации в едином
логирующем чекпоинте и в пути отказа.
- `cmd/healthlog` — подкоманда `uncovered`.
- `docs/architecture.md`, `docs/research/apple-health.md` — раздел про
неразобранные секции и сверка перечня не виденных живьём секций с множеством
покрытых имён разбора.