# План v2 — Go-Live Security Gate (пред-прод прогон безопасности)

## Цель

Прогнать пять шагов гейта безопасности по спеке (статика → ПДн/152-ФЗ → угрозы →
динамика → вердикт) на текущей ветке `main`, цель — локальная копия
`127.0.0.1:8000`, и собрать письменный отчёт с вердиктом GO / NO-GO. Прогон не
правит продуктовый код, схему и не коммитит; единственная запись — файл отчёта.

```skills-json
["security-go-live", "pdn-152fz-audit", "threat-model"]
```

```steps-json
[
  {"op":"Bash","object":"./bin/gitleaks.exe detect --source . --log-opts \"--all\"","ref":"D1"},
  {"op":"Bash","object":"npm run sast","ref":"D1"},
  {"op":"Bash","object":"./bin/ward.exe scan --path app/","ref":"D1"},
  {"op":"Bash","object":"php app/artisan serve --host 127.0.0.1 --port 8000 &","ref":"D4"},
  {"op":"Bash","object":"bin/nuclei.exe -u http://127.0.0.1:8000 -tags tech -rate-limit 20 -c 5 -timeout 5 -duc","ref":"D4"},
  {"op":"Bash","object":"bin/nuclei.exe -u http://127.0.0.1:8000 -rate-limit 20 -c 5 -timeout 5 -duc -severity medium,high,critical","ref":"D4"},
  {"op":"Write","object":"docs/security/2026-06-17-go-live-security-report.md","ref":"D5"}
]
```

```verified-context-json
[
  {"id":"vc1","kind":"EXTRACTED","ref":".claude/skills/security-go-live/references/gate.md","anchor":"IS8 — цель по умолчанию локальная"},
  {"id":"vc2","kind":"EXTRACTED","ref":"docs/Tooling_v8_3.md","anchor":"security-go-live — go-live security-gate"}
]
```

## Переговоры

### Круг 1

Доводы по составу шагов:

- **Статика (gitleaks/Semgrep/Ward)** — read-only по локальному репозиторию и
  `app/`, ничего не правит и не отправляет наружу. gitleaks читает git-историю,
  Semgrep (`npm run sast`) и Ward (`./bin/ward.exe scan`) читают код и конфиг.
  Это безопасные локальные проверки.
- **ПДн/152-ФЗ и угрозы** вынесены в навыки `pdn-152fz-audit` и `threat-model`
  (объявлены в skills-json) — они анализируют схему и код только чтением; их
  находки попадают в отчёт.
- **Динамика (Nuclei)** направлена строго на локальную копию `http://127.0.0.1:8000`
  (гард IS8 — боевой контур не трогается). Темп ограничен `-rate-limit 20 -c 5`
  под однопоточный `php artisan serve`, чтобы не перегрузить dev-сервер. Цель —
  `127.0.0.1`, не `localhost` (резолвер Nuclei на этой машине пропускает `localhost`).
  Сначала быстрый smoke по тегу `tech`, затем полный прогон severity medium+.
- **`php artisan serve`** нужен, чтобы портал был доступен сканеру; запускается
  фоном на локальном адресе, продуктовых данных и схемы не меняет.
- **ZAP (#68)** требует Java-демона и при его отсутствии даёт `PENDING` — поэтому
  отдельным Bash-шагом не закладывается, его статус (`PENDING`/результат) фиксируется
  в отчёте шагом 7.
- **Отчёт (шаг 7)** — единственная запись прогона: новый файл в `docs/security/`.
  Код, схема, миграции и git не трогаются; verify/criterion-гейты коммита не
  затрагиваются, так как коммита нет.

Известные долги F-T2 (`/api/admin/*` без app-гейта) и F-P1 (152-ФЗ:
`deals.phones[]` не вычищаются) проверяются фактом в рамках шагов ПДн и угроз и
явно отражаются в вердикте.

### Круг 2

Принято возражение наставника по шагу 4: синхронный `php artisan serve` заблокировал
бы поток и не дал бы выполнить шаги Nuclei. Исправлено — шаг 4 теперь запускает
сервер **фоном** (`php app/artisan serve --host 127.0.0.1 --port 8000 &`), сервер
работает параллельно с последующими шагами сканирования. Остальные шаги наставник
в круге 2 одобрил поимённо (пп. 1–3, 5–7 — OK); изменён только шаг 4.
