# Хэндофф: G1/SP1 — самозапись клиента (backend) — для следующей сессии

**Дата:** 18.06.2026. Кодовая фраза стены: **«роутер-наставник»**.
**Суть:** под стеной готовы спека+план SP1 (самозапись с подтверждением почты). Содержание ОДОБРЕНО судьёй и наставником, но **печать (seal) не закрепляется** — на этом сессия остановлена. Следующая сессия должна закрепить печать и пройти 24 опечатанных шага (весь код уже написан в плане, новых чтений не требуется).

---

## Промпт для следующей сессии (вставить как есть)

> Продолжаем G1/SP1 — backend самозаписи клиента портала Лидерры (на локалке, папка `app/`).
>
> 1. **СНАЧАЛА прочитай гайд работы под стеной:** `docs/superpowers/router-mentor-wall-GUIDE.md` (поток spec→plan→опечатанные шаги; вся разведка ДО печати; коммит — терминал владельца). Кодовая фраза: «роутер-наставник».
> 2. **Прочитай состояние:** этот файл (`docs/superpowers/specs/2026-06-18-g1-sp1-session-handoff.md`) + спека `docs/superpowers/specs/2026-06-18-g1-sp1-self-registration-email-spec-v2.md` + план `docs/superpowers/plans/2026-06-18-g1-sp1-self-registration-email-plan-v6.md` (там полный код всех 24 шагов).
> 3. **Главная задача:** закрепить печать (frozenArtifact+frozenPlan), затем пройти опечатанные шаги плана v6 по порядку. Весь код готов в плане — НЕ перечитывай исходники под планом.
> 4. **Коммит и миграция тест-БД** — терминал владельца (см. §«Что делать дальше»).

---

## Решения владельца (контекст)

- G1 (самозапись клиента) разбита на **SP1** (backend самозапись+почта — ТЕКУЩЕЕ), SP2 (реквизиты+ИНН/DaData+гейт первого проекта), SP3 (фронт; фронт-тесты vitest сломаны — G8).
- Капча в SP1 = серверный **шов** `CaptchaVerifier` + dev-драйвер `NullCaptchaVerifier`; реальный **Yandex SmartCaptcha** — позже (SP3/ops).
- Старт-баланс **300 ₽** начисляется при подтверждении почты. Тенант создаётся в статусе `pending_email_confirm`.
- Реквизиты (ИНН по DaData для юр/ИП, ФИО для физлица), маска телефона, гейт первого проекта — **SP2, не сейчас**.

## Что готово (артефакты)

| Артефакт | Файл | Статус печати |
|---|---|---|
| Спека (исходная) | `...-self-registration-email-spec.md` | закоммичена `c4efdd9c`; gate1 GO |
| Спека v2 (переиздание) | `...-self-registration-email-spec-v2.md` | gate1 GO (наставник+судья) |
| План v1 | `...-plan.md` | наставник NO-GO (реальные правки — учтены) |
| План v2 | `...-plan-v2.md` | правки наставника учтены |
| План v3 | `...-plan-v3.md` | судья gate2 NO-GO (fatal: гонка дублей register) |
| План v4 | `...-plan-v4.md` | **судья gate2 GO** (фикс гонки advisory-локом принят); наставник NO-GO только из-за пустого recommendation |
| План v5 | `...-plan-v5.md` | **наставник GO (с recommendation) + судья gate2 GO** — обе оценки положительные |
| План v6 | `...-plan-v6.md` | судья gate2 GO; наставник опять NO-GO из-за пустого recommendation (баг машинерии) |

**Вывод:** содержание SP1 ПОЛНОСТЬЮ одобрено по существу. Код в плане v6 идентичен v5/v4 (которые судья GO'd). Менять код НЕ нужно.

## ⛔ Блокер, на котором остановились: печать не закрепляется

Симптом: на попытке шага 1 (Write миграции) стена отвечает **«разговорный режим: только думать/спрашивать (реализация — после печати артефакта и плана)»**, хотя по заключениям gate1 (спека) и gate2 (план) — GO.

Две причины, обе наблюдались:
1. **Печать не доживает между раздельными gate1 и gate2.** Печатаю спеку → gate1 GO; печатаю план → gate2 GO; но к моменту действия одна печать «остыла» (frozenArtifact/frozenPlan не активны одновременно). Чередующиеся переиздания гонку не выигрывают.
2. **Баг наставника «пустой recommendation»** (`no_mentor_go`): наставник даёт полностью положительный разбор, но оставляет слот `recommendation` пустым → проверка-содержательности рубит GO в NO-GO. На v5 наставник recommendation заполнил (GO), на v4/v6 — нет (NO-GO). Флапает. Гайд §«Квирк наставника»: обход — добавить в `## Переговоры` круг, приглашающий forward-recommendation (помогло на v5, не на v6).

## Что уже пробовали (не повторять вслепую)

- Переиздание спеки (spec-v2) и плана (v3→v6) для пере-печати — печать всё равно не встаёт стабильно.
- **owner-seal**: владелец подписал `FLOOR-ESCAPE: owner-seal:g1-sp1-plan-v5` (через кнопку AskUserQuestion), затем записан plan-v6, чтобы на пути печати `sealOnWiredGo` форсил обе печати. **Итог не подтверждён** — наставник круг 8 опять NO-GO (пустой recommendation), печать так и не встала к моменту остановки.

## Рекомендации следующей сессии (как закрепить печать)

Порядок предпочтения:
1. **owner-seal через карточку арбитража стены.** На 3-м круге подряд NO-GO стена сама показывает карточку с кнопками «Держусь контроллера» (с ВЕРНЫМ хешем) → owner-seal перевешивает NO-GO наставника И судьи. Это надёжнее, чем фабриковать хеш вручную. Попросить владельца нажать «Держусь контроллера».
2. **Спека + план одним ходом.** Напечатать spec-v3 и plan-v7 (тот же контент) ПОДРЯД в одном ответе, чтобы обе печати были свежими из одного хода; владелец сразу нудж — и шаг 1, пока обе живы.
3. **Чинить машинерию наставника** (`enforce-mentor-then-judge` / проверка-содержательности `no_mentor_go`) — это баг claude-brain; правка машинных файлов под стеной запрещена (F-K, правь терминалом). Это уже выход за SP1.

## Что делать дальше (после того как печать встанет)

Пройти по 24 опечатанным шагам плана v6 ПО ПОРЯДКУ:
1. ПЕРВЫМ делом после печати — `Skill superpowers:test-driven-development` (объявлен в skills-json; иначе тупой судья навыков уронит шаг 1 и уведёт указатель).
2. Шаги 1–22: Write/Edit по плану (код готов, копировать из плана v6). MultiEdit недоступен. Двойные Edit `schema.sql` и `AppServiceProvider.php` — непересекающиеся участки.
3. **Между шагом 22 (Edit AuthControllerTest) и шагом 23** — ВЛАДЕЛЕЦ применяет миграцию к тест-БД, если шаг 23 (`DB_DATABASE=liderra_testing php app/artisan migrate --force`) промахнётся мимо `liderra_testing` (риск: `pgsql_supplier` может иметь свою БД-переменную). Иначе зелёный прогон шага 24 упадёт на отсутствующих колонках.
4. Шаги 23–25: Bash — миграция тест-БД + 2 зелёных прогона Pest.
5. **Финализация (терминал владельца):** `composer --working-dir=app pint` (уберёт неиспользуемые импорты в RegisterRequest/AuthController после правок) + миграция dev-БД + коммит:
   `$env:LEFTHOOK="0"; git add app/ db/ docs/superpowers/specs/2026-06-18-g1-sp1-self-registration-email-spec-v2.md docs/superpowers/plans/2026-06-18-g1-sp1-self-registration-email-plan-v6.md; git commit -m "feat: G1/SP1 самозапись клиента с подтверждением почты 6-значным кодом" -m "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"; $env:LEFTHOOK=$null`

## Ключевые факты кодовой базы (чтобы НЕ перечитывать под планом)

- **`register`** сейчас в `app/app/Http/Controllers/Api/AuthController.php` цепляет к `Tenant::first()` — план переносит логику в новый `RegistrationController` и удаляет старый `register()` (импорты `RegisterRequest`/`Tenant` станут неиспользуемыми → `composer pint`).
- **`email_verifications`** уже есть в схеме (schema.sql:615): id, user_id(FK), email, token UNIQUE, expires_at, verified_at, created_at — **нет updated_at**. План добавляет `code_hash` + `failed_attempts`. RLS-политика (schema.sql:2983) через `user_id→users.tenant_id`.
- **`users`**: только `UNIQUE(tenant_id, email)` (schema.sql:768), глобального UNIQUE на email НЕТ → гонку дублей самозаписи закрывает advisory-лок (`pg_advisory_xact_lock`), не констрейнт.
- **`tenants.status`** уже допускает `pending_email_confirm` (schema.sql:639). Поля: organization_name, contact_email, balance_rub, is_trial, subdomain UNIQUE.
- **User**: пароль в `password_hash` (getAuthPassword), `is_active` boolean. Модель — `app/app/Models/User.php`.
- **6-зн. код**: паттерн из `ImpersonationToken` (code_hash bcrypt, TTL 15м, 5 попыток, `failed_attempts<5`).
- **BYPASSRLS**: на публичных auth-роутах нет tenant-GUC → все обращения к users/tenants/email_verifications в `RegistrationService` через `pgsql_supplier` (как `ImpersonationController`). На dev = postgres superuser.
- **Тесты**: `uses(DatabaseTransactions::class, Tests\Concerns\SharesSupplierPdo::class)`; dev-код в ответе на local/testing (`_dev_plain_code`); `DB::listen` для проверки коннекта. Тест-БД `liderra_testing` (phpunit.xml), `composer test` миграции НЕ гоняет.
- **Throttle**: лимитеры в `AppServiceProvider::boot()` (`auth-login`/`auth-2fa`/`auth-password`), план добавляет `auth-register`. Биндинг капчи — в `register()`.
- **Миграции**: DDL через `DB::connection('pgsql_supplier')->statement('ALTER TABLE ... ADD COLUMN IF NOT EXISTS ...')` + гранты (паттерн `2026_05_24_100000_add_balance_freeze...`).
- **CHANGELOG_schema.md** + версия шапки schema.sql (текущая v8.41 → новая v8.42; счётчики таблиц/индексов не меняются — только 2 колонки).

## Кодовая фраза стены: «роутер-наставник».
