﻿# SYNC-RUNBOOK v5.1 — AI Film Project

> **01.11.2026 — ChatGPT / Work / Grok Bot:** роли, расписания, общий замок, защита от дублей и границы доказанной готовности — `ops/LAUNCHER-COORDINATION.md`; живой реестр — `ops/slot-backup.json`. Копии и прежние отчёты не переопределяют этот реестр.

> **27.10.2026 — «Продолжай»:** явный фокус задачи, проверяемый checkpoint и доказательства, компактный пакет и восстановление после обрыва — `ops/CONTINUE-PROTOCOL.md`. Пакет не разрешает внешние действия; живые проверки и полный fallback сохраняются.

> **23.10.2026 — точные статусы и отпечаток.** Готовность показывать по каждой части: слот / исходный результат / подготовка и QC стыка / отдельный референс / решение владельца. Существующий робот строит `ops/queue-readiness.json`; success не делает вход готовым. Сайт обновляет также master/status/сертификат, сохраняя черновики. Процедура и источники — `ops/QUEUE-READINESS.md`. Новая62 — мост к червям; кабина37/39/40/41/52/53/59/60 — очищенный `S37-cockpit-empty.png`, без людей и мечей.

**Назначение:** пошаговая инструкция записи, проверки и восстановления для master, инструкций, статусов и сайта. Это **единственный дом** правил authority, записи в канон, робота и мониторов, Topview (slow, слоты, телеметрия, привязка задач), кнопок владельца, валидатора и сайта; другие инструкции дают одну строку и ссылку сюда.
**Редакция:** 18.10.2026 — убраны повторы между инструкциями (одно правило — одно место); генеральная зачистка 11–14.10.2026 до этого. Прежние тексты — `git log` и `archive/instructions-before-cleanup-2026-10-14/`.

> **Источник истины (решение владельца 11.10.2026, 03:25 МСК).** Канон один — GitHub `virudik/ai-film-prompts`, ветка `main`: `video-prompts.md` и ровно 7 инструкций, статусы, сайт / Pages. Всё остальное — копии или телеметрия: Google Drive, Notion, Claude Project, ChatGPT Project и Library — резервные копии только для чтения (`BACKUP-AI-RUNBOOK.md`); Topview — телеметрия генераций; Notion — сюжет и история. Порядок приоритета: **GitHub `main` → Topview (телеметрия) → Notion (сюжет, идеи, история)**; копии никогда не побеждают `main`. Правка канона = минимальный коммит в `main`. Если конфликт — свежий `main` всегда побеждает. Роли хранилищ — `README-AI-SYNC.md` «Storage roles».

## Действующие решения 11–14.10.2026 (читать первыми)

**Проверка GitHub нескольких проектов (23.10.2026).** В общем цикле `sync-from-drive.yml` валидируются также все `projects/<id>/video-prompts.md` через `scripts/projects.py`. При неизменном содержимом публикуется фактическая повторная проверка раз в 180 минут, при изменении — сразу. Нельзя просто переписать дату без валидатора. `projects-sync.yml` остаётся дополнительной проверкой после push. Это тот же порог D5, не новое расписание ChatGPT и не запуск Topview; правила проектов — `projects/README.md`.

### Одна метка slow в карточке сцены (правило master, 14.10.2026; для робота, ChatGPT, Claude и ручных правок)

Ровно **одна** простая метка `**⏳ В МЕДЛЕННОЙ ГЕНЕРАЦИИ**` в карточке каждой canonical slow-сцены — отдельной строкой, **без технического хвоста** (никаких «· Wan 3.0 · task … (`init`, unlimited 0 credits)» после метки: хвост устаревает и противоречит живому статусу). Номера задач и их статусы живут в таблице «⏳ Сейчас в медленной генерации» и в телеметрии; техническая строка «… task `…` технически завершён …» пишется в карточку один раз. Вторую метку и жирные строки-статусы («**✅ Технический результат получен …**») в карточку не добавлять. `scripts/master_slow_edit.py` нормализует это сам при любой правке сцены. На сайте метка показывает живое состояние: зелёное «✅ ГОТОВО — ждёт решения владельца» / красное «❌ ОШИБКА TOPVIEW — ждёт решения владельца» / жёлтое «⏳ В МЕДЛЕННОЙ ГЕНЕРАЦИИ»; лишние метки и технические строки автоматики сайт скрывает.

### Canonical slow снимает только владелец (решение 11.10.2026)

При `success`, `fail`, `cancelled` Topview изменяет только техническую телеметрию, активные task ID, физические 6 слотов и журнал завершений. **Не удалять сцену из canonical slow / `project-status.slow_scenes` автоматически ни при каком техническом terminal.** Даже если не осталось активных задач, сцена остаётся «ждёт решения владельца». Освобождение слота ≠ снятие slow и ≠ approval. Снять slow может только явное решение владельца из панели «🔑 Владелец» (кнопки, Supabase `owner_decisions`) после проверенного применения в GitHub `main` (какие кнопки снимают — «Кнопки владельца и задачи текстом»). `topview-task-map.json.active_by_scene` — только реальные активные задачи; `topview-status.json.occupied_slots` — физически занятые слоты; master slow — владельческий статус; эти числа не обязаны совпадать. «Не ждать» снимает ожидание по желанию владельца, но **не отменяет реальную Topview-задачу и не освобождает её физический слот**. Монитор и робот не одобряют, не удаляют, не ререндерят и не создают новые Scene ID без указания владельца. Подтверждённые заявки Supabase применять однократно, неоднозначные — `needs_owner`. Коммит `5269865` (сохранение canonical slow) механически не откатывать.

### Робот GitHub — основной писатель телеметрии Topview (решение владельца 13.10.2026)

`monitor-role.json`: `primary=robot`, `standby=chatgpt`; монитор Claude выключен. Цепочка: `.github/workflows/topview-robot.yml` → `scripts/topview_api_scan.py` (Topview API, только GET) → `scripts/robot_telemetry.py`, одно решение на цикл:

- `noop` — ничего не изменилось и телеметрии меньше 50 минут;
- `publish` — новая / завершённая / сменившая статус задача либо телеметрии 50+ минут (пульс раньше порога «устарела» 120 мин): в **одном** коммите `topview-task-map` → журнал → `topview-status` → `review-ledger` (только `result_received`) → `topview-checkpoint` (последним); при необходимости минимальная правка slow-строк master (`scripts/master_slow_edit.py`, `apply_plan`) и `SYNC-TRIGGER.txt`; перед коммитом `build_project_status` обязан дать `health=ok`; запись цикла `runner=robot` в `automation-monitor-status.json`; push с проверкой (CAS) и read-back;
- `hold` — скан неполный (`detail_failed`), известная задача исчезла, задача без сцены или сцена не в master: ничего не публикует, один раз пишет честный `degraded`-цикл и событие в ленту.

Робот пишет только при `primary == robot` (`python3 scripts/monitor_role.py . --me robot`) и GitHub Variable `ROBOT_TELEMETRY` ≠ `shadow` (нет переменной = `on`). **Аварийный выключатель** — `ROBOT_TELEMETRY=shadow` (робот пишет только `shadow/robot-cycle-preview.json`, канон не затронут) или команда владельца «основной монитор — ChatGPT» (агент ставит `primary=chatgpt`, `standby=robot`). Роли, подхват и защита от одновременной записи — «Мониторы и расписание».

**Новые сцены и сбой публикации (16.10.2026).** Перед проверкой журнала робот сам добавляет **пустую** строку `review-ledger.json` для каждой активной сцены, у которой её нет (та же пустая строка, что у `scripts/reconcile_review_ledger.py`; решения владельца не выводятся). Публикация, не прошедшая проверку, записывает честный `degraded`-цикл (`publish failed: …`, только `automation-monitor-status.json`, повтор не чаще 50 мин) и одно событие в `topview-events`; телеметрия при этом не пишется.

**Подсцены.** Код подсцены (`A1`…`B10`, «Seedance 2.0 часть N») робот берёт из метки совпавшего блока промта (`mapping_confidence` «… master block 28 B6 (robot)»), хранит в `topview-status.active_tasks[].part`, в постоянной карте `topview-status.task_parts` (task → подсцена, остаётся после завершения задачи) и в `topview-task-map.processed_tasks[].part`; новую строку таблицы slow пишет как `| 28 · B6 · Танец 6 — … |` (скрипты master принимают после номера и «—», и «·»). Сайт показывает строку «Подсцены: …», статус у заголовка каждой подсцены и код в таблицах Topview / slow.

Робот один раз чинит строки master, где задача уже завершена по `topview-task-map.processed_tasks`, а строка таблицы slow осталась `init` / `running`: строка → технический результат (или ошибка), одна техническая строка в карточку, шапка пересчитывается по реальным занятым слотам; canonical slow не снимается.

Робот никогда не запускает, не одобряет, не перезапускает, не удаляет, не тратит кредиты, не создаёт Scene ID, не снимает canonical slow и не угадывает привязку «задача → сцена»: принимает только точное или нормализованное совпадение промта ровно с одной активной сценой (`scripts/topview_prompt_match.py`), иначе `hold` и событие в ленту. Лента оповещений владельца — один открытый issue с меткой `topview-events`, каждое событие — комментарий (результат готов и свободные слоты; задача без сцены; сбой); дубли гасятся по `automation-monitor-status.json.notification_state.robot_notified_keys`. Тесты: `tests/test_robot_telemetry.py`, `tests/test_monitor_failover.py` (роль `robot`). Подробно и откат — `ops/ROBOT-TELEMETRY.md`.

Робот не заменяет (остаётся за агентом / владельцем): привязку задачи без точного совпадения промта; выполнение текстовых `owner_task` (робот их только доставляет во входящие); применение `tv_mark_status(result_ok)`; «Не нужна» при зависимых сценах; ИИ-часть суточной проверки инструкций; копии в Notion / Library / Project.

**Сигнал свободного слота (26.10.2026).** Agent Relay включён после полной приёмки; Gmail V2 paused. Существующий робот после проверенной публикации результата со свободным слотом создаёт бот-issue и посылает DM; отдельный agent token хранится только в GitHub secret AGENT_RELAY_TOKEN. Обработчик проверяет sender/issue/ID/свежесть, дедуп, общий замок/CAS claim и Unlimited0. Часовая страховка6acae6ab… сохранена. Рабочий флаг и откат — `ops/relay-wake.json`; процедура и доказательства — `ops/TOPVIEW-EVENT-WAKE.md`, `reports/topview-event-wake.json`. Квитанции run ID/start/completed сохранять до следующего события: peek показывает только последний run; HTTP2xx или last_run_time не заменяют исполнение.

### Запуск автоматики снаружи (решение владельца 13.10.2026)

GitHub `schedule:` ненадёжен (по истории запусков 12–13.10 паузы по 5–7 ч вместо 30 мин у `topview-robot`, `sync-from-drive` и суточной копии Drive). Поэтому workflow запускает Supabase (проект `ai-film-comments`) `pg_cron` + `pg_net` через GitHub `workflow_dispatch` (функция `public.dispatch_github_workflow`):

- `dispatch-topview-robot` — каждые 10 минут (:00/:10/…) → `topview-robot.yml` (сканер и телеметрия Topview);
- `dispatch-sync-from-drive` — :02/:12/… → `sync-from-drive.yml` (кнопки владельца, статус, оповещения);
- `dispatch-topview-video-archive` — :05/:15/… → `topview-video-archive.yml` (копии MP4 в Drive).

Фактическое расписание проверено 16.10.2026 (`cron.job` в Supabase и журнал запусков Actions): все три задачи идут ровно раз в 10 минут. Робот **смотрит** Topview каждые 10 минут, а **выкладывает** телеметрию только при изменении или раз в 50 минут; поэтому `topview-status.checked_at` бывает старше 10 минут. Сайт показывает время последнего просмотра роботом (`shadow/topview-robot-status.json.checked_at`), только если набор активных задач в нём совпадает с опубликованным и последний цикл робота здоров; иначе — опубликованное время и «⚠ робот видит изменения, ещё не выложены». `checked_at` в телеметрии не подделывается.

Токен GitHub (fine-grained, один репозиторий, только Actions: Read and write) лежит в Supabase Vault как `github_dispatch_token`; в репозитории, чатах и логах его нет; срок действия выбирал владелец — продлить до окончания. Расписания `schedule:` внутри workflow (UTC: `topview-robot.yml` `7,37 * * * *`, `sync-from-drive.yml` `11,41 * * * *`, `topview-video-archive.yml` `17,47 * * * *`, `drive-write.yml` `20 3 * * *`) остаются запасными и могут опаздывать на часы — любые фразы «каждые 30 минут (:07/:37, :11/:41, :17/:47)» читать именно так. У каждого workflow своя `concurrency`-группа. Проверка: `select status_code, count(*) from net._http_response group by 1;` (ожидается 204) и запуски Actions с событием `workflow_dispatch`. Остановка: `select cron.unschedule('<имя>');` или отзыв токена (тогда остаётся расписание GitHub). При переименовании файла workflow задачу cron пересоздать с новым именем. Описание — `ops/ROBOT-TRIGGER.md`, SQL без секретов — `ops/supabase/2026-10-13_robot_dispatch_cron.sql`. Если запуски молчат больше 3 ч — сработает `monitor-alert`.

### Автоархив готовых Topview MP4 в Drive (13.10.2026)

`.github/workflows/topview-video-archive.yml` + `scripts/topview_video_archive.py` копируют успешные ролики **только активных сцен** master (`project-status.json.scene_ids`) в приватную папку Drive (`AI Film Prompts Master / AI Film Generated Videos / Scene-NN / <task_id>.mp4`); индекс — `topview-video-archive.json` (только метаданные). Кандидаты — только уже привязанные успешные задачи из `topview-task-map.json.processed_tasks`; до 2 роликов за запуск, сначала самые свежие. Полное описание — `ops/TOPVIEW-VIDEO-ARCHIVE.md`; восстановление и запреты для папки — `BACKUP-AI-RUNBOOK.md` «MP4-архив роликов Topview». Решение владельца 13.10: «🎞 В фильме» = сцена одобрена, добавлена в фильм и убрана из master — её ролики больше не копируются (уже заархивированное остаётся). Для исполнителя:

1. workflow независим от монитора, робота кнопок и canonical slow; пишет в git только `topview-video-archive.json`;
2. запись в индексе появляется лишь после проверки имени, папки `Scene-NN`, task ID, размера и MD5 в Drive; ошибки печатаются только как стадия + HTTP-статус, неудавшийся ролик повторяется в следующем запуске;
3. в индекс, JSON, логи и Pages не попадают подписанные URL, ключи, байты видео;
4. успех архива ≠ approval; ошибка архива не меняет сайт, slow или Scene ID; зелёное «Готово» на сайте от архива не зависит; архив ничего не генерирует и не запускает; папка с роликами — не канон; второй архиватор не создавать;
5. загрузка идёт в заранее выданные владельцем файлы-слоты (`topview-archive-seeds.json`); пул конечен (100 слотов на 13.10); при остатке ≤10 workflow открывает issue `topview-archive-pool`; при «No preauthorized owner-owned Drive upload slots remain» — остановиться и спросить владельца; пополняет слоты только владелец; IAM и ключи не менять, JSON-ключи не добавлять;
6. перед изменением скрипта — `python3 -m unittest discover -s tests -p 'test_topview_video_archive.py'`.

Ссылки на копии на сайте строятся из `file_id` в `topview-video-archive.json` только при совпадении сцены и задачи. Проверка работы: свежий прогон workflow, где успешны шаги «Copy and verify completed videos» и «Commit verified archive index only», плюс открытие записи индекса под аккаунтом владельца. Хранить MP4 в GitHub нельзя: репозиторий публичный; сменить хранилище — только по явному решению владельца.

### Несколько проектов в одном репозитории (решение владельца 20.10.2026)
Проекты: **Серёгиус** (корень, как раньше), **Котмонавты**, **Кот детектив**, **Роскосмос** (id `roscosmos`), **Разное** (id `raznoe`) — каждый в `projects/<id>/` со своим мастером, статусом, хендофом, инструкцией, референсами, очередью, замком и журналом решений; номера сцен у каждого свои. Реестр `projects/projects.json`, полные правила — `projects/README.md`. Коротко: сообщение владельца без названия проекта — Серёгиус (`python3 scripts/projects.py . detect "<текст>"`); правка внутри `projects/<id>/` — под замком проекта (`canon_lock.py --project <id>`), всё остальное — под общим замком; после правки мастера проекта — `projects.py . status --project <id> --write` (страхует `projects-sync.yml`). Кнопки других проектов помечены `value = "project:<id>"` / «[проект: <id>]»; фазы 1–3 их пропускают, применяет фаза 4 `scripts/robot_project_actions.py`. Робот телеметрии узнаёт задачи других проектов по точному совпадению промта и пишет их в `projects/topview-projects.json` (без `hold`); слоты Topview общие — 6 на все проекты. Сайт: переключатель вверху слева, `?p=<id>` (`projects.js`).

**Учёт повторных Relay-сигналов (26.10.2026).** Обработчик принимает также `slots:…`; каждый подтверждённый обработанный event_id сохраняет в `reports/topview-event-wake.json` → `events[]`, в том числе при `no_update`. Новый ID требует квитанции без Create; общий замок/CAS/readback обязательны. При чужом замке — честный `receipt_not_saved`, без записи/ложного ACK. Полный контракт и очистка: `ops/TOPVIEW-EVENT-WAKE.md` (до100 завершённых событий/30дней; остальное в архив, точные ID остаются для дедупа; незавершённые не переносить).

## 1. Preflight перед любой записью

Порядок приёма смены (короткий D7 или полное чтение 7 инструкций) — `AI-PROJECT-GUIDE.md` «Формат takeover и решение D7» и §1. Локальные клоны, старые чаты, вложения и сводки не считаются актуальными: первым шагом всегда `git pull`.

Перед первой записью окружение должно подтвердить (capability preflight): чтение и запись репозитория (`git pull` / `git push`), обновление `SYNC-TRIGGER.txt`, запуск проверок (`scripts/validate_site.py`, тесты, `scripts/cert_github.py`), возможность проверить Actions, статус и Pages. Если чего-то нет — агент только проверяет и читает (review-only), не создаёт новый master, не изображает выполненную запись и прямо называет недоступный шаг.

## 2. Один писатель, свежее чтение, ничего вслепую

- **Один писатель канона под замком** `ops/CANON-LOCK.md`; телеметрию независимо назначают `scripts/monitor_role.py` и `monitor-role.json`. Не смешивать эти полномочия. Исключения для входящих задач/архива/отметок и обязательные Relay-квитанции при `no_update` — в протоколе замка.
- **Свежее чтение.** Перед каждой записью — `git pull`; правка делается от свежего `main`.
- **Отклонённый push** означает, что писал другой: перечитать и повторить с нуля. Никогда не воспроизводить устаревшую заготовку правки — ни после таймаута, ни после неясного результата.
- **Последовательность.** 7 инструкций меняются по одной, не одним длинным пакетом. Проверка чтения (read-only) можно пачкой, запись — только последовательно.
- **Read-back.** После записи прочитать результат из `main` и проверить содержание, прежде чем сообщать об успехе.
- **Порядок зависимостей.** Сначала канон, затем производные статусы, затем сайт и Pages. Сгенерированный статус никогда не перезаписывает свежий канон.
- **Нет слепого отката.** Восстановление — только из проверенной версии (git-история), а не из кэша или копии.
- **Нет нагрузки на владельца.** Детерминированный дрейф, который чинится однозначно, чинится молча; о чём спрашивать владельца — `AI-PROJECT-GUIDE.md` §14.
- Никаких `v2`, `final`, `copy` вместо master или инструкций.
- Ключи (`SUPABASE_SERVICE_ROLE_KEY`, `TOPVIEW_API_KEY`, `TOPVIEW_UID`, `GCP_*`) — только в GitHub Secrets / Variables, токен запуска — в Supabase Vault; значения никогда не в чат, репозиторий, сайт или копии; у владельца ключи и пароли не просить.

## 3. Routine: изменить существующую scene / prompt

1. `git pull`; найти точный Scene ID.
2. Проверить slow-lock (`project-status.json.slow_scenes`) и `scene-meta`.
3. Если промт меняется существенно — `PROMPT-STYLE-GUIDE.md` + 1–2 соседние сцены.
4. Изменить только нужный блок сцены и связанные оглавление / счётчики / статус / meta. Минимальный diff (одна правка = один коммит).
5. Master — UTF-8 без BOM, только LF (проверить отсутствие `\r`).
6. Коммит → `SYNC-TRIGGER.txt` (ожидаемый SHA) → `git pull --rebase` → push.
7. Дождаться workflow `sync-from-drive.yml` («Canonical master check and owner buttons (GitHub main; Drive is only a copy)»; имя файла историческое, до 18.10.2026 workflow назывался «Sync canonical master from Google Drive»; master берётся из GitHub `main`); валидатор — `project-status.health=ok`.
8. Проверить `project-status.json` (`canonical_master_sha256` = SHA нового master) и сборку Pages; slow / Topview-телеметрия самовольно не менялась.
9. Если сцена в slow — не менять Topview-привязку без доказанной причины; новая задача-замена с тем же (с точностью до нормализации) промтом — доказанная причина обновить привязку.
10. Только после read-back и проверок сообщать «готово».

## 4. Routine: добавить новую scene

Новую сцену заводит только рабочий чат или монитор **с согласия владельца** (решение 10.10). Монитор сам новый Scene ID не создаёт.

Перед добавлением: `git pull`; взять `latest_scene` и список зарезервированных ID из `project-status.json`; не переиспользовать ни один зарезервированный номер. Если следующий ID однозначен, пользователя не спрашивать (правила Scene ID — `AI-PROJECT-GUIDE.md` §3).

Добавить: якорь, заголовок `## Сцена N`, `scene-meta`, русскую обёртку (контекст / референсы / что происходит), полный master-промт во всех версиях движка (`PROMPT-STYLE-GUIDE.md` §7А), строку оглавления, счётчики и revision-текст — только там, где они действительно текущие. Метка и таблица slow — только если генерация реально запущена. Далее — полный routine из раздела 3.

## 5. Routine: удалить / закрыть scene

Сцена убирается из активного master только после явного решения владельца (кнопка «🎞 В фильме» / «Не нужна» или команда): результат принят и промт больше не нужен. Topview `success` сам по себе approval не является.

При закрытии: убрать раздел, строку оглавления, запись slow (если есть и владелец так решил), обновить счётчики, **Scene ID зарезервировать навсегда**, проверить зависимости других `scene-meta` (мёртвые ссылки на закрытую сцену убрать из metadata; литературные связи в описании можно оставить), далее sync → валидатор → Pages. Текст промта остаётся в истории git. Если у сцены есть активная задача Topview — master не трогать, спросить владельца.

## 6. Routine: site-only change

Изменения сайта делаются в `index.html` (и связанных файлах) в `main`, если не меняют данные промтов. После изменения:

1. `python3 scripts/validate_site.py .` (синтаксис JS, дубли id, контракты сайта);
2. проверить отсутствие секретов;
3. убедиться, что данные сцен и статуса по-прежнему грузятся из master и JSON, а не зашиты в страницу;
4. `node tests/site_status_check.js` с локальным `python3 -m http.server 8765`;
5. коммит, дождаться Pages, проверить опубликованную страницу.

Постоянные изменения архитектуры сайта — материальные (раздел 9). **Базовый состав Control Center** (`https://virudik.github.io/ai-film-prompts/`, GitHub Pages, только чтение): русский UI; шапка «GitHub main — канон · Drive — копия»; карта активных сцен и полные промты; объединённая таблица slow + телеметрия Topview (модель / статус / запуск / прошло / очередь / ETA); трёхсостоянийный индикатор синхронизации; просмотр персонажей и референсов (`references.html`); светлая и тёмная темы (`localStorage` key `ai-film-theme`); сворачиваемый блок «Контрольный отпечаток», под ним сворачиваемый «💬 Комментарии, идеи и предложения» (комментарии через Supabase без входа в GitHub); панель «🔑 Владелец» с кнопками решений; чип «Монитор»; живая метка в карточке slow-сцены; ссылки на копии MP4; кнопки «Архив GitHub» нет. Контракты UI — «Валидатор, health и Control Center».

## 7. Routine: instruction change

Минимальный коммит → `python3 scripts/cert_github.py .` → тесты (`python3 -m unittest discover -s tests`) → `git pull --rebase` → push → проверка.

1. Определить все затронутые документы. Меняются только 7 канонических инструкций; `CLAUDE.md` — отдельный адаптер (`README-AI-SYNC.md` «Claude Code bootstrap adapter»).
2. Если изменение важно следующему чату — обновить тот же `NEW-CHAT-HANDOFF.md`; если менялся стандарт промтов — `PROMPT-STYLE-GUIDE.md`.
3. `cert_github.py` обновляет `instruction-sync-status.json` (раздел 8). Валидатор не должен показывать блокирующий `instruction_sync_error`; `instruction_sync_stale` допустим как не блокирующее обслуживание.
4. Notion-указатель — при изменении будущего workflow; резервные копии — best-effort (`BACKUP-AI-RUNBOOK.md`).
5. Прочитать результат из `main`; затем сообщать о завершении.

## 8. `instruction-sync-status.json`

Описывает **все семь** документов; обновляется командой `python3 scripts/cert_github.py .` после каждой правки инструкций. Для каждого: `github_blob`, `mirror_sha256`, `match`; справочно — `drive_copy_*` (состояние резервной копии на Drive, не блокирует). Общие поля: `checked_at`, `health`, `all_match`, `source_of_truth=github`, `verification_mode`, `freshness_max_hours`. Поток: файлы в `main` → `cert_github.py` (git-blob и sha256 каждого файла) → `instruction-sync-status.json` → проекция health в `project-status.json`. Старый `checked_at` сам по себе не означает порчу master — это просто означает, что проверку нужно обновить. Блокирует только подтверждённое расхождение с файлом в `main` или ошибка чтения.

**Граница сертификата:** `cert_github.py` подтверждает байты 7 файлов и адаптера Claude; не утверждает семантическую согласованность и успешное исполнение автоматики. Устаревшие дополнительные поля не копируются в новый сертификат; прежний снимок сохранён в `archive/ops/instruction-certificate-legacy-2026-10-26.json`. Недельная сверка файлов, живых Automations prompts/расписаний/Relay-подписки и настроек — `ops/AUTOMATION-CONSISTENCY.md`.

## 9. Material Change Documentation Rule

Изменение материальное, если меняет способ работы следующих чатов или архитектуру проекта: новая постоянная функция сайта; новый backend, сервис или постоянная интеграция; новый обязательный prompt rule; смена authority / источника истины; новый статус или workflow; новое правило восстановления; новый обязательный документ; смена способа синхронизации или порядка takeover.

Такое изменение **не завершено**, пока:
- не обновлены релевантные из 7 инструкций;
- не обновлён тот же `NEW-CHAT-HANDOFF.md` (handoff);
- обновлён prompt guide, если затронуты правила промтов;
- не запущены `cert_github.py` и тесты и инструкции не закоммичены в `main`;
- проверены `project-status.json` / Pages, если затронуты;
- Notion-указатель обновлён, если меняется workflow;
- резервные копии (Drive, Project, Library) могут быть устаревшими и **не блокируют** завершение (пропускать при интерактивном подтверждении).

Изменение кода без документации не считается законченным. Параллельных «новых финальных» инструкций не создавать. Runtime-телеметрию (очередь, ETA, SHA, слоты) в инструкции не копируют — её читают live из JSON.

## 10. Topview telemetry

Каноническая принадлежность slow — свежий master и `project-status.json.slow_scenes`. Пассивная телеметрия master не меняет. Исключение — цикл действующего писателя телеметрии: он может добавить **существующий Scene ID** в canonical slow при доказанной новой задаче существующей сцены и обновить привязку (раздел 18); новый Scene ID — только с согласия владельца.

Для каждой slow-сцены: точная проверенная привязка задачи; сравнение промта и референсов задачи со свежей сценой master; `verified=true` только при доказанном совпадении; `queueCount` и ETA провайдера — только из этой задачи; историческое ETA хранить отдельно; очередь и ETA между сценами не копировать; нет доказанной привязки — `verified=false`, очередь / ETA как факт не показывать.

Terminal задачи (`success` / `fail` / `cancelled`) меняет только техническую телеметрию и физические слоты (6); **canonical slow снимает только явная кнопка владельца** (верхний блок «Canonical slow снимает только владелец»), даже если активных задач у сцены не осталось. Terminal не меняет approval и редакторский статус. Technical success ≠ approval; приёмка — только решение владельца.

Если задача уже записана в `topview-task-map.processed_tasks` как завершённая, а строка таблицы «⏳ Сейчас в медленной генерации» в master всё ещё `init` / `running`, действующий писатель телеметрии (не только робот) один раз переводит строку в технический результат (или ошибку), добавляет одну техническую строку в карточку и пересчитывает шапку по **реальным** занятым слотам; canonical slow при этом не снимается.

Нельзя: перепривязывать по старому handoff или заголовку; копировать одну очередь на все сцены; автоматически перезапускать (rerun); автоматически одобрять (approve); автоматически снимать slow; удалять или закрывать сцены.

## 11. Comments / Supabase

Backend комментариев: проект Supabase `ai-film-comments` (ref `vzohfatqzyioydtgjiyd`, организация `Vint`), Edge Function `submit-comment`. Базовая безопасность: публичное чтение опубликованных комментариев; анонимная публикация и ответы (`parent_id`); RLS; honeypot; 5 сообщений / 10 минут / IP; во фронтенде только publishable-ключ; `service_role` и admin-секретов в `index.html`, публичном коде и репозитории нет; комментарии не могут менять master, статус или генерации. Любое изменение этой архитектуры — материальное.

Решения владельца кнопками и текстовые задачи (`owner_decisions`, Edge Function `owner-decision`) — раздел «Кнопки владельца» ниже.

## LIBRARY RECOVERY — best-effort, не блокирует

Library — резервный кэш, не authority и не шаг завершения. После материальных правок инструкций копии в Library обновляются **по возможности**, без интерактивных подтверждений владельца. Если интерфейс требует разрешения или даёт только «Try again» — не блокировать работу, не повторять запрос, не просить владельца идти в браузер: записать `pending/stale` и продолжить. Устаревшая Library не делает проект красным, не отменяет проверенную правку в `main`. Нельзя лишь утверждать, что Library свежая, если она не обновлена. Library никогда не переопределяет `main`. На takeover устаревшая или отсутствующая Library — информационное предупреждение. Состав копии Library — `BACKUP-AI-RUNBOOK.md`.

## 12. Notion

Notion `Кино` — сюжет, история, идеи, старый сценарий, локации, исторические промты; не заменяет master и не определяет runtime. Новые сюжетные решения владельца сильнее старых заметок; старый Notion-промт в master автоматически не переносить. Операционный указатель: `AI Film — Актуальная инструкция / Handoff`. При материальной смене workflow указатель обновляется так, чтобы он называл GitHub `main` каноном, перечислял 7 инструкций и не выдавал старые промты за master. `Важные промты` — архивный банк идей, не текущий стандарт.

## 13. Известные сбои

- **Non-fast-forward / одновременные писатели.** Перечитать `origin/main`, пересобрать правку с нуля, повторить push. Не перетирать более свежий телеметрический коммит.
- **Master — LF без BOM.** Блокирующие проверки `canonical_master_lf_line_endings` и `canonical_master_blank_spacing_compact`. После записи проверять отсутствие `\r` и серий пустых строк (подряд не более одной пустой строки). BOM в master уже ломал строгую проверку шапки.
- **Инструкции — концы строк и BOM как в самом файле.** Не менять конвенцию файла при правке (новые блоки — теми же концами строк); сертификат считается по байтам файла в `main`.
- **Устаревший сертификат инструкций.** Обновить `cert_github.py`, не объявлять master сломанным из-за возраста метки.
- **Исторический vs текущий конфликт.** Исторические записи, старые коммиты, письма GitHub Actions и старые страницы Notion — evidence, не live-инвариант. Текущие утверждения — единичные и явно помечены; runtime-факты не дублировать как вечную истину. Старое письмо об ошибке GitHub не объявлять текущей аварией, если после него есть успешный запуск и живой статус здоров; и наоборот, последний подтверждённый цикл — не бессрочная гарантия, следующий без отдельного свидетельства успешным не считать.
- **Ложное расхождение Topview.** Сравнивать конкретную задачу со свежим телом сцены, а не с памятью или старым заголовком.
- **Пропуски GitHub `schedule:` на 5–7 часов** — защита: внешний запуск («Запуск автоматики снаружи»). **Устаревшие строки `init` и двойные метки slow в master** — защита: одна метка slow и починка строк роботом (верхние блоки).

## 14. Verification before final answer

Для изменения master: коммит в `main` прочитан обратно; workflow `sync-from-drive.yml` («Canonical master check and owner buttons (GitHub main; Drive is only a copy)») успешен; валидатор `health=ok`; `project-status.json` соответствует новому master (`canonical_master_sha256`); Pages успешен.

Для изменения инструкций или материального изменения: все 7 файлов в `main` содержат новое правило; свежий `instruction-sync-status.json` (7/7, `cert_github.py`); тесты и `validate_site.py` зелёные; в `project-status` нет блокирующего предупреждения об инструкциях; Notion-указатель актуален; состояние резервных копий известно (`current` или `pending/stale`).

Не писать «готово», пока соответствующая проверка не завершена. Если какой-то обязательный слой не проверен, сообщить об этом явно, а не заявлять полное завершение.

## 15. Character / film-context preflight

Слой персонажей и монтажа при приёме смены — `AI-PROJECT-GUIDE.md` §15 (реестр персонажей) и §16 (монтажный разбор).

## 16. Takeover readiness audit

Проверка перед «ГОТОВ ПРОДОЛЖАТЬ» — `AI-PROJECT-GUIDE.md` §17; формат приёма — `AI-PROJECT-GUIDE.md` «Формат takeover и решение D7»; бриф — раздел «Бриф для короткого приёма» ниже.

## 17. Что проверять автоматически, а что нет

Лёгкая проверка целостности (монитор, CI): сертификат 7 из 7, наличие ключевых файлов сайта и ссылок, `character-references.json`, `references.html`, монтажные HTML, `film-analysis.md`, `film-backlog.md`, отсутствие публичных секретов, известные инварианты. Не перечитывать и не переписывать ежечасно весь монтажный анализ и весь массив изображений персонажей. Глубокая сверка персонажей с новыми промтами — при существенном изменении сцены или промта и на takeover. Notion и Library проверяют на явную устарелость, но автоматически туда без необходимости не пишут.

Раз в сутки ИИ-монитор-писатель делает глубокую проверку (робот её не делает: при роботе-основном её закрывают тесты и якоря инвариантов, ИИ-часть — по возможности агентом, `ops/ROBOT-TELEMETRY.md`): полное чтение 7 инструкций на противоречия между собой и с master, `scripts/validate_site.py`, живой сайт, здоровье мониторов, дрейф реестра персонажей, уборка разовых напоминаний; результат — `deep-audit-status.json` (метаданные, не authority). В глубокую проверку входит и семантическая проверка активных / новых промтов на регрессию относительно `PROMPT-STYLE-GUIDE.md` (раздел 19 guide; автоматически допустимы только однозначные механические и документационные правки, творческую переписку по аудиту не выполнять). Детерминированные мелочи чинятся обычным каноническим циклом по одному документу; спорное — владельцу. Ежедневная проверка здоровья канона (устаревшее, лишнее, битые ссылки) — `canon-health.yml` → `canon-health.json`.

## 18. Topview task intake / привязка к существующей сцене

Новая неизвестная задача Topview классифицируется одним из трёх способов (известный task ID — не новый intake, а обычная телеметрия; одна задача не импортируется дважды):

1. **Существующая сцена (render / retry).** Промт задачи совпадает с активным промтом сцены master точно или с точностью до нормализации (допустимо игнорировать только несемантические различия: `@image` ↔ `<<<Image>>>`, пробелы и переводы строк, формат токенов референсов) либо есть явное происхождение от Scene ID; модель, длительность и структура референсов совместимы. **Привязка автоматическая; Scene ID тот же.** Робот привязывает только по точному / нормализованному совпадению промта ровно с одной активной сценой (`scripts/topview_prompt_match.py`); всё остальное — `hold` и событие в issue `topview-events` для агента / владельца. Повторный запуск существующей сцены не отбрасывается как «семантически похожий» без обновления привязки и slow.
2. **Совсем новая сцена.** Задача явно описывает сцену, которой нет среди активных Scene ID. **Новый Scene ID монитор не создаёт** (решение 10.10): он сообщает владельцу, а сцену заводит рабочий чат по ответу владельца.
3. **Неоднозначно.** Нельзя безопасно доказать 1 или 2 — ничего не менять в master, сообщить владельцу. Одно лишь смысловое сходство не даёт права ни привязать, ни молча отбросить задачу.

Routine для существующей сцены: свежие master, `project-status.json`, `topview-status.json`, `topview-task-map.json` → новые видео-задачи за вычетом известных ID и не-видео → доказать совпадение → записать привязку «задача ↔ существующий Scene ID» (задача-замена может заменить прежнюю привязку) → если задача активна (`init` / `queued` / `running` / `processing`) — добавить Scene ID в canonical slow во всех связанных местах master, сохранив редакторский и производственный статус → `success` — обновить телеметрию (`RESULT_RECEIVED`), **никогда не `APPROVED`**, slow не снимать, дубль Scene ID не создавать → `failed` — ограниченное техническое восстановление только по `ops/TOPVIEW-RETRY.md`; `cancelled` владельцем — без rerun; slow не снимать, причину сохранить → править master только если canonical slow реально меняется (или чинится устаревшая строка таблицы slow) → обычный цикл триггер / валидатор / статус / Pages.

**Импорт новой сцены по согласию владельца:** у задачи должны быть конкретный task ID, модель и доступный фактический промт; перед записью — `git pull` и свежий master; новый ID = следующий неиспользованный стабильный Scene ID; промт, фактически отправленный в Topview, сохраняется **дословно** (`PROMPT-STYLE-GUIDE.md` §18); рядом — русский заголовок, «Контекст использования», «Референсы» (если известны), «Что происходит»; имена персонажей — через `character-references.json` и текущий master; активная задача → сцена в canonical slow; `success` → `RESULT_RECEIVED`, не `APPROVED`; failed / cancelled — без авто-rerun; после записи — обычный sync, валидатор, `project-status.json`, Pages, обновление привязки и телеметрии. Автоматика не может переписывать существующий промт по смысловому сходству.

## 19. Служебные файлы сайта

Control Center → **Служебные файлы** различает **7 инструкций** (нумерация в каноническом порядке чтения 1→7: HANDOFF, Sync Runbook, Project Guide, Prompt Style Guide, User Guide, README AI Sync, Backup AI Runbook; русские названия, вертикальный список) и **3 рабочих файла проекта** отдельным блоком, вертикально в порядке master → film-analysis → film-backlog (они не инструкции и не копии). Машинная логика считает размер набора инструкций равным 7 независимо от числа ссылок в UI. Также на сайте — ссылки на оба монтажных разбора и `references.html`. После изменения проверить синтаксис JS, дубли id и Pages.

## Мониторы и расписание

**Пишет всегда один.** Роли — в `monitor-role.json` (`primary` / `standby`, `failover_after_minutes=180`, `collision_guard_minutes=50`). С 13.10.2026 (решение владельца «пускай робот всё делает»): `primary=robot`, `standby=chatgpt`, монитор Claude выключен.

- **Робот GitHub** — основной писатель телеметрии; описание — верхний блок «Робот GitHub» и `ops/ROBOT-TELEMETRY.md`. Робот никогда не подхватывает запись по молчанию другого монитора (fail-closed).
- **ChatGPT «AI Film — монитор ChatGPT»** (`6acae6ab433481919e88665c520b8ef2`, ежечасно HH:55, часовой пояс задачи Europe/Moscow; быстрый протокол — `ops/CHATGPT-MONITOR-FAST-PATH.md`) — резервный писатель: при здоровом роботе только читает (`skip`). Писать может только пока `migration_state.chatgpt_writer_eligible=true` (выдаёт владелец; без поля — запрет, fail-closed). Каждый допущенный к записи запуск оставляет реальную запись в `automation-monitor-status.json`, даже при `degraded`; ложных heartbeat не бывает. Прежний часовой монитор ChatGPT (`6aac794245e481919ee7155c461cc77e`) отключён навсегда; архивные задачи Recovery и «Свободные слоты» остаются выключенными — не включать, дубли не создавать.
- **Монитор Claude** — scheduled task «AI Film — монитор Claude» (`trig_014eEvBooAV2hxx1asRo9snm`, HH:10 МСК, процедура `ops/CLAUDE-MONITOR.md`) — **выключен**; основным возвращается только по новой команде владельца. Не удалять и не пересоздавать (теряется история).
- **Перед записью** каждый монитор выполняет `python3 scripts/monitor_role.py . --me <claude|chatgpt|robot>`: `run` — обычный цикл; `skip` — ничего не писать и запись цикла не трогать (иначе спрячется отставание основного); `failover` — скрипт сделал этого монитора основным: обычный цикл, `monitor-role.json` закоммитить с ним, в note «takeover от <прежний основной>», владельцу одно сообщение.
- **Подхват.** Резервный (ChatGPT — только при `chatgpt_writer_eligible=true`) подхватывает, если последний подтверждённый **здоровый** полный цикл основного старше 180 мин (`health=ok`, без `phases_missing`; `degraded` / ошибочный / неполный цикл часы не освежает) и другой монитор не коммитил за 50 мин. Подхватчик становится основным (sticky; `standby_yield_minutes=0`), автоматического возврата нет; робот, потерявший роль, возвращается только по команде владельца. Исполняемая процедура — `scripts/monitor_role.py`, `scripts/monitor_status.py` и `tests/test_monitor_failover.py` (входит в CI). Автоматический takeover ChatGPT без разрешения владельца запрещён.
- **Защита от одновременной записи.** 50 мин: мониторы молчат, если другой коммитил в файлы телеметрии или master (`WRITER_FILES` в `monitor_role.py`); правки документации монитор не глушат.
- **Смена ролей** — только по команде владельца («основной монитор — Claude / ChatGPT»): агент меняет `primary` / `standby`, `set_by=owner` и `set_at` и коммитит. Аварийная остановка робота — `ROBOT_TELEMETRY=shadow` и/или «основной монитор — ChatGPT» (`primary=chatgpt`, `standby=robot`).
- **Не поднимать старые мониторы и не возвращать master на Drive.**
- **Молчание.** Шаг «Alert when the unified monitor is silent for more than 3 hours» workflow `sync-from-drive.yml`: если последний подтверждённый **здоровый** цикл (`automation-monitor-status.json`: `last_successful_cycle_at`, `last_successful_by_runner`, здоровый `last_scheduled_cycle.completed_at`; при отсутствии записи — возраст `topview-status.checked_at`) старше порога, открывается одна issue `monitor-alert` (письмо владельцу) и закрывается после свежего цикла. Порог по решению D3 — 3 ч; в коде сейчас временно `LIMIT_MIN = 240` (пометка в workflow: до сброса недельного лимита 16.10, затем вернуть 180). Сигнал означает «проверить основной монитор по `monitor-role.json` и восстановить его», а не «создать дубль». Отключённая задача сама себя не включит; ручная сверка не сбрасывает оповещение.
- **Ограничения ИИ-мониторов.** Монитор ChatGPT / Claude — обычная scheduled task: платформа может её остановить; API не раскрывает причину и не даёт настройки «никогда не приостанавливать». Не выдавать prompt-запрет самоотключения за гарантию. Изменение расписания или промта сохраняет `is_enabled=true`, если владелец не просил остановить. Явное решение владельца остановить задачу выше любых правил.
- **Ручной ремонт и фоновые запуски.** Фоновый запуск не вызывает `automations.update` и не меняет расписания. Для ручного ремонта — свежее чтение / проверка версии / `git pull --rebase`, конфликтующую запись отложить; расписание не останавливать.
- **Сбой коннектора / API** — «Background connector degradation» ниже (робот — `hold` и `degraded`-цикл).
- **Уведомления владельцу** — только по событию: освободился слот, сцена технически готова, новая задача, неоднозначность, сбой или недоступность. Тихие циклы без изменений — без сообщения. Робот пишет события в issue `topview-events`.

### Порядок фаз цикла монитора

**Робот** (один запуск `topview-robot.yml`): роль и режим (`monitor_role.py --me robot`, `ROBOT_TELEMETRY`) → скан Topview API (только GET, `scripts/topview_api_scan.py`) → решение `noop` / `publish` / `hold` (`scripts/robot_telemetry.py`) → при `publish` один коммит в порядке п. 5 ниже (с минимальной правкой slow-строк master и `SYNC-TRIGGER.txt`, если нужно) → `build_project_status` `health=ok` → запись цикла `runner=robot` → push (CAS) → read-back. Сертификат инструкций, кнопки владельца и глубокую проверку робот не делает (кнопки — `sync-from-drive.yml`).

**ИИ-монитор** (ChatGPT, или Claude по команде владельца), когда он писатель:

1. Роль (`monitor_role.py`).
2. Скан Topview (read-only; основная доска `1a6244cf1ae747ef847d949a80d6133c`; для известных задач — `topview_get_board_task`, не отдельный `query_task`): каждый цикл — список досок со счётчиками задач и первая страница новых задач основной доски (`topview_light_check.py` решает `light` или `full`); полный обход всех досок и страниц — не реже раза в ~3 ч (> 170 мин), при любом расхождении счётчиков, или при `--force-full`. Оба режима — полноценный здоровый цикл. Незавершённый скан или недоступная доска — не доказанная ёмкость; `queueCount` не равен слотам.
3. Классификация задач (раздел 18).
4. Правка master — только если меняется slow-набор (`scripts/master_slow_edit.py` → валидатор → коммит в `main` вместе с телеметрией и `SYNC-TRIGGER.txt` → read-back).
5. Публикация (`scripts/monitor_publish.py`): task-map → архив операций (при переносе) → журнал → публичный статус → ledger (`result_received`) → checkpoint **последним**. Архив и журнал — один CAS-коммит, правила и оба писателя: `ops/ROBOT-TELEMETRY.md` «Архив операций».
6. Сертификат инструкций (`cert_github.py`), если старше 24 ч или инструкции менялись.
7. Решения и задачи владельца (раздел «Кнопки владельца»): детерминированные кнопки уже применяет `sync-from-drive.yml`; монитору остаются текстовые `owner_task` и неоднозначное.
8. `scripts/monitor_status.py` — честная запись цикла в `automation-monitor-status.json` (фактически пройденные фазы, `missing`, `health`).
9. Коммит одним набором → `git pull --rebase` → push → проверка CI и `project-status.health`.

Время честное: `checked_at` — реальный конец скана, назад и вперёд не сдвигается. Успех scheduled run не заявлять по ручной проверке или сохранённому промту.

## Кнопки владельца и задачи текстом

Нажатие кнопки на сайте только **записывает** решение: Supabase `ai-film-comments` → таблица `owner_decisions` через Edge Function `owner-decision` (исходник `ops/supabase/owner-decision/`; RLS без публичных политик, 5 неверных паролей в час — блокировка). Пароль — собственный пароль владельца (секрет `OWNER_DECISION_KEY`); агент его не видит и не просит. Кнопки на сайте и их смысл для владельца — `USER-GUIDE.md` §20; каждую нажимают дважды. Supabase `action` / `task_id` кнопок и двукратное подтверждение не менять.

Применение (статусы `pending` → `in_progress` / `needs_owner` → `applied` / `rejected`; `superseded` — отменено владельцем):

| Действие | Что делается |
|---|---|
| `accept` («Принять») | ledger: `reviewed`, `accepted` = true; у завершённой slow-сцены тем же коммитом снять canonical slow, сцену сохранить |
| `redo` («Переделать») | ledger: `reviewed`, `needs_redo` = true; после terminal снять прежнее canonical slow в том же коммите; новый рендер — только по отдельной команде владельца |
| `to_montage` («В монтаж») | `reviewed`, `accepted` = true, `montage_note` «в монтаж»; после terminal снять slow тем же коммитом, `inserted_into_film` не трогать; «В монтаж» ≠ «В фильме» |
| `in_film` («🎞 В фильме») | ledger: `reviewed`, `accepted`, `inserted_into_film` = true, `montage_note` «в фильме»; затем сцена убирается из активного master, Scene ID резервируется навсегда; есть активная задача — master не трогать, спросить |
| `tv_mark_status result_bad` («Брак») | `reviewed` = true, `accepted` = false, `needs_redo` = true; canonical slow не снимает |
| `tv_mark_status result_ok` («Готово ✓») | автоматически не применяется (не доказано как автоприменение) — агент / владелец |
| `scene_not_needed` («Не нужна») | закрыть сцену в master, ID зарезервировать |
| `tv_drop_task` («Не ждать») | убрать задачу из slow-учёта (`abandoned_by_owner`, `topview-task-map.json.owner_released_task_ids`), снять slow, если задача последняя; реальную задачу Topview это не отменяет и её физический слот не освобождает — отменить её в Topview может только владелец вручную; у успешно готовой строки кнопки «Не ждать» нет (13.10) |

После применения: `status='applied'`, `applied_by`, `result_note` (по-русски, 1–3 фразы). Противоречащие кнопки по одной сцене (например accept + redo) — `needs_owner`.

**Решения по завершённым slow-сценам (подтверждено владельцем 14.10.2026).** «Принять», «Переделать», «В монтаж» — явное освобождение редакционного ожидания (фаза 2, ниже): ledger и минимальный diff `video-prompts.md` — одним коммитом, затем пересборка статуса, SHA / read-back и только потом `applied`. Физически активная задача Topview, нет подтверждённого terminal или открытая `owner_task` → запись отложена; противоречивые решения → `needs_owner`. Сцена остаётся в активном master; «Переделать» рендер не запускает; физический слот не освобождается; технический `success` одобрением не считается. Старые уже применённые решения автоматически не переписываются — проверять отдельно.

**Робот GitHub** (Actions, без ИИ). Job `owner_decisions` в `.github/workflows/sync-from-drive.yml` при каждом запуске (Supabase `pg_cron` :02/:12/…, запасное расписание `11,41 * * * *`, ручной запуск и прямой push человека; обычно в пределах 15 минут после нажатия) применяет однозначные кнопки: фаза 1 (`scripts/process_owner_decisions.py`) — `tv_mark_status result_bad` («Брак») → только `review-ledger.json`; фаза 2 (`scripts/robot_master_actions.py`) — `accept` / `redo` / `to_montage` (подтверждённый terminal) → одной проверенной записью ledger + canonical slow master + статус; также `in_film` / `scene_not_needed` / `tv_drop_task` → минимальный коммит master + `project-status.json` + `SYNC-TRIGGER.txt`. Фаза 2 **включена по умолчанию** (`ROBOT_MASTER_ACTIONS=${{ vars.ROBOT_MASTER_ACTIONS || 'on' }}`; разрешение владельца 12.10 на автоматическое применение «🎞 В фильме»); GitHub Variable `ROBOT_MASTER_ACTIONS=off` приостанавливает её. «В фильме» = принятие сцены владельцем, запись в ledger, удаление из **активного** GitHub master и с сайта, пожизненное резервирование Scene ID; готовые видео и история не удаляются. Гарантии: дублированные нажатия группируются; конфликт, активная задача Topview или неоднозначность останавливают действие; зелёный валидатор; CAS push; `applied` ставится только после проверенного push, `health=ok` master / статуса и GitHub read-back (**до** отметки в Supabase); push отклонён → всё с нуля; Pages должен опубликоваться. Генерации робот не запускает. Реальное исполнение подтверждать отдельным GitHub / Supabase read-back. Записи `in_progress` с `result_note`, начинающимся `github-owner-sync:`, принадлежат роботу — монитор их не трогает. При включённой фазе 2 монитор не обрабатывает `in_film` / `scene_not_needed` / `tv_drop_task`. `needs_owner` без изменений: у сцены активная задача Topview; противоречащие кнопки; открытая `owner_task` по сцене; нет строки в ledger; нераспознанный формат master; «Не нужна» при зависимых сценах.

**Причина ожидания на сайте (18.10.2026).** Если фаза 2 откладывает кнопку (активная задача Topview, нет terminal и т. п.), строка остаётся `pending`, а `result_note` = «Ждёт: <причина>. Применю автоматически, когда это изменится» (пишется один раз, без повторов).

**`owner_task`** — свободный текст владельца (до 2000 символов; номер сцены необязателен). Это его решение, но правил безопасности он не отменяет. Разбор:
1. Мелкое и однозначное — сразу, `applied` + `result_note`.
2. Точная правка промта — каноническим циклом (раздел 3), не больше одной за цикл.
3. Большое — `in_progress` с коротким планом; делать по частям или в рабочем чате.
4. Творческий выбор, неясность или то, что требует отдельного разрешения (запуск генераций и кредиты, удаление, закрытие сцены, approve без кнопки, изменение архитектуры) — `needs_owner` с одним коротким вопросом и вариантами.

`owner_task` выполняет агент, а не робот. **С 18.10.2026 робот доставляет:** фаза 3 (`scripts/robot_site_actions.py`) переносит каждую новую `owner_task` во входящие `ops/owner-tasks.json` с адресатом из `value` (`claude` / `chatgpt` / `any`, по умолчанию `any`) и ставит строке `in_progress` с `result_note` «site-inbox: …». Агент берёт и закрывает задачу в этом файле (`taken` → `done` / `needs_owner` / `cancelled`, порядок — `ops/OWNER-TASKS.md`); робот переносит итог обратно в Supabase (`applied` / `needs_owner` / `superseded`), и владелец видит его на сайте. ChatGPT читает файл на каждом часовом цикле. Claude с 26.10 запускается сам: новая задача `to: claude` (и `any`, не взятая 3 ч) → фаза 3b `scripts/claude_task_wake.py` вызывает задание Claude по API (`ops/claude-wake.json`, секрет `CLAUDE_FIRE_TOKEN`); задачи друг другу агенты тоже пишут в этот файл (`ops/OWNER-TASKS.md` «Задача от агента агенту»). Takeover нового чата по-прежнему читает открытые строки (`pending` / `in_progress` / `needs_owner`).

**Фаза 3 — кнопки сайта (18.10.2026, `scripts/robot_site_actions.py`, тесты `tests/test_site_actions.py`).** Очередь запуска: `queue_up` / `queue_down` меняют местами сцену с соседней (сдвигаются полосы `priority` её ожидающих элементов и `new_scene_order`; запущенные, отменённые и `superseded_*` не трогаются; в `selection_policy` один раз добавлено «OWNER SITE ORDER … priority wins»; журнал — `owner_site_actions`, последние 100); `queue_remove` → state `held_owner_site` с `previous_state_before_site_hold`; `queue_add` возвращает убранную сцену, снимает `blocked_owner_decision` → `waiting_for_slot`, а сцену без элементов очереди превращает в задачу `any` во входящих. Правка очереди — только при свободном замке канона; при занятом строка остаётся `pending` с причиной «Ждёт: канон занят …». `ref_feedback` (кнопки у картинок на `references.html`): «подходит» → `references/reference-review.json`; «перерисовать» с комментарием → там же и задача `chatgpt` во входящих. Закрытые задачи через 14 дней сначала сохраняются целиком в архив и только затем убираются из входящих; порядок и восстановление — `ops/OWNER-TASKS.md`. История задач с сайта дополнительно есть в Supabase. Отметка в Supabase — только после push и read-back; отклонённый push → всё с нуля.

## Canonical Topview state — minimal operational model

- **Scene ID** — творческая сцена; **Topview task ID** — одна попытка рендера. Перерендер или правка промта той же сцены сохраняет Scene ID.
- Постоянное состояние минимально: `topview-task-map.json.active_by_scene` — только активные ID задач по сценам; `processed_tasks` — ограниченный журнал дедупликации (`task_id`, `scene_id`, `final_status`, `finished_at`, не больше 200); истории очередей и ETA и деревьев `attempts[]` нет.
- Новая активная задача (`init` / `queued` / `running` / `processing`) существующей сцены добавляет тот же Scene ID в canonical slow (Scene ID в slow один раз, задачи — все в `active_by_scene`). Сцена в canonical slow имеет `render_state=SLOW_PENDING` и остаётся там до решения владельца, даже когда активных задач нет.
- Терминальная задача (`success`, `fail`, `failed`, `cancelled`) убирается из активного состояния и попадает в журнал; её слот освобождается. Canonical slow при этом не снимается (верхний блок «Canonical slow снимает только владелец»); slow «по догадке» не меняется.
- `topview-status.json` компактен и содержит `active_tasks[]` — по объекту на каждую задачу, активную прямо сейчас, плюс совместимый снимок текущей сцены и `active_task_ids`; без истории.
- Таблица slow на сайте — **одна строка на активную задачу / занятый слот**; один Scene ID может повторяться. Строки завершённых задач сцен, ещё ждущих решения владельца, показываются как готовые («✅ Готово») или ошибка и слот не занимают.
- Новый Scene ID — только для действительно новой творческой сцены и только с согласия владельца.
- Глобальные слоты считаются по полному скану всех досок аккаунта (VIDEO) и уникальным активным задачам безлимитного режима (`useUnlimitMode=true`); сцены проекта — только по доказанным привязкам AI Film. Чужой задаче Scene ID не придумывать; активная задача не с доски AI Film, занимающая слот, — сообщить владельцу, противоречивые счётчики не публиковать.

Принцип: хранить только то, что нужно для корректности и дедупликации; подробная история рендеров — не постоянная сущность проекта.

### Точное ТЗ — Topview slow slots, capacity = 6

1. **Ёмкость:** максимум **6 одновременно активных задач**; `slot_capacity = 6`.
2. Каждый `task_id` в `init` / `queued` / `running` / `processing` занимает **ровно 1 слот**.
3. Число unique Scene ID в `slow_scenes` и число занятых слотов — разные счётчики; число сцен нельзя выдавать за число слотов.
4. Одна сцена, запущенная 2–3 раза, — одна canonical-сцена, 2–3 занятых слота и 2–3 строки таблицы.
5. **Заголовок на сайте** рядом с «⏳ Сейчас в медленной генерации — Topview»: `занято X из 6 · свободно Y · DD.MM.YYYY, HH:MM:SS` (`X` — число реально активных `task_id`; время из `topview-status.json → checked_at` в локальном формате; обычным цветом и начертанием; метку «синхр.» не показывать; `free_slots` остаётся в JSON). Верхняя карточка: крупно `M из 6` («Занято слотов Topview»), ниже `Свободно Y · N сцен`; `M = len(active_tasks[])`, `Y = max(0, 6 − M)`, `N = unique(active_tasks[].scene_id)`. Не возвращать старый вариант, где свободные слоты скрыты или карточка считает только unique slow-сцены.
6. **Таблица:** 8 колонок — `#`, `Сцена`, `Модель`, `Статус`, `Запуск`, `Прошло`, `Очередь`, `Оценка времени`; колонку `Attempt` / `Task ID` не добавлять.
7. **Телеметрия** `topview-status.json`: `slot_capacity`, `occupied_slots`, `free_slots`, `active_tasks[]` (минимум `scene_id`, `task_id`, `model` / `model_id`, `topview_status`, `started_at`, `checked_at`, `queue_count`, оценки провайдера, уверенность привязки — если известны).
8. Очередь, ETA, статус и время запуска строки берутся **только** из её `task_id`: не усреднять и не переносить между параллельными попытками.
9. Сцен-уровневые поля снимка — для совместимости; они не источник счёта слотов.
10. Терминальная задача немедленно перестаёт занимать слот (убирается из `active_tasks[]` и `active_by_scene`).
11. Slow lifecycle: слот освобождается при terminal задачи; canonical slow сцены снимается только кнопкой владельца (не по terminal последней задачи).
12. **Over-capacity:** если `occupied_slots > 6`, показать фактическое `занято X из 6`, считать это предупреждением и уведомить владельца.
13. Это правило не возвращает постоянную историю `attempts[]`.
14. Проверка сайта и состояния: `occupied_slots == len(active_tasks[]) == sum(len(active_by_scene[...]))` и `free_slots == max(0, 6 − occupied_slots)`; с числом unique `slow_scenes` не сравнивать.

### Публикация Topview в трёх представлениях

Каждый успешный цикл монитора обязан не только прочитать Topview, но и **опубликовать свежий `topview-status.json`**, даже если Scene ID не изменились, а поменялись только `checked_at`, статус, очередь или ETA (у робота — по правилу пульса 50 минут, верхний блок). Три представления на сайте — `РЕВИЗИЯ / ТЕКУЩИЙ СТАТУС`, `⏳ В медленной генерации — Topview`, `🎬 Активные сцены проекта — карта и навигация` — читают **один и тот же** `topview-status.json.active_tasks[]` и один `checked_at`; трёх независимых копий live-состояния нет. `project-status.json` и master — только проверка согласованности slow, но не источник реального времени.

Для каждой активной задачи публикуются: `task_id`, `scene_id`, `topview_status`, `queue_count`, ETA провайдера, `started_at` / `completed_at`, `checked_at` цикла, `occupied_slots`, `free_slots`, кратность по сценам. Изменение только очереди / статуса / ETA — не no-op: без новой записи снимка цикл считается незавершённым.

Отображение: `init` / `queued` → **В ОЧЕРЕДИ**; `running` / `processing` → **ВЫПОЛНЯЕТСЯ**; терминальная задача слот не занимает; при нескольких задачах сцены кратность обязательна (`20×2`, «2 задачи»), смешанные статусы показываются как смешанное состояние. Кардинальность: ревизия — «N unique slow-сцен / M активных задач»; занятые слоты — ровно M активных задач; кратность сцены — число её активных задач. Число slow-сцен и число активных задач не обязаны совпадать (slow держится до решения владельца). «5 slow-сцен / 6 задач» корректно, только если видно, какая сцена занимает два слота.

### Publish gate

Цикл монитора успешен, только если одновременно:
- canonical slow в master (объявление, счётчик, таблица, оглавление, метки сцен) `== project-status.json.slow_scenes`; каждый `active_tasks[].scene_id` — активная сцена master (slow-набор и активные задачи не обязаны совпадать: slow снимает только владелец);
- `topview-task-map.json.active_by_scene` совпадает с `active_tasks[]` (те же task ID и Scene ID);
- `occupied_slots == len(active_tasks[]) == число строк активных задач в таблице` (строки завершённых задач слот не занимают); `free_slots == max(0, 6 − occupied_slots)`;
- кратность сцены на сайте равна числу её активных задач;
- статус сцены «В ОЧЕРЕДИ / ВЫПОЛНЯЕТСЯ» вычислен из тех же статусов задач;
- три представления относятся к одному `checked_at`;
- свежий `topview-status.json` реально закоммичен и Pages не оставлен на заведомо старом снимке.

Если запись изменила canonical slow или master — дополнительно обычный `SYNC-TRIGGER.txt` → валидатор (`build_project_status`: `health=ok`). Если менялись только очередь / статус / ETA — master не переписывается, но свежий `topview-status.json` и Pages обязательны. Расхождение хотя бы по одному пункту: цикл не завершён, сайт не зелёный; владельца не просят сравнивать вручную.

### Транзакционный порядок публикации

Монитор сначала считает полное состояние в памяти и публикует строго так:

A. если реально меняется canonical slow — свежий master → минимальная правка → read-back;
B. внутренний `topview-task-map.json` + компактный журнал → read-back;
C. публичный `topview-status.json` из того же состояния → read-back;
D. `topview-checkpoint.json` **последним** — с тем же `checked_at`, active task IDs, unique Scene ID и занятыми слотами;
E. только после checkpoint — обычный sync-trigger, если менялся master или slow.

Не прошёл B — C и D не выполняются; не прошёл C — D не выполняется. Checkpoint поверх частичного состояния не двигать. `topview-status.json` — единственный публичный runtime-источник; `topview-task-map.json` — внутренний кэш (UI из него не строится); `topview-checkpoint.json` — стабильный маркер фиксации, интеграционные тесты запускаются по нему, а не на промежуточных коммитах. Свежая запись журнала или успешная синхронизация master не доказывают обновление Topview: перед успехом нужен read-back map / status / checkpoint с совпадающими `checked_at`, `updated_at`, `last_scan_at`, task IDs и счётчиками. Успешный запуск automation свежесть не доказывает — доказывает только продвижение публичного `topview-status.json.checked_at`.

### Background connector degradation

Если Topview-коннектор недоступен именно в фоновом запуске: монитор **не отключает себя**; не выдумывает статус, очередь, ETA; не обновляет `checked_at`, `last_scan_at`, checkpoint; не меняет canonical slow по догадке; сохраняет последний подтверждённый снимок, записывает конкретный сбой (робот — `hold` и `degraded`-цикл), выполняет остальные доступные фазы и повторяет в следующем цикле. Это честное состояние «Topview telemetry stale / degraded», а не ошибка синхронизации master. Если публичная свежесть превышает 3 ч на нескольких циклах — один конкретный сигнал (`monitor-alert`), а не бесконечное молчание.

## Reliability write contract

- **Один писатель на домен.** Телеметрия, производная от Topview (`topview-task-map.json`, `topview-status.json`, `topview-checkpoint.json`, Topview-поля `project-status.json`, переходы canonical slow), — только активный монитор по `monitor-role.json`.
- **Оптимистичный конфликт:** источник изменился после подготовки — выбросить заготовку, перечитать, пересчитать, повторить один раз; при записи в GitHub использовать свежий SHA файла. Никогда не воспроизводить устаревшее целое тело поверх нового.
- **Read-back:** после каждой записи прочитать путь из `main` и проверить смысл и хеш до пересборки зависимых артефактов и до отчёта.
- Остальное — раздел 2.

## Review / montage ledger — постоянный контракт

`review-ledger.json` отделяет техническое получение рендера от редакторских и монтажных решений человека; он не переопределяет master, телеметрию Topview или реальный монтаж. На каждую сцену — пять независимых фактов: `result_received`, `reviewed`, `accepted`, `needs_redo`, `inserted_into_film`. Технический `success` Topview может выставить только `result_received=true`. Человеческие поля остаются `null`, пока явно не известны. `inserted_into_film=true` требует `reviewed=true` и `accepted=true`; `accepted=true` вместе с `needs_redo=true` недопустимо. Схема `schema_version 2` (поля `selected_result_task_id`, `result_url`, `film_version`, `insert_timecode`, `export_reviewed`); новые строки создаются сразу по ней.

`Reconcile review ledger` добавляет новые активные Scene ID и продвигает `result_received` по проверенному `processed_tasks`; он никогда не выводит и не перезаписывает редакторские поля. `Validate review ledger` блокирует противоречивое состояние. При конкурентном писателе — безопасная пересборка от свежего `origin`, не слепой повтор.

## Валидатор, health и Control Center

**Пять независимых health-доменов** (нельзя сворачивать в один красный «ошибка синхронизации»):
1. **Канон** — master и `project-status.json`, blob-сверка 7 инструкций в `main`. Красный — только при реальной поломке (health ≠ ok, SHA загруженного master ≠ статус, подтверждённое расхождение инструкций, ошибка чтения). Подтверждённое расхождение инструкций или ошибка чтения 7 из 7 — блокирующие.
2. **Телеметрия Topview** — возраст снимка, очередь, доступность коннектора: операционная, не блокирующая, показывается отдельно.
3. **Кэш `topview-task-map.json`** — внутренний; временный дрейф — обслуживание (`project-status.json.maintenance.topview_task_map`), не порча.
4. **Возраст сертификата** — обслуживание; старый `checked_at` не расхождение.
5. **Резервные копии / Library** — best-effort, не блокируют.

**Правила валидатора и сайта:**
- `project-status.json` публикуется даже при health ≠ ok (сгенерированный нездоровый статус записывается честно, затем workflow сообщает об ошибке). Если валидатор упал, статус не созданный текущим запуском, нечитаемый или с чужим SHA master не публикуется как свежий.
- Control Center зелёный только когда загруженный master соответствует `project-status.json.canonical_master_sha256`.
- Индикатор: **красный** — только проблема канона; **жёлтый** — канон в порядке, но `topview-status.json.checked_at` или `automation-monitor-status.json.last_scheduled_cycle.completed_at` старше 120 мин, отсутствует, некорректен, более чем на 10 мин в будущем, либо цикл не `ok`. Отсутствие файла монитора не окрашивает статус. Жёлтый на старых данных — верное поведение.
- Зелёная метка — `ПРОЕКТ СИНХРОНИЗИРОВАН`, красная — `ОШИБКА СИНХРОНИЗАЦИИ`; устаревший сертификат, устаревшая телеметрия, прошлые сбои CI и устаревшие копии глобального красного не дают.
- Пороги `scripts/check_public_freshness.py` (read-only, без доступа к Topview, не освежает метки; вызывается из `sync-from-drive.yml`, отдельного workflow-watchdog свежести нет): Topview 105 мин, сертификат 165 мин, master-sync 240 мин (`--master-limit 240`). Пульс-коммит синхронизации (`sync-from-drive.yml`) при неизменном master — не чаще раза в 3 ч (`HEARTBEAT_MIN = 180`, решение D5), смена содержимого публикуется сразу. Пульс телеметрии робота — 50 мин (`HEARTBEAT_MIN = 50` в `robot_telemetry.py`), раньше порога «устарела» 120 мин.
- `ci-status.json` публикует workflow `sync-from-drive.yml` (шаг «Publish CI state change for the Control Center»): `last_conclusion`, `last_failure_at`, `last_failure_run_url`, `last_success_at`, только при смене результата. Сайт к `api.github.com` не обращается.
- Дословные метки master для валидатора: поле `**Последняя полная синхронизация:** **...**` и отдельная метка `**⏳ В МЕДЛЕННОЙ ГЕНЕРАЦИИ**` в оглавлении и в теле каждой slow-сцены (в карточке — ровно одна, без технического хвоста, верхний блок «Одна метка slow»); число параллельных попыток (`Scene 27 × 2`) писать **вне** жирной метки.
- `revision_date` вычисляется, а не вводится вручную: `build_project_status.py` (флаги `--previous-status-file`, `--previous-master-file`, `--revision-timezone Europe/Moscow`) считает `canonical_revision_sha256`; при семантическом изменении ставит дату текущей синхронизации, при отсутствии — сохраняет прежнюю. Если хеш предыдущего опубликованного статуса отличается от текущего semantic master, дату обновлять (даже если `--previous-master-file` ошибочно указывает на текущий master): валидатор доверяет предыдущему опубликованному статусу, а не сравнивает мастер с самим собой. Строку `**N сцен ... · M полных текста промта**` держать без ручной даты. `project-status.json.revision_date` вручную не править.
- Пустые строки: в master не более одной пустой строки подряд (нормализация: единые переводы строк, серии 2+ пустых строк сводятся к одной, текст промтов не менять). Ревизионный отпечаток игнорирует переводы строк и пустые строки, поэтому чистка вёрстки дату ревизии не двигает. После нормализации проверить число сцен, число блоков кода, ID и якоря.
- Тесты не закрепляют конкретный live slow-набор как вечный; production-снимок проверяется общими инвариантами, переходы — на синтетических фикстурах. `instruction-sync-status.json.github_blob` сверяется с реальным git-blob файла.
- Реестр `character-references.json`: поле `scenes` — текущее использование в активных сценах (не архив); пути к файлам вместо data URI. Миниатюры `references/thumbs/` — только для показа: `build-thumbnails.yml` при push в `references/**` собирает WebP ≤ 640 px и `references/thumbs/manifest.json` (SHA-256 источника); сайт подменяет `src` на миниатюру, ссылки ведут на оригинал, при ошибке — откат на оригинал. Оригиналы и реестр обратно в base64 не менять.
- Markdown рендерит локальный `vendor/marked-15.0.12.min.js` (без CDN); HTML master проходит `safeHtml()` (удаляет script / iframe / object / embed / form, `on*`-атрибуты, `javascript:`-ссылки). `api.github.com` и CDN-версий `marked` в `index.html` быть не должно.
- Свежесть синхронизации master и `topview-status.json.checked_at` независимы: успешная синхронизация не доказывает обновления слотов; `project-status.synced_at` не подтверждает свежесть Topview или сертификата.
- `NEEDS_FIX` — не разрешение на автоматическую творческую перепись. Массовая автоперепись промтов по validator / audit запрещена: сцены разбираются по одной с решением владельца.
- Не вводить без отдельной реальной необходимости: второго конкурирующего писателя, тяжёлую постоянную историю попыток Topview, автоматический rerender, автоматическое редакторское принятие, миграцию референсов в base64 ради размера, сложные anti-spam-автоматы.

**Фильтры Control Center.** Левая панель строится только из актуальных `project-status.json.scene_meta` и активных сцен; закрытые сцены фильтров не создают. Все названия фильтров — по-русски (английский тег без русского label / group mapping не показывать). Перед добавлением фильтра проверить весь набор тегов активных сцен (частоту, смысл, дубли, синонимы, пересечение с `production_state`, движком, диалогом, зависимостями, slow). Одинаковые по смыслу теги — один фильтр (`comedy` + `deadpan_comedy` + `fantasy_comedy` → «Комедия»; музыкальные теги → «Музыкальный номер»). Узкие теги, ведущие к одной сцене, остаются метками сцены; исключение — явная рабочая ценность («Музыкальный номер», «Альтернативный вариант», «Ручная проверка»). Фильтр не дублирует состояние workflow (`needs_fix` ≠ `production_state=NEEDS_FIX`; `dialogue` ≠ основной «Диалог»). После существенного изменения сцен или тегов — filter audit, затем read-back `index.html`, `validate_site.py` и Pages. Базовые группы: «Экшен», «Комедия», «Непрерывный дубль», «Связность сцен», «Музыкальный номер»; список пересматривается по свежим сценам.

**Прочие контракты UI.** Карточка рабочих направлений показывает только число (сырые `W5…W15` в сводке и отпечатке не выводить). Левое меню информационно полное, но компактное (Service Files и Filters свёрнуты); активный фильтр виден. После прокрутки — плавающая «↑ Наверх». Метрика `Промтов` ведёт к `#full-prompts`, вставленному перед первым активным заголовком сцены (не жёстко к Scene 1). В светлой теме `.analysis-picker > summary` использует палитру светлой кнопки. В chooser «Монтажный разбор» два пункта: «Первая версия» (17.09.2026, `Seregius_montazhny_razbor.html`) и «Вторая версия» (24.09.2026, дата отчёта в самом HTML, `Seregius_montazhny_razbor-2.html`); обе версии должны оставаться опубликованными. Кнопки владельца в таблице Topview («Не ждать / Готово ✓ / Брак» и действия завершённых задач: Принять / Переделать / В монтаж / В фильме / Брак) — компактные горизонтальные `.owner-btn` в колонке «Сцена» под названием (`tr.cells[1]`, с 12.10; не возвращать в колонку «Статус», `tr.cells[3]`); на узких экранах ряд кнопок прокручивается вбок; у успешно готовой строки кнопки «Не ждать» нет (у активных задач, строк с ошибкой и «ждёт решения» — есть). Успешно готовые строки — зелёные «✅ Готово», ошибки — красные; автоскрытие строк по сроку (21 день) или только по признаку `reviewed` запрещено, пока владелец не решит. «▶ Версия N» (в карточке «▶ Ролик N») ведёт к задаче в проверенной доске Topview — это **не архив MP4**; версии строятся из `topview-task-map.json.processed_tasks`, последние результаты — из `topview-status.json.scenes`; рядом «💾 Drive N» (таблица) и «💾 MP4 N» (карточка) — копия в приватном Drive; открывают `videos.html?task=` (все копии по сценам, кнопка «📼 Ролики по сценам»), поток — Supabase `drive-video` (`ops/supabase/drive-video/`), потому что Drive не отдаёт видео чужим сайтам; `video.html` — только переадресация. Подписанные временные URL роликов в публичные JSON и на Pages не помещать. Технические строки автоматики (номера задач, «init, unlimited 0 credits», «технически завершён», «Правило владельца (11.10.2026)») в карточке скрыты; ссылки на ролики — строкой «Ролики:» под кнопками. Подписи «Промт: <target_engine>» / «Рендер: <model>». Подписи источника: «GitHub main — канон · Drive — копия»; одна строка чипов `Ревизия · Master · Topview · Монитор · Инструкции · Синхронизация`, детали в подсказках; чип «Монитор» читает `automation-monitor-status.last_scheduled_cycle`, «Успешный цикл» — `automation-monitor-status.last_successful_cycle_at` (запуск без завершённого цикла успехом не считается; чип показывается, только если его время отличается от «Topview» больше чем на 2 мин; отдельного чипа «Неполный цикл» нет — это пишет плашка состояния, возраст цикла в её подсказке); «Проверка GitHub» — возраст `project-status.json.synced_at` по master из GitHub `main`; «Инструкции» — сертификат семи инструкций GitHub; Drive — только резервная копия. Эти правила проверяют `validate_site.py`, `tests/site_status_check.js` и `tests/test_recovery_integration.py`.

## Scene Reference Pack automation

**Reference-first.** Для новой или существенно изменённой сцены до финального промта или отправки в Topview определить минимальный набор референсов: листы персонажей, точная локация, реквизит, первый / последний кадр непрерывности, позы и композиции. Сначала использовать утверждённые активы; не пересоздавать хороший утверждённый кадр без творческой причины.

**QC по одному кадру.** Сцен-специфические кадры генерируются по одному. После каждого проверить: личность, возраст, волосы / шерсть, одежду, пропорции, число персонажей, право-лево, геометрию локации, освещение, позу. При дрейфе отклонить и продолжить другим методом. Для многоперсонажных сцен — проверенные малые подгруппы, затем итоговая группа; листы персонажей приоритетнее вспомогательных композиций.

**Save-before-next.** Как только кадр принят как полезный, сохранить его **до** следующего: в GitHub `references/scenes/scene-N/` (канон; используется на сайте) и описать в manifest сцены; сохранность во внешних копиях — по `BACKUP-AI-RUNBOOK.md`. Файл в scratch или превью чата сохранением не считается: нужен commit / push / read-back. Папка Drive `Scene Reference Packs` — только обменный канал для изображений, которые готовит ChatGPT (не канон): оттуда Claude берёт кадр как обычный референс. Сайт показывает референсы компактными миниатюрами со ссылкой на полный файл; полноразмерная картинка прямо в сцене — регресс. Отклонённые, дублирующие или смешавшие лица кадры не публиковать как утверждённые.

**Манифест сцены.** `references/scenes/scene-N/manifest.json` (и общие `scene-reference-plan.json` / `.md` — текущий аудит, каким активным сценам нужны дополнительные кадры, и `scene-reference-sources.json`) — целевой набор полей: `identity_refs`, `location_refs`, `prop_refs`, `start_frame`, `end_frame`, `pose_composition_helpers`, `approved`, `rejected`, `topview_source_provenance`, `prompt_reference_mapping` (`@ImageN` / `@VideoN`), `site_published`, sha256 / file IDs, `last_qc_at`. Нумерация `@ImageN` локальна для каждого автономного промта (у Scene 28 — 20 разных маппингов); маппинг задаётся по каноническим ролям, а не по историческому имени файла `ImageN`; исторические Topview ImageN и текущие prompt slots различать явно. Визуальную проверку ассистента отделять от approval владельца. Команда «создаём сцену N» = автоматический аудит референсов + предложение / создание недостающих; «запускай сцену N» = манифест → маппинг промта → проверка Topview → отправка.

**Существующие сцены Topview.** Не просить владельца повторно загружать то, что доступно в Topview: точные входные изображения задачи восстанавливаются из метаданных доски / S3 через авторизованный Reference Bridge (`BACKUP-AI-RUNBOOK.md` «Scene Reference Pack — восстановление»), происхождение записывается в manifest, предлагаются только аддитивные улучшения. Topview — телеметрия и происхождение, не авторитет сюжета.

**Команда запуска.** «Запускай сцену N» означает: свежий master и статус → найти пакет и промт сцены N → проверить или создать действительно недостающие референсы → при необходимости обновить маппинг → живая проверка Topview (модель / режим входа, шесть слотов, безлимит или кредиты) → отправить генерацию. **Запуск генераций — только по команде владельца, в безлимитном режиме через сайт Topview под входом владельца; платные credits (кредиты) не тратить** (платный путь, в том числе Canvas / MCP submit, запрещён; параметр `useUnlimitMode` в коннекторе не поддерживается). Не тратить кредиты молча на вспомогательные изображения: использовать подтверждённо безлимитный путь или остановиться до отправки и сообщить ограничение. Technical success не означает approval.

**Практический веб-запуск и условный следующий ролик.** Проверенный маршрут ChatGPT Work / веб-Topview, импорт файлов, бесплатные 720p, проверка полного промта и task ID, подготовка недостающих референсов и защита от повторной отправки — `ops/TOPVIEW-FREE-LAUNCH.md`. Фоновое задание не гарантирует браузер/вход; если они недоступны, фиксирует блокировку и сообщает, не заменяя сайт платным API. Текущая разрешённая очередь — `ops/topview-launch-queue.json`: все подготовленные сцены по свободным слотам; первый запуск по бюджету item, до двух дополнительных технических попыток по `ops/TOPVIEW-RETRY.md` (30.10), затем следующий независимый готовый item без простоя. Наличие записи не означает состоявшийся запуск; после каждого submit сохранять проверенный receipt и продолжать следующие готовые items.

**Длинная работа — по контрольным точкам:** структура пакета → восстановление источников → генерация и QC новых референсов → публикация на сайте → инструкции / handoff / проверка. Каждая завершённая точка сохраняется до следующей; преемник продолжает с первой незавершённой по handoff и `scene-reference-plan`.

**Цикл публикации референса:** принятый кадр → `references/scenes/scene-N/` + manifest → компактная миниатюра и ссылка в том же разделе сцены master → `SYNC-TRIGGER` → проверка хеша master, `project-status.json` и Pages.

## Workflows и тесты

Карта workflow и скриптов — `README-AI-SYNC.md` «Компоненты и workflow». Локальные проверки: `python3 -m unittest discover -s tests`, `python3 scripts/validate_site.py .`, `node tests/site_status_check.js` (с `python3 -m http.server 8765`), `python3 scripts/cert_github.py .`, `python3 scripts/build_takeover_brief.py . shadow`, `python3 scripts/canon_health.py .`.

## CLAUDE.md — адаптер Claude Code

Корневой `CLAUDE.md` — не-канонический bootstrap, не восьмая инструкция: `README-AI-SYNC.md` «Claude Code bootstrap adapter».

## Бриф для короткого приёма (D7; папка `shadow/`, не authority)

`shadow/` (`takeover-brief.md/.json`, `current-checkpoint.md`) строит `scripts/build_takeover_brief.py` в workflow `shadow-brief.yml` (своего расписания нет: запускается при изменении 7 инструкций, master, `instruction-sync-status.json` и после каждого запуска `Canonical master check and owner buttons (GitHub main; Drive is only a copy)` (`sync-from-drive.yml`); коммитит только при изменении содержимого). Это производный навигатор: якоря инвариантов в инструкциях проверяются кодом (должно быть 15 из 15; при переименовании заголовка обновить `INVARIANTS` в скрипте), `valid` требует совпадения хешей с сертификатом и `project-status`. Brief не authority и не часть 7/7; не править вручную; падение workflow на health проекта не влияет. Короткий приём D7 принят владельцем 14.10.2026; пилот завершён, журнал — `shadow/pilot-log.md`. Валидный бриф допускает короткий приём по правилам `AI-PROJECT-GUIDE.md` «Формат takeover и решение D7»; при невалидном брифе, правке инструкций, изменении workflow, восстановлении или сомнении обязательно полное чтение. Отмена D7 — только решением владельца с возвратом правила «только полный приём»; удалять рабочие файлы брифа автоматически нельзя.

## История

Журнал решений — `NEW-CHAT-HANDOFF.md` (журнал) и `git log`; полные прежние тексты — `archive/instructions-before-cleanup-2026-10-14/`. Из действующих правил убраны (справка): запись канона на Google Drive и сверка Drive↔GitHub, ключ `GDRIVE_SA_KEY`, локальный диск владельца, часовые схемы ChatGPT-монитора, Recovery и slot-watcher, двухуровневые расписания, ежевечернее обслуживание Claude 21:40.

## Дополнительный исполнитель Grok · 01.11.2026

Зарегистрированный Grok Bot работает с тем же каноном, замком и очередью; профильные правила, дневное окно, Telegram, один Create и проверка первого запуска — `ops/LAUNCHER-COORDINATION.md`. Наблюдение Grok (часть запусков в :12/:27/:42/:57) только читает и уведомляет, роль `monitor-role.json` не меняет. Тишина при полных слотах — отдельное решение для Grok, не отмена ChatGPT receipts. Текущие инструкции/настройки/выполнение проверяются раздельно; семантический аудит — `reports/grok-integration-review-2026-11-01.json`.

## Общая работа с Grok · 01.11.2026

Входы всех исполнителей: GitHub images/master/manifests + Google Drive MP4, реестр `ops/shared-inputs.json`; не оставлять готовый обязательный стык только в Library. Перед отправкой скачать из основного shared источника, проверить SHA/длительность/QC и соответствие слотов. После изменения очереди/входов: `python3 scripts/queue_readiness.py .` и `python3 scripts/shared_input_registry.py .`; реестр производный, не новое разрешение. Действующие потребление run/message IDs и ночные роли — `ops/LAUNCHER-COORDINATION.md`; файлы очереди и ledger публиковать одной CAS-транзакцией.

Задачи сайта для Grok · 01.11.2026 03:04. Владелец: «Делай сразу оба: быстрый способ и добавь Grok в список «Кому» на сайте». Адресат `grok` есть в форме сайта, allowlist Edge Function `owner-decision` и `robot_site_actions.py`. Grok Bot берёт `to: grok`, `to: any` и `to: claude` старше 3 ч по тем же правилам захвата, что ChatGPT (маленький коммит `taken`, `taken_by: grok:<кратко>`, затем `done` / `needs_owner` / `cancelled`; первый записавший владеет; `taken` не трогать), опрос — рутина «Поручения: Telegram и задачи с сайта» каждые 10 минут с 08:00 до 23:50 Europe/Amsterdam (±5 мин; сервер срабатывает в :05, :15, …, :55; решение владельца 01.11.2026 03:16: «И В инструкциях поправь свое время»). Платные Topview-запуски по-прежнему только по отдельному «да» владельца; неоднозначное — `needs_owner`. Подробности — `ops/OWNER-TASKS.md`.

Расписание Grok · 01.11.2026 03:16. Владелец: «Объединяй обе пары, пусть будет три рутины»; «И В инструкциях поправь свое время». Grok Bot работает по трём рутинам (Europe/Amsterdam): «Поручения: Telegram и задачи с сайта» — каждые 10 минут 08:00–23:50 (±5 мин); «Topview: наблюдение и запуск сцен (grok)» — :12, :27, :42, :57, 08:12–23:57, сцены запускаются только в :12 и :27 (окно :10–:40); «Утренняя сводка в Telegram» — 09:00. Прежние часовой опрос :40 и монитор :00/:30 заменены. Правила запуска не менялись; подробности — `ops/LAUNCHER-COORDINATION.md`.
