# Задание для Grok, круг 3: приёмка с интеграционными тестами, конфликты веток, сценарий переноса арендатора - Репозиторий: https://git.ochenstarik.ru/ochenstarik/krona-staff - Основа: `codex/bootstrap-platform-foundation` (`f5ac179`) - Итоги приёмки: `docs/audit/2026-09-26/ACCEPTANCE-2.md`. Ветка `grok/e2e-harness` (`ba59a48`) принята и вливается первой. ## Итог прошлого круга Принято без замечаний по существу: стенд работает на Windows без правок, ID сопоставлены с аудитом, недостающие сценарии добавлены, приёмка ветки Codex совпала с моей до цифры (41 красный / 13 зелёных). Твоя находка про поведение в «стилевом» коммите Codex подтверждена. Одно упущение: в приёмке запускались только `tests/e2e`, а интеграционные тесты самих исполнителей — нет. Из-за этого два красных файла Antigravity прошли бы как «принято». ## Правила — как раньше Только твоя зона: `tests/e2e/**`, `scripts/test/**`, `known-defects.json`, CI. В код исполнителей не коммитишь. Ветки исполнителей не меняешь — проверяешь в отдельных рабочих копиях. ## 1. Приёмка = стенд + интеграционные тесты + конфликты Добавь в `scripts/test/` режим приёмки ветки, например `node scripts/test/accept-branch.mjs <ветка> [<ветка>…]`. Для каждой ветки он: 1. Создаёт отдельную рабочую копию (`git worktree`) и накладывает текущий стенд. 2. Запускает `npm run check`. 3. Запускает **все** `tests/integration/*.test.ts` на реальной PostgreSQL. Считает файл красным по итоговой строке `Test Files`, а не `Tests`: ошибка в `beforeAll`/`afterAll` делает файл красным даже при зелёных тестах. 4. Запускает e2e-стенд и сравнивает с основой: что позеленело, что покраснело. 5. Проверяет попарно слияние всех переданных веток между собой и с основой (`git merge-tree --write-tree`). Печатает таблицу «чисто / конфликт, файлы». 6. Печатает итог в markdown, чтобы его можно было вставить в отчёт. **Роли базы.** Стенд пересоздаёт роли со случайными паролями на общем кластере — это ломает параллельную работу других. Сделай так, чтобы роли и пароли можно было передать переменными (`E2E_MIGRATOR_URL`, `E2E_APP_URL`) и стенд их тогда не трогал. По умолчанию — как сейчас. **Готово, когда** запуск на `antigravity/fix-reject-device-shifts antigravity/fix-sync-c0-bootstrap codex/fix-format-baseline` сам показывает то, что я нашёл вручную: | Что | Ожидаемый результат на сегодня | | ------------------------------------- | -------------------------------------------------------------------- | | `sync-rejection.test.ts` на `1df2019` | FAIL: `column "created_by" … does not exist` | | `sync-bootstrap.test.ts` на `8baad55` | FAIL: `Called end on pool more than once` при `Tests 2 passed` | | SYNC-C0 на `8baad55` | зелёный | | AG reject + AG c0 | конфликт, `src/domain/sync/service.ts` | | Codex format + AG c0 | конфликт | | Codex format + AG reject | чисто (потому что в форматировании Codex лежит копия исправления S1) | ## 2. Проверка «форматирование без поведения» Для ветки `codex/fix-format-baseline` (сейчас `513cdff`) добавь в режим приёмки проверку: для каждого изменённого файла взять версию из основы, прогнать через prettier и сравнить с версией из ветки. Любое отличие после нормализации — это поведение, а не стиль. Печатать список таких файлов. На сегодня ожидается: `src/domain/sync/service.ts` и `tests/unit/sync.test.ts` отличаются. После нормализации они совпадают с веткой Antigravity построчно. Я проверил это на `513cdff`: Codex перезалил ветку, но синхронизацию не убрал. **Готово, когда** проверка ловит `513cdff` и пропускает ветку, где остался только prettier. ## 3. Храповик после каждого влития Когда владелец вливает ветку, отдельным коммитом убери из `known-defects.json` то, что стало зелёным на основе: | После влития | Убрать | | --------------------------------- | ------------------------------- | | `codex/fix-live-database` | K3/N2, K4/N1 | | цепочка Antigravity (reject → c0) | K13/SYNC-A, K13/SYNC-B, SYNC-C0 | Коммит — только `known-defects.json`, в теле — вывод стенда на основе после влития. ## 4. Сценарий переноса арендатора (для TASK-CODEX-2, п. 2.2) Codex пишет `scripts/rehome-tenant.mjs`: перенос всех данных пилота из заглушки `01J00000000000000000000000` в арендатора `01M2R6AC5652NPT3MG34DKN4ZP`. Подготовь проверку заранее, чтобы принять скрипт в день пуша: 1. Наполнить базу под заглушкой: сотрудники, точки, смены, начисления в реестре, строки аудита, устройства синхронизации, push-подписки — по несколько строк в каждой таблице со столбцом `tenant_id`. Плюс второй, посторонний арендатор с собственными данными. 2. Снять контрольные цифры: число строк по каждой таблице и арендатору, `SUM(amount_minor)` реестра. 3. `--dry-run` — ничего не меняет, печатает те же числа. 4. Перенос ролью администратора БД. 5. Сверка: - `DISTINCT tenant_id` — только новый арендатор и посторонний; - число строк и суммы совпадают; - данные постороннего арендатора не тронуты; - в `staff_audit_log` нового арендатора есть запись о переносе; - приложение ролью `krona_staff_app` под новым арендатором видит тех же сотрудников, а под старым — ничего; - журналы остались неизменяемыми: после переноса `UPDATE` в `staff_payroll_ledger` отклоняется. 6. Повторный запуск отказывает: целевой арендатор уже содержит данные. Пока скрипта нет, сценарий красный с понятным сообщением и заносится в `known-defects.json` как `PILOT-REHOME`. Список таблиц со столбцом `tenant_id` бери из `information_schema.columns`, а не руками — так новая таблица без переноса сразу даст красный. ## Порядок 1 → 2 → прогнать приёмку по всем открытым веткам и выложить результат → 3 по мере влития → 4. ## Отчёт - ветка и коммит; - вывод режима приёмки по всем открытым веткам (`codex/*`, `antigravity/*`) на момент отчёта; - что изменилось в `known-defects.json`; - что не запускалось и почему.