задачи: мета переехала в блок, поле «Хук» стало «Зачем»
49 файлов, миграция сделана командой tasks.py check --fix — той самой, ради которой в скрипте оставлена читаемость старой формы. Побочно тот же прогон проставил тег decomposed целям, у которых есть задачи: это его штатная работа. check после миграции зелёный, индексы согласованы. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
# Импорт родного экспорта Apple Health
|
# Импорт родного экспорта Apple Health
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут · **Теги:** goal:native-export-import
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут
|
||||||
|
- **Теги:** goal:native-export-import
|
||||||
|
|
||||||
Слой `sample` пуст: настоящих сэмплов HealthKit в потоке нет вовсе — HAE отдаёт
|
Слой `sample` пуст: настоящих сэмплов HealthKit в потоке нет вовсе — HAE отдаёт
|
||||||
посекундную развёртку, а не измерения (находка 34). Полная история и точные
|
посекундную развёртку, а не измерения (находка 34). Полная история и точные
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Словарь категориальных значений → коды HealthKit
|
# Словарь категориальных значений → коды HealthKit
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Фазы сна и типы тренировок приходят строками русской локали — с экспортом Apple их не сверить · **Теги:** goal:parsing-and-storage
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Фазы сна и типы тренировок приходят строками русской локали — с экспортом Apple их не сверить
|
||||||
|
- **Теги:** goal:parsing-and-storage
|
||||||
|
|
||||||
HAE отдаёт перечислимые значения строками локали телефона: «БДГ», «Сидячий
|
HAE отдаёт перечислимые значения строками локали телефона: «БДГ», «Сидячий
|
||||||
образ жизни», «В помещении Ходьба». Родной экспорт Apple при этом говорит
|
образ жизни», «В помещении Ходьба». Родной экспорт Apple при этом говорит
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Умолчания конфига указывают на прежнюю раскладку
|
# Умолчания конфига указывают на прежнюю раскладку
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Запуск без конфига заведёт пустую базу в корне рядом с настоящей — тихая ловушка · **Теги:** goal:deploy
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Запуск без конфига заведёт пустую базу в корне рядом с настоящей — тихая ловушка
|
||||||
|
- **Теги:** goal:deploy
|
||||||
|
|
||||||
Данные переехали в `./data` (база + сырой архив, он же том контейнера), а
|
Данные переехали в `./data` (база + сырой архив, он же том контейнера), а
|
||||||
умолчания в `internal/config` остались прежними: `./healthlog.db` и `./raw`.
|
умолчания в `internal/config` остались прежними: `./healthlog.db` и `./raw`.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Data-миграции не отбирают строки по обрезаемым спискам
|
# Data-миграции не отбирают строки по обрезаемым спискам
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Миграция 00007 отбирает по uncovered_sections, который обрезается на 32 — следующая покрытая секция унаследует слепую зону · **Теги:** goal:journal-and-rebuild
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Миграция 00007 отбирает по uncovered_sections, который обрезается на 32 — следующая покрытая секция унаследует слепую зону
|
||||||
|
- **Теги:** goal:journal-and-rebuild
|
||||||
|
|
||||||
Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change
|
Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change
|
||||||
`dozakryt-nahodki-sushchnostej`).
|
`dozakryt-nahodki-sushchnostej`).
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Что считать сутками при смене часового пояса
|
# [idea] Что считать сутками при смене часового пояса
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Шаги за день — базовый запрос трекера и игры, но чей это день при перелёте, не решено · **Теги:** goal:read-api
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Шаги за день — базовый запрос трекера и игры, но чей это день при перелёте, не решено
|
||||||
|
- **Теги:** goal:read-api
|
||||||
|
|
||||||
«Шаги за день» — базовый запрос трекера и фитнес-игры. Но точка несёт метку с
|
«Шаги за день» — базовый запрос трекера и фитнес-игры. Но точка несёт метку с
|
||||||
офсетом исходной зоны, и при перелёте сутки перестают быть однозначными: день
|
офсетом исходной зоны, и при перелёте сутки перестают быть однозначными: день
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Предел на размер и число заголовков доставки
|
# Предел на размер и число заголовков доставки
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** MaxHeaderBytes не задан, в базу заголовки пишутся целиком: дефект спит до деплоя, а просыпается вместе с ним · **Теги:** goal:limits-and-load
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** MaxHeaderBytes не задан, в базу заголовки пишутся целиком: дефект спит до деплоя, а просыпается вместе с ним
|
||||||
|
- **Теги:** goal:limits-and-load
|
||||||
|
|
||||||
У тела доставки предел есть (`max_body`), у заголовков — нет ни одного:
|
У тела доставки предел есть (`max_body`), у заголовков — нет ни одного:
|
||||||
`MaxHeaderBytes` серверу не задан, а `delivery.headers` пишутся в базу целиком,
|
`MaxHeaderBytes` серверу не задан, а `delivery.headers` пишутся в базу целиком,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Заголовки доставки в архиве рядом с телом
|
# Заголовки доставки в архиве рядом с телом
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Заголовки живут только в базе — потеря базы навсегда ломает вывод слоя при пересборке · **Теги:** goal:journal-and-rebuild
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Заголовки живут только в базе — потеря базы навсегда ломает вывод слоя при пересборке
|
||||||
|
- **Теги:** goal:journal-and-rebuild
|
||||||
|
|
||||||
Состояние объявлено свёрткой по журналу, а журналом — сырой архив. Но в архиве
|
Состояние объявлено свёрткой по журналу, а журналом — сырой архив. Но в архиве
|
||||||
лежит только **тело**: заголовки запроса (`automation-id`,
|
лежит только **тело**: заголовки запроса (`automation-id`,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Деплой на rivendell
|
# Деплой на rivendell
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Сервис живёт на рабочей машине — телефон достаёт до него только дома · **Теги:** goal:deploy
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Сервис живёт на рабочей машине — телефон достаёт до него только дома
|
||||||
|
- **Теги:** goal:deploy
|
||||||
|
|
||||||
Сервис живёт в контейнере на рабочей машине, телефон достаёт до него только
|
Сервис живёт в контейнере на рабочей машине, телефон достаёт до него только
|
||||||
дома. Вне дома экспорт копится и уезжает пачкой при возвращении — работает, но
|
дома. Вне дома экспорт копится и уезжает пачкой при возвращении — работает, но
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Деплой
|
# [goal] Деплой
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Сервис живёт на рабочей машине — телефон достаёт до него только дома, и оба контура открыты
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Сервис живёт на рабочей машине — телефон достаёт до него только дома, и оба контура открыты
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Сервис переезжает на rivendell и становится доступен телефону из любой сети.
|
Сервис переезжает на rivendell и становится доступен телефону из любой сети.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Выведенные из данных схемы содержимого
|
# Выведенные из данных схемы содержимого
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке · **Теги:** goal:self-description
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке
|
||||||
|
- **Теги:** goal:self-description
|
||||||
|
|
||||||
Метрик у Apple больше сотни, формы точек разные, и рукописный каталог описывал
|
Метрик у Apple больше сотни, формы точек разные, и рукописный каталог описывал
|
||||||
бы документацию HAE, а не то, что он реально прислал. Схема содержимого
|
бы документацию HAE, а не то, что он реально прислал. Схема содержимого
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Отказ от heartbeatSeries
|
# [idea] Отказ от heartbeatSeries
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** 93% объёма HRV ради данных, которых нет ни в одном планируемом запросе · **Теги:** goal:lower-layer-cleanup
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** 93% объёма HRV ради данных, которых нет ни в одном планируемом запросе
|
||||||
|
- **Теги:** goal:lower-layer-cleanup
|
||||||
|
|
||||||
`heart_rate_variability` приезжает вместе с `heartbeatSeries` — рядом
|
`heart_rate_variability` приезжает вместе с `heartbeatSeries` — рядом
|
||||||
межударных интервалов внутри точки. Это **93% объёма метрики** (находка 39)
|
межударных интервалов внутри точки. Это **93% объёма метрики** (находка 39)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Пределы на размер сущности и потоковый расчёт формы
|
# Пределы на размер сущности и потоковый расчёт формы
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Тело 40 МиБ даёт 768 МиБ пика кучи, 63 МиБ держат блокировку 5.019 с — предела на одну сущность нет вовсе · **Теги:** goal:limits-and-load
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Тело 40 МиБ даёт 768 МиБ пика кучи, 63 МиБ держат блокировку 5.019 с — предела на одну сущность нет вовсе
|
||||||
|
- **Теги:** goal:limits-and-load
|
||||||
|
|
||||||
Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change
|
Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change
|
||||||
`dozakryt-nahodki-sushchnostej`). Та задача убрала канонизацию приехавшей
|
`dozakryt-nahodki-sushchnostej`). Та задача убрала канонизацию приехавшей
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Сущность с id, но неразобранной меткой
|
# Сущность с id, но неразобранной меткой
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Тренировка с меткой в неизвестном формате пропадает целиком — а её id и содержимое разобраны · **Теги:** goal:parsing-and-storage, question
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Тренировка с меткой в неизвестном формате пропадает целиком — а её id и содержимое разобраны
|
||||||
|
- **Теги:** goal:parsing-and-storage, question
|
||||||
|
|
||||||
Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change
|
Остаток задачи «Дозакрыть находки ревью по слиянию сущностей» (архивный change
|
||||||
`dozakryt-nahodki-sushchnostej`). Та задача сделала мягким чтение заголовка:
|
`dozakryt-nahodki-sushchnostej`). Та задача сделала мягким чтение заголовка:
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Проверка целостности собранной витрины перед подменой
|
# Проверка целостности собранной витрины перед подменой
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Подмена файла необратима, а годность выхода подтверждена отпечатком на ещё открытом дескрипторе · **Теги:** goal:journal-and-rebuild
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Подмена файла необратима, а годность выхода подтверждена отпечатком на ещё открытом дескрипторе
|
||||||
|
- **Теги:** goal:journal-and-rebuild
|
||||||
|
|
||||||
`healthlog reindex` собирает витрину в отдельный файл и снимает с него
|
`healthlog reindex` собирает витрину в отдельный файл и снимает с него
|
||||||
отпечаток, а подмену делает человек: остановить сервис, переименовать файл,
|
отпечаток, а подмену делает человек: остановить сервис, переименовать файл,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Журнал и пересборка
|
# [goal] Журнал и пересборка
|
||||||
|
|
||||||
**Секция:** темы · **Хук:** Расхождение витрины с журналом сейчас молчит: reindex печатает оба отпечатка, а сравнивать их некому
|
- **Секция:** темы
|
||||||
|
- **Зачем:** Расхождение витрины с журналом сейчас молчит: reindex печатает оба отпечатка, а сравнивать их некому
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Тема: инвариант «`import` + `replay` даёт то же состояние» и всё, что его
|
Тема: инвариант «`import` + `replay` даёт то же состояние» и всё, что его
|
||||||
держит — архив, ретеншен, отпечаток витрины, расход памяти пересборки.
|
держит — архив, ретеншен, отпечаток витрины, расход памяти пересборки.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Порядок журнала при конкурентных приёмах
|
# Порядок журнала при конкурентных приёмах
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Решено: повторы, но после /stats. Доставка, свёрнутая раньше своей предшественницы, уходит в failed навсегда · **Теги:** goal:journal-and-rebuild, question
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Решено: повторы, но после /stats. Доставка, свёрнутая раньше своей предшественницы, уходит в failed навсегда
|
||||||
|
- **Теги:** goal:journal-and-rebuild, question
|
||||||
|
|
||||||
**Решение принято владельцем 2026-08-02: вариант (в), но не раньше `/stats`.**
|
**Решение принято владельцем 2026-08-02: вариант (в), но не раньше `/stats`.**
|
||||||
До появления наблюдаемости живём вариантом (г) с уже записанным в спеке
|
До появления наблюдаемости живём вариантом (г) с уже записанным в спеке
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Пределы и поведение под объёмом
|
# [goal] Пределы и поведение под объёмом
|
||||||
|
|
||||||
**Секция:** темы · **Хук:** Предела на одну сущность нет вовсе: 63 МиБ держат блокировку 5.019 с, соседние доставки уходят в failed
|
- **Секция:** темы
|
||||||
|
- **Зачем:** Предела на одну сущность нет вовсе: 63 МиБ держат блокировку 5.019 с, соседние доставки уходят в failed
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Тема: названные пределы на размер тела, сущности, заголовков и ответа плюс
|
Тема: названные пределы на размер тела, сущности, заголовков и ответа плюс
|
||||||
поведение под удерживаемой блокировкой.
|
поведение под удерживаемой блокировкой.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Устаревание нижнего слоя
|
# [goal] Устаревание нижнего слоя
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
После проверенного экспорта нижний слой HAE избыточен и подлежит чистке.
|
После проверенного экспорта нижний слой HAE избыточен и подлежит чистке.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Устаревание нижнего слоя после экспорта
|
# Устаревание нижнего слоя после экспорта
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен · **Теги:** goal:lower-layer-cleanup
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Нижний слой растёт на ~100 тысяч координат в сутки, а после экспорта Apple он избыточен
|
||||||
|
- **Теги:** goal:lower-layer-cleanup
|
||||||
|
|
||||||
Нижний слой растёт примерно на 100 тысяч координат в сутки против ~3 700 у
|
Нижний слой растёт примерно на 100 тысяч координат в сутки против ~3 700 у
|
||||||
минутного и ~100 у часового — разница в три порядка (находка 41). Всё давление
|
минутного и ~100 у часового — разница в три порядка (находка 41). Всё давление
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# MCP-сервер поверх Read API
|
# MCP-сервер поверх Read API
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем · **Теги:** goal:mcp
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем
|
||||||
|
- **Теги:** goal:mcp
|
||||||
|
|
||||||
Агент-медик — первый заказчик проекта. Ему нужна актуальная сводка, а не срез
|
Агент-медик — первый заказчик проекта. Ему нужна актуальная сводка, а не срез
|
||||||
на дату последнего ручного экспорта.
|
на дату последнего ручного экспорта.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] MCP
|
# [goal] MCP
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Агент-медик — первый заказчик проекта, а подключить его сейчас нечем
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Агент-медик — первый заказчик проекта — подключается к хранилищу.
|
Агент-медик — первый заказчик проекта — подключается к хранилищу.
|
||||||
|
|
||||||
|
|||||||
@@ -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`, враждебный
|
Вынуто ревью кода задачи `pravilo-sliyaniya-tochek` (профиль `deep`, враждебный
|
||||||
проход и независимая реализация — независимо друг от друга).
|
проход и независимая реализация — независимо друг от друга).
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Счётчики слияния переживают ротацию логов
|
# Счётчики слияния переживают ротацию логов
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** единственный след несравнимых наборов — строка WARN в docker-логе с ротацией 3×10 МБ: событие может произойти и не оставить ничего · **Теги:** goal:observability
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** единственный след несравнимых наборов — строка WARN в docker-логе с ротацией 3×10 МБ: событие может произойти и не оставить ничего
|
||||||
|
- **Теги:** goal:observability
|
||||||
|
|
||||||
Вынуто ревью кода задачи `pravilo-sliyaniya-tochek` (профиль `deep`, проход
|
Вынуто ревью кода задачи `pravilo-sliyaniya-tochek` (профиль `deep`, проход
|
||||||
негативного пространства, подтверждено эксплуатационным).
|
негативного пространства, подтверждено эксплуатационным).
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Прочность слияния и идентичности
|
# [goal] Прочность слияния и идентичности
|
||||||
|
|
||||||
**Секция:** темы · **Хук:** Правила слияния держатся на замерах, и каждый новый замер находит зависимость от порядка на проводе
|
- **Секция:** темы
|
||||||
|
- **Зачем:** Правила слияния держатся на замерах, и каждый новый замер находит зависимость от порядка на проводе
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Тема: правила, по которым две версии одних данных превращаются в одну.
|
Тема: правила, по которым две версии одних данных превращаются в одну.
|
||||||
В порядок не встаёт — работа приходит находками ревью и замерами на
|
В порядок не встаёт — работа приходит находками ревью и замерами на
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Месячный проход по ручным секциям
|
# [idea] Месячный проход по ручным секциям
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Симптомы и лекарства заводятся задним числом на недели — недельного глубокого прохода им не хватит · **Теги:** goal:parsing-and-storage
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Симптомы и лекарства заводятся задним числом на недели — недельного глубокого прохода им не хватит
|
||||||
|
- **Теги:** goal:parsing-and-storage
|
||||||
|
|
||||||
Окно досчёта не единое, и это измеренное различие, а не предположение.
|
Окно досчёта не единое, и это измеренное различие, а не предположение.
|
||||||
Количественные метрики (пульс, шаги, энергия) человек руками не правит — они
|
Количественные метрики (пульс, шаги, энергия) человек руками не правит — они
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Импорт родного экспорта Apple
|
# [goal] Импорт родного экспорта Apple
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Слой sample пуст: полная история и точные сэмплы лежат в zip-архиве и никуда не едут
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
`healthlog import`: снапшот всей истории из родного экспорта Apple Health
|
`healthlog import`: снапшот всей истории из родного экспорта Apple Health
|
||||||
ложится в хранилище перед проигрыванием хвоста доставок.
|
ложится в хранилище перед проигрыванием хвоста доставок.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] NDJSON-поток для больших выборок Read API
|
# [idea] NDJSON-поток для больших выборок Read API
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Выборка нижнего слоя за месяц не влезает в один JSON-ответ — либо поток, либо пагинация · **Теги:** goal:read-api
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Выборка нижнего слоя за месяц не влезает в один JSON-ответ — либо поток, либо пагинация
|
||||||
|
- **Теги:** goal:read-api
|
||||||
|
|
||||||
Read API отдаёт ответ одним JSON. Для выборок нижнего слоя за длинный период
|
Read API отдаёт ответ одним JSON. Для выборок нижнего слоя за длинный период
|
||||||
это не работает: `heart_rate` в слое `raw` — порядка сотни тысяч координат в
|
это не работает: `heart_rate` в слое `raw` — порядка сотни тысяч координат в
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Наблюдаемость
|
# [goal] Наблюдаемость
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Тихо сломавшаяся автоматизация — главный эксплуатационный риск: телефон шлёт
|
Тихо сломавшаяся автоматизация — главный эксплуатационный риск: телефон шлёт
|
||||||
молча, и молчание неотличимо от нормы.
|
молча, и молчание неотличимо от нормы.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# OpenAPI-спека и Swagger UI
|
# OpenAPI-спека и Swagger UI
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Потребителей три и один из них агент — контракт должен читаться машиной, а не пересказываться в чате · **Теги:** goal:read-api
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Потребителей три и один из них агент — контракт должен читаться машиной, а не пересказываться в чате
|
||||||
|
- **Теги:** goal:read-api
|
||||||
|
|
||||||
Потребителей три, и один из них — агент, который читает контракт машиной.
|
Потребителей три, и один из них — агент, который читает контракт машиной.
|
||||||
Пересказывать форму ответа в чате не годится, а самоописание из плана покрывает
|
Пересказывать форму ответа в чате не годится, а самоописание из плана покрывает
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Пересекающиеся источники одной метрики
|
# [idea] Пересекающиеся источники одной метрики
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Сон пишут и часы, и стороннее приложение — сумма по обоим задвоит ночь · **Теги:** goal:read-api
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Сон пишут и часы, и стороннее приложение — сумма по обоим задвоит ночь
|
||||||
|
- **Теги:** goal:read-api
|
||||||
|
|
||||||
Одну метрику пишут несколько источников: сон — часы и стороннее приложение
|
Одну метрику пишут несколько источников: сон — часы и стороннее приложение
|
||||||
AutoSleep, шаги — часы и телефон одновременно. Поле `source` при этом не
|
AutoSleep, шаги — часы и телефон одновременно. Поле `source` при этом не
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Выгрузка в parquet отдельной командой
|
# [idea] Выгрузка в parquet отдельной командой
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Дверь для тяжёлой аналитики снаружи: DuckDB читает и parquet, и файл SQLite — спешить некуда, но и закрывать не нужно · **Теги:** goal:read-api
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Дверь для тяжёлой аналитики снаружи: DuckDB читает и parquet, и файл SQLite — спешить некуда, но и закрывать не нужно
|
||||||
|
- **Теги:** goal:read-api
|
||||||
|
|
||||||
Отдельная команда, выгружающая хранилище в parquet, — дверь для тяжёлой
|
Отдельная команда, выгружающая хранилище в parquet, — дверь для тяжёлой
|
||||||
аналитики снаружи, без миграции самого хранилища.
|
аналитики снаружи, без миграции самого хранилища.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Разбор и хранилище
|
# [goal] Разбор и хранилище
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Секции живого потока разобраны все, кроме словаря категориальных значений и пяти невиденных
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Секции живого потока разобраны все, кроме словаря категориальных значений и пяти невиденных
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Метрики, тренировки и записи со своими `id` разбираются и ложатся в часовые
|
Метрики, тренировки и записи со своими `id` разбираются и ложатся в часовые
|
||||||
объекты; тела перестали быть недифференцированной кучей.
|
объекты; тела перестали быть недифференцированной кучей.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Ретеншен сырого архива
|
# Ретеншен сырого архива
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Архив не подчищается вовсе — 14-дневный срок объявлен, но не работает · **Теги:** goal:journal-and-rebuild
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Архив не подчищается вовсе — 14-дневный срок объявлен, но не работает
|
||||||
|
- **Теги:** goal:journal-and-rebuild
|
||||||
|
|
||||||
Срок жизни сырого архива объявлен (14 дней, `storage.raw_retention`), но
|
Срок жизни сырого архива объявлен (14 дней, `storage.raw_retention`), но
|
||||||
удаления нет: архив растёт бесконечно. Пока это 16 МБ и проблемой не является.
|
удаления нет: архив растёт бесконечно. Пока это 16 МБ и проблемой не является.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Read API: точки, выбор слоя, свёртка по сетке
|
# Read API: точки, выбор слоя, свёртка по сетке
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может · **Теги:** goal:read-api
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может
|
||||||
|
- **Теги:** goal:read-api
|
||||||
|
|
||||||
Сейчас данные достаются только `sqlite3` на хосте. Все три сценария —
|
Сейчас данные достаются только `sqlite3` на хосте. Все три сценария —
|
||||||
агент-медик, трекер тренировок, фитнес-игра — упираются в отсутствие чтения.
|
агент-медик, трекер тренировок, фитнес-игра — упираются в отсутствие чтения.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Read API
|
# [goal] Read API
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Данные видны только через sqlite на хосте — ни один из трёх потребителей ничего прочитать не может
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Потребители читают точки: выбор слоя, свёртка по сетке, предел размера ответа.
|
Потребители читают точки: выбор слоя, свёртка по сетке, предел размера ответа.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Сверка живой витрины с пересборкой
|
# Сверка живой витрины с пересборкой
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** reindex печатает оба отпечатка, но сравнивать их некому — расхождение с журналом молчит · **Теги:** goal:journal-and-rebuild
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** reindex печатает оба отпечатка, но сравнивать их некому — расхождение с журналом молчит
|
||||||
|
- **Теги:** goal:journal-and-rebuild
|
||||||
|
|
||||||
`healthlog reindex` печатает отпечаток собранной витрины и отпечаток рабочей —
|
`healthlog reindex` печатает отпечаток собранной витрины и отпечаток рабочей —
|
||||||
то есть данные для сверки уже есть, и **сравнивать их некому**. Расхождение
|
то есть данные для сверки уже есть, и **сравнивать их некому**. Расхождение
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Пересборка держит весь журнал в памяти
|
# Пересборка держит весь журнал в памяти
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Учёт доставок и список путей архива материализуются целиком: расход растёт вместе с журналом, а у журнала конца нет · **Теги:** goal:journal-and-rebuild
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Учёт доставок и список путей архива материализуются целиком: расход растёт вместе с журналом, а у журнала конца нет
|
||||||
|
- **Теги:** goal:journal-and-rebuild
|
||||||
|
|
||||||
`healthlog reindex` материализует целиком две вещи: учёт доставок из базы и
|
`healthlog reindex` материализует целиком две вещи: учёт доставок из базы и
|
||||||
список путей архива. На сегодняшнем объёме (сотня тел) это незаметно, на
|
список путей архива. На сегодняшнем объёме (сотня тел) это незаметно, на
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Чем откатывать релиз после наката миграции
|
# Чем откатывать релиз после наката миграции
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Решено: копия файла базы перед накатом. Страж версии схемы делает возврат бинаря отказом, а понизить схему нечем · **Теги:** goal:deploy, question
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Решено: копия файла базы перед накатом. Страж версии схемы делает возврат бинаря отказом, а понизить схему нечем
|
||||||
|
- **Теги:** goal:deploy, question
|
||||||
|
|
||||||
**Решение принято владельцем 2026-08-02: вариант (2) — копия файла базы перед
|
**Решение принято владельцем 2026-08-02: вариант (2) — копия файла базы перед
|
||||||
накатом.** Entrypoint контейнера копирует файл базы рядом до старта бинаря,
|
накатом.** Entrypoint контейнера копирует файл базы рядом до старта бинаря,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Человеческие аннотации поверх выведенных схем
|
# [idea] Человеческие аннотации поверх выведенных схем
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Выведенная схема говорит форму, но не смысл метрики — нужно ли описание сверху, зависит от стабильности формата · **Теги:** goal:self-description
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Выведенная схема говорит форму, но не смысл метрики — нужно ли описание сверху, зависит от стабильности формата
|
||||||
|
- **Теги:** goal:self-description
|
||||||
|
|
||||||
Схема содержимого выводится из данных и говорит **форму** — какие поля есть,
|
Схема содержимого выводится из данных и говорит **форму** — какие поля есть,
|
||||||
какого типа, с какой заполненностью. Чего она не говорит — что метрика значит,
|
какого типа, с какой заполненностью. Чего она не говорит — что метрика значит,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Порог sealed: с какого возраста час считается запечатанным
|
# [idea] Порог sealed: с какого возраста час считается запечатанным
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** WARN на изменение старого часа уже пишется, но порог не выбран — ставим по факту, когда накопится статистика досчёта · **Теги:** goal:merge-robustness
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** WARN на изменение старого часа уже пишется, но порог не выбран — ставим по факту, когда накопится статистика досчёта
|
||||||
|
- **Теги:** goal:merge-robustness
|
||||||
|
|
||||||
Флаг `sealed` отмечает часы, которые уже не должны меняться. Механика готова:
|
Флаг `sealed` отмечает часы, которые уже не должны меняться. Механика готова:
|
||||||
изменение запечатанного объекта не отвергается, а пишется `WARN`, и данные
|
изменение запечатанного объекта не отвергается, а пишется `WARN`, и данные
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [goal] Самоописание
|
# [goal] Самоописание
|
||||||
|
|
||||||
**Секция:** порядок · **Хук:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке
|
- **Секция:** порядок
|
||||||
|
- **Зачем:** Метрик больше сотни и формы точек разные — клиент вынужден угадывать структуру по выборке
|
||||||
|
- **Теги:** decomposed
|
||||||
|
|
||||||
Клиент узнаёт форму данных из ответа сервиса, а не угадывает её по выборке.
|
Клиент узнаёт форму данных из ответа сервиса, а не угадывает её по выборке.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Остановка и миграция: раздельные бюджеты и следы в логе
|
# Остановка и миграция: раздельные бюджеты и следы в логе
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Долгий запрос чтения съедает бюджет остановки, и WARN обвиняет воркер свёртки; миграция молчит и не прерывается SIGTERM · **Теги:** goal:deploy
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Долгий запрос чтения съедает бюджет остановки, и WARN обвиняет воркер свёртки; миграция молчит и не прерывается SIGTERM
|
||||||
|
- **Теги:** goal:deploy
|
||||||
|
|
||||||
Две находки эксплуатационного и идиоматического проходов ревью каталога. Обе
|
Две находки эксплуатационного и идиоматического проходов ревью каталога. Обе
|
||||||
существовали и раньше, но достижимыми их сделал первый маршрут чтения:
|
существовали и раньше, но достижимыми их сделал первый маршрут чтения:
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Наблюдаемость: /stats
|
# Наблюдаемость: /stats
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах · **Теги:** goal:observability
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Тихо сломавшаяся автоматизация — главный эксплуатационный риск, а сейчас факт виден только в логах
|
||||||
|
- **Теги:** goal:observability
|
||||||
|
|
||||||
Тихо сломавшаяся автоматизация — главный эксплуатационный риск коллектора:
|
Тихо сломавшаяся автоматизация — главный эксплуатационный риск коллектора:
|
||||||
данные просто перестают приходить, и заметить это можно только по молчанию.
|
данные просто перестают приходить, и заметить это можно только по молчанию.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Активный алерт «данных нет N часов»
|
# Активный алерт «данных нет N часов»
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Пропажу потока сейчас замечает человек, а не сервис · **Теги:** goal:observability
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Пропажу потока сейчас замечает человек, а не сервис
|
||||||
|
- **Теги:** goal:observability
|
||||||
|
|
||||||
Пропажу потока сейчас замечает человек. `/stats` покажет факт, но только если
|
Пропажу потока сейчас замечает человек. `/stats` покажет факт, но только если
|
||||||
туда заглянуть — а заглядывают ровно тогда, когда уже что-то заподозрили.
|
туда заглянуть — а заглядывают ровно тогда, когда уже что-то заподозрили.
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Тай-брейк при равной полноте точек
|
# Тай-брейк при равной полноте точек
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Решено: брать бо́льшее значение. Порядок канонических форм берёт меньшее в 96% случаев — для накопительных это систематический недосчёт · **Теги:** goal:merge-robustness, question
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Решено: брать бо́льшее значение. Порядок канонических форм берёт меньшее в 96% случаев — для накопительных это систематический недосчёт
|
||||||
|
- **Теги:** goal:merge-robustness, question
|
||||||
|
|
||||||
**Решение принято владельцем 2026-08-02: вариант (б) — брать бо́льшее значение
|
**Решение принято владельцем 2026-08-02: вариант (б) — брать бо́льшее значение
|
||||||
точки.** Ниже — исходная постановка блокера, она же ТЗ; рекомендация в конце
|
точки.** Ниже — исходная постановка блокера, она же ТЗ; рекомендация в конце
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Управление токенами и секретами
|
# Управление токенами и секретами
|
||||||
|
|
||||||
**Секция:** инфра · **Хук:** Проверка токенов выключена, config.docker.toml коммитится — так нельзя выезжать наружу · **Теги:** goal:deploy
|
- **Секция:** инфра
|
||||||
|
- **Зачем:** Проверка токенов выключена, config.docker.toml коммитится — так нельзя выезжать наружу
|
||||||
|
- **Теги:** goal:deploy
|
||||||
|
|
||||||
Сейчас проверка токенов выключена сознательно — доверенная локальная сеть, — и
|
Сейчас проверка токенов выключена сознательно — доверенная локальная сеть, — и
|
||||||
`config.docker.toml` коммитится без секретов. Для локальной разработки это
|
`config.docker.toml` коммитится без секретов. Для локальной разработки это
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Проверка секций, которых поток ещё не приносил
|
# Проверка секций, которых поток ещё не приносил
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Симптомы, ЭКГ, лекарства, цикл и вес не виденны живьём — разбор писался вслепую · **Теги:** goal:parsing-and-storage
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Симптомы, ЭКГ, лекарства, цикл и вес не виденны живьём — разбор писался вслепую
|
||||||
|
- **Теги:** goal:parsing-and-storage
|
||||||
|
|
||||||
Разбор пишется по тем данным, что видел поток, а он приносил только `metrics`,
|
Разбор пишется по тем данным, что видел поток, а он приносил только `metrics`,
|
||||||
`workouts` и `stateOfMind`. Не виденны живьём: `symptoms`, `ecg`,
|
`workouts` и `stateOfMind`. Не виденны живьём: `symptoms`, `ecg`,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Идентичность тренировок при импорте родного экспорта
|
# Идентичность тренировок при импорте родного экспорта
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** В export.xml у тренировки нет id — импорт снапшота задвоит тренировки, приехавшие от HAE · **Теги:** goal:native-export-import
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** В export.xml у тренировки нет id — импорт снапшота задвоит тренировки, приехавшие от HAE
|
||||||
|
- **Теги:** goal:native-export-import
|
||||||
|
|
||||||
Тренировка в витрине адресуется своим `id` из HealthKit — его шлёт HAE. В
|
Тренировка в витрине адресуется своим `id` из HealthKit — его шлёт HAE. В
|
||||||
`export.xml` этого идентификатора **нет вовсе**: у элемента `Workout` только
|
`export.xml` этого идентификатора **нет вовсе**: у элемента `Workout` только
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# [idea] Разворачивание маршрутов тренировок в отдельную таблицу
|
# [idea] Разворачивание маршрутов тренировок в отдельную таблицу
|
||||||
|
|
||||||
**Секция:** ядро · **Хук:** Маршрут лежит блобом внутри тренировки — понадобится, только если появится клиент, которому мало отдачи одним пакетом · **Теги:** goal:read-api
|
- **Секция:** ядро
|
||||||
|
- **Зачем:** Маршрут лежит блобом внутри тренировки — понадобится, только если появится клиент, которому мало отдачи одним пакетом
|
||||||
|
- **Теги:** goal:read-api
|
||||||
|
|
||||||
Тренировка хранится нераскрытой: заголовок — колонками, всё остальное, включая
|
Тренировка хранится нераскрытой: заголовок — колонками, всё остальное, включая
|
||||||
маршрут и внутренние ряды, — блобом `payload`. Решение осознанное: структура
|
маршрут и внутренние ряды, — блобом `payload`. Решение осознанное: структура
|
||||||
|
|||||||
Reference in New Issue
Block a user