Files
clickstream-ch-kafka-supers…/.scratch/generator-model-time-startup-history/PRD.md
T
ddadminandClaude Fable 5 c672ed0329 docs(issues): дооформлены задачи 12 и 14, обновлён граф бэклога генератора
- Зачем:
  - подготовить цепочку 12 -> 14 -> 09 -> 10 -> 08 к передаче в coordinator-loop:
    задаче 12 не хватало решений после 07 и 11, задача 14 родилась из обсуждения
    учебного UX (суточная волна вживую).
- Что:
  - issue 12 (DAG-пульт): решения 2026-07-04 — без Docker-доступа из Airflow,
    операции как Python-код генератора в тасках, генератор без автостарта,
    границы пульта, предпроверки чистоты (топики + STG), ожидание ETL перед
    check; учтены находки адверсарного ревью и ревью Codex.
  - issue 14 (новая): профиль daily-wave переводится на speed=60 при тике 1 с —
    модельный час за настенную минуту без изменения фактуры мира.
  - issue 08: мягкие зависимости от 14 и 09 (артефакт курса рождается после
    них), режим ревью; PRD: задача 14 в списке и графе, 12 помечена дооформленной.
- Проверка:
  - вычитка: статусы задач ready-for-agent, порядок в PRD и Blocked by
    согласованы; mermaid-граф рендерится.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 20:42:46 +03:00

140 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Модельное время и стартовая история генератора
Status: Draft
## Зачем
Нужно довести решение ADR-0005 и ADR-0006 до рабочего процесса: генератор живёт
по модельному времени, умеет быстро создать прошлое, сохранить слепок состояния
и продолжить поток так, чтобы результат был проверяем в ClickHouse.
Источник решений:
- `docs/specs/2026-06-14-generator-model-time-and-startup-history.md`
- `docs/adr/0005-generator-model-clock.md`
- `docs/adr/0006-generation-as-sole-analytics-source.md`
- `docs/research/2026-06-11-subagent-coordinator-experiment.md`
## Общие правила приёмки
- Каждый кодовый срез должен заканчиваться проверкой через ClickHouse, а не
только локальными тестами генератора.
- Кодовые AFK-задачи идут через `/tdd`: один поведенческий тест, минимальная
реализация, зелёная проверка. HITL- и документные задачи идут через
обсуждение и фиксацию решения, без искусственного теста.
- Координатор не работает в `/goal` на всю цепочку. Один worker получает один
issue, не коммитит и не реализует следующие задачи.
- После реализации worker делает саморевью без правок. Координатор
классифицирует находки и возвращает только обязательные исправления.
- В задачах 03 и 05 worker заранее даёт промежуточный статус, если статистический
прогон или стендовая проверка идут долго.
- Если исправление после review gate меняет дизайн, формат state, манифест или
схему проверки, результат исправления проходит повторный review gate.
- Коммиты делает координатор после своих проверок и `git status --short`.
- Ручная проверка дашбордов глазами выполняется только в конце всей цепочки.
## Сквозные инварианты
- Рабочий контракт реализации живёт в
`docs/specs/2026-06-14-generator-model-time-and-startup-history.md`, раздел
«Рабочий контракт реализации». Задачи 02–06 берут имена настроек, формат
манифеста, границу `T_end` и правила проверки оттуда.
- `event_timestamp` — модельное время, а не настенные часы компьютера.
- Операционные метки сервиса, история пачек, метрики здоровья и длительность
тика остаются настенным временем, если отдельная задача не докажет обратное.
- Живой ход часов идёт фиксированным модельным шагом
`GEN_TICK_SECONDS * GEN_MODEL_TIME_SPEED`; промотка прошлого тоже повторяется
точно при тех же настройках и чистом состоянии.
- При ×K модельное время и событийный бюджет идут по модельной длительности
тика, а не по реальной длительности сна процесса.
- Часовой пояс модельных часов явно задан в контракте; дневной коэффициент
считается по нему, а не по неявному локальному времени.
- После сбоя точка возобновления считается из сохранённой связки модельного и
настенного времени, а не простым `datetime.now()`.
- Стартовая история — это события плюс слепок состояния плюс манифест, чтобы не
смешать данные от разных `GEN_SEED`, `T0` и `T_end`.
- Стартовая история покрывает `[T0, T_end)`, живое продолжение начинается из
слепка на `T_end`; на стыке не должно быть дублей и дыр.
- Повторная проверка на чистом стенде должна быть воспроизводимой: либо команда
явно чистит ClickHouse, Kafka-топики данных и состояние генератора, либо
процесс идемпотентен.
## Задачи
Номер в имени файла — просто идентификатор задачи, порядок выполнения он не
задаёт. Порядок и зависимости живут здесь и в секциях «Blocked by» самих задач;
при изменении порядка файлы не переименовываются.
Сделано (ядро фичи, закрыто на триаже 2026-07-04):
- `issues/01-time-and-startup-history-contract.md` — контракт модельного
времени и стартовой истории.
- `issues/02-model-time-to-clickhouse.md` — минимальный поток по модельному
времени до ClickHouse.
- `issues/03-model-speed-and-day-factor.md` — ×K и дневной коэффициент по
модельному времени.
- `issues/04-state-v2-model-resume.md` — восстановление state v2 от модельной
точки возобновления.
- `issues/05-startup-history-backfill-to-clickhouse.md` — промотка прошлого,
стартовая история и живое продолжение до ClickHouse.
- `issues/06-generated-history-as-analytics-source.md` — штатный путь стенда
переводится на стартовую историю как источник аналитики.
- `issues/07-startup-history-portable-artifact-and-usage-docs.md` — портативный
артефакт стартовой истории и runbook.
- `issues/11-generator-launch-verbs-and-profiles.md` — глаголы, длительность и
профили запуска генератора.
Остаток — порядок выполнения (решение 2026-07-04: пульт вперёд, потому что
узкое место — время человека на ручную приёмку; тяжелее всего проверять руками
миграцию курса, поэтому она идёт последней, когда пульт уже есть):
- Основная ветка: `issues/12-...` (Airflow-DAG как пульт; дооформлен
2026-07-04: без Docker-доступа из Airflow, конечные операции — Python-код
генератора в тасках, live и полный сброс остаются консолью).
- Параллельно, независимы: `issues/09-...` (фикс браузерной фактуры на
стыке), `issues/10-...` (читаемость гео-карты) и `issues/14-...` (быстрый
учебный профиль: суточная волна вживую за ~24 минуты; заведён 2026-07-04,
лучше до 08 — артефакт курса рождается из этого профиля).
- После фикса 09: `issues/13-...` (доливка истории от слепка; без приоритета,
`needs-triage` — доливка тиражирует стыки восстановления, дооформлять после
фикса).
- Последней: `issues/08-...` (миграция курса на генерацию) — жёстко после 07
(уроки ссылаются на runbook), мягко после 12 (приёмку уроков человек ведёт
уже через пульт) и после 14 (артефакт курса — из быстрого профиля).
```mermaid
flowchart LR
i07["07 артефакт + runbook"] --> i11["11 глаголы запуска"]
i11 --> i12["12 DAG-пульт"]
i07 --> i08["08 миграция курса"]
i12 -. "приёмка через пульт" .-> i08
i14["14 быстрый профиль"] --> i08
i09["09 фикс стыка"] --> i13["13 доливка"]
i10["10 гео-карта"]
```
## Контрольные точки
- После задачи 3 нужен внешний review gate по сквозному инварианту времени:
проверить, где ещё остались настенные часы, и не расходятся ли живой путь,
расчёт интенсивности и сохранение состояния.
- После задачи 5 нужен внешний review gate по распределениям и двум путям
генерации: проверить форму данных, стык истории и живого продолжения,
однородность визита до и после восстановления.
Для review gate после задачи 3 reviewer другой родословной сильно желателен.
Для review gate после задачи 5 он обязателен: research показал, что форма
распределений и свойства на стыке двух путей хуже ловятся одной линией проверки.
Если такого reviewer-а нет, координатор останавливает цепочку и явно отдаёт
решение человеку.
## Финальная ручная приёмка
После задачи 6 человек смотрит Superset/Grafana и проверяет, что стенд живёт на
генерации: видны история, возвраты, воронка и суточное «дыхание». Если текущих
панелей не хватает для такого просмотра, создаётся отдельная задача на панель
или runbook, а не расширяется эта цепочка задним числом.
Миграция уроков по ADR-0006 сознательно отслеживается отдельно. Задача 6 должна
создать follow-up, если учебные материалы требуют нетривиальной переделки.