Перейти к содержанию

Task card: deploy Resend Auth candidate в DEV

  • Дата: 2026-08-25.
  • Статус: BLOCKED_PENDING_EXPLICIT_DEV_DEPLOY_RESUME_AFTER_CLOSEOUT_CI.
  • Исполнитель: основной агент.
  • Независимые verifier: project reviewer до server mutation; отдельный tester/reviewer для post-deploy external/runtime/Auth/log gate.
  • Rejected candidate commit: 0ddd04d0126322b83cfa069be495f5210d8645e0 из приватной origin/DEV.
  • Повторный candidate: 5e63c5e148b00660ccc9e88f6d5bed9406ed2dbf из приватной origin/DEV; local/remote equality и CI проверяются перед mutation.
  • Связанные решения: 0013, 0016, 0017, 0024, 0025, 0026.

Цель

Развернуть в существующем DEV-контуре новый зафиксированный candidate на базе 0ddd04d после принятия security fix, подключить подготовленный Resend HTTPS transport без раскрытия секретов и пройти полный синтетический sign-up → email verify → login.

Scope

Включено

  • read-only preflight DEV и контроль неизменности STAGE;
  • точечное чтение только необходимых известных secret-файлов без вывода значений;
  • проверяемый logical dump DEV до запуска migration;
  • content-addressed release из нового проверенного commit, build server/web images и deploy только Compose project skuaro-dev;
  • переключение активного root-only DEV env на Resend: Gmail credentials в активном env отсутствуют/пусты, а обратимый Gmail fallback сохраняется только во внешнем secret-file и в защищённой rollback-копии предыдущего .env;
  • health, migration, worker, internal/external HTTPS и security-header smoke;
  • синтетическая регистрация без клиентских данных, переход по фактической одноразовой verification-ссылке и успешный login/access check;
  • удаление созданной синтетической учётной записи допускается только если это явно предусмотрено безопасным тестовым cleanup; иначе она остаётся отмеченным DEV test artifact.

Исключено

  • STAGE/PROD, merge, PR, DNS, GitHub settings и pipeline;
  • реальные клиентские данные и массовая отправка;
  • изменение Auth/email product policy, onboarding implementation и новые зависимости;
  • удаление volumes, старых releases/images, backups или изменение backup timer/retention;
  • обновление ОС и reboot.

Критерии приёмки

  1. Server release построен из точного нового commit, а не dirty worktree; локальные evidence-документы не входят в content-addressed archive и не подменяют source SHA.
  2. До migration создан logical dump DEV и проверен через pg_restore --list.
  3. Предыдущие image/env ссылки сохранены как rollback point; STAGE не изменился.
  4. SKUARO_EMAIL_PROVIDER=resend и полный Resend config переданы API без вывода значений; активный env не содержит непустых Gmail credentials, secret-файлы имеют mode 600, а предыдущий Gmail env сохранён только как rollback point.
  5. Migration завершилась 0; DEV PostgreSQL/API/web healthy, worker работает без restart loop; readiness возвращает 200.
  6. Внешний DEV сохраняет HTTPS, HSTS/noindex и expected guest/API access behavior.
  7. Синтетический sign-up принят; login до verify возвращает 403 EMAIL_NOT_VERIFIED; фактическое письмо доставлено; первая verification-ссылка успешна; повтор той же ссылки с фактическим callbackURL возвращает 302 на разрешённый callback и не создаёт session, tenant или capabilities; login после verify успешен.
  8. /api/v1/access возвращает platformRole: null, settings: true, today: false, admin: false, startPath: /home; прямые /today и /admin/* остаются закрыты.
  9. API, edge access/process и web Caddy process logs не содержат API key, email, пароль или synthetic verification/reset/referrer markers; success и upstream fail-path проверяются для verification API URL, reset API callback, frontend /reset-password?token=... и последующих same-origin запросов.
  10. При любом fail после переключения выполняется откат только DEV на сохранённые images/env; volumes и backups не удаляются.

Ожидаемые артефакты

  • точный release/content ID и image IDs;
  • backup/rollback evidence без secret values;
  • migration/health/runtime/external smoke evidence;
  • evidence полного Auth flow с редактированными идентификаторами;
  • обновлённые task card, docs/STATUS.md и session log без commit/push.

Обязательные проверки

  • local/remote commit equality и clean worktree;
  • preflight disk/containers/images/Compose/STAGE snapshot;
  • logical dump + pg_restore --list;
  • Compose config и image build;
  • migration exit, health, worker/log smoke;
  • external HTTPS guest/access/security headers;
  • controlled Auth flow и post-login fail-closed access;
  • login-before-verify, безопасный идемпотентный verification replay без новой session/ tenant/capabilities и marker search в DEV access log, edge/web Caddy process logs и API logs для verification/reset/frontend/referrer success и fail-path;
  • post-deploy STAGE image/start-time и внешнего header behavior comparison; shared edge logger и Product App security contract соответствуют принятому решению 0026.

Permissions

  • пользователь явно возобновил следующий шаг сообщением «следующий шаг» сразу после closeout и предложения deploy exact commit 5e63c5e в DEV с полным синтетическим Auth flow;
  • разрешение относится только к DEV deploy, одной необходимой Auth-отправке и точечному использованию существующих секретов;
  • на момент deploy отдельной команды закрываем сессию не было: commit/push тогда не разрешались; последующая команда закрытия зафиксирована отдельным разделом ниже.

Blocked when

  • новый candidate ещё не зафиксирован в origin/DEV или local/remote SHA различаются;
  • рабочее дерево содержит неизвестные изменения до deploy packaging;
  • невозможно определить точный server target или безопасно получить необходимый secret;
  • нет проверяемого dump/rollback point, недостаточно диска или STAGE isolation не доказана;
  • provider config неполон/смешан, migration/health fail или verification email недоступен;
  • новый candidate не закрывает token redaction одновременно в API и edge logs;
  • для продолжения требуется раскрыть secret/PII, изменить STAGE/PROD/DNS либо удалить данные.

Результат preflight review

Независимый reviewer выдал REJECTED: Better Auth 1.7.1 формирует ссылку /verify-email?token=..., candidate 0ddd04d логирует полный req.url в Fastify и полный request URI в Caddy access log. До нового SHA с проверенной защитой обоих слоёв server mutation запрещена. Read-only preflight подтвердил достаточный диск, healthy DEV/STAGE, корректные Compose/Caddy и существующий rollback state; сервер не изменялся.

Первоначальное локальное исправление после четырёх review-итераций получило VERIFIED, но DEV/STAGE-развилка позднее заменена принятым решением 0026: Auth log security становится общей production-ready policy для всех Product App runtime. Повторный независимый gate этой реализации завершён; deploy остаётся заблокирован до нового clean commit в origin/DEV и преддеплойной проверки candidate.

Повторный gate решения 0026 завершён: после исправления percent-encoded query-key bypass tester и reviewer независимо выдали VERIFIED, coordinator присвоил ACCEPTED_FOR_HANDOFF. Git-closeout разрешён отдельной командой владельца; после него оставшаяся блокировка — явное возобновление DEV deploy и преддеплойная проверка нового совпадающего local/remote candidate SHA.

Preflight exact candidate 5e63c5e

  • Local HEAD, origin/DEV и GitHub CI head совпадают на 5e63c5e148b00660ccc9e88f6d5bed9406ed2dbf; divergence 0/0, CI run 32884394033 завершён успешно.
  • Read-only server snapshot: DEV/STAGE/edge Compose валидны, текущий Caddy валиден, ожидаемые контейнеры работают без restart loop, доступно около 6108 MiB, env имеют mode 600, STAGE image/start/checksum snapshot зафиксирован.
  • DEV всё ещё использует Gmail; переключение на Resend и server mutation не выполнены.
  • Независимый reviewer выдал BLOCKED: общий skuaro-edge обслуживает DEV и legacy STAGE App, поэтому применение решения 0026 изменит security header/logging behavior STAGE. Это несовместимо с текущим разрешением «только DEV» и требует отдельного разрешения на shared-edge mutation и rollback обоих доменов.
  • Системный permission gate отдельно отклонил чтение/перенос значений из трёх известных внешних secret-files по общей формулировке «следующий шаг». Для продолжения нужно прямое разрешение на использование этих точных файлов без вывода значений.
  • До mutation должен быть назначен независимый post-deploy verifier; основной агент не может быть единственным финальным проверяющим критического Auth/security deploy.

Разрешение владельца 2026-08-26

Владелец ответил «ок, приступаем» непосредственно на запрос разрешения, который явно перечислял:

  • точечное использование без вывода значений config_server-skuaro_top.env, config_deploy-skuaro_top.env, config_skuaro_Email.env и config_skuaro_Resend.env;
  • security-only обновление общего skuaro-edge по решению 0026, включая ожидаемое изменение header/logging legacy STAGE и безопасный rollback edge;
  • DEV logical dump, deploy exact commit 5e63c5e, один синтетический Auth flow и точечное получение его тестового письма;
  • независимую post-deploy проверку.

Назначен независимый verifier dev_runtime_verifier; он работает read-only и не исправляет результат executor.

Live deploy attempt и обязательный rollback 2026-08-26

  • Exact release git-5e63c5e148b0 собран из archive SHA-256 729789531b29b9399495e70f83b08715499de8e2261312e8761ff27cdea71c4f; image labels подтвердили полный source SHA.
  • Перед migration созданы два валидных pre-deploy DEV dump с mode 600; второй актуальный dump skuaro-dev-20260825T191404Z-pre-git-5e63c5e148b0.dump повторно проверен через pg_restore --list.
  • Первая попытка остановилась на невозможном caddy reload при admin off. Первый rollback trap под set -e остановился на unhealthy старом API до возврата edge: exported Resend variables из candidate shell перекрыли восстановленный Gmail .env, несмотря на --env-file. Recovery завершён из чистого SSH process; процедура исправлена на edge recreate, очистку candidate env перед DEV Compose и независимую фиксацию recovery exit status. DEV/edge восстановлены и readiness подтверждён до повторной попытки.
  • Повторный deploy завершил migration 0, DEV был healthy на exact images и Resend без активных Gmail credentials; edge candidate применился через recreate.
  • Обязательный external smoke обнаружил дефект candidate: DEV возвращал Referrer-Policy: no-referrer, но legacy STAGE продолжал возвращать upstream strict-origin-when-cross-origin. Обычный edge header выполнялся до reverse_proxy и не перекрывал header старого STAGE App.
  • До Auth sign-up/email выполнен обязательный rollback DEV и общего edge. DEV снова healthy на прежних images/Gmail; STAGE images, start times, volumes и данные не изменились; оба домена вернули прежний header. Backups, release и images сохранены, volumes не удалялись.
  • Изолированный Caddy 2.10.2 proxy-test подтвердил, что deferred directive header >Referrer-Policy no-referrer перекрывает upstream header. Локально внесено это узкое исправление и усилено regression assertion; новый deploy заблокирован до independent verification и нового clean SHA в origin/DEV.

Первый independent cycle этого live-header fix дал REJECTED: deferred directive один исправлял proxied 200, но не добавлял header на ранний Basic Auth 401 и Caddy-generated upstream 502. Negative control verifier подтвердил требуемую пару: immediate header Referrer-Policy no-referrer для edge responses и deferred header >Referrer-Policy no-referrer для перекрытия legacy upstream. Executor внёс эту пару и расширил regression assertion. Cycle 2 tester независимо подтвердил Caddy 2.10.2 normal upstream 200, early Basic Auth 401, upstream-fail 502, отсутствие duplicate header, narrow sensitive log_skip и ordinary access logging; статус local-fix gate — VERIFIED. Reviewer независимо подтвердил correctness, security, решение 0026 и narrow scope; coordinator присвоил локальному fix ACCEPTED_FOR_HANDOFF только к новому Git-closeout.

Git-closeout live-header fix 2026-08-26

  • Владелец отдельной командой разрешил документирование, проверки, commit и обычный push только в приватную ветку DEV; deploy, merge, PR и STAGE/PROD исключены.
  • Closeout повторил toolchain, boundaries, lint, typecheck, unit 128/128, product build, Storybook и OpenAPI drift. Sandbox-запуск browser gate остановился только на listen EPERM; отдельные разрешённые loopback-запуски дали E2E 25/25 и visual 30/30.
  • Edge/app Caddyfile повторно прошли validate и adapt --validate на Caddy 2.10.2; git diff --check успешен.
  • После private push требуется успешный remote CI. Даже успешный CI не разрешает повторный DEV deploy: владелец должен возобновить его отдельно.