diff --git a/openspec/config.yaml b/openspec/config.yaml index 392946c..6e48d46 100644 --- a/openspec/config.yaml +++ b/openspec/config.yaml @@ -1,20 +1,68 @@ schema: spec-driven -# Project context (optional) -# This is shown to AI when creating artifacts. -# Add your tech stack, conventions, style guides, domain knowledge, etc. -# Example: -# context: | -# Tech stack: TypeScript, React, Node.js -# We use conventional commits -# Domain: e-commerce platform +context: | + Language: Russian + Пиши на русском, но: + - Структурные заголовки оставляй на английском: + ## ADDED/MODIFIED/REMOVED Requirements, ### Requirement:, #### Scenario: + - Ключевые слова GIVEN/WHEN/THEN и RFC 2119 (SHALL/MUST/SHOULD) — на английском + - Технические термины (API, REST, JSON, MCP), пути и код — на английском + + Имена capabilities: + - Capability — это ПОВЕДЕНИЕ/домен системы, а не пакет кода (совпадение с + именем пакета допустимо, но не критерий). + - Существительное, понятное без знания кода: ingest, parsing, storage, + read-api, self-description. НЕ store/httpapi (это реализация). + - Гранулярность по принципу «требования меняются вместе». Дробить, когда в + одной спеке смешиваются разные заботы. Переименовать дёшево (RENAMED + Requirements) — не дроби преждевременно в маленьком проекте. + + RFC 2119 — это требование валидатора, не стиль: + - Каждое ### Requirement ОБЯЗАНО содержать литерал SHALL или MUST, иначе + `openspec validate` падает (проверено). Поэтому эти слова и WHEN/THEN не + русифицируем — они несут точную нормативную/структурную семантику. + + Ревью (процесс, не артефакт): + - Нетривиальная/архитектурная задача — два чекпоинта: ревью дизайна (после + design/specs, ДО кода — дешевле чинить направление) и ревью кода (после + apply, до archive). + - Тривиальная задача — достаточно одного прохода (код). + + Конвенции кода (соблюдать при apply): + - Механизируемое проверяет `task gate` (.golangci.yml: sloglint, forbidigo, + errorlint, depguard; плюс сборка, тесты, race, покрытие изменённых строк, + миграции, образцы конфига). Пересказывать его здесь не нужно — гейт скажет + точнее. + - Прозой остаётся то, что правилом не выражается, и это читаем в источнике: + docs/conventions.md — уровень лога по адресату, единственный логирующий + чекпоинт на доменной границе, трансляция доменной ошибки на внешней + границе, самодокументируемый config.example.toml, время в БД в UTC + RFC 3339 через store.Now(), ULID через internal/ident. + - Безопасность: данные о здоровье чувствительнее токенов. Ни тела запросов, + ни значения точек не попадают в логи выше DEBUG; ничего из ./data не + попадает под контроль версий (гейт проверяет шагом no-health-data). + + Что это за проект: + - healthlog — хранилище данных Apple Health, а не аналитика: принять, + дедуплицировать, сохранить, отдать. Агрегат считается только в ответе на + запрос и только там, где род метрики измерен сверкой слоёв. + - Источников два: поток Health Auto Export (непрерывный и молчаливый) и + родной экспорт Apple раз в 2–3 месяца. Вместе они образуют журнал событий: + состояние = import(снапшот экспорта) + replay(доставки по received_at). + Отсюда требование детерминированной свёртки. + - Инварианты целиком — в CLAUDE.md, архитектура — в docs/architecture.md. + + Разведка уже проведена, догадки о формате не нужны: + - docs/local-research.md — 46 находок на живом потоке, половина расходится с + документацией Health Auto Export. ПРОВЕРЬ ТАМ, прежде чем строить + предположение о формате входа: скорее всего вопрос закрыт измерением. + - Тесты на разбор формата держим на реальных пакетах (testdata), а не на + выдуманных: документация формата тонкая и местами врёт. # Per-artifact rules (optional) -# Add custom rules for specific artifacts. -# Example: -# rules: -# proposal: -# - Keep proposals under 500 words -# - Always include a "Non-goals" section -# tasks: -# - Break tasks into chunks of max 2 hours +rules: + proposal: + - Capabilities называй по поведению/домену системы, не по пакету кода + specs: + - Каждое ### Requirement обязано содержать SHALL или MUST (иначе валидация падает) + - Заголовки и WHEN/THEN/GIVEN — на английском, остальной текст на русском