- находка 47: ключ (date,start,end) даёт 174 координаты сна против 170 по метке и ноль столкновений внутри доставки против 33; value в ключе лишний - UUID в выгрузку Apple не попадает, другой идентичности у эпизода нет - поэпизодный sleep_analysis вернулся в scope razbor-metrik-v-obekty
7.0 KiB
7.0 KiB
Why
Приём работает третьи сутки, но дальше архива данные не идут: 89 доставок лежат
телами .json.gz, а в SQLite только строки delivery. Ни одна из трёх целей
проекта — агент-медик, трекер тренировок, фитнес-игра — не может прочитать
ничего, потому что читать нечего. Каталог, Read API, MCP и OpenAPI упираются в
эту задачу.
Правила разбора не надо изобретать: они выведены измерением на живом потоке и
записаны в docs/local-research.md (находки 30, 33, 35, 36, 38, 39, 41).
Задача — перенести их в код, а не спроектировать заново.
What Changes
- Секция
metricsтела доставки разбирается в точки: метрика, слой, метка времени, содержимое как пришло. - Слой выводится из выравнивания меток, а не из заголовка HAE: плотная
метрика (≥10 точек) классифицируется сама, редкая наследует преобладающий
слой доставки. Заголовок
automation-aggregationнепригоден — значениеDefaultсоответствует трём разным режимам. - Точки складываются в часовые объекты (
bucket, ключметрика + слой + час), содержимое — gzip-BLOB. Запись — read-modify-write со слиянием. - Идентичность точки — координаты (
метрика + слой + метка).sourceв ключ не входит: он нестабилен и меняется задним числом. При столкновении выигрывает более полная точка, а не последняя пришедшая. - Точка-интервал адресуется интервалом:
метрика + слой + начало + конец. Под одной меткой лежит до трёх эпизодов сна, и 33 столкновения из измеренных происходят внутри одной доставки, где тай-брейк по времени приёма неприменим. Эпизодность выводится из формы точки, а не из списка имён метрик. - Канонизация с округлением чисел до ~12 значащих цифр; хеш канонической формы — детектор изменений, а не ключ.
sleep_analysisразводится на два имени: поэпизодное и суточную сводку — под одним именем HAE шлёт две несовместимые схемы.- Метка точки разбирается из локального времени со смещением и хранится в UTC
плюс офсет исходной зоны. Эпоха внутри
heartbeatSeriesне разбирается — серия проходит исходными байтами; RFC 3339 встречается только вstateOfMindи нормируется вместе с ним, отдельной задачей. - Разбор не влияет на код ответа приёма: непонятое содержимое по-прежнему
даёт 200, исход разбора виден в
delivery.parse_statusи в логе.
Не входит в изменение (сознательно, чтобы задача мерджилась целиком):
- тренировки и секции с собственными
id(workouts,stateOfMind, прочиеrecord) — отдельная задача, у них другая модель хранения; healthlog reindex— отдельная задача. Следствие: разбираются только доставки, пришедшие после выката; накопленные 89 доедут пересборкой. Сходимость на них проверяется скриптом поверх архива, а не командой сервиса;- словарь категориальных значений (переведённые строки → коды HealthKit) — отдельная задача; пока строка хранится дословно и без кода рядом;
- род агрегации и каталог разрезов — отдельная задача, она следующая.
Capabilities
New Capabilities
parsing: превращение тела доставки Health Auto Export в точки — вывод слоя, разбор трёх форматов времени, канонизация содержимого, разделение схем под одним именем метрики. Отдельно от хранения потому, что импорт родного экспорта Apple будет другим разбором поверх того же хранилища.storage: идентичность точки, слияние и хранение часовыми объектами — координатный ключ, правило разрешения столкновений, хеш как детектор изменений, признак запечатанного часа.
Modified Capabilities
Нет: openspec/specs/ пуст, приём кодом существует, но спекой не описан и в
этом изменении не трогается.
Impact
- Новые пакеты
internal/hae(разбор),internal/canon(каноническая форма, полнота, хеш — общий дом для разбора и хранения) и расширениеinternal/store(объекты). - Миграция
internal/store/migrations/00003_bucket.sql— первая миграция после приёма; вместе с ней заводитсяdocs/database.md(ER-схема), которую требует шаг гейтаer-schema. internal/ingestполучает шаг разбора после записи в архив; контракт приёма не меняется.- Появляется
testdataс реальными пакетами HAE. Значения в них вычищаются: структура, порядок ключей, форматы времени, неразрывные пробелы в именах устройств и точность чисел сохраняются, измеренные величины заменяются — данные о здоровье не попадают под контроль версий.