# Технический аудит портала Лидерра — Этап 2, добор + фиксация

## Цель

Добрать недовыполненные проверки наблюдательного аудита локальной dev-копии (backend-тесты
и детализацию найденной утечки) и зафиксировать сводку всех находок в документ аудита.

**Окружение и безопасность.** Локальная dev-копия (native Windows). Backend-тесты идут на
выделенной **тестовой** БД testing-окружения Laravel; боевая БД `liderra.ru` недоступна.
Деструктивных команд нет: тесты не пересоздают и не дропают боевые данные, миграций боевой
схемы нет. Детализация утечки выполняется в **редактирующем** режиме инструмента — значение
секрета не раскрывается, фиксируются только файл/правило/строка. Единственная запись на диск —
итоговый документ находок (новый markdown-файл отчёта).

## Backend-тесты {#E1}

**Контракт:** прогнать backend-сюиту параллельно (`artisan test --parallel`) напрямую через
PHP — в обход обёртки composer, чей внутренний process-timeout (300с) обрывал последовательный
прогон до завершения. Параллельный запуск переиспользует существующие тестовые БД процессов и
не пересоздаёт их.

**Критерий находки:** любой упавший тест = **P1** (нарушение функциональности). Зелёный свод
подтверждает отсутствие backend-регрессий. Если суммарное время превышает разумный предел —
зафиксировать как «суйта не уложилась», частичный результат.

**Конвенция:** запуск из корня с путём `app/artisan`; параллельный раннер пишет только в
изолированные тестовые БД testing-окружения; боевые данные не затрагиваются.

## Детализация утечки {#E2}

**Контракт:** повторить скан секретов (gitleaks detect) в **редактирующем** многословном
режиме (`--redact --verbose`), чтобы установить координаты единственной найденной ранее утечки —
файл, правило, коммит — **без вывода значения секрета** (redact заменяет значение).

**Критерий находки:** утечка в актуальном рабочем дереве = **P0** (требует ротации/вычистки
истории); утечка только в старой истории (например, тестовый пароль, уже удалённый из текущих
файлов) = **P1** (вычистка истории/ротация по решению владельца). Классификация — по тому, где
именно правило сработало.

**Конвенция:** gitleaks из корня (`bin/gitleaks.exe`), режим redact — значение секрета в вывод
не попадает; фиксируются только метаданные находки.

## Документ находок {#E3}

**Контракт:** записать единый markdown-документ аудита со сводкой всех находок Этапа 2:
перечень P0–P3 (CVE-зависимости, утечка, упавшие frontend-тесты, долг статанализа Pint/Prettier/
vue-tsc/Larastan, docs-долг), результат backend-свода и детализации утечки, список
недовыполненных фаз (schema-deep, UI-smoke, semgrep, coverage — требуют MCP/сервера) и сверку
с хендоффом поиска хвостов.

**Критерий:** документ содержит каждую находку с серьёзностью, местом и кратким описанием
причины; открытые вопросы реестра не закрываются (только фиксируются как требующие решения).

**Конвенция:** новый файл `docs/superpowers/audits/2026-06-15-portal-tech-audit-findings.md`;
запись справочная, код и данные не меняются.

## Серьёзность находок {#E4}

**P0** — блокирует production / порча данных / инцидент безопасности. **P1** — нарушение
функциональности / упавший тест / уязвимость. **P2** — предупреждение / стиль / тех-долг /
дрейф инструмента. **P3** — косметика / docs. Закрытие открытых вопросов реестра (Б-/CTO-/Биз-/
Диз-/DO-/SEC-) в этот этап не входит — требует явного решения владельца.

```verified-context-json
[
  {"id":"C1","kind":"EXTRACTED","ref":"app/composer.json","anchor":"\"test\": ["},
  {"id":"C2","kind":"EXTRACTED","ref":"package.json","anchor":"\"sast\": \"semgrep --config=p/php"},
  {"id":"C3","kind":"EXTRACTED","ref":"tools/cost-pricing.mjs","anchor":"export const PRICING = Object.freeze("}
]
```
