Добавлен ручной main-only workflow публикации образов через rootless Kaniko, с digest references и минимальной package-only registry credential boundary. PR CI остаётся no-push.
Добавлены проверка corpus alias/count/RU+KY canaries, owner-run guarded release cutover, общий lock deploy/rollback, pinned state и recovery journal.
Добавлен owner packet с неизвестными production prerequisites и ограничениями безопасности.
Production/VPS не менялись, helper не запускался, registry secrets не создавались. Descriptor unsigned; run log используется как ограниченный retrieval fallback, пока artifact action для установленного act_runner 0.2.13 не проверен. Для cutover нужны owner-verified backup/restore, image state, данные индекса и RU/KY canary queries. Не сливать автоматически.
## Что меняется
- Добавлен ручной main-only workflow публикации образов через rootless Kaniko, с digest references и минимальной package-only registry credential boundary. PR CI остаётся no-push.
- Добавлены проверка corpus alias/count/RU+KY canaries, owner-run guarded release cutover, общий lock deploy/rollback, pinned state и recovery journal.
- Добавлен owner packet с неизвестными production prerequisites и ограничениями безопасности.
- Search API patch version поднята до 0.13.3.
## Проверки
- Backend: 62 passed, 1 skipped (требуется локальный OpenSearch).
- Telegram: 6 passed. Backup: 16 passed. Deploy: 63 passed.
- Host identity guard, py_compile, YAML parse и git diff --check прошли.
## Границы
Production/VPS не менялись, helper не запускался, registry secrets не создавались. Descriptor unsigned; run log используется как ограниченный retrieval fallback, пока artifact action для установленного act_runner 0.2.13 не проверен. Для cutover нужны owner-verified backup/restore, image state, данные индекса и RU/KY canary queries. Не сливать автоматически.
Проверил весь PR #59 на head 852d639c455ff1c60202405e112d47b8128d66c6 против mainb5adc09203cbbbd298054248206b9f47ae4a44ca. Запрашиваю один пакет исправлений:
[P1] Восстановление после записи image refs может запустить новый релиз под видом старого.infra/deploy/deploy_release.py:183-225: replace_images() может выполнить os.replace, а затем выбросить ошибку при fsync каталога (release_refs.py:72-77). В этот момент switched ещё False; обработчик запускает compose up с уже новыми refs и записывает «previous stack restarted», сохраняя прежний release state. Это воспроизведено на изолированных mock-файлах. В обработчике ошибки нужно перечитать фактические обе ссылки, восстановить old refs перед запуском старого стека и остановиться на любом неожиданном состоянии; добавить тест ошибки после os.replace.
[P1] Неоднозначный результат переключения alias оставляет неверный checkpoint.backend/search/minjust_opensearch.py:459-481,408-414: OpenSearch может применить атомарный POST /_aliases, после чего ответ теряется. request_json() повторяет тот же POST; повторное remove с must_exist уже не проходит. Загрузка падает с complete=false, хотя alias указывает на новый индекс; --resume снова требует старый target и не может завершиться. После таймаута/ошибки нужно перечитать target: новый — подтвердить публикацию и завершить checkpoint, старый — безопасно повторить, иной — остановиться; покрыть такой сценарий тестом.
[P1] Текущий CI красный из-за глобального mock Path.stat.Run 177 падает на test_digest_rollback_fails_before_stopping_or_changing_references. В infra/deploy/test_rollback.py:121-129 подмена rollback.Path.stat действует и на JOURNAL_FILE.exists() в Python 3.12, поэтому тест получает ложный «recovery journal exists». Локальный Python 3.14 этого не воспроизводит из-за другой реализации Path.exists; моделирование семантики 3.12 воспроизводит точную ошибку CI. Ограничить mock конкретным backup/stat и изолировать пути journal/state/lock в tmp; добиться зелёного CI на текущем head. Smoke run 178 успешен.
[P2] Rollback не сверяет фактически запущенные образы.infra/deploy/rollback.py:243-265: после compose up проверяется /review, но state записывается из ожидаемого plan без проверки image IDs обоих работающих контейнеров. При неожиданном запуске другого образа helper объявит успех и закрепит неверный state. Пере�� записью state сравнить running IDs backend и OpenSearch с plan, как уже делает deploy helper; проверить несовпадение тестом.
[P2] Сохраняемый release descriptor отсутствует из-за неверного предположения о cache..gitea/workflows/release-images.yaml:52-58 только печатает JSON и checksum в лог; deploy/production/README.md и owner packet объясняют это отключённым cache. В точном act_runner 0.2.13cache.enabled=false убирает лишь ACTIONS_CACHE_URL, но сохраняет ACTIONS_RUNTIME_URL; собранный upload-artifact@v3 использует runtime URL, а Gitea 1.25.5 реализует этот upload API. Добавить артефакт JSON+SHA-256 через v3 и подтвердить получение в пробном CI запуске; до живого теста считать совместимость доказанной по протоколу, а не фактом успешной загрузки на этом экземпляре. Настройки runner/cache менять не требуется.
Owner-only registry/host/backup/corpus права и данные остаются неизвестными; это отдельные документированные предусловия первого production cutover. Merge в initial_review не выполняю.
Проверил весь PR #59 на head `852d639c455ff1c60202405e112d47b8128d66c6` против `main` `b5adc09203cbbbd298054248206b9f47ae4a44ca`. Запрашиваю один пакет исправлений:
1. **[P1] Восстановление после записи image refs может запустить новый релиз под видом старого.** `infra/deploy/deploy_release.py:183-225`: `replace_images()` может выполнить `os.replace`, а затем выбросить ошибку при `fsync` каталога (`release_refs.py:72-77`). В этот момент `switched` ещё `False`; обработчик запускает `compose up` с уже новыми refs и записывает «previous stack restarted», сохраняя прежний release state. Это воспроизведено на изолированных mock-файлах. В обработчике ошибки нужно перечитать фактические обе ссылки, восстановить old refs перед запуском старого стека и остановиться на любом неожиданном состоянии; добавить тест ошибки после `os.replace`.
2. **[P1] Неоднозначный результат переключения alias оставляет неверный checkpoint.** `backend/search/minjust_opensearch.py:459-481,408-414`: OpenSearch может применить атомарный `POST /_aliases`, после чего ответ теряется. `request_json()` повторяет тот же POST; повторное `remove` с `must_exist` уже не проходит. Загрузка падает с `complete=false`, хотя alias указывает на новый индекс; `--resume` снова требует старый target и не может завершиться. После таймаута/ошибки нужно перечитать target: новый — подтвердить публикацию и завершить checkpoint, старый — безопасно повторить, иной — остановиться; покрыть такой сценарий тестом.
3. **[P1] Текущий CI красный из-за глобального mock `Path.stat`.** [Run 177](https://git.vakanaut.ru/admin/akyldash/actions/runs/177/jobs/0#jobstep-15-68) падает на `test_digest_rollback_fails_before_stopping_or_changing_references`. В `infra/deploy/test_rollback.py:121-129` подмена `rollback.Path.stat` действует и на `JOURNAL_FILE.exists()` в Python 3.12, поэтому тест получает ложный «recovery journal exists». Локальный Python 3.14 этого не воспроизводит из-за другой реализации `Path.exists`; моделирование семантики 3.12 воспроизводит точную ошибку CI. Ограничить mock конкретным backup/stat и изолировать пути journal/state/lock в tmp; добиться зелёного CI на текущем head. Smoke run 178 успешен.
4. **[P2] Rollback не сверяет фактически запущенные образы.** `infra/deploy/rollback.py:243-265`: после `compose up` проверяется `/review`, но state записывается из ожидаемого `plan` без проверки image IDs обоих работающих контейнеров. При неожиданном запуске другого образа helper объявит успех и закрепит неверный state. Пере�� записью state сравнить running IDs backend и OpenSearch с `plan`, как уже делает deploy helper; проверить несовпадение тестом.
5. **[P2] Сохраняемый release descriptor отсутствует из-за неверного предположения о cache.** `.gitea/workflows/release-images.yaml:52-58` только печатает JSON и checksum в лог; `deploy/production/README.md` и owner packet объясняют это отключённым cache. В точном [act_runner 0.2.13](https://proxy.golang.org/gitea.com/gitea/act_runner/@v/v0.2.13.zip) `cache.enabled=false` убирает лишь `ACTIONS_CACHE_URL`, но сохраняет `ACTIONS_RUNTIME_URL`; собранный [upload-artifact@v3](https://raw.githubusercontent.com/actions/upload-artifact/v3/dist/index.js) использует runtime URL, а [Gitea 1.25.5](https://raw.githubusercontent.com/go-gitea/gitea/v1.25.5/routers/api/actions/artifacts.go) реализует этот upload API. Добавить артефакт JSON+SHA-256 через v3 и подтвердить получение в пробном CI запуске; до живого теста считать совместимость доказанной по протоколу, а не фактом успешной загрузки на этом экземпляре. Настройки runner/cache менять не требуется.
Owner-only registry/host/backup/corpus права и данные остаются неизвестными; это отдельные документированные предусловия первого production cutover. Merge в initial_review не выполняю.
Повторно проверил все 30 изменённых файлов PR #59 на 9d8ce6b67fadefa1f10bda1eb05c7a285a0b0df6 против mainb5adc09203cbbbd298054248206b9f47ae4a44ca. Четыре исправления к review #308 проверены: восстановление refs после post-rename ошибки, согласование результата alias switch и checkpoint, изоляция Path.stat для Python 3.12, сверка обоих running image IDs при rollback. Локальные целевые тесты прошли (deployment 39, importer 10); CI run 179 и smoke run 180 зелёные.
[P2] Пробный CI не доказывает доступность release artifact. В .gitea/workflows/ci.yaml (шаг Verify Gitea runtime artifact upload) и .gitea/workflows/release-images.yaml (шаг Upload verified release descriptor) не задано if-no-files-found: error. Для закреплённого v3 action отсутствие файла по умолчанию даёт предупреждение и успешный шаг (документация этого commit). Поэтому зелёный CI допускает пустую загрузку. Более того, доступный мне read-only API GET /repos/admin/akyldash/actions/runs/179/artifacts и список артефактов репозитория вернули total_count=0; этому API principal недоступен сам run (404), так что это не доказывает глобальное отсутствие артефакта, но и не подтверждает требуемое скачивание.
Минимальное исправление: задать if-no-files-found: error для обоих upload steps и подтвердить на новом PR запуске, что synthetic marker действительно появился и скачивается из run artifact (достаточно ID/имени/размера и факта успешного чтения, без содержимого секретов). Если текущий run уже имеет артефакт в авторизованном UI, приложить это свидетельство; проверку отсутствующего файла всё равно нужно сделать строгой. Registry publishing, runner/cache, VPS и production не менять. Changelog — после зелёного initial review, merge здесь запрещён.
Повторно проверил все 30 изменённых файлов PR #59 на `9d8ce6b67fadefa1f10bda1eb05c7a285a0b0df6` против `main` `b5adc09203cbbbd298054248206b9f47ae4a44ca`. Четыре исправления к review #308 проверены: восстановление refs после post-rename ошибки, согласование результата alias switch и checkpoint, изоляция `Path.stat` для Python 3.12, сверка обоих running image IDs при rollback. Локальные целевые тесты прошли (deployment 39, importer 10); CI run 179 и smoke run 180 зелёные.
**[P2] Пробный CI не доказывает доступность release artifact.** В `.gitea/workflows/ci.yaml` (шаг `Verify Gitea runtime artifact upload`) и `.gitea/workflows/release-images.yaml` (шаг `Upload verified release descriptor`) не задано `if-no-files-found: error`. Для закреплённого v3 action отсутствие файла по умолчанию даёт предупреждение и успешный шаг ([документация этого commit](https://gitea.com/actions/gitea-upload-artifact/src/commit/055b8b3f04a4a7ed853f2c6ab04256f83e4874dc/README.md)). Поэтому зелёный CI допускает пустую загрузку. Более того, доступный мне read-only API `GET /repos/admin/akyldash/actions/runs/179/artifacts` и список артефактов репозитория вернули `total_count=0`; этому API principal недоступен сам run (`404`), так что это не доказывает глобальное отсутствие артефакта, но и не подтверждает требуемое скачивание.
Минимальное исправление: задать `if-no-files-found: error` для обоих upload steps и подтвердить на новом PR запуске, что synthetic marker действительно появился и скачивается из run artifact (достаточно ID/имени/размера и факта успешного чтения, без содержимого секретов). Если текущий run уже имеет артефакт в авторизованном UI, приложить это свидетельство; проверку отсутствующего файла всё равно нужно сделать строгой. Registry publishing, runner/cache, VPS и production не менять. Changelog — после зелёного initial review, merge здесь запрещён.
[P1] Align Kaniko destination validation with the new SHA/run-ID tag. The release workflow now passes backend:${{ github.sha }}-${{ github.run_id }} and the equivalent OpenSearch tag (.gitea/workflows/release-images.yaml:27,37). But .gitea/actions/kaniko-push/release-build.sh:13,18 still requires a third -[1-9][0-9]* attempt suffix. An actual SHA/run-ID destination fails this check before /kaniko/executor, so the manual release cannot publish either image. Update both validators and their messages/tests to the chosen tag format. I reproduced the rejection with the exact regex. The current PR CI and runner smoke checks pass; they do not execute this credential-gated publishing path.
The earlier recovery and rollback fixes remain intact. Both artifact upload steps now set if-no-files-found: error; the previous synthetic artifact was independently downloaded and verified. No production release was attempted.
[P1] Align Kaniko destination validation with the new SHA/run-ID tag. The release workflow now passes `backend:${{ github.sha }}-${{ github.run_id }}` and the equivalent OpenSearch tag (.gitea/workflows/release-images.yaml:27,37). But `.gitea/actions/kaniko-push/release-build.sh:13,18` still requires a third `-[1-9][0-9]*` attempt suffix. An actual SHA/run-ID destination fails this check before `/kaniko/executor`, so the manual release cannot publish either image. Update both validators and their messages/tests to the chosen tag format. I reproduced the rejection with the exact regex. The current PR CI and runner smoke checks pass; they do not execute this credential-gated publishing path.
The earlier recovery and rollback fixes remain intact. Both artifact upload steps now set `if-no-files-found: error`; the previous synthetic artifact was independently downloaded and verified. No production release was attempted.
Reviewed the complete PR at commit 779743fdb0a950a8295da2c6e035fe8ba4d5a502 against b5adc09203cbbbd298054248206b9f47ae4a44ca. The new validator accepts the workflow's SHA-run_id destinations for both images and rejects invalid repositories, commits, run IDs and Dockerfiles; this resolves review #310. The earlier recovery/rollback findings and artifact-upload findings remain resolved. CI and runner smoke checks pass at this head; local deploy and importer tests and shell syntax checks pass. The registry-backed manual release and production owner evidence remain separate owner gates and were not exercised in this review.
Reviewed the complete PR at commit `779743fdb0a950a8295da2c6e035fe8ba4d5a502` against `b5adc09203cbbbd298054248206b9f47ae4a44ca`. The new validator accepts the workflow's `SHA-run_id` destinations for both images and rejects invalid repositories, commits, run IDs and Dockerfiles; this resolves review #310. The earlier recovery/rollback findings and artifact-upload findings remain resolved. CI and runner smoke checks pass at this head; local deploy and importer tests and shell syntax checks pass. The registry-backed manual release and production owner evidence remain separate owner gates and were not exercised in this review.
Полное финальное ревью PR 59: code SHA eff81c150423402de47e266d2d4550ac1e93216d, base b5adc09203cbbbd298054248206b9f47ae4a44ca. Код: APPROVED. Все 32 изменённых файла сопоставлены с предыдущим полным ревью; после APPROVED #311 изменился только CHANGELOG. Исправления замечаний #308–#310 сохранены. CI и runner smoke на этом SHA успешны; локально прошли 41 deploy-тест, 10 тестов импортера и shell syntax. Реальная публикация образов и production cutover не выполнялись.
RUSSIAN_OWNER_PACKET: APPROVED. Файл OWNER_HANDOFF_PR59.md, SHA-256 1a3fd807acabe445509b035f3876a9f1ac754e4c805229f596022246facc1aa9; проверил reviewer agent (ID 7), 2026-10-26 16:37 MSK, относительно code SHA eff81c150423402de47e266d2d4550ac1e93216d. Проверены команды, аргументы, происхождение read-only audit-скрипта, границы backup/restore, требование полного корпуса без исключений и явные неизвестные owner gates. Исправленная процедура скачанного ZIP (новый пустой каталог → release/ → checksum → allowlist) успешно воспроизведена локально на синтетическом descriptor. В документации репозитория неверной команды распаковки нет. Owner gates остаются открытыми: свежий аудит хоста, резервная копия и отдельное восстановление, фактический корпус/alias/canaries, права и retention registry/artifacts, TLS. Это одобрение не подтверждает готовность production и не разрешает деплой или merge.
Полное финальное ревью PR 59: code SHA `eff81c150423402de47e266d2d4550ac1e93216d`, base `b5adc09203cbbbd298054248206b9f47ae4a44ca`. Код: **APPROVED**. Все 32 изменённых файла сопоставлены с предыдущим полным ревью; после APPROVED #311 изменился только CHANGELOG. Исправления замечаний #308–#310 сохранены. CI и runner smoke на этом SHA успешны; локально прошли 41 deploy-тест, 10 тестов импортера и shell syntax. Реальная публикация образов и production cutover не выполнялись.
**RUSSIAN_OWNER_PACKET: APPROVED.** Файл `OWNER_HANDOFF_PR59.md`, SHA-256 `1a3fd807acabe445509b035f3876a9f1ac754e4c805229f596022246facc1aa9`; проверил reviewer `agent` (ID 7), 2026-10-26 16:37 MSK, относительно code SHA `eff81c150423402de47e266d2d4550ac1e93216d`. Проверены команды, аргументы, происхождение read-only audit-скрипта, границы backup/restore, требование полного корпуса без исключений и явные неизвестные owner gates. Исправленная процедура скачанного ZIP (новый пустой каталог → `release/` → checksum → allowlist) успешно воспроизведена локально на синтетическом descriptor. В документации репозитория неверной команды распаковки нет. Owner gates остаются открытыми: свежий аудит хоста, резервная копия и отдельное восстановление, фактический корпус/alias/canaries, права и retention registry/artifacts, TLS. Это одобрение не подтверждает готовность production и не разрешает деплой или merge.
[P2] Сделать checksum проверяемым из скачанного release artifact без восстановления исходной структуры workspace. Сейчас .gitea/workflows/release-images.yaml:50 записывает в sidecar путь release/release-manifest.json; шаг загрузки берёт два файла из одного каталога release/ (:55–57), поэтому v3 upload action помещает их в корень ZIP. После обычной распаковки sha256sum -c release-manifest.json.sha256 ищет отсутствующий release/release-manifest.json и завершается с кодом 1. Локально воспроизведено на синтетическом descriptor; реально скачанный smoke artifact того же action также имел файл в корне ZIP. Проверка :62 проходит только в исходном workspace и не проверяет формат скачанного artifact. Минимальное исправление: формировать checksum в каталоге release с именем release-manifest.json и проверять его из того же каталога; добавить проверку формы скачанного artifact, чтобы регрессия не возвращалась. Обновить owner-команду после изменения формата.
Ранее опубликованный APPROVED #313 на этом SHA больше не отражает итог ревью: это формальное REQUEST_CHANGES его заменяет. Остальные исправления #308–#310, changelog, тесты и CI проверены, новых находок по ним нет. RUSSIAN_OWNER_PACKET: текущий документ SHA-256 1a3fd807acabe445509b035f3876a9f1ac754e4c805229f596022246facc1aa9 корректно описывает временное восстановление каталога release/ для текущего sidecar; после изменения workflow этот шаг станет неверным и документ должен быть пересмотрен на новом hash вместе с новым code SHA. Reviewer agent (ID 7), 26 октября 2026 года. Публикация образов, merge и production-действия не выполнялись.
[P2] Сделать checksum проверяемым из скачанного release artifact без восстановления исходной структуры workspace. Сейчас `.gitea/workflows/release-images.yaml:50` записывает в sidecar путь `release/release-manifest.json`; шаг загрузки берёт два файла из одного каталога `release/` (:55–57), поэтому v3 upload action помещает их в корень ZIP. После обычной распаковки `sha256sum -c release-manifest.json.sha256` ищет отсутствующий `release/release-manifest.json` и завершается с кодом 1. Локально воспроизведено на синтетическом descriptor; реально скачанный smoke artifact того же action также имел файл в корне ZIP. Проверка :62 проходит только в исходном workspace и не проверяет формат скачанного artifact. Минимальное исправление: формировать checksum в каталоге `release` с именем `release-manifest.json` и проверять его из того же каталога; добавить проверку формы скачанного artifact, чтобы регрессия не возвращалась. Обновить owner-команду после изменения формата.
Ранее опубликованный APPROVED #313 на этом SHA больше не отражает итог ревью: это формальное REQUEST_CHANGES его заменяет. Остальные исправления #308–#310, changelog, тесты и CI проверены, новых находок по ним нет. **RUSSIAN_OWNER_PACKET:** текущий документ SHA-256 `1a3fd807acabe445509b035f3876a9f1ac754e4c805229f596022246facc1aa9` корректно описывает временное восстановление каталога `release/` для текущего sidecar; после изменения workflow этот шаг станет неверным и документ должен быть пересмотрен на новом hash вместе с новым code SHA. Reviewer `agent` (ID 7), 26 октября 2026 года. Публикация образов, merge и production-действия не выполнялись.
Полное ревью PR 59 на текущем code SHA e40a32971d510683094d9decc7f77b650df59aea против base b5adc09203cbbbd298054248206b9f47ae4a44ca: APPROVED. После REQUEST_CHANGES #314 исправлены генерация и локальная проверка checksum из каталога release: sidecar теперь содержит basename release-manifest.json, который совпадает с корнем скачанного ZIP. Новый тест запускает shell-команды и проверяет извлечённый артефакт. Я независимо проверил синтетический ZIP: producer checksum, checksum после извлечения и validate_release.py прошли. Все остальные файлы полного PR, включая исправления #308–#310 и changelog, сверены с предыдущим ревью. На этом SHA оба CI-check успешны; локально прошли 42 deploy-теста, 10 тестов импортера и shell syntax.
RUSSIAN_OWNER_PACKET: APPROVED.OWNER_HANDOFF_PR59.md SHA-256 a00bb5ea7863a10ef5aa475999efb0427a38c81382f5cad65026f51b8da047f4 проверил reviewer agent (ID 7), 2026-10-26 16:46 MSK, относительно code SHA e40a32971d510683094d9decc7f77b650df59aea. Команда из нового пустого каталога скачанного артефакта sha256sum -c release-manifest.json.sha256 и валидация release-manifest.json проверены синтетически. Проверены команды, guards, provenance checksum read-only audit, backup/restore, полный корпус без исключений, явные неизвестные и запрет автоматического merge. Owner gates по свежему аудиту хоста, backup/отдельному restore, корпусу/alias/canaries, registry rights/retention и TLS остаются неподтверждёнными; ручной release и production cutover не запускались. Это ревью не разрешает merge или deploy.
Полное ревью PR 59 на текущем code SHA `e40a32971d510683094d9decc7f77b650df59aea` против base `b5adc09203cbbbd298054248206b9f47ae4a44ca`: **APPROVED**. После REQUEST_CHANGES #314 исправлены генерация и локальная проверка checksum из каталога `release`: sidecar теперь содержит basename `release-manifest.json`, который совпадает с корнем скачанного ZIP. Новый тест запускает shell-команды и проверяет извлечённый артефакт. Я независимо проверил синтетический ZIP: producer checksum, checksum после извлечения и validate_release.py прошли. Все остальные файлы полного PR, включая исправления #308–#310 и changelog, сверены с предыдущим ревью. На этом SHA оба CI-check успешны; локально прошли 42 deploy-теста, 10 тестов импортера и shell syntax.
**RUSSIAN_OWNER_PACKET: APPROVED.** `OWNER_HANDOFF_PR59.md` SHA-256 `a00bb5ea7863a10ef5aa475999efb0427a38c81382f5cad65026f51b8da047f4` проверил reviewer `agent` (ID 7), 2026-10-26 16:46 MSK, относительно code SHA `e40a32971d510683094d9decc7f77b650df59aea`. Команда из нового пустого каталога скачанного артефакта `sha256sum -c release-manifest.json.sha256` и валидация `release-manifest.json` проверены синтетически. Проверены команды, guards, provenance checksum read-only audit, backup/restore, полный корпус без исключений, явные неизвестные и запрет автоматического merge. Owner gates по свежему аудиту хоста, backup/отдельному restore, корпусу/alias/canaries, registry rights/retention и TLS остаются неподтверждёнными; ручной release и production cutover не запускались. Это ревью не разрешает merge или deploy.
Проверил весь PR #59 на head 74aa167d16f0343321c9cc0133ba71c8074a26c3 против mainf90161f3800de7410d44a9c248d107de220e68f8. Формально запрашиваю исправления:
[P1] Автоматическая публикация всегда останавливается на source guard..gitea/workflows/release-images.yaml:16-26 передаёт SOURCE_WORKFLOW/EVENT/CONCLUSION/BRANCH/SHA, но не SOURCE_RUN_ID. infra/deploy/release_handoff.py:46-47 требует непустой числовой run ID для стадии release. При точном окружении workflow проверка завершается source run ID or commit SHA is invalid до registry credentials. Передать ID завершённого CI run и проверить тестом связку YAML → CLI, а не только валидатор с вручную заполненным fixture.
[P1] Идентичность исходного workflow читается из неподтверждённого поля workflow_run.name. Оба workflow задают SOURCE_WORKFLOW через gitea.event.workflow_run.name (release-images.yaml:19, deploy-handoff.yaml:27). Реальные ActionWorkflowRun ответы Gitea 1.25.5 для CI run 583 и smoke run 586 не содержат name, но содержат path; документация события описывает отдельный объект workflow. Поэтому текущий guard может получать пустое значение и отклонять оба запуска даже после исправления ID. Использовать проверяемое поле/объект исходного workflow и тест с фактической формой payload Gitea 1.25, сохранив отказ при чужом workflow.
[P2] Owner packet оставляет действующей запрещённую локальную backup-процедуру.docs/operations/DEPLOYMENT_OWNER_PACKET.md:52-55 требует архив по документированной cold-backup процедуре, а docs/operations/BACKUP.md и DEPLOYMENT.md всё ещё дают команды полного локального архива в /var/backups/akyldash. Владелец уже запретил хранить на VPS даже временный полный архив. Явно пометить эти команды как отменённые текущим owner-решением и направить к отдельному проекту внешней копии; реализацию внешнего backup в этот CD-патч не добавлять.
Ранее отмеченные recovery/alias/rollback/artifact-checksum исправления перепроверены на текущем дереве; локально прошли 74 deployment и 10 importer тестов. Gitea CI и runner smoke на этом SHA успешны, но новые workflow_run пути ими не исполнялись. Handoff остаётся честно dry-run: ZIP и host не проверены. Registry secrets, host transport и production не менялись. Это initial_review; merge запрещён.
Проверил весь PR #59 на head `74aa167d16f0343321c9cc0133ba71c8074a26c3` против `main` `f90161f3800de7410d44a9c248d107de220e68f8`. Формально запрашиваю исправления:
1. **[P1] Автоматическая публикация всегда останавливается на source guard.** `.gitea/workflows/release-images.yaml:16-26` передаёт SOURCE_WORKFLOW/EVENT/CONCLUSION/BRANCH/SHA, но не SOURCE_RUN_ID. `infra/deploy/release_handoff.py:46-47` требует непустой числовой run ID для стадии release. При точном окружении workflow проверка завершается `source run ID or commit SHA is invalid` до registry credentials. Передать ID завершённого CI run и проверить тестом связку YAML → CLI, а не только валидатор с вручную заполненным fixture.
2. **[P1] Идентичность исходного workflow читается из неподтверждённого поля `workflow_run.name`.** Оба workflow задают SOURCE_WORKFLOW через `gitea.event.workflow_run.name` (`release-images.yaml:19`, `deploy-handoff.yaml:27`). Реальные ActionWorkflowRun ответы Gitea 1.25.5 для CI run 583 и smoke run 586 не содержат `name`, но содержат `path`; документация события описывает отдельный объект `workflow`. Поэтому текущий guard может получать пустое значение и отклонять оба запуска даже после исправления ID. Использовать проверяемое поле/объект исходного workflow и тест с фактической формой payload Gitea 1.25, сохранив отказ при чужом workflow.
3. **[P2] Owner packet оставляет действующей запрещённую локальную backup-процедуру.** `docs/operations/DEPLOYMENT_OWNER_PACKET.md:52-55` требует архив по документированной cold-backup процедуре, а `docs/operations/BACKUP.md` и `DEPLOYMENT.md` всё ещё дают команды полного локального архива в `/var/backups/akyldash`. Владелец уже запретил хранить на VPS даже временный полный архив. Явно пометить эти команды как отменённые текущим owner-решением и направить к отдельному проекту внешней копии; реализацию внешнего backup в этот CD-патч не добавлять.
Ранее отмеченные recovery/alias/rollback/artifact-checksum исправления перепроверены на текущем дереве; локально прошли 74 deployment и 10 importer тестов. Gitea CI и runner smoke на этом SHA успешны, но новые workflow_run пути ими не исполнялись. Handoff остаётся честно dry-run: ZIP и host не проверены. Registry secrets, host transport и production не менялись. Это initial_review; merge запрещён.
Проверил весь PR #59 на head f8483badcf0bad100ff331b1e2daca7d7c39ace9 против mainf90161f3800de7410d44a9c248d107de220e68f8. Исправления review #318 проверены: release передаёт ID исходного CI run; оба workflow сверяют имя из отдельного объекта workflow, фактический run path, repository, event, branch, conclusion и SHA; тест связывает YAML-env с CLI на форме Gitea 1.25. Предыдущие исправления #308–#314 и merge main остаются в текущем дереве. Запрет локального полного backup на VPS отражён в BACKUP, DEPLOYMENT и owner packet; внешняя backup-цепочка остаётся отдельным обязательным gate перед live apply.
Локально: 75 deployment и 10 importer тестов, AST syntax и diff --check прошли. Gitea CI и runner smoke успешны на этом SHA. Release workflow с registry credentials и вложенная цепочка workflow_run ещё не исполнялись на main; handoff остаётся dry-run без ZIP/SSH/host apply. Поэтому APPROVED означает готовность текущего PR к следующему этапу ревью/changelog, а не production-readiness. В initial_review merge и production-действия запрещены. Новых существенных замечаний нет.
Проверил весь PR #59 на head `f8483badcf0bad100ff331b1e2daca7d7c39ace9` против `main` `f90161f3800de7410d44a9c248d107de220e68f8`. Исправления review #318 проверены: release передаёт ID исходного CI run; оба workflow сверяют имя из отдельного объекта workflow, фактический run path, repository, event, branch, conclusion и SHA; тест связывает YAML-env с CLI на форме Gitea 1.25. Предыдущие исправления #308–#314 и merge main остаются в текущем дереве. Запрет локального полного backup на VPS отражён в BACKUP, DEPLOYMENT и owner packet; внешняя backup-цепочка остаётся отдельным обязательным gate перед live apply.
Локально: 75 deployment и 10 importer тестов, AST syntax и diff --check прошли. Gitea CI и runner smoke успешны на этом SHA. Release workflow с registry credentials и вложенная цепочка workflow_run ещё не исполнялись на main; handoff остаётся dry-run без ZIP/SSH/host apply. Поэтому APPROVED означает готовность текущего PR к следующему этапу ревью/changelog, а не production-readiness. В initial_review merge и production-действия запрещены. Новых существенных замечаний нет.
Повторно проверил весь PR #59 на head 6be28418ab1732785d7947cf9cfada85185ddddc против mainf90161f3800de7410d44a9c248d107de220e68f8. После APPROVED #319 изменился только CHANGELOG.md; код и workflow остались теми же. Новая запись корректно описывает цепочку successful main CI → digest image release → dry-run handoff, условность registry secrets, отсутствие ZIP download/SSH/host apply и отдельный обязательный внешний backup/restore gate. Запрещённая владельцем локальная полная копия на VPS помечена в операционных документах как superseded.
Исправления прежних замечаний #308–#314 и #318 остаются в текущем дереве: source run ID, отдельный workflow.name, фактический run path/repository/event/branch/conclusion/SHA, YAML-env→CLI регрессионный тест, rollback/recovery/alias и checksum. Локально на неизменном кодовом дереве прошли 75 deployment и 10 importer тестов; текущий diff --check чист. Gitea CI run 591 и runner smoke run 592 успешны на этом SHA. Существенных замечаний к PR-коду нет.
Это APPROVED для текущего PR head, не подтверждение живого CD: release workflow с registry credentials и вложенная workflow_run цепочка на main ещё не исполнялись; ZIP, host transport и внешний backup/restore не реализованы или не проверены. В текущем назначении phase=initial_review merge и production-действия запрещены.
Повторно проверил весь PR #59 на head `6be28418ab1732785d7947cf9cfada85185ddddc` против `main` `f90161f3800de7410d44a9c248d107de220e68f8`. После APPROVED #319 изменился только CHANGELOG.md; код и workflow остались теми же. Новая запись корректно описывает цепочку successful main CI → digest image release → dry-run handoff, условность registry secrets, отсутствие ZIP download/SSH/host apply и отдельный обязательный внешний backup/restore gate. Запрещённая владельцем локальная полная копия на VPS помечена в операционных документах как superseded.
Исправления прежних замечаний #308–#314 и #318 остаются в текущем дереве: source run ID, отдельный workflow.name, фактический run path/repository/event/branch/conclusion/SHA, YAML-env→CLI регрессионный тест, rollback/recovery/alias и checksum. Локально на неизменном кодовом дереве прошли 75 deployment и 10 importer тестов; текущий diff --check чист. Gitea CI run 591 и runner smoke run 592 успешны на этом SHA. Существенных замечаний к PR-коду нет.
Это APPROVED для текущего PR head, не подтверждение живого CD: release workflow с registry credentials и вложенная workflow_run цепочка на main ещё не исполнялись; ZIP, host transport и внешний backup/restore не реализованы или не проверены. В текущем назначении phase=initial_review merge и production-действия запрещены.
Формальное первичное ревью коммита 4a7e907be7: изменения и тесты проверены, CI и runner smoke успешны. Замечаний по коду нет. Production gates и deploy-handoff остаются отдельными условиями; деплой не подтверждён.
Формальное первичное ревью коммита 4a7e907be7d024eb2b3be654f77ef8e5423ac182: изменения и тесты проверены, CI и runner smoke успешны. Замечаний по коду нет. Production gates и deploy-handoff остаются отдельными условиями; деплой не подтверждён.
Финальное ревью полного PR на коммите 0630a774cf: изменения, прежние исправления и новый CHANGELOG проверены; CI и runner smoke успешны. Замечаний по коду нет. Handoff остаётся NOT DEPLOYED; production D:, SSH/VPS и полный backup/restore ещё требуют отдельной проверки. Это ревью не подтверждает production deployment.
Финальное ревью полного PR на коммите 0630a774cf9981cebcbb79f335dc5142cf42f8a3: изменения, прежние исправления и новый CHANGELOG проверены; CI и runner smoke успешны. Замечаний по коду нет. Handoff остаётся NOT DEPLOYED; production D:, SSH/VPS и полный backup/restore ещё требуют отдельной проверки. Это ревью не подтверждает production deployment.
Блокирующее замечание к infra/deploy/windows-release-trigger.example.xml:41: путь C:\Program Files\Akyldash\receive_external.py в не заключён в кавычки. После включения задачи Windows разделит его по пробелу, Python не откроет нужный скрипт, и --once не запустится. Заключите путь к скрипту в кавычки внутри Arguments и добавьте проверку итогового argv на Windows. Остальные проверенные новые guards выглядят согласованно; CI успешен. Production CD и развёртывание не подтверждены.
Блокирующее замечание к infra/deploy/windows-release-trigger.example.xml:41: путь C:\Program Files\Akyldash\receive_external.py в <Arguments> не заключён в кавычки. После включения задачи Windows разделит его по пробелу, Python не откроет нужный скрипт, и --once не запустится. Заключите путь к скрипту в кавычки внутри Arguments и добавьте проверку итогового argv на Windows. Остальные проверенные новые guards выглядят согласованно; CI успешен. Production CD и развёртывание не подтверждены.
Первичное ревью полного PR на коммите 8ede9f2123: замечание #367 по кавычкам в Task Scheduler XML исправлено; точный diff и целевой Windows fixture проверены. Ранее проверенные source/backup/deploy guards сохраняются, CI и runner smoke успешны. Новых замечаний по коду нет. Шаблон остаётся выключенным; production D:, SSH/VPS, полный backup/restore и активация CD не подтверждены.
Первичное ревью полного PR на коммите 8ede9f2123adbcf3f2953645ed208cdb0e61c7d3: замечание #367 по кавычкам в Task Scheduler XML исправлено; точный diff и целевой Windows fixture проверены. Ранее проверенные source/backup/deploy guards сохраняются, CI и runner smoke успешны. Новых замечаний по коду нет. Шаблон остаётся выключенным; production D:, SSH/VPS, полный backup/restore и активация CD не подтверждены.
Финальное ревью полного PR на коммите 6cab6fcc95: код привязки и прежние исправления проверены, новый CHANGELOG корректно описывает выключенный trigger и ограничения. Замечание #367 устранено; CI и runner smoke успешны. Замечаний по коду нет. Handoff остаётся NOT DEPLOYED, Windows Task Scheduler/SSH/VPS и production D: не активировались; полный backup/restore и owner bootstrap ещё требуются.
Финальное ревью полного PR на коммите 6cab6fcc95a11f17aec57dff1c69cde59224425e: код привязки и прежние исправления проверены, новый CHANGELOG корректно описывает выключенный trigger и ограничения. Замечание #367 устранено; CI и runner smoke успешны. Замечаний по коду нет. Handoff остаётся NOT DEPLOYED, Windows Task Scheduler/SSH/VPS и production D: не активировались; полный backup/restore и owner bootstrap ещё требуются.
admin
merged commit c8d0086a9f into main2026-11-01 19:43:48 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Что меняется
Проверки
Границы
Production/VPS не менялись, helper не запускался, registry secrets не создавались. Descriptor unsigned; run log используется как ограниченный retrieval fallback, пока artifact action для установленного act_runner 0.2.13 не проверен. Для cutover нужны owner-verified backup/restore, image state, данные индекса и RU/KY canary queries. Не сливать автоматически.
Проверил весь PR #59 на head
852d639c455ff1c60202405e112d47b8128d66c6противmainb5adc09203cbbbd298054248206b9f47ae4a44ca. Запрашиваю один пакет исправлений:[P1] Восстановление после записи image refs может запустить новый релиз под видом старого.
infra/deploy/deploy_release.py:183-225:replace_images()может выполнитьos.replace, а затем выбросить ошибку приfsyncкаталога (release_refs.py:72-77). В этот моментswitchedещёFalse; обработчик запускаетcompose upс уже новыми refs и записывает «previous stack restarted», сохраняя прежний release state. Это воспроизведено на изолированных mock-файлах. В обработчике ошибки нужно перечитать фактические обе ссылки, восстановить old refs перед запуском старого стека и остановиться на любом неожиданном состоянии; добавить тест ошибки послеos.replace.[P1] Неоднозначный результат переключения alias оставляет неверный checkpoint.
backend/search/minjust_opensearch.py:459-481,408-414: OpenSearch может применить атомарныйPOST /_aliases, после чего ответ теряется.request_json()повторяет тот же POST; повторноеremoveсmust_existуже не проходит. Загрузка падает сcomplete=false, хотя alias указывает на новый индекс;--resumeснова требует старый target и не может завершиться. После таймаута/ошибки нужно перечитать target: новый — подтвердить публикацию и завершить checkpoint, старый — безопасно повторить, иной — остановиться; покрыть такой сценарий тестом.[P1] Текущий CI красный из-за глобального mock
Path.stat. Run 177 падает наtest_digest_rollback_fails_before_stopping_or_changing_references. Вinfra/deploy/test_rollback.py:121-129подменаrollback.Path.statдействует и наJOURNAL_FILE.exists()в Python 3.12, поэтому тест получает ложный «recovery journal exists». Локальный Python 3.14 этого не воспроизводит из-за другой реализацииPath.exists; моделирование семантики 3.12 воспроизводит точную ошибку CI. Ограничить mock конкретным backup/stat и изолировать пути journal/state/lock в tmp; добиться зелёного CI на текущем head. Smoke run 178 успешен.[P2] Rollback не сверяет фактически запущенные образы.
infra/deploy/rollback.py:243-265: послеcompose upпроверяется/review, но state записывается из ожидаемогоplanбез проверки image IDs обоих работающих контейнеров. При неожиданном запуске другого образа helper объявит успех и закрепит неверный state. Пере�� записью state сравнить running IDs backend и OpenSearch сplan, как уже делает deploy helper; проверить несовпадение тестом.[P2] Сохраняемый release descriptor отсутствует из-за неверного предположения о cache.
.gitea/workflows/release-images.yaml:52-58только печатает JSON и checksum в лог;deploy/production/README.mdи owner packet объясняют это отключённым cache. В точном act_runner 0.2.13cache.enabled=falseубирает лишьACTIONS_CACHE_URL, но сохраняетACTIONS_RUNTIME_URL; собранный upload-artifact@v3 использует runtime URL, а Gitea 1.25.5 реализует этот upload API. Добавить артефакт JSON+SHA-256 через v3 и подтвердить получение в пробном CI запуске; до живого теста считать совместимость доказанной по протоколу, а не фактом успешной загрузки на этом экземпляре. Настройки runner/cache менять не требуется.Owner-only registry/host/backup/corpus права и данные остаются неизвестными; это отдельные документированные предусловия первого production cutover. Merge в initial_review не выполняю.
Повторно проверил все 30 изменённых файлов PR #59 на
9d8ce6b67fadefa1f10bda1eb05c7a285a0b0df6противmainb5adc09203cbbbd298054248206b9f47ae4a44ca. Четыре исправления к review #308 проверены: восстановление refs после post-rename ошибки, согласование результата alias switch и checkpoint, изоляцияPath.statдля Python 3.12, сверка обоих running image IDs при rollback. Локальные целевые тесты прошли (deployment 39, importer 10); CI run 179 и smoke run 180 зелёные.[P2] Пробный CI не доказывает доступность release artifact. В
.gitea/workflows/ci.yaml(шагVerify Gitea runtime artifact upload) и.gitea/workflows/release-images.yaml(шагUpload verified release descriptor) не заданоif-no-files-found: error. Для закреплённого v3 action отсутствие файла по умолчанию даёт предупреждение и успешный шаг (документация этого commit). Поэтому зелёный CI допускает пустую загрузку. Более того, доступный мне read-only APIGET /repos/admin/akyldash/actions/runs/179/artifactsи список артефактов репозитория вернулиtotal_count=0; этому API principal недоступен сам run (404), так что это не доказывает глобальное отсутствие артефакта, но и не подтверждает требуемое скачивание.Минимальное исправление: задать
if-no-files-found: errorдля обоих upload steps и подтвердить на новом PR запуске, что synthetic marker действительно появился и скачивается из run artifact (достаточно ID/имени/размера и факта успешного чтения, без содержимого секретов). Если текущий run уже имеет артефакт в авторизованном UI, приложить это свидетельство; проверку отсутствующего файла всё равно нужно сделать строгой. Registry publishing, runner/cache, VPS и production не менять. Changelog — после зелёного initial review, merge здесь запрещён.[P1] Align Kaniko destination validation with the new SHA/run-ID tag. The release workflow now passes
backend:${{ github.sha }}-${{ github.run_id }}and the equivalent OpenSearch tag (.gitea/workflows/release-images.yaml:27,37). But.gitea/actions/kaniko-push/release-build.sh:13,18still requires a third-[1-9][0-9]*attempt suffix. An actual SHA/run-ID destination fails this check before/kaniko/executor, so the manual release cannot publish either image. Update both validators and their messages/tests to the chosen tag format. I reproduced the rejection with the exact regex. The current PR CI and runner smoke checks pass; they do not execute this credential-gated publishing path.The earlier recovery and rollback fixes remain intact. Both artifact upload steps now set
if-no-files-found: error; the previous synthetic artifact was independently downloaded and verified. No production release was attempted.Reviewed the complete PR at commit
779743fdb0a950a8295da2c6e035fe8ba4d5a502againstb5adc09203cbbbd298054248206b9f47ae4a44ca. The new validator accepts the workflow'sSHA-run_iddestinations for both images and rejects invalid repositories, commits, run IDs and Dockerfiles; this resolves review #310. The earlier recovery/rollback findings and artifact-upload findings remain resolved. CI and runner smoke checks pass at this head; local deploy and importer tests and shell syntax checks pass. The registry-backed manual release and production owner evidence remain separate owner gates and were not exercised in this review.New commits pushed, approval review dismissed automatically according to repository settings
Полное финальное ревью PR 59: code SHA
eff81c150423402de47e266d2d4550ac1e93216d, baseb5adc09203cbbbd298054248206b9f47ae4a44ca. Код: APPROVED. Все 32 изменённых файла сопоставлены с предыдущим полным ревью; после APPROVED #311 изменился только CHANGELOG. Исправления замечаний #308–#310 сохранены. CI и runner smoke на этом SHA успешны; локально прошли 41 deploy-тест, 10 тестов импортера и shell syntax. Реальная публикация образов и production cutover не выполнялись.RUSSIAN_OWNER_PACKET: APPROVED. Файл
OWNER_HANDOFF_PR59.md, SHA-2561a3fd807acabe445509b035f3876a9f1ac754e4c805229f596022246facc1aa9; проверил revieweragent(ID 7), 2026-10-26 16:37 MSK, относительно code SHAeff81c150423402de47e266d2d4550ac1e93216d. Проверены команды, аргументы, происхождение read-only audit-скрипта, границы backup/restore, требование полного корпуса без исключений и явные неизвестные owner gates. Исправленная процедура скачанного ZIP (новый пустой каталог →release/→ checksum → allowlist) успешно воспроизведена локально на синтетическом descriptor. В документации репозитория неверной команды распаковки нет. Owner gates остаются открытыми: свежий аудит хоста, резервная копия и отдельное восстановление, фактический корпус/alias/canaries, права и retention registry/artifacts, TLS. Это одобрение не подтверждает готовность production и не разрешает деплой или merge.[P2] Сделать checksum проверяемым из скачанного release artifact без восстановления исходной структуры workspace. Сейчас
.gitea/workflows/release-images.yaml:50записывает в sidecar путьrelease/release-manifest.json; шаг загрузки берёт два файла из одного каталогаrelease/(:55–57), поэтому v3 upload action помещает их в корень ZIP. После обычной распаковкиsha256sum -c release-manifest.json.sha256ищет отсутствующийrelease/release-manifest.jsonи завершается с кодом 1. Локально воспроизведено на синтетическом descriptor; реально скачанный smoke artifact того же action также имел файл в корне ZIP. Проверка :62 проходит только в исходном workspace и не проверяет формат скачанного artifact. Минимальное исправление: формировать checksum в каталогеreleaseс именемrelease-manifest.jsonи проверять его из того же каталога; добавить проверку формы скачанного artifact, чтобы регрессия не возвращалась. Обновить owner-команду после изменения формата.Ранее опубликованный APPROVED #313 на этом SHA больше не отражает итог ревью: это формальное REQUEST_CHANGES его заменяет. Остальные исправления #308–#310, changelog, тесты и CI проверены, новых находок по ним нет. RUSSIAN_OWNER_PACKET: текущий документ SHA-256
1a3fd807acabe445509b035f3876a9f1ac754e4c805229f596022246facc1aa9корректно описывает временное восстановление каталогаrelease/для текущего sidecar; после изменения workflow этот шаг станет неверным и документ должен быть пересмотрен на новом hash вместе с новым code SHA. Revieweragent(ID 7), 26 октября 2026 года. Публикация образов, merge и production-действия не выполнялись.Полное ревью PR 59 на текущем code SHA
e40a32971d510683094d9decc7f77b650df59aeaпротив baseb5adc09203cbbbd298054248206b9f47ae4a44ca: APPROVED. После REQUEST_CHANGES #314 исправлены генерация и локальная проверка checksum из каталогаrelease: sidecar теперь содержит basenamerelease-manifest.json, который совпадает с корнем скачанного ZIP. Новый тест запускает shell-команды и проверяет извлечённый артефакт. Я независимо проверил синтетический ZIP: producer checksum, checksum после извлечения и validate_release.py прошли. Все остальные файлы полного PR, включая исправления #308–#310 и changelog, сверены с предыдущим ревью. На этом SHA оба CI-check успешны; локально прошли 42 deploy-теста, 10 тестов импортера и shell syntax.RUSSIAN_OWNER_PACKET: APPROVED.
OWNER_HANDOFF_PR59.mdSHA-256a00bb5ea7863a10ef5aa475999efb0427a38c81382f5cad65026f51b8da047f4проверил revieweragent(ID 7), 2026-10-26 16:46 MSK, относительно code SHAe40a32971d510683094d9decc7f77b650df59aea. Команда из нового пустого каталога скачанного артефактаsha256sum -c release-manifest.json.sha256и валидацияrelease-manifest.jsonпроверены синтетически. Проверены команды, guards, provenance checksum read-only audit, backup/restore, полный корпус без исключений, явные неизвестные и запрет автоматического merge. Owner gates по свежему аудиту хоста, backup/отдельному restore, корпусу/alias/canaries, registry rights/retention и TLS остаются неподтверждёнными; ручной release и production cutover не запускались. Это ревью не разрешает merge или deploy.New commits pushed, approval review dismissed automatically according to repository settings
Проверил весь PR #59 на head
74aa167d16f0343321c9cc0133ba71c8074a26c3противmainf90161f3800de7410d44a9c248d107de220e68f8. Формально запрашиваю исправления:[P1] Автоматическая публикация всегда останавливается на source guard.
.gitea/workflows/release-images.yaml:16-26передаёт SOURCE_WORKFLOW/EVENT/CONCLUSION/BRANCH/SHA, но не SOURCE_RUN_ID.infra/deploy/release_handoff.py:46-47требует непустой числовой run ID для стадии release. При точном окружении workflow проверка завершаетсяsource run ID or commit SHA is invalidдо registry credentials. Передать ID завершённого CI run и проверить тестом связку YAML → CLI, а не только валидатор с вручную заполненным fixture.[P1] Идентичность исходного workflow читается из неподтверждённого поля
workflow_run.name. Оба workflow задают SOURCE_WORKFLOW черезgitea.event.workflow_run.name(release-images.yaml:19,deploy-handoff.yaml:27). Реальные ActionWorkflowRun ответы Gitea 1.25.5 для CI run 583 и smoke run 586 не содержатname, но содержатpath; документация события описывает отдельный объектworkflow. Поэтому текущий guard может получать пустое значение и отклонять оба запуска даже после исправления ID. Использовать проверяемое поле/объект исходного workflow и тест с фактической формой payload Gitea 1.25, сохранив отказ при чужом workflow.[P2] Owner packet оставляет действующей запрещённую локальную backup-процедуру.
docs/operations/DEPLOYMENT_OWNER_PACKET.md:52-55требует архив по документированной cold-backup процедуре, аdocs/operations/BACKUP.mdиDEPLOYMENT.mdвсё ещё дают команды полного локального архива в/var/backups/akyldash. Владелец уже запретил хранить на VPS даже временный полный архив. Явно пометить эти команды как отменённые текущим owner-решением и направить к отдельному проекту внешней копии; реализацию внешнего backup в этот CD-патч не добавлять.Ранее отмеченные recovery/alias/rollback/artifact-checksum исправления перепроверены на текущем дереве; локально прошли 74 deployment и 10 importer тестов. Gitea CI и runner smoke на этом SHA успешны, но новые workflow_run пути ими не исполнялись. Handoff остаётся честно dry-run: ZIP и host не проверены. Registry secrets, host transport и production не менялись. Это initial_review; merge запрещён.
Проверил весь PR #59 на head
f8483badcf0bad100ff331b1e2daca7d7c39ace9противmainf90161f3800de7410d44a9c248d107de220e68f8. Исправления review #318 проверены: release передаёт ID исходного CI run; оба workflow сверяют имя из отдельного объекта workflow, фактический run path, repository, event, branch, conclusion и SHA; тест связывает YAML-env с CLI на форме Gitea 1.25. Предыдущие исправления #308–#314 и merge main остаются в текущем дереве. Запрет локального полного backup на VPS отражён в BACKUP, DEPLOYMENT и owner packet; внешняя backup-цепочка остаётся отдельным обязательным gate перед live apply.Локально: 75 deployment и 10 importer тестов, AST syntax и diff --check прошли. Gitea CI и runner smoke успешны на этом SHA. Release workflow с registry credentials и вложенная цепочка workflow_run ещё не исполнялись на main; handoff остаётся dry-run без ZIP/SSH/host apply. Поэтому APPROVED означает готовность текущего PR к следующему этапу ревью/changelog, а не production-readiness. В initial_review merge и production-действия запрещены. Новых существенных замечаний нет.
New commits pushed, approval review dismissed automatically according to repository settings
Повторно проверил весь PR #59 на head
6be28418ab1732785d7947cf9cfada85185ddddcпротивmainf90161f3800de7410d44a9c248d107de220e68f8. После APPROVED #319 изменился только CHANGELOG.md; код и workflow остались теми же. Новая запись корректно описывает цепочку successful main CI → digest image release → dry-run handoff, условность registry secrets, отсутствие ZIP download/SSH/host apply и отдельный обязательный внешний backup/restore gate. Запрещённая владельцем локальная полная копия на VPS помечена в операционных документах как superseded.Исправления прежних замечаний #308–#314 и #318 остаются в текущем дереве: source run ID, отдельный workflow.name, фактический run path/repository/event/branch/conclusion/SHA, YAML-env→CLI регрессионный тест, rollback/recovery/alias и checksum. Локально на неизменном кодовом дереве прошли 75 deployment и 10 importer тестов; текущий diff --check чист. Gitea CI run 591 и runner smoke run 592 успешны на этом SHA. Существенных замечаний к PR-коду нет.
Это APPROVED для текущего PR head, не подтверждение живого CD: release workflow с registry credentials и вложенная workflow_run цепочка на main ещё не исполнялись; ZIP, host transport и внешний backup/restore не реализованы или не проверены. В текущем назначении phase=initial_review merge и production-действия запрещены.
New commits pushed, approval review dismissed automatically according to repository settings
Формальное первичное ревью коммита
4a7e907be7: изменения и тесты проверены, CI и runner smoke успешны. Замечаний по коду нет. Production gates и deploy-handoff остаются отдельными условиями; деплой не подтверждён.New commits pushed, approval review dismissed automatically according to repository settings
Финальное ревью полного PR на коммите
0630a774cf: изменения, прежние исправления и новый CHANGELOG проверены; CI и runner smoke успешны. Замечаний по коду нет. Handoff остаётся NOT DEPLOYED; production D:, SSH/VPS и полный backup/restore ещё требуют отдельной проверки. Это ревью не подтверждает production deployment.New commits pushed, approval review dismissed automatically according to repository settings
Блокирующее замечание к infra/deploy/windows-release-trigger.example.xml:41: путь C:\Program Files\Akyldash\receive_external.py в не заключён в кавычки. После включения задачи Windows разделит его по пробелу, Python не откроет нужный скрипт, и --once не запустится. Заключите путь к скрипту в кавычки внутри Arguments и добавьте проверку итогового argv на Windows. Остальные проверенные новые guards выглядят согласованно; CI успешен. Production CD и развёртывание не подтверждены.
Первичное ревью полного PR на коммите
8ede9f2123: замечание #367 по кавычкам в Task Scheduler XML исправлено; точный diff и целевой Windows fixture проверены. Ранее проверенные source/backup/deploy guards сохраняются, CI и runner smoke успешны. Новых замечаний по коду нет. Шаблон остаётся выключенным; production D:, SSH/VPS, полный backup/restore и активация CD не подтверждены.New commits pushed, approval review dismissed automatically according to repository settings
Финальное ревью полного PR на коммите
6cab6fcc95: код привязки и прежние исправления проверены, новый CHANGELOG корректно описывает выключенный trigger и ограничения. Замечание #367 устранено; CI и runner smoke успешны. Замечаний по коду нет. Handoff остаётся NOT DEPLOYED, Windows Task Scheduler/SSH/VPS и production D: не активировались; полный backup/restore и owner bootstrap ещё требуются.