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.
Критерии приёмки¶
- Server release построен из точного нового commit, а не dirty worktree; локальные evidence-документы не входят в content-addressed archive и не подменяют source SHA.
- До migration создан logical dump DEV и проверен через
pg_restore --list. - Предыдущие image/env ссылки сохранены как rollback point; STAGE не изменился.
SKUARO_EMAIL_PROVIDER=resendи полный Resend config переданы API без вывода значений; активный env не содержит непустых Gmail credentials, secret-файлы имеют mode600, а предыдущий Gmail env сохранён только как rollback point.- Migration завершилась
0; DEV PostgreSQL/API/web healthy, worker работает без restart loop; readiness возвращает200. - Внешний DEV сохраняет HTTPS, HSTS/noindex и expected guest/API access behavior.
- Синтетический sign-up принят; login до verify возвращает
403 EMAIL_NOT_VERIFIED; фактическое письмо доставлено; первая verification-ссылка успешна; повтор той же ссылки с фактическимcallbackURLвозвращает302на разрешённый callback и не создаёт session, tenant или capabilities; login после verify успешен. /api/v1/accessвозвращаетplatformRole: null,settings: true,today: false,admin: false,startPath: /home; прямые/todayи/admin/*остаются закрыты.- 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 запросов. - При любом 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; divergence0/0, CI run32884394033завершён успешно. - Read-only server snapshot: DEV/STAGE/edge Compose валидны, текущий Caddy валиден,
ожидаемые контейнеры работают без restart loop, доступно около
6108 MiB, env имеют mode600, 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-256729789531b29b9399495e70f83b08715499de8e2261312e8761ff27cdea71c4f; image labels подтвердили полный source SHA. - Перед migration созданы два валидных pre-deploy DEV dump с mode
600; второй актуальный dumpskuaro-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 продолжал возвращать upstreamstrict-origin-when-cross-origin. Обычный edgeheaderвыполнялся до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.2proxy-test подтвердил, что deferred directiveheader >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-запуски дали E2E25/25и visual30/30. - Edge/app Caddyfile повторно прошли
validateиadapt --validateна Caddy2.10.2;git diff --checkуспешен. - После private push требуется успешный remote CI. Даже успешный CI не разрешает повторный DEV deploy: владелец должен возобновить его отдельно.