docs(generator): зафиксирован контракт модельного времени

- Зачем:
  - нужно закрепить принятое человеком HITL-решение до кодовых задач 02-06.
- Что:
  - добавлен рабочий контракт настроек, хода часов, state, манифеста и ClickHouse-проверки.
  - выбран один живой ход часов через фиксированный модельный шаг без отдельной матрицы драйверов.
  - уточнена граница стартовой истории как [T0, T_end) и закрыт чек-лист issue 01.
- Проверка:
  - git diff --cached --check.
This commit is contained in:
2026-06-14 16:30:15 +03:00
parent 79c2c2657c
commit 31a71f93ea
4 changed files with 177 additions and 32 deletions
@@ -35,12 +35,16 @@ Status: Draft
## Сквозные инварианты
- Рабочий контракт реализации живёт в
`docs/specs/2026-06-14-generator-model-time-and-startup-history.md`, раздел
«Рабочий контракт реализации». Задачи 02–06 берут имена настроек, формат
манифеста, границу `T_end` и правила проверки оттуда.
- `event_timestamp` — модельное время, а не настенные часы компьютера.
- Операционные метки сервиса, история пачек, метрики здоровья и длительность
тика остаются настенным временем, если отдельная задача не докажет обратное.
- Контракт задачи 1 должен разделить, где повторяемость точная, а где
статистическая: промотка прошлого должна быть точной, живой режим зависит от
выбранного драйвера часов.
- Живой ход часов идёт фиксированным модельным шагом
`GEN_TICK_SECONDS * GEN_MODEL_TIME_SPEED`; промотка прошлого тоже повторяется
точно при тех же настройках и чистом состоянии.
- При ×K модельное время и событийный бюджет идут по модельной длительности
тика, а не по реальной длительности сна процесса.
- Часовой пояс модельных часов явно задан в контракте; дневной коэффициент
@@ -49,7 +53,8 @@ Status: Draft
настенного времени, а не простым `datetime.now()`.
- Стартовая история — это события плюс слепок состояния плюс манифест, чтобы не
смешать данные от разных `GEN_SEED`, `T0` и `T_end`.
- На стыке `[T0, T_end]` и живого продолжения не должно быть дублей и дыр.
- Стартовая история покрывает `[T0, T_end)`, живое продолжение начинается из
слепка на `T_end`; на стыке не должно быть дублей и дыр.
- Повторная проверка на чистом стенде должна быть воспроизводимой: либо команда
явно чистит ClickHouse, Kafka-топики данных и состояние генератора, либо
процесс идемпотентен.
@@ -19,32 +19,47 @@ Status: ready-for-human
## Acceptance criteria
- [ ] Выбраны имена и формат настроек для `T0`, скорости ×K и режима промотки
- [x] Выбраны имена и формат настроек для `T0`, скорости ×K и режима промотки
прошлого.
- [ ] Описан драйвер живых часов: модельное время идёт фиксированным шагом
`tick_seconds * K` или по измеренному настенному интервалу. Для каждого режима
записано, что именно считается повторяемым.
- [ ] Разделены уровни повторяемости: точная повторяемость промотки прошлого и
повторяемость живого режима по правилам выбранного драйвера часов.
- [ ] Описано, как после сбоя вычисляется модельная точка возобновления при ×K:
- [x] Описан живой ход часов: модельное время идёт фиксированным шагом
`tick_seconds * K`; измеренный настенный интервал между тиками не входит в
текущий контракт.
- [x] Разделены уровни повторяемости: точная повторяемость промотки прошлого и
точная повторяемость живого режима при тех же настройках и числе успешных
тиков.
- [x] Описано, как после сбоя вычисляется модельная точка возобновления при ×K:
из сохранённой модельной метки, сохранённой настенной метки и скорости.
- [ ] Описано, что короткий и долгий простой считаются по модельному времени:
- [x] Описано, что короткий и долгий простой считаются по модельному времени:
при большом ×K короткий настенный простой может стать долгим модельным.
- [ ] Описан манифест стартовой истории: минимум `GEN_SEED`, `T0`, `T_end`,
- [x] Описан манифест стартовой истории: минимум `GEN_SEED`, `T0`, `T_end`,
настройки генерации, версия state и контрольные числа.
- [ ] Описана граница `T_end`: где заканчивается прошлое и с какой метки
- [x] Описана граница `T_end`: где заканчивается прошлое и с какой метки
начинается живое продолжение, без дублей и дыр.
- [ ] Разделены модельные метки событий и настенные операционные метки сервиса.
- [ ] Зафиксирован часовой пояс модельных часов для дневного коэффициента.
- [ ] Решено, как координатор будет получать повторяемую ClickHouse-проверку:
- [x] Разделены модельные метки событий и настенные операционные метки сервиса.
- [x] Зафиксирован часовой пояс модельных часов для дневного коэффициента.
- [x] Решено, как координатор будет получать повторяемую ClickHouse-проверку:
через очистку данных или идемпотентный прогон.
- [ ] Если выбран чистый прогон, перечислены поверхности сброса: таблицы
- [x] Если выбран чистый прогон, перечислены поверхности сброса: таблицы
ClickHouse, Kafka-топики данных и состояние генератора (`generator_state` или
явный сброс состояния при старте).
- [ ] Контракт записан в durable-документ: обновление `PRD.md`, короткий
- [x] Контракт записан в durable-документ: обновление `PRD.md`, короткий
design note в `.scratch/generator-model-time-startup-history/` или уточнение
спеки. Сам issue 01 только ссылается на источник истины.
## Решение
Контракт записан в durable-документ:
`docs/specs/2026-06-14-generator-model-time-and-startup-history.md`, раздел
«Рабочий контракт реализации».
PRD ссылается на этот раздел в сквозных инвариантах. Для следующих задач важная
граница: стартовая история покрывает `[T0, T_end)`, а живое продолжение стартует
из слепка на `T_end`.
Дополнительную матрицу «фиксированный шаг / измеренная настенная дельта» не
вводим: ADR-0005 не требовала такого публичного выбора, а текущей учебной
цепочке нужен один повторяемый живой ход часов.
## Blocked by
None - can start immediately
@@ -19,7 +19,7 @@ Status: ready-for-agent
## Acceptance criteria
- [ ] Промотка прошлого создаёт события за `[T0, T_end]`, слепок состояния и
- [ ] Промотка прошлого создаёт события за `[T0, T_end)`, слепок состояния и
манифест с контрольными данными.
- [ ] При одинаковых `GEN_SEED`, `T0`, `T_end` и настройках артефакт промотки
прошлого повторяем точно; проверки в ClickHouse следуют правилам допуска из