Почему: таблица приёмки и разбор C6 должны соответствовать текущим SHA веток Codex, а владелец должен видеть, какие расхождения с C6 остались послеd52ecf3и какая часть красного была ошибкой сценария (типы счётчиков,d477dde), а не продукта. - REPORT: таблица по повторному прогону (b022885,d52ecf3), разборd52ecf3. - NOTES C6: что закрыл d52ecf3; открыто — многострочный JSON, сумма журнала в dry-run, dry-run по умолчанию и обязательные --apply/--actor/--backup-evidence. - NOTES разд. 8: K18 наb022885— ротация на ПК есть, на сервере нет, личные пути в новых файлах.
56 KiB
PR: e2e-стенд на реальной PostgreSQL 17 и независимая приёмка (grok/e2e-harness)
База: codex/bootstrap-platform-foundation @ f5ac179 (содержит 331e490). Ветка перебазирована
без конфликтов. Сравнение:
https://git.ochenstarik.ru/ochenstarik/krona-staff/compare/codex/bootstrap-platform-foundation...grok/e2e-harness
Изменены только tests/e2e/**, tests/integration/tenant-isolation.test.ts,
.forgejo/workflows/ci.yml, scripts/test/** и одна строка в корневом .gitignore
(tests/e2e/evidence/, по требованию TASK-GROK-2 §1). src/, apps/, migrations/,
deploy/, package.json не тронуты. Всё, что требует правки продукта, — в
NOTES-FOR-EXECUTORS.md.
Зачем
156 зелёных тестов на поддельной БД не заметили, что создание сотрудника, подтверждение
смены и расчёт зарплаты на реальной PostgreSQL падают всегда. Стенд запускает реальный сервер
под ролью приложения без привилегий на реальной PostgreSQL 17, миграции применяет мигратор без
SUPERUSER, все токены и пароли случайные (crypto.randomBytes). Каждый сценарий проверяет
правильное поведение: красный = открытый дефект.
Что изменилось во втором круге (TASK-GROK-2)
| Пункт | Что сделано |
|---|---|
| §1 | Запуск без .cmd-обёрток: scripts/test/node-commands.mjs — всегда process.execPath + JS-точка входа из require.resolve (vitest.mjs, prettier.cjs); сервер — один процесс node --import tsx src/server.ts (без дочернего процесса CLI tsx, чтобы kill() под Windows не оставлял сироту). Проверка на Linux — tests/e2e/harness/node-commands.test.ts (в npm test) |
| §1 | tests/e2e/evidence/ убран из git и добавлен в .gitignore; в CI — артефакт e2e-evidence. Разовые доказательства (N5, N13, приёмка) — в tests/e2e/report-evidence/, скрипты туда не пишут |
| §1 | Задача windows в CI (включается переменной KRONA_WINDOWS_RUNNER=true, раннера пока нет) |
| §1 | Перебазирование на f5ac179 — без конфликтов |
| §2 | Двойные ID [владелец/мой] в названиях тестов и ключах known-defects.json |
| §3 | Новые сценарии [K6/D5], [K7/D2], [K8/D1], [K9/D3], [S9], [A4], [N12-DATE] (tests/e2e/50-money-and-errors.e2e.ts), все красные и в known-defects.json |
| §4 | Приёмка antigravity/fix-reject-device-shifts, codex/fix-format-baseline, codex/fix-live-database — таблицы ниже |
| — | Синтетическая ставка 123,45 → 123,00 ₽/ч: расчёт округляет строку до рубля (rounding_unit_minor), тест не должен зависеть от округления (выяснилось на fix-live-database) |
Круг 3 (TASK-GROK-3)
Ветка продолжена поверх ba59a48 без переписывания истории (без rebase на b0243d5, без force-push).
| Пункт | Что сделано |
|---|---|
| п.1 | scripts/test/accept-branch.mjs <ветка>…: worktree на ветку в ../krona-staff-acceptance/ + оверлей текущего стенда (tests/e2e/**, scripts/test/**), npm run check без переменных БД, каждый tests/integration/*.test.ts отдельно на свежей мигрированной БД PG17 (красный — по строке Test Files, ловит ошибки beforeAll/afterAll; файл, где всё пропущено, — отдельный вердикт SKIP), e2e и разница с основой по ID, попарный git merge-tree --write-tree (все ветки между собой и с основой), итог в markdown. Логи — tests/e2e/evidence/accept/<время>/ (пароли в URL заменены на ***) |
| п.1 | Готовые роли: если заданы E2E_MIGRATOR_URL и E2E_APP_URL, global-setup и accept-branch роли не создают и пароли не меняют (БД — из URL, сброс откатом всех миграций). По умолчанию как раньше. provision-pg.mjs --roles keep пересоздаёт только БД: accept-branch создаёт роли один раз на прогон |
| п.1 | Предохранитель изолированной БД для live-postgres-remediation.test.ts (Codex): в admin-режиме интеграционная БД одноразовая (krona_staff_audit_acc_it), krona_staff_test_guard со случайным маркером, DATABASE_TEST_ISOLATED=true — без этого файл пропускается целиком |
| п.2 | «Форматирование без поведения» (для веток с format в имени и --format-check <ветка>): версия из merge-base → prettier (конфиг основы, API из node_modules) → сравнение с веткой; для лишних строк — сколько из них есть в других переданных ветках |
| п.3 | Прогон по всем открытым codex/*, antigravity/* — ниже |
| п.4 | Храповик не тронут: origin/codex/bootstrap-platform-foundation = b0243d5 (только docs поверх f5ac179); git merge-base --is-ancestor origin/<ветка> origin/codex/bootstrap-platform-foundation — NOT merged для fix-live-database, fix-reject-device-shifts, fix-sync-c0-bootstrap, fix-format-baseline |
| п.5 | [PILOT-REHOME-SEED] (зелёный) и [PILOT-REHOME] (красный, в known-defects.json) — tests/e2e/60-pilot-rehome.e2e.ts |
| — | run-e2e.mjs: проверка секретов в evidence/ больше не падает EISDIR на подкаталоге accept/ |
п.1: ожидания владельца на SHA из задания
Команда: node scripts/test/accept-branch.mjs 1df2019 antigravity/fix-sync-c0-bootstrap codex/fix-format-baseline
(16:04 NOVT; 1df2019 передан SHA, потому что ветка Antigravity к этому времени была перезаписана
на 6c5bf36). Полный вывод — report-evidence/round3-accept-owner-shas.md.
| Ожидание владельца | Фактический вывод |
|---|---|
sync-rejection.test.ts на 1df2019 FAIL column "created_by" … does not exist |
FAIL | 1 failed (1) | 2 skipped (2) | error: column "created_by" of relation "staff_employees" does not exist |
sync-bootstrap.test.ts на 8baad55 FAIL Called end on pool more than once при Tests 2 passed |
FAIL | 1 failed (1) | 2 passed (2) | Error: Called end on pool more than once |
SYNC-C0 зелёный на 8baad55 |
e2e «стало зелёным»: SYNC-C0 |
| AG reject + AG c0 — конфликт в src/domain/sync/service.ts | 1df2019 | origin/antigravity/fix-sync-c0-bootstrap | КОНФЛИКТ | src/domain/sync/service.ts |
| Codex format + AG c0 — конфликт | origin/antigravity/fix-sync-c0-bootstrap | origin/codex/fix-format-baseline | КОНФЛИКТ | src/domain/sync/service.ts |
| Codex format + AG reject — чисто | 1df2019 | origin/codex/fix-format-baseline | чисто |
Все шесть совпали. На 6c5bf36 (первый прогон по именам веток,
round3-accept-owner-branches-first.md)
sync-rejection.test.ts уже зелёный (1 passed (1) | 2 passed (2)).
п.2: форматирование без поведения
Команда: node scripts/test/accept-branch.mjs --format-check tmp/prettier-only-f5ac179 --format-check codex/fix-format-baseline
(round3-format-proof.md).
tmp/prettier-only-f5ac179 (c552d38) — локальная синтетическая ветка: prettier --write . поверх
f5ac179, 24 файла; не запушена.
| Ветка | Результат |
|---|---|
tmp/prettier-only-f5ac179 (c552d38) |
изменено файлов: 24 — ТОЛЬКО ФОРМАТИРОВАНИЕ |
codex/fix-format-baseline (513cdff, прежняя голова) |
ЕСТЬ ИЗМЕНЕНИЯ СВЕРХ PRETTIER: src/domain/sync/service.ts 232 строки, tests/unit/sync.test.ts 130 строк; в antigravity/fix-reject-device-shifts есть 232/232 и 130/130 этих строк |
codex/fix-format-baseline (a05777c, текущая, 16:09 NOVT) |
изменено файлов: 19 — ТОЛЬКО ФОРМАТИРОВАНИЕ |
п.3: все открытые ветки
Команда: node scripts/test/accept-branch.mjs <все origin/codex/* и origin/antigravity/* кроме основы>
после git fetch в 16:16 NOVT, стенд 6f408bc. Полный вывод (интеграционные тесты по файлам, 55 пар
merge-tree) — report-evidence/round3-accept-all-open.md.
Основа b0243d5: check OK, integration 3/4 (FAIL tenant-isolation), e2e 46 red / 5 green.
| Ветка | SHA | Влита в основу | check | integration | e2e red/green | Стало зелёным | Стало красным |
|---|---|---|---|---|---|---|---|
| antigravity/fix-reject-device-shifts | b283736 |
нет (+1) | OK | 4/5, FAIL tenant-isolation | 44/7 | K13/SYNC-A, K13/SYNC-B | — |
| antigravity/fix-sync-c0-bootstrap | 24cc18d |
нет (+3, включает b283736) |
OK | 5/6, FAIL tenant-isolation | 43/8 | K13/SYNC-A, K13/SYNC-B, SYNC-C0 | — |
| codex/fix-format-baseline | a05777c |
нет (+1, от f5ac179) |
OK | 3/4, FAIL tenant-isolation | 46/5 | — | — |
| codex/fix-live-database | 1573860 |
нет (+2, на a05777c) |
OK | 4/5, FAIL tenant-isolation (live-postgres-remediation OK) | 44/7 | K3/N2, K4/N1 | — |
| antigravity/employee-notifications | 3e20544 |
да (предок) | OK | 3/4 | 49/2 | — | HARNESS, PILOT-REHOME-SEED, SYNC-L (старый код: нет таблиц/маршрутов sync) |
| antigravity/offline-sync-backend | 5ee7517 |
да (предок) | OK | 3/4 | 46/5 | — | — |
| codex/finance-calendar-dashboard | c08a7e6 |
да (предок) | OK | 4/4 | 48/3 | A4, K4/N1 | CTRL, HARNESS, PILOT-REHOME-SEED, SYNC-L (старый код) |
| codex/frontend-library | 331e490 |
да (предок) | OK | 3/4 | 46/5 | — | — |
| codex/security-finance-production | f74aa6d |
да (предок) | OK | 4/4 | 49/2 | — | HARNESS, PILOT-REHOME-SEED, SYNC-L (старый код) |
| codex/server-web-production | 2f6b367 |
да (предок) | OK | 4/4 | 49/2 | K4/N1 | CTRL, HARNESS, PILOT-REHOME-SEED, SYNC-L (старый код) |
git merge-tree: конфликтов нет ни в одной из 55 пар (Antigravity выстроил цепочку reject → c0, Codex пересобрал format без sync). Шесть веток — предки основы (уже влиты), для них «стало красным» означает только «код старше основы».tenant-isolation.test.tsкрасный на основе и всех ветках отf5ac179(error: permission denied for table staff_employees) — это N5, исправление есть вgrok/e2e-harness(ba59a48), в основу ещё не влито.
Сборка «как будет после слияния» (локально, не запушено)
tmp/combined-round3 = b0243d5 + merge codex/fix-live-database (1573860) + merge
antigravity/fix-sync-c0-bootstrap (24cc18d) — без конфликтов; tmp/combined-round3-grok = то же +
merge grok/e2e-harness. Вывод — round3-combined-merge.md.
| Сборка | check | integration | e2e red/green | Стало зелёным |
|---|---|---|---|---|
| combined-round3 (48128c8) | OK (199 passed, 6 skipped) | 6/7, FAIL tenant-isolation | 41/10 | K13/SYNC-A, K13/SYNC-B, K3/N2, K4/N1, SYNC-C0 |
| combined-round3-grok (e94415a) | OK (199 passed, 6 skipped) | 7/7 | 41/10 | то же |
Храповик на combined-round3-grok: [run-e2e] FAIL: K13/SYNC-A, K13/SYNC-B, K3/N2, K4/N1, SYNC-C0 — дефект исправлен, обновите known-defects.json — ровно список из TASK-GROK-3 п.4. Удалю их отдельным
коммитом, когда ветки действительно окажутся в основе.
п.5: PILOT-REHOME
[PILOT-REHOME-SEED]— зелёный: 27 таблиц сtenant_idизinformation_schema.columns, в каждую 2+ строки заглушки01J00000000000000000000000и постороннего случайного арендатора (SQL мигратором,app.tenant_id/app.user_idв транзакции); таблица без сида → красный со списком.[PILOT-REHOME]— красный (вknown-defects.json):scripts/rehome-tenant.mjs отсутствует (TASK-CODEX-2 п.2.2): … Засеяно таблиц: 27, ledger SUM(amount_minor)=….- Сценарий проверен временным эталоном скрипта (не коммитился, удалён): с ним зелёный; мутации
«без записи аудита», «без отказа на повтор», «пропущена таблица», «dry-run пишет» — красные
(
report-evidence/round3-pilot-rehome.txt). - Контракт, который проверяет сценарий, —
NOTES-FOR-EXECUTORS.md, C6.
Круг 3б: основа f7d3c73 (ACCEPTANCE-3), 16:59 и 17:14 NOVT
Храповик не тронут: после git fetch git merge-base --is-ancestor origin/<ветка> origin/codex/bootstrap-platform-foundation — not merged для grok/e2e-harness, fix-live-database,
fix-format-baseline, fix-reject-device-shifts, fix-sync-c0-bootstrap, fix-tenant-config,
fix-tenant-rehome, fix-pilot-backups.
Команда: node scripts/test/accept-branch.mjs <7 веток, не являющихся предками основы>. Первый прогон (16:59, стенд
18f944e) — round3-accept-f7d3c73.md. Пока шёл разбор, Codex
запушил fix-tenant-rehome d52ecf3 (17:02) и fix-pilot-backups b022885 (17:07), поэтому все 7 веток прогнаны
повторно (17:14, стенд a6a1b5e) — round3-accept-f7d3c73-rerun.md.
В таблице — повторный прогон; на первом прогоне по c73bb3b и a005c5e результаты те же.
| Ветка | SHA | check | integration | e2e red/green | Стало зелёным | Стало красным |
|---|---|---|---|---|---|---|
| основа | f7d3c73 |
OK (195 passed, 1 skipped) | 3/4, FAIL tenant-isolation | 46/5 | n/a | n/a |
| antigravity/fix-reject-device-shifts | b283736 |
OK | 4/5, FAIL tenant-isolation | 44/7 | K13/SYNC-A, K13/SYNC-B | — |
| antigravity/fix-sync-c0-bootstrap | 24cc18d |
OK | 5/6, FAIL tenant-isolation | 43/8 | K13/SYNC-A, K13/SYNC-B, SYNC-C0 | — |
| codex/fix-format-baseline | a05777c |
OK | 3/4, FAIL tenant-isolation | 46/5 | — | — |
| codex/fix-live-database | 1573860 |
OK | 4/5, FAIL tenant-isolation | 44/7 | K3/N2, K4/N1 | — |
| codex/fix-pilot-backups | b022885 |
OK | 3/4, FAIL tenant-isolation | 46/5 | — | — |
| codex/fix-tenant-config | 535052e |
FAIL Error: STANDALONE_TENANT_ID uses the development placeholder… |
3/4, FAIL tenant-isolation | 46/5 | — | — |
| codex/fix-tenant-rehome | d52ecf3 |
OK | 4/5 (rehome-tenant.test.ts OK), FAIL tenant-isolation | 46/5 | — | — |
git merge-tree: 28 пар (7 с основой + 21 между собой) — все чисто.- «Форматирование без поведения»
a05777c:изменено файлов: 19 — ТОЛЬКО ФОРМАТИРОВАНИЕ. tenant-isolation.test.ts— N5 (permission denied for table staff_employees), исправление в grok/e2e-harness.- accept-branch дополнен (
18f944e): дляrehome-tenant.test.tsсоздаётся пустаяkrona_acc_rehome_test(суперпользователь,DATABASE_REHOME_TEST_CONFIRMизdocs/TENANT-REHOME.md) — иначе файл пропускается.
codex/fix-tenant-config — вывод владельца подтверждён. Лог npm run check:
FAIL tests/unit/sync.test.ts [ tests/unit/sync.test.ts ], Error: STANDALONE_TENANT_ID uses the development placeholder, which is allowed only in development on loopback, ❯ tests/unit/sync.test.ts:556:18,
Test Files 1 failed | 18 passed | 1 skipped (20). В ветке: строка 553 const tenantId = '01J00000000000000000000000',
556 loadConfig({, 563 NODE_ENV: 'test'. (У владельца 1 failed | 17 passed; у меня на один файл больше
из-за оверлея стенда — tests/e2e/harness/node-commands.test.ts.)
codex/fix-tenant-rehome — [PILOT-REHOME] красный. Вывод на ветке:
dry-run exit: Tenant rehome stopped. Unknown option --from. … expected 1 to be +0. Скрипт есть, но интерфейс
не совпадает с C6 (разница — NOTES, C6). По существу скрипт проверен двумя способами
(round3-k18-and-rehome.md):
- На восстановленной копии (после учебного восстановления K18), интерфейсом продукта: dry-run exit 0 и БД не изменилась;
apply без
--backup-evidence→ отказ; apply → exit 0, под заглушкой 0 строк, счётчики совпали, audit 2 → 3 (tenant.rehomed tenant_rehome), прочие арендаторы не изменились, ledgerRUB 263568до и после, FK до и после совпали (md5),krona_staff_app: 0 под заглушкой / 3 под новым tenant,UPDATE staff_payroll_ledger→permission denied, повтор →Target tenant already contains staff data; refusing merge, exit 1. - Сценарий
[PILOT-REHOME]через диагностический адаптер C6 →c73bb3b(не в продукте и не в сценарии): вариант 1 (только перевод флагов и формата) —expected 'undefined' to be '328228': в dry-run нет суммы журнала; вариант 2 (сумму досчитывает адаптер) —✓ [PILOT-REHOME]. Других расхождений сценарий не нашёл.
На d52ecf3 (17:02) Codex добавил синонимы --from/--to, --json, DATABASE_ADMIN_URL и сделал dry-run режимом
по умолчанию. [PILOT-REHOME] всё равно красный: dry-run без JSON-отчёта: { "mode": "dry-run", … } : expected null not to be null — JSON печатается на нескольких строках, а C6 требует его последней строкой. Если снимать
расхождения по одному в копии сценария (не в коммите, round3-k18-and-rehome.md, разд. 6.3), дальше
падают: счётчики-строки ('2' vs 2) → это ошибка сценария, исправлена в d477dde (сравнение через Number());
expected 'undefined' to be '375888' — в dry-run нет суммы журнала; под заглушкой остались строки — вызов без
флага теперь dry-run, а по C6 это перенос, для которого продукт требует --apply --actor --backup-evidence.
Других изменений в сценарии нет.
codex/fix-pilot-backups (K18). bash scripts/test-backup.sh и bash scripts/test-backup-pull.sh —
оба passed, exit 0 (моки docker/ssh/scp) и на a005c5e, и на b022885 (b022885 добавил ротацию копий на ПК, 90 дней,
и пользовательский systemd-сервис; ротации на сервере нет). В npm run check и CI они не входят. Учебное восстановление без
Docker (шим docker compose exec → локальный pg_dump PG17): backup.sh exit 0, на сервере 0 незашифрованных
файлов, sha256sum -c OK, расшифровка ключом вне сервера, pg_restore --exit-on-error exit 0,
restore-drill-report.sql на источнике и копии — идентичны (79 строк, RLS|27|t), isolation:
source-employee-count|3, target-employee-count|0. Восстановление в кластер без ролей: pg_restore exit 1,
61 ошибка role "krona_migrator" does not exist — в копии нет ролей (globals).
Как запустить
export E2E_PG_ADMIN_URL=postgres://<admin>:<pw>@127.0.0.1:55433/postgres # только создание ролей и БД
E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs # храповик known-defects (как в CI)
node scripts/test/run-e2e.mjs --no-known-defects # строго: любой красный = exit 1
./scripts/test/ci-local.sh # локальный эквивалент verify/format/e2e (bash)
node scripts/test/accept-branch.mjs <ветка> [<ветка>…] # приёмка веток (worktree, check, integration, e2e, merge-tree)
# роли уже есть (общий кластер): E2E_MIGRATOR_URL=… E2E_APP_URL=… — роли и пароли не трогаются
Таблица по ID (основная ветка f5ac179 + этот стенд)
Команда: ./scripts/test/ci-local.sh (внутри E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs),
2026-09-26 ~16:25 (UTC+7), PostgreSQL 17.11, стенд круга 3:
::: [check] with_db_env npm run check
Test Files 20 passed (20)
Tests 196 passed (196)
::: [format-check] FAIL exit=1 # 23 файла базовой линии основы, ни одного из tests/e2e, scripts/test, .forgejo
Test Files 6 failed | 1 passed (7)
Tests 46 failed | 10 passed (56)
[run-e2e] OK: стенд работает, все красные сценарии — известные открытые дефекты
Круг 3 добавил [PILOT-REHOME-SEED] (GREEN) и [PILOT-REHOME] (RED, scripts/rehome-tenant.mjs отсутствует (TASK-CODEX-2 п.2.2)); остальные строки таблицы — без изменений со второго круга.
| ID владельца / мой | Цвет | Фактический вывод (первая строка assert) |
|---|---|---|
| HARNESS (×5), CTRL (×2) | GREEN | 7/7 passed — стенд и позитивные контроли |
| K1/F2 | RED | { portal: 200, payroll: 200, write: 201 } вместо 401 |
| K1/SYNC-I | RED | анонимная регистрация устройства HTTP 201 |
| K1/PILOT-1 | RED | 14 подстановок без :? (первая STANDALONE_MANAGER_TOKEN) |
| K2/PILOT-2 | RED | NODE_ENV=development у сервиса app |
| K3/N2 | RED | подтверждение смены HTTP 500 code 23502 null value in column "occurred_at" of "staff_outbox" |
| K4/N1 | RED | HTTP 500 code 42P08 inconsistent types deduced for parameter $2 |
| K5/N4 | RED | блокирован K3 (500 на подтверждении) |
| K6/D5 | RED | блокирован K3 (500 на подтверждении) |
| K7/D2 | RED | afterFirst: 22200, afterSecond: 22200 вместо 33300, 37700 |
| K8/D1 | RED | блокирован K3 (500 на подтверждении) |
| K9/D3 | RED | params.shift_rate_minor не сохранён (HTTP 200, в params нет ключа) |
| K10/F3 | RED | rawTokenInCookie: true |
| K11/F4 | RED | все попытки 401, 429 нет |
| K12/N3 | RED | подписка на https://127.0.0.1:<port> HTTP 201, 1 входящее соединение |
| K13/SYNC-A, K13/SYNC-B | RED | upsert_work_session / upsert_timesheet_entry → status: applied |
| K17/OWN-10, K17/OWN-11 | RED | 404 Route GET .../terminal/employees/:id/enrollment / PUT .../biometric-consent (нет API, C3) |
| K19/OWN-07 | RED | 404 Route POST /access-grants (нет API, C1/C2) |
| D6/OWN-01, D6/OWN-02 | RED | 404 Route POST /access-grants (нет API, C1) |
| OWN-03..06, OWN-08, OWN-09 | RED | 404 Route POST /access-grants (нет API, C1/C2) |
| S2/SYNC-J | RED | отметка 2001 года → status: applied |
| S3/SYNC-G | RED | HTTP 500 code 22007 на весь пакет |
| S4/SYNC-E | RED | отметка уволенного → applied |
| S4/SYNC-F | RED | { ownOrgUnit: null, foreign: "applied" } |
| S5/SYNC-C | RED | HTTP 500 code 42703 column "status" does not exist (блокирован SYNC-C0) |
| S5/SYNC-D | RED | изменение из портала не видно в инкрементальном pull |
| S8/SYNC-H | RED | регистрация устройства по cookie с чужим Origin HTTP 201 |
| S9 | RED | удаление точки с устройством: 23502 null value in column "tenant_id" |
| A4 | RED | 2 тела 500 с SQLSTATE/текстом PostgreSQL (POST /employees 42P08, month=2026-13 22008) |
| N9 | RED | чужой push-endpoint перепривязан HTTP 201 |
| N10 | RED | терминал: { professions: 200, units: 200 } |
| N11 | RED | импорт с неверным kind HTTP 500 code 23514 |
| N12 | RED | лишнее поле и нереальная сумма → HTTP 200 |
| N12-DATE | RED | month=2026-13 → HTTP 500 code 22008; 2026-02-30 уже 400 |
| F7 | RED | повтор Idempotency-Key создал второе событие |
| F10 | RED | мутация по cookie без Origin HTTP 201 |
| SYNC-C0 (нет ID у владельца) | RED | bootstrap pull HTTP 500 code 42703 column "status" does not exist |
| SYNC-K (нет ID у владельца) | RED | ack курсора из будущего HTTP 200 |
| SYNC-L | GREEN | отозванное устройство получает 403 (позитивный контроль) |
| PILOT-REHOME-SEED | GREEN | 27 таблиц с tenant_id засеяны (заглушка + посторонний арендатор) |
| PILOT-REHOME | RED | scripts/rehome-tenant.mjs отсутствует (TASK-CODEX-2 п.2.2) |
| PILOT-3 | GREEN | у app нет учётных данных мигратора |
| N5 (tenant-isolation) | GREEN | в npm run check с тестовой БД: Test Files 20 passed (20), Tests 196 passed (196) |
| N13 (скрипт, не vitest) | — | не воспроизведено: 0 из 30 попыток при 10/25/50 (обход K3 в одноразовой БД), см. ниже |
Сверх таблицы TASK-GROK-2 §2 (по тексту AUDIT.md): K1/SYNC-I (анонимный доступ без токенов на
/sync), K1/PILOT-1 (подстановки без :? названы в K1), K2/PILOT-2 (development в пилоте — суть K2).
Приёмка веток исполнителей (TASK-GROK-2 §4)
Способ: git worktree add --detach <dir> origin/<ветка>, поверх — tests/e2e/ и scripts/test/
из этой ветки (в ветки исполнителей ничего не коммитилось), затем
E2E_MIGRATIONS=roundtrip E2E_DATABASE_NAME=krona_staff_acc node scripts/test/run-e2e.mjs.
«Было» — основная ветка f5ac179 с тем же стендом (45 red / 9 green, храповик OK). Полные таблицы —
tests/e2e/report-evidence/acceptance-*.txt. Ни одна ветка не влита в основную
(git merge-base --is-ancestor → нет), поэтому known-defects.json не сокращён.
codex/fix-live-database @ ea68e12, перепроверено на b289dd6
== roundtrip OK: rolledBack=11 reapplied=11
Tests 41 failed | 13 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K3/N2 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K4/N1 | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| ID | Было | Стало | Доказательство |
|---|---|---|---|
| K3/N2 | RED | GREEN | было: подтверждение смены 500 23502 occurred_at; стало: passed (8 ч × 123,00 ₽ = 98400 в ledger) |
| K4/N1 | RED | GREEN | было: 500 42P08; стало: passed (201, сотрудник в БД) |
| K13/SYNC-A | RED | GREEN | было: upsert_work_session → applied; стало: passed (см. находку по fd1ec3d) |
| K13/SYNC-B | RED | GREEN | было: upsert_timesheet_entry → applied; стало: passed |
| K5/N4 | RED | RED | было: блокирован K3; стало: смена должна быть начислена ровно один раз: expected 196800n to be 98400n |
| K6/D5 | RED | RED | было: блокирован K3; стало: после отклонения оплаченной смены должно быть сторно: expected 98400n to be 0n |
| K8/D1 | RED | RED | было: блокирован K3; стало: C4 verify: HTTP 404 Route GET .../payroll/runs/:id/verify not found |
| A4 | RED | RED | было: 2 утечки; стало: 1 — POST /payroll/calculate month=2026-13 → code=22008 |
| F14 | RED | GREEN | prettier --check . → All matched files use Prettier code style! (без оверлея evidence) |
Ветку обновили force-push во время приёмки (ea68e12 → b289dd6, изменён только
tests/integration/live-postgres-remediation.test.ts); повторный прогон на b289dd6 дал те же
41 red / 13 green и ту же таблицу.
Вердикт: K3 и K4 исправлены (подтверждено на живой PostgreSQL 17, миграции roundtrip). После влития
убрать K3/N2, K4/N1 из known-defects.json. Цепочка расчёта теперь доходит до денежных дефектов:
K5 и K6 подтверждены по существу.
codex/fix-format-baseline @ fd1ec3d
Tests 43 failed | 11 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
$ node node_modules/prettier/bin/prettier.cjs --check .
All matched files use Prettier code style!
| ID | Было | Стало | Доказательство |
|---|---|---|---|
| F14 | RED (23 файла) | GREEN | All matched files use Prettier code style! |
| K13/SYNC-A | RED | GREEN | было: applied; стало: passed |
| K13/SYNC-B | RED | GREEN | было: applied; стало: passed |
| остальные | без изменений | — | compare по e2e-results.json: других отличий нет |
Находка: «style»-коммит fd1ec3d содержит функциональное исправление Antigravity.
После нормализации prettier src/domain/sync/service.ts отличается от 331e490 на 255 строк diff
и совпадает с antigravity/fix-reject-device-shifts (0 строк); tests/unit/sync.test.ts — 139 и 0.
Изменение поведения скрыто в коммите форматирования — смешение тем (AGENTS.md).
antigravity/fix-reject-device-shifts @ 795bba0, перепроверено на 1df2019
Tests 43 failed | 11 passed (54)
| K13/SYNC-A | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| K13/SYNC-B | GREEN | 1/1 | зелёный — ИСПРАВЛЕН, уберите из known-defects.json |
| ID | Было | Стало | Доказательство |
|---|---|---|---|
| K13/SYNC-A | RED | GREEN | было: upsert_work_session → applied; стало: passed |
| K13/SYNC-B | RED | GREEN | было: upsert_timesheet_entry → applied; стало: passed |
| остальные | — | — | других отличий нет |
Ветку перебазировали на f5ac179 во время приёмки (795bba0 → 1df2019); повторный прогон
на 1df2019: те же 43 red / 11 green, отличия только K13/SYNC-A/B.
Вердикт: K13 исправлен. Убрать K13/SYNC-A,
K13/SYNC-B отдельным коммитом после влития (и после исправления очистки в
sync-rejection.test.ts, TASK-GROK-2 §4.1).
Windows
- Запуск стенда переписан без
npxиnode_modules/.bin(раньшеspawn('npx')иspawn('.../.bin/tsx')падали на Windows сENOENT). Проверка на Linux:tests/e2e/harness/node-commands.test.ts— 8 тестов: команды начинаются сprocess.execPath, без.cmd/.bin/npx, файлы существуют; подwin32дочерний процесс получаетSystemRoot/TEMP, секреты родителя не наследуются. - Реальный запуск на Windows 11 — не проверено: Windows-раннера у git.ochenstarik.ru нет.
В CI добавлена задача
windows(runs-on: windows), включаемая переменнойKRONA_WINDOWS_RUNNER=true; для полного e2e нужен секретWINDOWS_E2E_PG_ADMIN_URL. scripts/test/ci-local.sh— bash, на Windows не предназначен (под Windows запускатьnode scripts/test/run-e2e.mjs).
Evidence вне git
$ E2E_MIGRATIONS=roundtrip node scripts/test/run-e2e.mjs # (повторный прогон)
[run-e2e] OK: стенд работает, все красные сценарии — известные открытые дефекты
$ git status --porcelain
# (пусто)
N5 (tenant-isolation)
До (778ba2d, очистка ролью приложения) — report-evidence/n5-before.txt:
error: permission denied for table staff_employees, exit=1. После (очистка ролью мигратора с
app.tenant_id) — report-evidence/n5-after.txt: 2 прогона, exit=0.
На f5ac179: npm run check с тестовой БД — Test Files 20 passed (20), Tests 196 passed (196).
CI (.forgejo/workflows/ci.yml)
verify:postgres:17-alpine@sha256:…, роли как в pilot (мигратор NOSUPERUSER, app NOBYPASSRLS), миграцииup → откат всех 11 → up → up,npm run checkс тестовой БД,npm audit.format: отдельно (F14 красный до влитияcodex/fix-format-baseline).e2e: PostgreSQL 17,E2E_MIGRATIONS=roundtrip, храповик; evidence — артефактe2e-evidence(actions/upload-artifact@ea165f8… # v4.6.2, Forgejo 9.0.3).windows: выключена без раннера (см. выше).docker-build: меткаdocker-host,needs: verify, только push.- Все actions закреплены SHA (F13), SHA совпадают на github.com и code.forgejo.org.
Механизм красных сценариев — храповик known-defects.json, а не «allowed to fail»: сломанный стенд,
новый красный ID или исправленный, но не вычеркнутый ID делают задачу e2e красной.
Валидация: actionlint -config-file actionlint.yaml .forgejo/workflows/ci.yml (1.7.12, метки
docker, docker-host, windows) → 0 замечаний. Локально ./scripts/test/ci-local.sh:
::: [migrate-roundtrip] OK (== roundtrip OK: rolledBack=11 reapplied=11)
::: [check] OK (Test Files 20 passed (20), Tests 196 passed (196))
::: [audit] OK (found 0 vulnerabilities)
::: [format-check] FAIL (Code style issues found in 23 files — F14)
::: [e2e] OK (Tests 45 failed | 9 passed (54), храповик OK)
N13 (гонка первого расчёта)
node scripts/test/n13-race.mjs (10/25/50 параллельных первых расчётов × 5 попыток) —
report-evidence/n13-race.txt: как есть 15/15 → 500 (K3); с обходом K3
в одноразовой БД — 0 некорректных из 30 (с подтверждённой сменой и без). Не воспроизведено, как и у
владельца; вероятная причина (гипотеза по коду) — upsert ensureDefaultPayRules сериализует расчёты
тенанта. Прогон до перебазирования, на 778ba2d.
Не проверено
- Реальный Forgejo-раннер (workflow выполнялся только локальным эквивалентом),
docker build. - Запуск на Windows 11 (раннера нет); Windows-only: DPAPI, ACL каталога данных, установщик, WinUI,
named pipe — см. тесты Codex в
apps/KronaStaffTerminal.Tests. - OWN-01..11, K8 (C4) и K9 (C5) проверяют предполагаемые контракты из NOTES.
- K5/N4, K6/D5, K8/D1 на основной ветке блокированы K3; по существу проверены только на
codex/fix-live-database. - S9 проверен удалением SQL-запросом мигратора (публичного API удаления точки нет).
- Причина невоспроизводимости N13 — гипотеза по коду.
- Круг 3: в основе
scripts/rehome-tenant.mjsнет; наcodex/fix-tenant-rehomeскрипт проверен на копии и через диагностический адаптер (интерфейс не совпадает с C6).accept-branchв CI не запускается (разовый инструмент владельца/приёмщика). РежимE2E_MIGRATOR_URL/E2E_APP_URLпроверен на том же локальном кластере (роли созданы заранееprovision-pg), на чужом кластере — не проверено. - Круг 3б (K18) без Docker не проверено: настоящий
docker compose execв пилотном контейнере, systemd timer/service,pull-pilot-backups.shс реальным ssh/scp (только моки из тестов Codex), восстановление в контейнерpostgresсinit-app-role.sh, хранение ключа и политика хранения. Учебное восстановление Codex на пилоте (sha2562fc680ae…, 51 сотрудник) не перепроверялось — данных пилота у меня нет.