Договор ЮKassa подписан, магазин 1392092, на проде в кластерной базе заведены legal_entities ИП id=1 + payment_gateways yookassa id=2 active + webhook payment.succeeded. Осталось включить флаг billing_yookassa_enabled + живой тест 100р. Поправка к ранбуку: после переезда на Managed PG данные приложения заводить через app/Eloquent, не через peer-psql на VM.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Полный комплект под фичу «матч источника по слепку, без потери лидов»:
- findings: ультра-гранулярный аудит швов денежного ядра (9 субагентов, §9a-9c)
- plans: реализация в 6 эпиков (TDD, флаг отката, порядок выката)
- runbooks: план проверки (код + глаза + деньги, GO/NO-GO)
- specs: design-gate Путь A — согласован владельцем 25.06.2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Лиды не идут с 3 июня = намеренное решение владельца он сам выключил
проекты подтверждено 23.06 не дефект. Развёрнута вчерашняя поправка
ушедшая в крайность реальный инцидент. Новый файл-разбор
2026-06-23-LEADS-STOPPED-correction.md с доказательствами прода
read-only SSH плюс баннеры во всех связанных доках. Телефон-источник
замаскирован.
Приёмка раунд-2 сверена живьём все 5 закрыты M-1 M-2 apiv1-rate на проде
hash 21 schema v8.51 Раздел B тесты.
Долги докалки проверены 23.06 всё ещё открыты deptrac 1 живое нарушение
ProjectResource SupplierSnapshotGuard larastan env-квирк диагностируемость
молчаливого дропа no_snapshot_skipped всё ещё Log info.
Только docs прод и код не тронуты.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FN-RESET: письмо сброса строило именованный роут password.reset которого нет в SPA.
ResetPassword::createUrlUsing → /reset/{token}?email= в AppServiceProvider boot.
FN-LOGIN-ROUTE: гость без Accept json на auth:sanctum уводил в именованный роут
login которого нет → 500. redirectGuestsTo /login + render AuthenticationException
→ 401 JSON для api/*.
FN-SESSION: chromium.launch стоял вне try/catch — отказ запуска браузера маскировался
unhandled-rejection в opaque exit 1 двойник login-rejected. launch в try + top-level
catch → чистый exit 4 + JSON stderr в refresh-session.js и manage-project.js.
Тесты: PasswordResetUrlTest, UnauthenticatedApiResponseTest, node:test launch-failure
в обоих playwright-скриптах. Разбор FN-SESSION + ops-долг playwright install под
www-data + поправки отчёта приёмки + новая находка FN-INN-LOOKUP.
Прод не трогался. Накат — позже вместе с остальным.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
R3b + launch-промт: 6-значный код приходит письмом на ящик владельца (в ответе
API на проде его нет, в чужую почту исполнитель не зайдёт) → владелец читает код
и передаёт исполнителю для шага ONB-CODE. На живом онбординге владелец даёт две
вещи: решение капчи + код.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
R3b §A: капча на проде реальная (Yandex, test=false) — два способа пройти
онбординг (владелец сам регистрируется ИЛИ решает капчу в видимом Playwright);
массовый провижининг — SQL (R1). Удалённые ящики kdv1@/stels_info@ убраны из текста.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
N-4: пометка digest_sent ПОСЛЕ отправки (mark-after-send) — повтор не
дублирует И сбой джоба до отправки не теряет дайджест. TDD-тест GREEN 6/6.
N-2: инъекции R2 с TEST-диапазоном vid 9e12..1e13 → R5 чистит 4 orphan-таблицы
детерминированно по vid/lead_id, без ручного манифеста.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
N-4: SendNewLeadsDigestJob выбирал сделки received_at>now()-30min без маркера
отправки → ручной/повторный прогон (R3b велит дёргать вручную) дублировал
письмо-дайджест. Окно «непересекается» только при ровно-30-мин прогонах.
Фикс без схемы: идемпотентность по сделке через Redis SETNX
(Cache::add 'digest_sent:<id>', TTL 1 сутки) — паттерн как rate-limit
ZeroBalancePausedMail. Уже отправленная сделка в дайджест повторно не входит.
TDD: тест «повторный прогон НЕ дублирует» (RED 2 письма → GREEN 1), сюит 5/5.
R3b DIGEST-ON + owner-decisions + NEW-статус обновлены (N-4 → закрыто).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
R5 teardown/сверки (сверено по db/schema.sql):
- N-1 (CRITICAL): TD3 падал — supplier_lead_costs БЕЗ tenant_id (→ через deal_id,
до deals) + DELETE FROM reminders по дропнутой таблице (убрано). Прежде вся
транзакция откатывалась → тест-данные оставались на боевом.
- N-2: + DELETE pd_processing_log/tenant_operations_log (по tenant_id) + нота про
orphan-таблицы инъекции без tenant_id (чистить по манифесту R2).
- N-3: нота — НЕ удалять глобальные auth_log/saas_admin_audit_log (разрыв
hash-цепочки → F3 красный); per-tenant цепочки рвутся безопасно.
- N-8: F4 маржа — supplier_lead_costs.cost_kopecks→cost_rub + JOIN deals;
lead_charges.price_kopecks→price_per_lead_kopecks (ревьюер ошибся, сверено).
R2: N-5 — предупреждение про snapshot:rebuild (DELETE без фильтра тенанта/транзакции,
снесёт слепок дня вкл. lkomega); по умолчанию backfill с явной --date.
R1: N-7 — предусловие PR2: гейт реквизитов (422 requisites_required) + preflight
баланса (409) ДО создания проектов через портал.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Пошаговый деплой-пайплайн liderra.ru: clone из gitea, npm build на проде,
artisan down, rsync overlay с исключениями, composer и optimize от www-data,
миграции через postgres superuser, up и smoke. Грабли PowerShell-ssh кавычек,
heredoc с dollar-dollar, привилегии www-data и crm_app_user, rollback.
GitHub Actions deploy.yml мёртв, аккаунт CoralMinister suspended.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
C: LeadRouter.activeSnapshotDate после 21:00 МСК = завтра; снимок только на сегодня не активен -> снимки на обе даты. A: PII-процессор на остальные лог-каналы, 6/6.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Monolog PiiScrubbingProcessor (телефоны/email -> [PHONE]/[EMAIL]) + ScrubPii tap на single/daily в config/logging.php. Pest 6/6 GREEN. Sentry-scrubbing (OPEN-И-16) не реализуем: sentry-laravel не установлен — open-item.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Именованные лимитеры auth-login/auth-2fa/auth-password (perMinute 20 by IP) в AppServiceProvider; throttle-middleware на login/forgot/reset/2fa-verify/recovery в web.php. Закрывает per-IP объёмный перебор. Pest tests/Feature/Auth 97/97 GREEN.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code-quality reviewer flagged 2 IMPORTANT factual inaccuracies in
recovery-procedures.md (commit 3ce73a68):
1. Section 6 RECOMMENDED code example imported resolvePathNormalize from
the wrong module path (tools/shell-content-rules.mjs). Actual exporter
is tools/enforce-router-gate.mjs (verified via Grep at line 174).
shell-content-rules.mjs only exports defaultPathNormalize. A future
reader copying the RECOMMENDED pattern would get an import error.
Also corrected the call signature: resolvePathNormalize() takes no
arguments and is async — returns the normalize function directly.
2. Section 4 (Stale-process) cited tools/enforce-bash-content-gate.mjs —
no such file exists in tools/ (verified via Glob). Correct hook
filenames are enforce-router-gate.mjs (Bash) and
enforce-powershell-gate.mjs (PowerShell).
Fix: replace both module references with the verified correct filenames
(Grep'd against tools/ exports + Glob'd file existence). Also includes
the lefthook MD032 blank-lines-around-lists auto-format diff carried
over from the previous commit's post-commit hook.
Surgical edit — no new content, no restructuring.
Adds first-time recovery runbook with:
- 3 self-recovery levels (Level 1 ≤5min sentinel reset, Level 2 ≤15min VS Code
restart, Level 3 destructive workspace rebuild)
- Stale-process / hook reload trap (Smoke 5 chistaa-session hypothesis +
refutation method); key takeaway: live restart-test is the only way to
confirm a hook-modifying fix landed
- Self-fabrication patterns — 7 cases enumerated from Smokes 3/4/5/7 with
pattern signature, detection signal, mitigation for each
- Test methodology lesson — Smoke 5 root cause showed unit tests with inline
mocks can give false-green if they bypass the live resolver function; debug
scripts have the same trap
- Smoke methodology — statusline-setup system prompt overrides user tasks
(Smoke 9 Run 1); use semgrep-scanner for echo-probes, statusline-setup OK
for gate-inheritance smokes
Docs-only change; verified via docs-only short-circuit in enforce-verify-
before-push (§5 п.13 CLAUDE.md).
Stream H Task 1 of 11. Plan: docs/superpowers/plans/2026-05-30-router-gate-v4-stream-H.md