# Read API: точки, выбор слоя, свёртка по сетке **Приоритет:** высокий Сейчас данные достаются только `sqlite3` на хосте. Все три сценария — агент-медик, трекер тренировок, фитнес-игра — упираются в отсутствие чтения. Формы запроса ровно две, и это один запрос с необязательным параметром: `?from&to` — все значения за период (вес, лекарства, симптомы), `?from&to&bucket` — с разбивкой (шаги, энергия). Решение по размеру ответа (вариант «б»): разбивка не задана и ответ не влезает — сервер сам берёт сетку погрубее и **называет её в ответе**; разбивка задана явно и не влезает — ошибка со списком доступных сеток, а не тихая подмена. Различие существенно: иначе агент, попросивший минутную сетку, получит суточные суммы. **Отдача тренировок и записей входит сюда же.** Разбор и хранение сущностей с собственным `id` сделаны (change `2026-08-02-trenirovki-i-zapisi`), а эндпоинтов нет: тренировка с маршрутом и записи `stateOfMind` лежат в витрине и наружу не отдаются. Вводить их раньше конверта ответа значило бы задать контракт мимоходом, поэтому `GET /workouts`, `GET /workouts/{id}` и `GET /records/{kind}` закрываются этой задачей — вместе с формой конверта и правилом размера ответа. Второй сценарий паспорта (трекер) до тех пор не закрыт. Готово, когда «шаги за неделю по дням» и «вес за год» отвечаются одним запросом каждый, тренировка отдаётся одним пакетом вместе с маршрутом, а в ответе всегда видно `layer`, `bucket` и `aggregation`. **Порог неполного ведра решается здесь, и вместе с ним — его полярность.** Каталог и род агрегации сделаны (change `2026-08-02-katalog-i-rod-agregacii`), и измерению порог заполненности не понадобился: у него две конкурирующие гипотезы, и неполный час не сходится ни с одной сам собой. Свёртке в ответе он нужен, а готовые решения задают его **противоположно**: Graphite `xFilesFactor` — доля обязательно известных точек (умолчание 0.5 при роллапе и 0 при рендере, один параметр с двумя умолчаниями), RRDtool `xff` — доля допустимо неизвестных. Обе величины выглядят как «0.5», означая разное; полярность придётся назвать вслух в `architecture.md`, иначе через полгода два места кода поймут поле по-разному. **Предел размера ответа тоже здесь.** У каталога его нет намеренно: правило размера — общее для маршрутов чтения, и задавать его мимоходом на первой ручке значило бы решить контракт до того, как известна форма тяжёлого ответа. Каталог станет первым его потребителем. **Форма провода наследуется от каталога, и это надо решить один раз.** Сегодня типы `internal/catalog` сами несут json-теги, а транспорт владеет только обёрткой: переименование поля в домене меняет публичный контракт без касания `httpapi`. Держит это один байтовый тест непустого ответа. Либо объявить в `architecture.md`, что типы чтения и есть форма провода для всех транспортов (HTTP и MCP отдают её байт в байт), либо завести DTO в транспорте — но выбрать до того, как образец скопирует эта задача. **Клиент обязан смотреть на границы окна измерения.** Род метрики измерен по 48 самым свежим ОБЩИМ часам, а не по последним 48 часам календаря: если минутная автоматизация HAE выключена, множество общих часов не пополняется и окно замирает. Род при этом продолжает объявляться, и единственный след — `last_hour` в ответе. Правило выбора свёртки в Read API обязано это учитывать (или явно объявить, что не учитывает). Связано: `docs/architecture.md` → «Read API», «Измерение рода агрегации», план → шаг «Read API».