GR-1: Global Rule about preview-страницы

Каждый артефакт системы (постер, карусель, explainer-видео) автоматически сопровождается self-contained HTML preview с payload-сайдбаром. Это контракт между генератором и тем, кто будет ревьюить результат.

Что такое GR-1

GR-1 (Global Rule №1): любой creative-* скилл, который выдаёт боевой артефакт, обязан вместе с артефактом положить рядом standalone HTML-страницу, где видно и сам артефакт, и полный payload его создания (промпт / референсы / brand / model / параметры / стоимость / timestamp). Файл должен открываться offline и не зависеть от внешних ресурсов.

Это правило родилось из одного простого факта: agency-review не работает без provenance. Когда reviewer открывает 6 PNG-постеров без контекста — он не знает, какой промпт это дал, какие референсы использовались, какая модель, в какой версии бренда. Он не может ни одобрить, ни сказать что починить. Поэтому каждый артефакт должен сам себя «объяснять».

Зачем это нужно

СценарийБез GR-1С GR-1
Клиент просит «доработать постер #3» Лезешь в БД, выясняешь какой это poster_id, тянешь payload, восстанавливаешь промпт Открываешь preview.html, в сайдбаре весь payload — кидаешь в refine.py
QA отлетел на 3-м слайде карусели Гадаешь — это плохой промпт или плохой бренд-цвет В preview видишь visual_hint, brand-палитру и сразу понимаешь причину
Отчёт по стоимости батча Считаешь по логам В каждом preview — model + cost; легко сагрегировать
«Покажи клиенту что мы наклепали» ZIP с PNG и отдельный текстовый файл Один HTML-файл, отправляешь в чат / email
Дебаг «почему этот explainer длится 3:14 а не 3:00» Считаешь руками длительность каждой сцены из плана В preview по сцене — duration_seconds, видно где растянулось

Реализации в трёх скиллах

creative-poster · present.py

Файл: ~/.claude/skills/creative-poster/scripts/present.py.

Что внутри HTML:

Файл лежит рядом с PNG, например:

~/video-projects/apparatus/posters/2026-05-16/poster_a_4x5.png
~/video-projects/apparatus/posters/2026-05-16/poster_a_4x5.html  ← preview

creative-carousel · present.py

Файл: ~/.claude/skills/creative-carousel/scripts/present.py.

Что внутри HTML:

Файл лежит рядом со слайдами, например:

~/video-projects/apparatus/carousel/2026-05-16/slide_01.png
~/video-projects/apparatus/carousel/2026-05-16/slide_02.png
~/video-projects/apparatus/carousel/2026-05-16/plan.json
~/video-projects/apparatus/carousel/2026-05-16/preview.html  ← preview

creative-explainer-video · present.py

Файл: ~/.claude/skills/creative-explainer-video/scripts/present.py.

Что внутри HTML:

Файл лежит рядом с mp4:

~/Desktop/apparatus_explainer.mp4
~/Desktop/apparatus_explainer.html  ← preview

Авто-вызов

Каждый present.py автоматически зовётся в конце своего генератора:

ГенераторКогда зовёт present.py
creative-poster · gen.pyСразу после успешного сохранения PNG
creative-poster · multi_aspect.pyПосле outpaint каждого аспекта
creative-carousel · render_slides.pyПосле рендера всех слайдов
creative-explainer-video · render.pyПосле завершения Remotion render + ffmpeg mix

Можно отключить флагом --no-present если не нужно (например когда orchestrator делает батч и не хочет открывать N окон в браузере). По дефолту — открыт всегда.

Что лежит в Sidebar (универсальная структура)

СекцияПоля
Production meta renderer / aspect / template / cost / timestamp / project / generation_seed
Brand context имя бренда / palette swatches с hex / fonts (headline/body/mono) / voice tone / VO voice_id (для explainer)
Topic / brief исходный topic + offer/bullets/profits
Per-item payload prompt (для poster) / per-slide visual_hint (carousel) / per-scene vo_text + visual_hint (explainer)
References thumbnails использованных reference-фото (multi-shot для poster, product-photo для carousel/explainer)
QA / refine history score, suggested_fix, число итераций (только для poster — другие не QA-ятся)

Coverage по скиллам

Скиллpresent.pyЧто в HTML
creative-posterестьsingle poster + lightbox + payload
creative-carouselестьmulti-slide scroll-snap + thumbnails + lightbox + per-slide payload
creative-explainer-videoестьembedded mp4 + clickable scene timeline + per-scene payload
video-orchestratorTODOпланируется: финальный mp4 + timeline клипов + per-clip payload

Self-contained = offline-friendly

Один из критических контрактов GR-1: HTML должен работать без сетевого доступа. Это значит:

Профит: можно прислать в Telegram / Slack / email одним аттачментом. Можно отдать клиенту на флешке. Можно сохранить в Notion / Confluence без потери визуала. Это не «preview в браузере проекта» — это законченный артефакт.

Как добавить GR-1 в новый скилл

Если ты пишешь новый creative-* скилл, который выдаёт боевые артефакты, ему нужен свой present.py. Минимальный контракт:

  1. Принимает на вход путь к артефакту + JSON-план (если есть)
  2. Собирает payload из артефакта, плана и meta (project.yaml, brand.yaml, БД)
  3. Генерирует HTML с inline CSS/JS + embedded media
  4. Пишет рядом с артефактом
  5. Опционально открывает (--open через webbrowser.open() на macOS)

Стандартный CLI:

python <skill>/scripts/present.py \
  --plan plan.json \
  --output-dir <artifacts>/ \
  --output ~/Desktop/<name>.html \
  [--open]
Структура HTML — посмотри как сделано в creative-poster/scripts/present.py и адаптируй. Все три существующих present.py намеренно похожи структурно, чтобы reviewer переключался между ними без когнитивного оверхеда.