# План v10: регенерация larastan baseline с двойным проходом (стабилизация кэша)

## Цель

Привести `app/phpstan-baseline.neon` к набору сообщений, который **детерминированно
совпадает** с прогоном `composer stan`, поглотив дрейф lead-region и шум вывода типов
Pest. Опирается на спеку
[2026-06-16-larastan-baseline-regen-v2.md](../specs/2026-06-16-larastan-baseline-regen-v2.md)
(D1 — контракт регенерации, D2 — критерий приёмки). Изменяется только baseline-конфиг;
код приложения не трогается.

**Зачем двойной реген.** Одиночный `--generate-baseline` на этом проекте дал
недетерминизм: правило `noEnvCallsOutsideOfConfig` для `config/*.php` попало в baseline
при генерации, но не воспроизвелось при последующем verify (11 `ignore.unmatched`).
Источник — результат-кэш `.phpstan-cache`: первый проход анализирует «вхолодную»,
второй — со стабилизированным кэшем. Повторная генерация baseline после прогрева кэша
записывает набор, совпадающий с устойчивым анализом, после чего verify проходит чисто.

**Предусловие (read-only, уже выполнено).** Рабочая копия baseline была равна HEAD до
первой перезаписи; зафиксированная версия — валидная точка восстановления. Откат:
`git checkout HEAD -- app/phpstan-baseline.neon`.

**Каталог гарантирован явно.** Все шаги используют `composer --working-dir=app`, что
детерминированно указывает composer на `app/composer.json` без зависимости от CWD.

```skills-json
[]
```

```steps-json
[
  {
    "op": "Bash",
    "object": "composer --working-dir=app stan -- --generate-baseline",
    "ref": "D1"
  },
  {
    "op": "Bash",
    "object": "composer --working-dir=app stan -- --generate-baseline",
    "ref": "D1"
  },
  {
    "op": "Bash",
    "object": "composer --working-dir=app stan",
    "ref": "D2"
  }
]
```

```verified-context-json
[
  {
    "id": "phpstan-config",
    "kind": "EXTRACTED",
    "ref": "app/phpstan.neon",
    "anchor": "checkModelProperties: true"
  },
  {
    "id": "baseline-file",
    "kind": "EXTRACTED",
    "ref": "app/phpstan-baseline.neon",
    "anchor": "ignoreErrors:"
  }
]
```

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

### Круг 1

Шаги — три mutating/analysis-команды composer, read-only guard вынесен в предусловие
(он уже выполнен, baseline был равен HEAD; read-only команда не продвигает указатель
impl-режима, поэтому не является исполняемым шагом).

Закрытые ранее замечания наставника (v6–v9) сохранены:

1. **Директория** — `composer --working-dir=app` детерминированно, без `cd` и без риска
   `app/app`.
2. **Навык #12 Larastan** — CLI-инструмент composer, вызывается шагами, не Superpowers-skill;
   `skills-json` пуст.

Новое в v10: **второй идентичный шаг регенерации** перед verify. Это не дубль-ошибка, а
устранение недетерминизма результат-кэша: первый `--generate-baseline` прогревает кэш,
второй записывает baseline, совпадающий с устойчивым анализом, после чего шаг 3 (verify)
проходит без `ignore.unmatched`. Откат гарантирован git (baseline версионируется).
