diff --git a/docs/tasks/items/apple-export-import.md b/docs/tasks/items/apple-export-import.md index 6771f0e..bb2cd82 100644 --- a/docs/tasks/items/apple-export-import.md +++ b/docs/tasks/items/apple-export-import.md @@ -1,6 +1,8 @@ # Импорт родного экспорта Apple Health -**Секция:** ядро · **Хук:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут · **Теги:** goal:native-export-import +- **Секция:** ядро +- **Зачем:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут +- **Теги:** goal:native-export-import Слой `sample` пуст: настоящих сэмплов HealthKit в потоке нет вовсе — HAE отдаёт посекундную развёртку, а не измерения (находка 34). Полная история и точные diff --git a/docs/tasks/items/categorical-value-dictionary.md b/docs/tasks/items/categorical-value-dictionary.md index de348f5..2a1dce5 100644 --- a/docs/tasks/items/categorical-value-dictionary.md +++ b/docs/tasks/items/categorical-value-dictionary.md @@ -1,6 +1,8 @@ # Словарь категориальных значений → коды HealthKit -**Секция:** ядро · **Хук:** Фазы сна и типы тренировок приходят строками русской локали — с экспортом Apple их не сверить · **Теги:** goal:parsing-and-storage +- **Секция:** ядро +- **Зачем:** Фазы сна и типы тренировок приходят строками русской локали — с экспортом Apple их не сверить +- **Теги:** goal:parsing-and-storage HAE отдаёт перечислимые значения строками локали телефона: «БДГ», «Сидячий образ жизни», «В помещении Ходьба». Родной экспорт Apple при этом говорит diff --git a/docs/tasks/items/config-defaults-data-dir.md b/docs/tasks/items/config-defaults-data-dir.md index 9dd3d15..48b9e4e 100644 --- a/docs/tasks/items/config-defaults-data-dir.md +++ b/docs/tasks/items/config-defaults-data-dir.md @@ -1,6 +1,8 @@ # Умолчания конфига указывают на прежнюю раскладку -**Секция:** инфра · **Хук:** Запуск без конфига заведёт пустую базу в корне рядом с настоящей — тихая ловушка · **Теги:** goal:deploy +- **Секция:** инфра +- **Зачем:** Запуск без конфига заведёт пустую базу в корне рядом с настоящей — тихая ловушка +- **Теги:** goal:deploy Данные переехали в `./data` (база + сырой архив, он же том контейнера), а умолчания в `internal/config` остались прежними: `./healthlog.db` и `./raw`. diff --git a/docs/tasks/items/data-migration-row-selection.md b/docs/tasks/items/data-migration-row-selection.md index 0ded7d2..4b06629 100644 --- a/docs/tasks/items/data-migration-row-selection.md +++ b/docs/tasks/items/data-migration-row-selection.md @@ -1,6 +1,8 @@ # Data-миграции не отбирают строки по обрезаемым спискам -**Секция:** ядро · **Хук:** Миграция 00007 отбирает по uncovered_sections, который обрезается на 32 — следующая покрытая секция унаследует слепую зону · **Теги:** goal:journal-and-rebuild +- **Секция:** ядро +- **Зачем:** Миграция 00007 отбирает по uncovered_sections, который обрезается на 32 — следующая покрытая секция унаследует слепую зону +- **Теги:** goal:journal-and-rebuild Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change `dozakryt-nahodki-sushchnostej`). diff --git a/docs/tasks/items/day-boundary-timezone.md b/docs/tasks/items/day-boundary-timezone.md index 64be339..9b6a06e 100644 --- a/docs/tasks/items/day-boundary-timezone.md +++ b/docs/tasks/items/day-boundary-timezone.md @@ -1,6 +1,8 @@ # [idea] Что считать сутками при смене часового пояса -**Секция:** ядро · **Хук:** Шаги за день — базовый запрос трекера и игры, но чей это день при перелёте, не решено · **Теги:** goal:read-api +- **Секция:** ядро +- **Зачем:** Шаги за день — базовый запрос трекера и игры, но чей это день при перелёте, не решено +- **Теги:** goal:read-api «Шаги за день» — базовый запрос трекера и фитнес-игры. Но точка несёт метку с офсетом исходной зоны, и при перелёте сутки перестают быть однозначными: день diff --git a/docs/tasks/items/delivery-header-limits.md b/docs/tasks/items/delivery-header-limits.md index d0688dc..bbbe999 100644 --- a/docs/tasks/items/delivery-header-limits.md +++ b/docs/tasks/items/delivery-header-limits.md @@ -1,6 +1,8 @@ # Предел на размер и число заголовков доставки -**Секция:** ядро · **Хук:** MaxHeaderBytes не задан, в базу заголовки пишутся целиком: дефект спит до деплоя, а просыпается вместе с ним · **Теги:** goal:limits-and-load +- **Секция:** ядро +- **Зачем:** MaxHeaderBytes не задан, в базу заголовки пишутся целиком: дефект спит до деплоя, а просыпается вместе с ним +- **Теги:** goal:limits-and-load У тела доставки предел есть (`max_body`), у заголовков — нет ни одного: `MaxHeaderBytes` серверу не задан, а `delivery.headers` пишутся в базу целиком, diff --git a/docs/tasks/items/delivery-headers-in-archive.md b/docs/tasks/items/delivery-headers-in-archive.md index 6fa43ae..121aa21 100644 --- a/docs/tasks/items/delivery-headers-in-archive.md +++ b/docs/tasks/items/delivery-headers-in-archive.md @@ -1,6 +1,8 @@ # Заголовки доставки в архиве рядом с телом -**Секция:** ядро · **Хук:** Заголовки живут только в базе — потеря базы навсегда ломает вывод слоя при пересборке · **Теги:** goal:journal-and-rebuild +- **Секция:** ядро +- **Зачем:** Заголовки живут только в базе — потеря базы навсегда ломает вывод слоя при пересборке +- **Теги:** goal:journal-and-rebuild Состояние объявлено свёрткой по журналу, а журналом — сырой архив. Но в архиве лежит только **тело**: заголовки запроса (`automation-id`, diff --git a/docs/tasks/items/deploy-rivendell.md b/docs/tasks/items/deploy-rivendell.md index fbe596d..e128108 100644 --- a/docs/tasks/items/deploy-rivendell.md +++ b/docs/tasks/items/deploy-rivendell.md @@ -1,6 +1,8 @@ # Деплой на rivendell -**Секция:** инфра · **Хук:** Сервис живёт на рабочей машине — телефон достаёт до него только дома · **Теги:** goal:deploy +- **Секция:** инфра +- **Зачем:** Сервис живёт на рабочей машине — телефон достаёт до него только дома +- **Теги:** goal:deploy Сервис живёт в контейнере на рабочей машине, телефон достаёт до него только дома. Вне дома экспорт копится и уезжает пачкой при возвращении — работает, но diff --git a/docs/tasks/items/deploy.md b/docs/tasks/items/deploy.md index a0e6133..27e602d 100644 --- a/docs/tasks/items/deploy.md +++ b/docs/tasks/items/deploy.md @@ -1,6 +1,8 @@ # [goal] Деплой -**Секция:** порядок · **Хук:** Сервис живёт на рабочей машине — телефон достаёт до него только дома, и оба контура открыты +- **Секция:** порядок +- **Зачем:** Сервис живёт на рабочей машине — телефон достаёт до него только дома, и оба контура открыты +- **Теги:** decomposed Сервис переезжает на rivendell и становится доступен телефону из любой сети. diff --git a/docs/tasks/items/derived-content-schemas.md b/docs/tasks/items/derived-content-schemas.md index e07cee4..544da0d 100644 --- a/docs/tasks/items/derived-content-schemas.md +++ b/docs/tasks/items/derived-content-schemas.md @@ -1,6 +1,8 @@ # Выведенные из данных схемы содержимого -**Секция:** ядро · **Хук:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке · **Теги:** goal:self-description +- **Секция:** ядро +- **Зачем:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке +- **Теги:** goal:self-description Метрик у Apple больше сотни, формы точек разные, и рукописный каталог описывал бы документацию HAE, а не то, что он реально прислал. Схема содержимого diff --git a/docs/tasks/items/drop-heartbeat-series.md b/docs/tasks/items/drop-heartbeat-series.md index 1213231..36b08b5 100644 --- a/docs/tasks/items/drop-heartbeat-series.md +++ b/docs/tasks/items/drop-heartbeat-series.md @@ -1,6 +1,8 @@ # [idea] Отказ от heartbeatSeries -**Секция:** ядро · **Хук:** 93% объёма HRV ради данных, которых нет ни в одном планируемом запросе · **Теги:** goal:lower-layer-cleanup +- **Секция:** ядро +- **Зачем:** 93% объёма HRV ради данных, которых нет ни в одном планируемом запросе +- **Теги:** goal:lower-layer-cleanup `heart_rate_variability` приезжает вместе с `heartbeatSeries` — рядом межударных интервалов внутри точки. Это **93% объёма метрики** (находка 39) diff --git a/docs/tasks/items/entity-size-limits.md b/docs/tasks/items/entity-size-limits.md index f8a68f5..78afcca 100644 --- a/docs/tasks/items/entity-size-limits.md +++ b/docs/tasks/items/entity-size-limits.md @@ -1,6 +1,8 @@ # Пределы на размер сущности и потоковый расчёт формы -**Секция:** ядро · **Хук:** Тело 40 МиБ даёт 768 МиБ пика кучи, 63 МиБ держат блокировку 5.019 с — предела на одну сущность нет вовсе · **Теги:** goal:limits-and-load +- **Секция:** ядро +- **Зачем:** Тело 40 МиБ даёт 768 МиБ пика кучи, 63 МиБ держат блокировку 5.019 с — предела на одну сущность нет вовсе +- **Теги:** goal:limits-and-load Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change `dozakryt-nahodki-sushchnostej`). Та задача убрала канонизацию приехавшей diff --git a/docs/tasks/items/entity-without-parsed-label.md b/docs/tasks/items/entity-without-parsed-label.md index 2c750d8..84a8ffe 100644 --- a/docs/tasks/items/entity-without-parsed-label.md +++ b/docs/tasks/items/entity-without-parsed-label.md @@ -1,6 +1,8 @@ # Сущность с id, но неразобранной меткой -**Секция:** ядро · **Хук:** Тренировка с меткой в неизвестном формате пропадает целиком — а её id и содержимое разобраны · **Теги:** goal:parsing-and-storage, question +- **Секция:** ядро +- **Зачем:** Тренировка с меткой в неизвестном формате пропадает целиком — а её id и содержимое разобраны +- **Теги:** goal:parsing-and-storage, question Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change `dozakryt-nahodki-sushchnostej`). Та задача сделала мягким чтение заголовка: diff --git a/docs/tasks/items/integrity-before-swap.md b/docs/tasks/items/integrity-before-swap.md index a53b913..97a3a00 100644 --- a/docs/tasks/items/integrity-before-swap.md +++ b/docs/tasks/items/integrity-before-swap.md @@ -1,6 +1,8 @@ # Проверка целостности собранной витрины перед подменой -**Секция:** ядро · **Хук:** Подмена файла необратима, а годность выхода подтверждена отпечатком на ещё открытом дескрипторе · **Теги:** goal:journal-and-rebuild +- **Секция:** ядро +- **Зачем:** Подмена файла необратима, а годность выхода подтверждена отпечатком на ещё открытом дескрипторе +- **Теги:** goal:journal-and-rebuild `healthlog reindex` собирает витрину в отдельный файл и снимает с него отпечаток, а подмену делает человек: остановить сервис, переименовать файл, diff --git a/docs/tasks/items/journal-and-rebuild.md b/docs/tasks/items/journal-and-rebuild.md index 3a0d63b..6edd7e3 100644 --- a/docs/tasks/items/journal-and-rebuild.md +++ b/docs/tasks/items/journal-and-rebuild.md @@ -1,6 +1,8 @@ # [goal] Журнал и пересборка -**Секция:** темы · **Хук:** Расхождение витрины с журналом сейчас молчит: reindex печатает оба отпечатка, а сравнивать их некому +- **Секция:** темы +- **Зачем:** Расхождение витрины с журналом сейчас молчит: reindex печатает оба отпечатка, а сравнивать их некому +- **Теги:** decomposed Тема: инвариант «`import` + `replay` даёт то же состояние» и всё, что его держит — архив, ретеншен, отпечаток витрины, расход памяти пересборки. diff --git a/docs/tasks/items/journal-order-on-ingest.md b/docs/tasks/items/journal-order-on-ingest.md index 43d1ee1..f7a7566 100644 --- a/docs/tasks/items/journal-order-on-ingest.md +++ b/docs/tasks/items/journal-order-on-ingest.md @@ -1,6 +1,8 @@ # Порядок журнала при конкурентных приёмах -**Секция:** ядро · **Хук:** Решено: повторы, но после /stats. Доставка, свёрнутая раньше своей предшественницы, уходит в failed навсегда · **Теги:** goal:journal-and-rebuild, question +- **Секция:** ядро +- **Зачем:** Решено: повторы, но после /stats. Доставка, свёрнутая раньше своей предшественницы, уходит в failed навсегда +- **Теги:** goal:journal-and-rebuild, question **Решение принято владельцем 2026-08-02: вариант (в), но не раньше `/stats`.** До появления наблюдаемости живём вариантом (г) с уже записанным в спеке diff --git a/docs/tasks/items/limits-and-load.md b/docs/tasks/items/limits-and-load.md index 9824695..a1567e3 100644 --- a/docs/tasks/items/limits-and-load.md +++ b/docs/tasks/items/limits-and-load.md @@ -1,6 +1,8 @@ # [goal] Пределы и поведение под объёмом -**Секция:** темы · **Хук:** Предела на одну сущность нет вовсе: 63 МиБ держат блокировку 5.019 с, соседние доставки уходят в failed +- **Секция:** темы +- **Зачем:** Предела на одну сущность нет вовсе: 63 МиБ держат блокировку 5.019 с, соседние доставки уходят в failed +- **Теги:** decomposed Тема: названные пределы на размер тела, сущности, заголовков и ответа плюс поведение под удерживаемой блокировкой. diff --git a/docs/tasks/items/lower-layer-cleanup.md b/docs/tasks/items/lower-layer-cleanup.md index 8266a41..280bdc2 100644 --- a/docs/tasks/items/lower-layer-cleanup.md +++ b/docs/tasks/items/lower-layer-cleanup.md @@ -1,6 +1,8 @@ # [goal] Устаревание нижнего слоя -**Секция:** порядок · **Хук:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен +- **Секция:** порядок +- **Зачем:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен +- **Теги:** decomposed После проверенного экспорта нижний слой HAE избыточен и подлежит чистке. diff --git a/docs/tasks/items/lower-layer-expiry.md b/docs/tasks/items/lower-layer-expiry.md index 3739dcc..b87dbb1 100644 --- a/docs/tasks/items/lower-layer-expiry.md +++ b/docs/tasks/items/lower-layer-expiry.md @@ -1,6 +1,8 @@ # Устаревание нижнего слоя после экспорта -**Секция:** ядро · **Хук:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен · **Теги:** goal:lower-layer-cleanup +- **Секция:** ядро +- **Зачем:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен +- **Теги:** goal:lower-layer-cleanup Нижний слой растёт примерно на 100 тысяч координат в сутки против ~3 700 у минутного и ~100 у часового — разница в три порядка (находка 41). Всё давление diff --git a/docs/tasks/items/mcp-server.md b/docs/tasks/items/mcp-server.md index 39342f9..e45aad5 100644 --- a/docs/tasks/items/mcp-server.md +++ b/docs/tasks/items/mcp-server.md @@ -1,6 +1,8 @@ # MCP-сервер поверх Read API -**Секция:** ядро · **Хук:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем · **Теги:** goal:mcp +- **Секция:** ядро +- **Зачем:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем +- **Теги:** goal:mcp Агент-медик — первый заказчик проекта. Ему нужна актуальная сводка, а не срез на дату последнего ручного экспорта. diff --git a/docs/tasks/items/mcp.md b/docs/tasks/items/mcp.md index f4ded69..257b694 100644 --- a/docs/tasks/items/mcp.md +++ b/docs/tasks/items/mcp.md @@ -1,6 +1,8 @@ # [goal] MCP -**Секция:** порядок · **Хук:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем +- **Секция:** порядок +- **Зачем:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем +- **Теги:** decomposed Агент-медик — первый заказчик проекта — подключается к хранилищу. diff --git a/docs/tasks/items/merge-cost-wide-delivery.md b/docs/tasks/items/merge-cost-wide-delivery.md index 81418d2..688ce58 100644 --- a/docs/tasks/items/merge-cost-wide-delivery.md +++ b/docs/tasks/items/merge-cost-wide-delivery.md @@ -1,6 +1,8 @@ # Цена слияния на широкой доставке -**Секция:** ядро · **Хук:** 63 МБ на одной координате держат транзакцию 5.15 с при busy_timeout 5 с — соседние доставки уходят в failed · **Теги:** goal:limits-and-load +- **Секция:** ядро +- **Зачем:** 63 МБ на одной координате держат транзакцию 5.15 с при busy_timeout 5 с — соседние доставки уходят в failed +- **Теги:** goal:limits-and-load Вынуто ревью кода задачи `pravilo-sliyaniya-tochek` (профиль `deep`, враждебный проход и независимая реализация — независимо друг от друга). diff --git a/docs/tasks/items/merge-counters-in-db.md b/docs/tasks/items/merge-counters-in-db.md index a524d69..25be49f 100644 --- a/docs/tasks/items/merge-counters-in-db.md +++ b/docs/tasks/items/merge-counters-in-db.md @@ -1,6 +1,8 @@ # Счётчики слияния переживают ротацию логов -**Секция:** инфра · **Хук:** единственный след несравнимых наборов — строка WARN в docker-логе с ротацией 3×10 МБ: событие может произойти и не оставить ничего · **Теги:** goal:observability +- **Секция:** инфра +- **Зачем:** единственный след несравнимых наборов — строка WARN в docker-логе с ротацией 3×10 МБ: событие может произойти и не оставить ничего +- **Теги:** goal:observability Вынуто ревью кода задачи `pravilo-sliyaniya-tochek` (профиль `deep`, проход негативного пространства, подтверждено эксплуатационным). diff --git a/docs/tasks/items/merge-robustness.md b/docs/tasks/items/merge-robustness.md index f67b5d8..4f1c1c8 100644 --- a/docs/tasks/items/merge-robustness.md +++ b/docs/tasks/items/merge-robustness.md @@ -1,6 +1,8 @@ # [goal] Прочность слияния и идентичности -**Секция:** темы · **Хук:** Правила слияния держатся на замерах, и каждый новый замер находит зависимость от порядка на проводе +- **Секция:** темы +- **Зачем:** Правила слияния держатся на замерах, и каждый новый замер находит зависимость от порядка на проводе +- **Теги:** decomposed Тема: правила, по которым две версии одних данных превращаются в одну. В порядок не встаёт — работа приходит находками ревью и замерами на diff --git a/docs/tasks/items/monthly-manual-sections-pass.md b/docs/tasks/items/monthly-manual-sections-pass.md index 5b3cbd6..9963fc1 100644 --- a/docs/tasks/items/monthly-manual-sections-pass.md +++ b/docs/tasks/items/monthly-manual-sections-pass.md @@ -1,6 +1,8 @@ # [idea] Месячный проход по ручным секциям -**Секция:** ядро · **Хук:** Симптомы и лекарства заводятся задним числом на недели — недельного глубокого прохода им не хватит · **Теги:** goal:parsing-and-storage +- **Секция:** ядро +- **Зачем:** Симптомы и лекарства заводятся задним числом на недели — недельного глубокого прохода им не хватит +- **Теги:** goal:parsing-and-storage Окно досчёта не единое, и это измеренное различие, а не предположение. Количественные метрики (пульс, шаги, энергия) человек руками не правит — они diff --git a/docs/tasks/items/native-export-import.md b/docs/tasks/items/native-export-import.md index 184a9ed..9d03177 100644 --- a/docs/tasks/items/native-export-import.md +++ b/docs/tasks/items/native-export-import.md @@ -1,6 +1,8 @@ # [goal] Импорт родного экспорта Apple -**Секция:** порядок · **Хук:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут +- **Секция:** порядок +- **Зачем:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут +- **Теги:** decomposed `healthlog import`: снапшот всей истории из родного экспорта Apple Health ложится в хранилище перед проигрыванием хвоста доставок. diff --git a/docs/tasks/items/ndjson-stream.md b/docs/tasks/items/ndjson-stream.md index d35e5a0..e4e2c77 100644 --- a/docs/tasks/items/ndjson-stream.md +++ b/docs/tasks/items/ndjson-stream.md @@ -1,6 +1,8 @@ # [idea] NDJSON-поток для больших выборок Read API -**Секция:** ядро · **Хук:** Выборка нижнего слоя за месяц не влезает в один JSON-ответ — либо поток, либо пагинация · **Теги:** goal:read-api +- **Секция:** ядро +- **Зачем:** Выборка нижнего слоя за месяц не влезает в один JSON-ответ — либо поток, либо пагинация +- **Теги:** goal:read-api Read API отдаёт ответ одним JSON. Для выборок нижнего слоя за длинный период это не работает: `heart_rate` в слое `raw` — порядка сотни тысяч координат в diff --git a/docs/tasks/items/observability.md b/docs/tasks/items/observability.md index 0113556..447846e 100644 --- a/docs/tasks/items/observability.md +++ b/docs/tasks/items/observability.md @@ -1,6 +1,8 @@ # [goal] Наблюдаемость -**Секция:** порядок · **Хук:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах +- **Секция:** порядок +- **Зачем:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах +- **Теги:** decomposed Тихо сломавшаяся автоматизация — главный эксплуатационный риск: телефон шлёт молча, и молчание неотличимо от нормы. diff --git a/docs/tasks/items/openapi-swagger.md b/docs/tasks/items/openapi-swagger.md index 01074f1..9a4c57f 100644 --- a/docs/tasks/items/openapi-swagger.md +++ b/docs/tasks/items/openapi-swagger.md @@ -1,6 +1,8 @@ # OpenAPI-спека и Swagger UI -**Секция:** ядро · **Хук:** Потребителей три и один из них агент — контракт должен читаться машиной, а не пересказываться в чате · **Теги:** goal:read-api +- **Секция:** ядро +- **Зачем:** Потребителей три и один из них агент — контракт должен читаться машиной, а не пересказываться в чате +- **Теги:** goal:read-api Потребителей три, и один из них — агент, который читает контракт машиной. Пересказывать форму ответа в чате не годится, а самоописание из плана покрывает diff --git a/docs/tasks/items/overlapping-sources.md b/docs/tasks/items/overlapping-sources.md index 3f34ebb..3891d3d 100644 --- a/docs/tasks/items/overlapping-sources.md +++ b/docs/tasks/items/overlapping-sources.md @@ -1,6 +1,8 @@ # [idea] Пересекающиеся источники одной метрики -**Секция:** ядро · **Хук:** Сон пишут и часы, и стороннее приложение — сумма по обоим задвоит ночь · **Теги:** goal:read-api +- **Секция:** ядро +- **Зачем:** Сон пишут и часы, и стороннее приложение — сумма по обоим задвоит ночь +- **Теги:** goal:read-api Одну метрику пишут несколько источников: сон — часы и стороннее приложение AutoSleep, шаги — часы и телефон одновременно. Поле `source` при этом не diff --git a/docs/tasks/items/parquet-export.md b/docs/tasks/items/parquet-export.md index cf611ed..6aed1e6 100644 --- a/docs/tasks/items/parquet-export.md +++ b/docs/tasks/items/parquet-export.md @@ -1,6 +1,8 @@ # [idea] Выгрузка в parquet отдельной командой -**Секция:** ядро · **Хук:** Дверь для тяжёлой аналитики снаружи: DuckDB читает и parquet, и файл SQLite — спешить некуда, но и закрывать не нужно · **Теги:** goal:read-api +- **Секция:** ядро +- **Зачем:** Дверь для тяжёлой аналитики снаружи: DuckDB читает и parquet, и файл SQLite — спешить некуда, но и закрывать не нужно +- **Теги:** goal:read-api Отдельная команда, выгружающая хранилище в parquet, — дверь для тяжёлой аналитики снаружи, без миграции самого хранилища. diff --git a/docs/tasks/items/parsing-and-storage.md b/docs/tasks/items/parsing-and-storage.md index f2672c1..8b2e37d 100644 --- a/docs/tasks/items/parsing-and-storage.md +++ b/docs/tasks/items/parsing-and-storage.md @@ -1,6 +1,8 @@ # [goal] Разбор и хранилище -**Секция:** порядок · **Хук:** Секции живого потока разобраны все, кроме словаря категориальных значений и пяти невиденных +- **Секция:** порядок +- **Зачем:** Секции живого потока разобраны все, кроме словаря категориальных значений и пяти невиденных +- **Теги:** decomposed Метрики, тренировки и записи со своими `id` разбираются и ложатся в часовые объекты; тела перестали быть недифференцированной кучей. diff --git a/docs/tasks/items/raw-archive-retention.md b/docs/tasks/items/raw-archive-retention.md index 9f77d81..bbae8fa 100644 --- a/docs/tasks/items/raw-archive-retention.md +++ b/docs/tasks/items/raw-archive-retention.md @@ -1,6 +1,8 @@ # Ретеншен сырого архива -**Секция:** инфра · **Хук:** Архив не подчищается вовсе — 14-дневный срок объявлен, но не работает · **Теги:** goal:journal-and-rebuild +- **Секция:** инфра +- **Зачем:** Архив не подчищается вовсе — 14-дневный срок объявлен, но не работает +- **Теги:** goal:journal-and-rebuild Срок жизни сырого архива объявлен (14 дней, `storage.raw_retention`), но удаления нет: архив растёт бесконечно. Пока это 16 МБ и проблемой не является. diff --git a/docs/tasks/items/read-api-points.md b/docs/tasks/items/read-api-points.md index 5ecce87..846f94a 100644 --- a/docs/tasks/items/read-api-points.md +++ b/docs/tasks/items/read-api-points.md @@ -1,6 +1,8 @@ # Read API: точки, выбор слоя, свёртка по сетке -**Секция:** ядро · **Хук:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может · **Теги:** goal:read-api +- **Секция:** ядро +- **Зачем:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может +- **Теги:** goal:read-api Сейчас данные достаются только `sqlite3` на хосте. Все три сценария — агент-медик, трекер тренировок, фитнес-игра — упираются в отсутствие чтения. diff --git a/docs/tasks/items/read-api.md b/docs/tasks/items/read-api.md index c8b8d07..7eedbe9 100644 --- a/docs/tasks/items/read-api.md +++ b/docs/tasks/items/read-api.md @@ -1,6 +1,8 @@ # [goal] Read API -**Секция:** порядок · **Хук:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может +- **Секция:** порядок +- **Зачем:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может +- **Теги:** decomposed Потребители читают точки: выбор слоя, свёртка по сетке, предел размера ответа. diff --git a/docs/tasks/items/rebuild-comparison-check.md b/docs/tasks/items/rebuild-comparison-check.md index 86e40b7..f3ef590 100644 --- a/docs/tasks/items/rebuild-comparison-check.md +++ b/docs/tasks/items/rebuild-comparison-check.md @@ -1,6 +1,8 @@ # Сверка живой витрины с пересборкой -**Секция:** ядро · **Хук:** reindex печатает оба отпечатка, но сравнивать их некому — расхождение с журналом молчит · **Теги:** goal:journal-and-rebuild +- **Секция:** ядро +- **Зачем:** reindex печатает оба отпечатка, но сравнивать их некому — расхождение с журналом молчит +- **Теги:** goal:journal-and-rebuild `healthlog reindex` печатает отпечаток собранной витрины и отпечаток рабочей — то есть данные для сверки уже есть, и **сравнивать их некому**. Расхождение diff --git a/docs/tasks/items/rebuild-memory-footprint.md b/docs/tasks/items/rebuild-memory-footprint.md index f342364..3d44183 100644 --- a/docs/tasks/items/rebuild-memory-footprint.md +++ b/docs/tasks/items/rebuild-memory-footprint.md @@ -1,6 +1,8 @@ # Пересборка держит весь журнал в памяти -**Секция:** ядро · **Хук:** Учёт доставок и список путей архива материализуются целиком: расход растёт вместе с журналом, а у журнала конца нет · **Теги:** goal:journal-and-rebuild +- **Секция:** ядро +- **Зачем:** Учёт доставок и список путей архива материализуются целиком: расход растёт вместе с журналом, а у журнала конца нет +- **Теги:** goal:journal-and-rebuild `healthlog reindex` материализует целиком две вещи: учёт доставок из базы и список путей архива. На сегодняшнем объёме (сотня тел) это незаметно, на diff --git a/docs/tasks/items/release-rollback-after-migration.md b/docs/tasks/items/release-rollback-after-migration.md index 6eac011..96f3da0 100644 --- a/docs/tasks/items/release-rollback-after-migration.md +++ b/docs/tasks/items/release-rollback-after-migration.md @@ -1,6 +1,8 @@ # Чем откатывать релиз после наката миграции -**Секция:** инфра · **Хук:** Решено: копия файла базы перед накатом. Страж версии схемы делает возврат бинаря отказом, а понизить схему нечем · **Теги:** goal:deploy, question +- **Секция:** инфра +- **Зачем:** Решено: копия файла базы перед накатом. Страж версии схемы делает возврат бинаря отказом, а понизить схему нечем +- **Теги:** goal:deploy, question **Решение принято владельцем 2026-08-02: вариант (2) — копия файла базы перед накатом.** Entrypoint контейнера копирует файл базы рядом до старта бинаря, diff --git a/docs/tasks/items/schema-annotations.md b/docs/tasks/items/schema-annotations.md index b625d1a..881d54e 100644 --- a/docs/tasks/items/schema-annotations.md +++ b/docs/tasks/items/schema-annotations.md @@ -1,6 +1,8 @@ # [idea] Человеческие аннотации поверх выведенных схем -**Секция:** ядро · **Хук:** Выведенная схема говорит форму, но не смысл метрики — нужно ли описание сверху, зависит от стабильности формата · **Теги:** goal:self-description +- **Секция:** ядро +- **Зачем:** Выведенная схема говорит форму, но не смысл метрики — нужно ли описание сверху, зависит от стабильности формата +- **Теги:** goal:self-description Схема содержимого выводится из данных и говорит **форму** — какие поля есть, какого типа, с какой заполненностью. Чего она не говорит — что метрика значит, diff --git a/docs/tasks/items/sealed-threshold.md b/docs/tasks/items/sealed-threshold.md index 0a39b9a..ea0971d 100644 --- a/docs/tasks/items/sealed-threshold.md +++ b/docs/tasks/items/sealed-threshold.md @@ -1,6 +1,8 @@ # [idea] Порог sealed: с какого возраста час считается запечатанным -**Секция:** ядро · **Хук:** WARN на изменение старого часа уже пишется, но порог не выбран — ставим по факту, когда накопится статистика досчёта · **Теги:** goal:merge-robustness +- **Секция:** ядро +- **Зачем:** WARN на изменение старого часа уже пишется, но порог не выбран — ставим по факту, когда накопится статистика досчёта +- **Теги:** goal:merge-robustness Флаг `sealed` отмечает часы, которые уже не должны меняться. Механика готова: изменение запечатанного объекта не отвергается, а пишется `WARN`, и данные diff --git a/docs/tasks/items/self-description.md b/docs/tasks/items/self-description.md index ad51991..f2c872a 100644 --- a/docs/tasks/items/self-description.md +++ b/docs/tasks/items/self-description.md @@ -1,6 +1,8 @@ # [goal] Самоописание -**Секция:** порядок · **Хук:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке +- **Секция:** порядок +- **Зачем:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке +- **Теги:** decomposed Клиент узнаёт форму данных из ответа сервиса, а не угадывает её по выборке. diff --git a/docs/tasks/items/shutdown-and-migration-traces.md b/docs/tasks/items/shutdown-and-migration-traces.md index 01a215e..a2b5f75 100644 --- a/docs/tasks/items/shutdown-and-migration-traces.md +++ b/docs/tasks/items/shutdown-and-migration-traces.md @@ -1,6 +1,8 @@ # Остановка и миграция: раздельные бюджеты и следы в логе -**Секция:** инфра · **Хук:** Долгий запрос чтения съедает бюджет остановки, и WARN обвиняет воркер свёртки; миграция молчит и не прерывается SIGTERM · **Теги:** goal:deploy +- **Секция:** инфра +- **Зачем:** Долгий запрос чтения съедает бюджет остановки, и WARN обвиняет воркер свёртки; миграция молчит и не прерывается SIGTERM +- **Теги:** goal:deploy Две находки эксплуатационного и идиоматического проходов ревью каталога. Обе существовали и раньше, но достижимыми их сделал первый маршрут чтения: diff --git a/docs/tasks/items/stats-endpoint.md b/docs/tasks/items/stats-endpoint.md index 0badf6d..a25fe54 100644 --- a/docs/tasks/items/stats-endpoint.md +++ b/docs/tasks/items/stats-endpoint.md @@ -1,6 +1,8 @@ # Наблюдаемость: /stats -**Секция:** инфра · **Хук:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах · **Теги:** goal:observability +- **Секция:** инфра +- **Зачем:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах +- **Теги:** goal:observability Тихо сломавшаяся автоматизация — главный эксплуатационный риск коллектора: данные просто перестают приходить, и заметить это можно только по молчанию. diff --git a/docs/tasks/items/stream-silence-alert.md b/docs/tasks/items/stream-silence-alert.md index 77dd1bd..53986a0 100644 --- a/docs/tasks/items/stream-silence-alert.md +++ b/docs/tasks/items/stream-silence-alert.md @@ -1,6 +1,8 @@ # Активный алерт «данных нет N часов» -**Секция:** инфра · **Хук:** Пропажу потока сейчас замечает человек, а не сервис · **Теги:** goal:observability +- **Секция:** инфра +- **Зачем:** Пропажу потока сейчас замечает человек, а не сервис +- **Теги:** goal:observability Пропажу потока сейчас замечает человек. `/stats` покажет факт, но только если туда заглянуть — а заглядывают ровно тогда, когда уже что-то заподозрили. diff --git a/docs/tasks/items/tie-break-equal-completeness.md b/docs/tasks/items/tie-break-equal-completeness.md index ffb2720..10d736a 100644 --- a/docs/tasks/items/tie-break-equal-completeness.md +++ b/docs/tasks/items/tie-break-equal-completeness.md @@ -1,6 +1,8 @@ # Тай-брейк при равной полноте точек -**Секция:** ядро · **Хук:** Решено: брать бо́льшее значение. Порядок канонических форм берёт меньшее в 96% случаев — для накопительных это систематический недосчёт · **Теги:** goal:merge-robustness, question +- **Секция:** ядро +- **Зачем:** Решено: брать бо́льшее значение. Порядок канонических форм берёт меньшее в 96% случаев — для накопительных это систематический недосчёт +- **Теги:** goal:merge-robustness, question **Решение принято владельцем 2026-08-02: вариант (б) — брать бо́льшее значение точки.** Ниже — исходная постановка блокера, она же ТЗ; рекомендация в конце diff --git a/docs/tasks/items/token-and-secret-management.md b/docs/tasks/items/token-and-secret-management.md index 22a3cab..494a522 100644 --- a/docs/tasks/items/token-and-secret-management.md +++ b/docs/tasks/items/token-and-secret-management.md @@ -1,6 +1,8 @@ # Управление токенами и секретами -**Секция:** инфра · **Хук:** Проверка токенов выключена, config.docker.toml коммитится — так нельзя выезжать наружу · **Теги:** goal:deploy +- **Секция:** инфра +- **Зачем:** Проверка токенов выключена, config.docker.toml коммитится — так нельзя выезжать наружу +- **Теги:** goal:deploy Сейчас проверка токенов выключена сознательно — доверенная локальная сеть, — и `config.docker.toml` коммитится без секретов. Для локальной разработки это diff --git a/docs/tasks/items/unseen-sections-check.md b/docs/tasks/items/unseen-sections-check.md index b388bc8..1fbedef 100644 --- a/docs/tasks/items/unseen-sections-check.md +++ b/docs/tasks/items/unseen-sections-check.md @@ -1,6 +1,8 @@ # Проверка секций, которых поток ещё не приносил -**Секция:** ядро · **Хук:** Симптомы, ЭКГ, лекарства, цикл и вес не виденны живьём — разбор писался вслепую · **Теги:** goal:parsing-and-storage +- **Секция:** ядро +- **Зачем:** Симптомы, ЭКГ, лекарства, цикл и вес не виденны живьём — разбор писался вслепую +- **Теги:** goal:parsing-and-storage Разбор пишется по тем данным, что видел поток, а он приносил только `metrics`, `workouts` и `stateOfMind`. Не виденны живьём: `symptoms`, `ecg`, diff --git a/docs/tasks/items/workout-identity-on-import.md b/docs/tasks/items/workout-identity-on-import.md index a1daeff..e37c5b8 100644 --- a/docs/tasks/items/workout-identity-on-import.md +++ b/docs/tasks/items/workout-identity-on-import.md @@ -1,6 +1,8 @@ # Идентичность тренировок при импорте родного экспорта -**Секция:** ядро · **Хук:** В export.xml у тренировки нет id — импорт снапшота задвоит тренировки, приехавшие от HAE · **Теги:** goal:native-export-import +- **Секция:** ядро +- **Зачем:** В export.xml у тренировки нет id — импорт снапшота задвоит тренировки, приехавшие от HAE +- **Теги:** goal:native-export-import Тренировка в витрине адресуется своим `id` из HealthKit — его шлёт HAE. В `export.xml` этого идентификатора **нет вовсе**: у элемента `Workout` только diff --git a/docs/tasks/items/workout-routes-table.md b/docs/tasks/items/workout-routes-table.md index 35e10ea..460d9be 100644 --- a/docs/tasks/items/workout-routes-table.md +++ b/docs/tasks/items/workout-routes-table.md @@ -1,6 +1,8 @@ # [idea] Разворачивание маршрутов тренировок в отдельную таблицу -**Секция:** ядро · **Хук:** Маршрут лежит блобом внутри тренировки — понадобится, только если появится клиент, которому мало отдачи одним пакетом · **Теги:** goal:read-api +- **Секция:** ядро +- **Зачем:** Маршрут лежит блобом внутри тренировки — понадобится, только если появится клиент, которому мало отдачи одним пакетом +- **Теги:** goal:read-api Тренировка хранится нераскрытой: заголовок — колонками, всё остальное, включая маршрут и внутренние ряды, — блобом `payload`. Решение осознанное: структура