# Хэндофф: G1/SP1 ЗАКРЫТ + что дальше (для новой сессии)

**Дата:** 18.06.2026. Кодовая фраза стены: **«роутер-наставник»**.
**Режим работы прошлой сессии:** реализация под стеной **через per-step escape** (владелец даёт эскейп на каждый шаг). Не печать плана, а пошаговые эскейпы.

---

## Статус: SP1 ГОТОВ и закоммичен

**Коммит `53fb7b77` на `main`** — «feat: G1/SP1 самозапись клиента с подтверждением почты 6-значным кодом» (53 файла, 14 новых).

Что построено (backend самозаписи):
- 3 публичных эндпоинта: `POST /api/auth/register`, `/confirm-email`, `/resend-code` (+throttle `auth-register`).
- `RegistrationService` (register/confirm/resend; advisory-лок `pg_advisory_xact_lock` против гонки дублей; генерация subdomain; старт-баланс **300 ₽** при подтверждении).
- `RegistrationController`, шов капчи (`CaptchaVerifier` + dev-драйвер `NullCaptchaVerifier`; реальный Yandex SmartCaptcha — позже, SP3/ops), модель `EmailVerification`, письмо `EmailVerificationCodeMail`, 3 form-request.
- Схема v8.42: `email_verifications +code_hash +failed_attempts`; **`tenants.status` расширен VARCHAR(20)→(30)**; миграция `2026_06_18_120000`, `schema.sql`, `CHANGELOG_schema.md`.
- Удалён старый `AuthController::register()` (был attach к первому тенанту); роут переехал на `RegistrationController`.

**Тесты (на `liderra_testing`):** `RegistrationTest` 11/11 ✅, `AuthControllerTest` 10/10 ✅. Pint чистый, миграция dev-БД применена.

Спека: `docs/superpowers/specs/2026-06-18-g1-sp1-self-registration-email-spec-v3.md`.
План: `docs/superpowers/plans/2026-06-18-g1-sp1-self-registration-email-plan-v7.md`.

### 3 бага, найденных и закрытых по ходу (для контекста)
1. **Транзакция на shared-PDO**: под `DatabaseTransactions`+`SharesSupplierPdo` соединение `pgsql_supplier` делит уже-открытый PDO, но не уровень транзакции → `->transaction()` падал «active transaction». Фикс — хелпер `RegistrationService::atomic()` (если PDO уже в транзакции — участвуем без вложенного begin; иначе открываем свою). Прод-поведение не изменилось.
2. **`tenants.status` не в `$fillable`** модели Tenant → `create([...'status'...])` молча отбрасывал → DB-default `'active'`. Фикс — выставляем `$tenant->status` явно + `save()`.
3. **Латентный дефект схемы**: `status VARCHAR(20)`, а CHECK допускал `'pending_email_confirm'` (21 символ) → не влезало. Расширили до VARCHAR(30) (миграция + schema.sql + CHANGELOG).

### Хвосты (необязательные, на усмотрение владельца)
- `pint` форматнул весь `app/` → в рабочем дереве остались **незакоммиченные** стилевые правки чужих файлов (NotificationService, BillingController, Imitation-тесты и т.п.) — в коммит SP1 НЕ вошли. Откатить: `git checkout -- <файлы>` или оставить.
- Черновики спеки/плана (spec-v2, plan-v2…v6 и пр.) — untracked мусор от итераций; почистить при желании. Канон — **spec-v3 + plan-v7**.
- Прод-выката не было (работа на локалке).

---

## Что дальше (G1 не закрыт целиком)

G1 (самозапись клиента) = **SP1 (готов)** + **SP2** + **SP3**:
- **SP2** — реквизиты юр.лица/ИП/физлица + тяга ИНН по DaData + маска телефона + **гейт первого проекта** (нельзя создать первый проект до заполнения реквизитов). Backend, проверяемо Pest.
- **SP3** — фронт самозаписи/подтверждения/реквизитов. ⚠️ Фронт-тесты vitest сломаны (находка **G8**) — фронт-правки тестами не проверить.

Решения владельца по SP1 (контекст для SP2): старт-баланс 300 ₽ при подтверждении почты; тенант в `pending_email_confirm` до подтверждения; капча = серверный шов (реальный провайдер позже).

---

## КАК РАБОТАТЬ НОВОЙ СЕССИИ — per-step escape (важно)

Стена «роутер-наставник» включена (block). Прошлая сессия делала реализацию НЕ через печать плана, а **через эскейп на каждый шаг** (решение владельца). Рецепт, который ОТРАБОТАЛ:

1. **Сначала прочитать гайд** `docs/superpowers/router-mentor-wall-GUIDE.md` (поток, escape-механика, грабли).
2. Вся **разведка ДО** (Read/Grep схемы, конфигов, точных строк для Edit) — в разговорном режиме чтение свободно.
3. **Эскейп подписывается ТОЛЬКО кнопкой AskUserQuestion**, текст которой = `FLOOR-ESCAPE: <canonicalAction>`. Владелец выбирает кнопку → среда подписывает грант (окно 5 мин, one-shot).
4. **Канонические строки действия** (точное совпадение обязательно):
   - Write/Edit → `write:<абсолютный путь, lowercase, прямые слэши>`. Пример: `write:c:/моя/проекты/портал crm/документация/app/app/models/emailverification.php`.
   - Bash → `bash:<команда, пробелы схлопнуты в один>`. Пример: `bash:composer --working-dir=app test -- tests/Feature/Auth/RegistrationTest.php`.
5. **Батчинг**: одна карточка AskUserQuestion = **до 4 вопросов**, хук подписывает грант на КАЖДЫЙ ответ → до 4 эскейпов за клик-сессию. Владелец просил батчить по 3-4, не дёргать по одному.
6. **Грабли батча**: НЕ класть два действия с ОДИНАКОВОЙ canonical-строкой (два Edit одного файла) в одну карточку — у грантов совпадёт `ts`, гашение первого погасит второй. Одинаковые файлы — в разные карточки.
7. **Edit требует предварительного Read** файла в этой сессии (Grep не считается). Читай файл перед Edit.
8. **Удаление кода**: Edit с anchor-подходом (включить в old_string и new_string стабильный «якорь» после удаляемого блока), не пустой new_string.
9. **Bash под эскейпом**: команды одиночные (без `;`/`&&`/пайпов). `migrate`/`composer test` — ок; `migrate:fresh`/`node -e`/install — floor-опасны (но escape чтит и пол). Тест-прогоны короткие, в окно 5 мин укладываются.
10. **Зелёные прогоны** Pest гонять самому через эскейп (TDD «watch it pass»); диагностику упавших — навыком `systematic-debugging`.
11. **Коммит/финализация (pint + миграция dev-БД) — терминал владельца** (минует стену): `composer --working-dir=app pint`, `php app/artisan migrate --force`, затем `$env:LEFTHOOK="0"; git add <точные пути>; git commit -m "…" -m "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"; $env:LEFTHOOK=$null`.
12. **Каждый ход с мутацией**: первой строкой `coverage: skill:<вызванный-в-этом-ходе> | direct:<role>`; при user-directed методе — строка `<!-- routing: provenance=user_directed_method node=<…> counterfactual=<…> -->`. Навык для coverage:skill должен быть РЕАЛЬНО вызван в ТЕКУЩЕМ ходе.

Тест-БД `liderra_testing` (phpunit.xml). `composer test` миграции НЕ гоняет — миграцию тест-БД применять явным `DB_DATABASE=liderra_testing php app/artisan migrate --force` (pgsql_supplier наследует `DB_DATABASE`). Если миграция уже отмечена выполненной — `migrate:rollback --step=1` + `migrate`.

---

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