Files
portal/docs/superpowers/plans/2026-05-20-a1-backend-tooling.md
T
Дмитрий 89c257febd docs(backend): A1 backend-tooling spec + plan + cspell words
Spec: docs/superpowers/specs/2026-05-20-a1-backend-tooling-design.md
Plan: docs/superpowers/plans/2026-05-20-a1-backend-tooling.md
4 узла A1 (#64-67): Rector / PHP Insights / laravel-backend-patterns / NightOwl.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 04:21:26 +03:00

30 KiB
Raw Blame History

A1 backend-tooling Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking. Project wrapper: .claude/skills/subagent-driven-development/ (git-safety per Pravila §15.1).

Goal: Наполнить раздел A1 «Программирование — backend» четырьмя инструментами (Rector #64, PHP Insights #65, laravel-backend-patterns скил #66, NightOwl #67) с полным footprint роутера и наблюдателя.

Architecture: Off-phase tooling integration в изолированном worktree (паттерн A11/C10/finance). Rector/PHP Insights — Composer dev-deps + конфиги; backend-patterns — self-authored project-скил; NightOwl — self-hosted телеметрия в PG. Нормативка bump-ится атомарным набором (cross-ref-checker C2 STRICT). Spike-задачи определяют 2 gate-решения до сборки.

Tech Stack: PHP 8.3 / Laravel 13 / Composer / lefthook / PostgreSQL 16 / Markdown-нормативка / vis.js карта.

Spec: docs/superpowers/specs/2026-05-20-a1-backend-tooling-design.md


Pre-flight (исполнитель — перед Task 1)

  • Worktree от свежего origin/main через superpowers:using-git-worktrees. После создания скопировать gitignored-файлы (учёт Sprint 4): app/.env, app/storage/, app/vendor/, app/node_modules/, bin/*.exe, лендинг/ — иначе composer/тесты/lefthook не запустятся.
  • git fetch && git log HEAD..origin/main --oneline — pre-flight sync 8 нормативных файлов (Pravila §15.2).
  • Закоммитить уже написанные spec (docs/superpowers/specs/2026-05-20-a1-backend-tooling-design.md) + этот план первым коммитом.

File Structure

Файл Ответственность Задача
app/composer.json dev-deps (rector, rector-laravel, phpinsights, nightwatch) + scripts 1,2,8
app/rector.php Rector ruleset (LaravelSetProvider + dead-code/code-quality) 4
app/phpinsights.php PHP Insights config (complexity+architecture оси) 5
lefthook.yml (условно) job 16 Rector dry-run 4
.claude/skills/laravel-backend-patterns/SKILL.md + references/ свод backend-конвенций Лидерры 6
.claude/skills/laravel-backend-patterns/evals/evals.json trigger-евалы скила 7
.mcp.json (условно) NightOwl MCP READ-ONLY 8
tools/.l1-watcher-aliases.txt (условно) alias NightOwl MCP-имени 8
docs/adr/ADR-013-backend-tooling.md границы узлов + BT1–BT9 9
docs/routing-off-phase.md +4 строки routing + связка L14 10
docs/router-procedure.md bump cross-ref 10
docs/Tooling_v8_3.md §4.39–4.42 (9-атрибутные блоки) + §0 счётчик + header 11
docs/Plugin_stack_rules_v1.md R10.1 +4 строки + header 11
docs/Pravila_raboty_Claude_v1_1.md §13.2 +абзац + header 11
CLAUDE.md §3.3 +#6467, §6 +абзац, §9 +запись, header 11
docs/automation-graph-data.js +4 узла NODE_SECTION + рёбра + версии-метки 12

Phase 0 — Spikes (определяют gate-решения)

Task 1: Rector — установка + dry-run count spike

Files:

  • Modify: app/composer.json (require-dev + scripts)

  • Create: (нет в этой задаче — конфиг в Task 4)

  • Step 1: Установить Rector + rector-laravel

Run (root app/):

composer require rector/rector driftingly/rector-laravel --dev

Expected: добавлены rector/rector ^2.4, driftingly/rector-laravel в require-dev; composer.lock обновлён.

  • Step 2: Временный минимальный конфиг для замера

Create app/rector.php (временный, финальный — Task 4):

<?php
use Rector\Config\RectorConfig;
use RectorLaravel\Set\LaravelSetProvider;
return RectorConfig::configure()
    ->withPaths([__DIR__ . '/app'])
    ->withSetProviders(LaravelSetProvider::class)
    ->withPreparedSets(deadCode: true, codeQuality: true);
  • Step 3: Прогнать dry-run и посчитать

Run (root app/):

php vendor/bin/rector process --dry-run

Expected: вывод со списком предлагаемых изменений + итоговая строка N files would have been changed. Записать N.

  • Step 4: Зафиксировать решение по gate-постуре

Записать в коммит-сообщение и в Task 4 решение:

  • N ≤ ~5 → блокирующий lefthook job 16 (паттерн deptrac).

  • N > ~5 → composer script + CI; lefthook-гейт отложить, в ADR-013 пометить.

  • Step 5: Commit

git add app/composer.json app/composer.lock app/rector.php
git commit -m "feat(backend): install Rector + rector-laravel; dry-run baseline N=<N>"

Task 2: PHP Insights — установка + baseline run

Files:

  • Modify: app/composer.json (require-dev)

  • Step 1: Установить PHP Insights

Run (root app/):

composer require nunomaduro/phpinsights --dev

Expected: nunomaduro/phpinsights в require-dev.

  • Step 2: Сгенерировать дефолтный конфиг

Run (root app/):

php artisan vendor:publish --provider="NunoMaduro\PhpInsights\Application\Adapters\Laravel\InsightsServiceProvider"

Expected: создан config/insights.php (переедет в app/phpinsights.php в Task 5 — пока для baseline).

  • Step 3: Прогнать baseline-анализ

Run (root app/):

php artisan insights --no-interaction --summary

Expected: 4 балла (Code / Complexity / Architecture / Style). Записать значения.

  • Step 4: Зафиксировать пороги

По baseline выбрать --min-quality / --min-complexity / --min-architecture чуть ниже текущих (anti-regression), записать для Task 5.

  • Step 5: Commit
git add app/composer.json app/composer.lock app/config/insights.php
git commit -m "feat(backend): install PHP Insights; baseline scores recorded"

Task 3: NightOwl — feasibility spike

Files: (нет правок — разведка)

  • Step 1: Проверить доступность пакетов и MCP

Run:

npm view @lemed99/nightowl-agent 2>$null; composer show laravel/nightwatch --available 2>$null

Прочитать README github.com/lemed99/nightowl-agent (WebFetch): (a) поддерживается ли self-hosted ingest в PostgreSQL без managed-аккаунта; (b) есть ли MCP-сервер в open-source варианте или только в managed (usenightowl.com).

  • Step 2: Зафиксировать access-path

Записать решение для Task 8:

  • MCP в open-source есть → регистрируем MCP-сервер в .mcp.json (READ-ONLY) + alias в l1-watcher.

  • MCP только managed → fallback: телеметрия пишется в PG, Claude читает через Boost database-query; .mcp.json не трогаем.

  • Self-hosted ingest на native-Windows невозможен/тяжёл → эскалировать заказчику (узел остаётся, но access-path = только Boost-чтение PG-таблиц nightwatch).

  • Step 3: Commit (документ разведки)

git add docs/backend/nightowl-spike.md
git commit -m "docs(backend): NightOwl feasibility spike — access-path decided"

(Создать docs/backend/nightowl-spike.md с выводами Step 1–2.)


Phase 1 — Rector финализация (#64)

Task 4: Rector финальный конфиг + scripts + (условно) lefthook

Files:

  • Modify: app/rector.php

  • Modify: app/composer.json (scripts)

  • Modify: lefthook.yml (условно — только если Task 1 N ≤ ~5)

  • Step 1: Финализировать app/rector.php

Заменить временный конфиг (оставить conservative ruleset — без typeDeclarations: true на первом заходе):

<?php
use Rector\Config\RectorConfig;
use RectorLaravel\Set\LaravelSetProvider;
return RectorConfig::configure()
    ->withPaths([__DIR__ . '/app', __DIR__ . '/database', __DIR__ . '/routes'])
    ->withSetProviders(LaravelSetProvider::class)
    ->withPreparedSets(deadCode: true, codeQuality: true)
    ->withSkip([
        __DIR__ . '/app/Console/Kernel.php',  // bootstrap — не трогать
    ]);
  • Step 2: Добавить composer scripts

В app/composer.json scripts:

"rector": "@php vendor/bin/rector process --dry-run",
"rector:fix": "@php vendor/bin/rector process"
  • Step 3: Проверить, что dry-run чист после финального конфига

Run (root app/):

composer rector

Expected: 0 files would have been changed ИЛИ зафиксированный baseline-список (если N>0 и решено не блокировать).

  • Step 4 (условно, N ≤ ~5): Добавить lefthook job 16 + доказать red-green

В lefthook.yml pre-commit.jobs после job 15:

    # 16. Rector — авто-рефакторинг / version-aware апгрейды (Прил. Н #64,
    # backend-tooling). dry-run на staged app/**/*.php — падает, если есть
    # неприменённые Rector-правки. Чистый PHP, без LLM (BT1-BT3).
    - name: rector
      glob: "app/**/*.php"
      root: "app/"
      run: php vendor/bin/rector process --dry-run --no-progress-bar
      fail_text: |
        Rector предлагает правки в staged-коде. Запусти `cd app && composer rector:fix`,
        проверь diff, прогони тесты и закоммить. Если правило неприменимо — добавь в withSkip() в app/rector.php.

Red-green доказательство: внести намеренный устаревший паттерн (напр. array() вместо [] в тест-файле) → git addlefthook run pre-commit падает на job rector; откатить → проходит.

  • Step 5: Commit
git add app/rector.php app/composer.json lefthook.yml
git commit -m "feat(backend): Rector config + composer scripts + lefthook gate (#64)"

Phase 2 — PHP Insights финализация (#65)

Task 5: PHP Insights конфиг (оси) + script

Files:

  • Create: app/phpinsights.php (или оставить config/insights.php по факту publish)

  • Modify: app/composer.json (scripts)

  • Step 1: Настроить конфиг — выключить Style-ось, акцент Complexity+Architecture

В опубликованном конфиге (config/insights.php):

  • в remove добавить sniff-классы стиля, которыми владеет Pint (PSR12, line-length, пробелы), чтобы не дублировать;

  • задать requirements дефолты под baseline из Task 2 (min-quality/complexity/architecture).

  • Step 2: Добавить composer script

В app/composer.json scripts:

"insights": "@php artisan insights --no-interaction --min-quality=<Q> --min-complexity=<C> --min-architecture=<A>"

(подставить пороги из Task 2 Step 4).

  • Step 3: Прогнать и убедиться, что проходит пороги

Run (root app/):

composer insights

Expected: exit 0 (баллы ≥ порогов). Если падает — поднять remove/скорректировать порог (baseline-аккуратно, не маскируя реальный долг).

  • Step 4: НЕ добавлять в lefthook (BT9 — избегаем четверного гейта). Зафиксировать в коммит-сообщении.

  • Step 5: Commit

git add app/config/insights.php app/composer.json
git commit -m "feat(backend): PHP Insights config (complexity+architecture axes, on-demand) (#65)"

Phase 3 — laravel-backend-patterns скил (#66)

Task 6: SKILL.md + references

Files:

  • Create: .claude/skills/laravel-backend-patterns/SKILL.md

  • Create: .claude/skills/laravel-backend-patterns/references/conventions.md

  • Step 1: Написать SKILL.md (frontmatter + тело)

---
name: laravel-backend-patterns
description: Backend-конвенции Лидерры (Laravel 13) — как писать controller→service→job, RLS-aware Eloquent, деньги через bcmath/LedgerService, идемпотентные джобы, partition-aware запросы. Используй при «как писать backend в Лидерре», «паттерн контроллера/сервиса/джоба», scaffolding новой backend-фичи. НЕ для generic-паттернов (architecture-patterns #38), аудита денег (billing-audit #62), РСБУ/налогов (ru-tax-accounting), security-аудита (D3).
---

# Laravel backend patterns — Лидерра

[Тело: 5 разделов-конвенций со ссылками на reference и реальные файлы-образцы кода проекта.]
  • Step 2: Написать references/conventions.md — 5 конвенций с code-образцами из проекта

Каждая конвенция = правило + образец из существующего кода (file:line) + anti-pattern:

  1. Слоистость controller → FormRequest → service → job (deptrac 13 слоёв app/deptrac.yaml); образец — существующий контроллер/сервис.
  2. RLS-aware Eloquent: SetTenantContext middleware + SET LOCAL app.current_tenant_id; в queued-джобах под crm_supplier_worker (BYPASSRLS) — явный where('tenant_id', ...); образец — CsvReconcileJob/ImportLeadsJob.
  3. Деньги: bcmath / LedgerService (cross-ref billing-audit #62 — без копирования инвариантов, ссылка); образец — LedgerService.
  4. Идемпотентные джобы: advisory-locks; образец — HistoricalImportService.
  5. Partition-aware запросы к deals / supplier_lead_costs.
  • Step 3: Проверить, что скил обнаруживается

Run: проверить, что .claude/skills/laravel-backend-patterns/SKILL.md валиден (frontmatter name+description). Запустить markdownlint/cspell локально (он линтуется — не в ignorePaths).

npx markdownlint-cli2 ".claude/skills/laravel-backend-patterns/**/*.md"

Expected: 0 ошибок (или авто-fix).

  • Step 4: Commit
git add .claude/skills/laravel-backend-patterns/SKILL.md .claude/skills/laravel-backend-patterns/references/
git commit -m "feat(backend): laravel-backend-patterns skill — SKILL.md + conventions (#66)"

Task 7: Скил evals (trigger-проверка)

Files:

  • Create: .claude/skills/laravel-backend-patterns/evals/evals.json

  • Step 1: Написать failing evals (trigger + near-miss)

{
  "skill": "laravel-backend-patterns",
  "cases": [
    {"prompt": "как написать контроллер для новой backend-фичи в Лидерре", "should_trigger": true},
    {"prompt": "как правильно списать деньги в джобе под crm_supplier_worker", "should_trigger": true},
    {"prompt": "проверь, не теряются ли копейки в списании", "should_trigger": false, "expected": "billing-audit"},
    {"prompt": "опиши Clean Architecture в общем", "should_trigger": false, "expected": "architecture-patterns"},
    {"prompt": "учёт выручки по РСБУ", "should_trigger": false, "expected": "ru-tax-accounting"}
  ]
}
  • Step 2: Прогнать классификацию (skill-creator eval или ручная проверка description)

Прогнать евал-кейсы против description (через skill-creator:skill-creator eval-режим или ручную проверку триггеров). Expected: trigger-кейсы → laravel-backend-patterns; near-miss → корректный сосед (billing-audit / architecture-patterns / ru-tax). Если near-miss перетягивает — уточнить description (граница по слою/операции).

  • Step 3: Commit
git add .claude/skills/laravel-backend-patterns/evals/evals.json
git commit -m "test(backend): laravel-backend-patterns trigger evals (#66)"

Phase 4 — NightOwl (#67)

Task 8: NightOwl установка/конфиг per spike

Files:

  • Modify: app/composer.json (require-dev)

  • Modify (условно): .mcp.json, tools/.l1-watcher-aliases.txt

  • Create: docs/backend/nightowl-setup.md

  • Step 1: Установить пакет сбора телеметрии

Run (root app/):

composer require laravel/nightwatch --dev

Expected: laravel/nightwatch в require-dev.

  • Step 2: Настроить self-hosted ingest в PG (по выводам Task 3)

По access-path из Task 3: настроить агент NightOwl на запись телеметрии в PostgreSQL Лидерры (отдельная схема/таблицы). Зафиксировать команды/конфиг в docs/backend/nightowl-setup.md. READ-ONLY для Claude.

  • Step 3 (условно — MCP доступен): зарегистрировать MCP + alias

В .mcp.json добавить блок nightowl (READ-ONLY). В tools/.l1-watcher-aliases.txt добавить alias имени MCP-сервера → имя в Tooling Прил. Н (иначе C1 l1-watcher STRICT заблокирует коммит). Smoke: npx <nightowl-mcp> --help (или эквивалент) verified.

  • Step 4 (условно — MCP только managed): зафиксировать Boost-fallback

Если MCP недоступен — .mcp.json не трогаем; в docs/backend/nightowl-setup.md описать доступ к телеметрии через Boost database-query по таблицам nightwatch.

  • Step 5: Commit
git add app/composer.json app/composer.lock docs/backend/nightowl-setup.md .mcp.json tools/.l1-watcher-aliases.txt
git commit -m "feat(backend): NightOwl self-hosted telemetry + access-path (#67)"

Phase 5 — ADR + роутер/наблюдатель

Task 9: ADR-013

Files:

  • Create: docs/adr/ADR-013-backend-tooling.md

  • Step 1: Прочитать шаблон ADR

Прочитать docs/adr/ADR-012-*.md (последний) как шаблон структуры (Status / Context / Decision / Consequences / Enforcement).

  • Step 2: Написать ADR-013

Содержание: Decision — 4 узла backend-tooling + границы; Consequences — BT1BT9 (§8 спеки); Enforcement-блок (если применимо к adr-judge — декларативные forbid/require; иначе пустой/информационный). Включить gate-решения из Task 1/3 (Rector posture, NightOwl access-path).

  • Step 3: Проверить adr-judge не падает

Run (root):

git diff --cached --unified=0 | python -X utf8 tools/adr-judge.py --diff - --adr-dir docs/adr/

Expected: нет нарушений на собственном диффе.

  • Step 4: Commit
git add docs/adr/ADR-013-backend-tooling.md
git commit -m "docs(adr): ADR-013 backend-tooling boundaries (BT1-BT9)"

Task 10: routing-off-phase.md + router-procedure.md

Files:

  • Modify: docs/routing-off-phase.md

  • Modify: docs/router-procedure.md

  • Step 1: Прочитать текущие файлы

Прочитать docs/routing-off-phase.md (формат routing-таблицы + связки L1–L13) и docs/router-procedure.md (header version v1.1).

  • Step 2: Добавить 4 строки routing-таблицы

Для #64–67 — строки «триггер задачи → узел» (значения routing-trigger из спеки §3 / Task 11 атрибутов). Bump version routing-off-phase v1.2 → v1.3.

  • Step 3: Добавить каноническую связку L14

L14 «backend-quality chain»: Rector (#64) → PHP Insights (#65) → Larastan (#12) → deptrac (#43). + anti-pattern: Rector-автоправка и PHP Insights-метрика — разные фазы, не один блокирующий шаг.

  • Step 4: Bump router-procedure.md

router-procedure v1.1 → v1.2: процедура не меняется, обновить cross-ref-строку/счётчик узлов под новый набор.

  • Step 5: Verify lychee + commit
./bin/lychee.exe --config .lychee.toml "docs/routing-off-phase.md" "docs/router-procedure.md"
git add docs/routing-off-phase.md docs/router-procedure.md
git commit -m "docs(router): +4 backend nodes routing + L14 chain (routing-off-phase v1.3, router-procedure v1.2)"

Phase 6 — Нормативка (АТОМАРНЫЙ набор — C2 STRICT)

Task 11: Tooling + PSR_v1 + Pravila + CLAUDE.md — один атомарный коммит

Критично: cross-ref-checker (C2, lefthook job 12) STRICT — все §0/header cross-refs между этими 4 файлами должны совпасть. Поэтому все 4 файла редактируются и коммитятся ОДНИМ коммитом. l1-watcher (C1) тоже проверит NightOwl MCP формализацию (см. Task 8 alias).

Files:

  • Modify: docs/Tooling_v8_3.md

  • Modify: docs/Plugin_stack_rules_v1.md

  • Modify: docs/Pravila_raboty_Claude_v1_1.md

  • Modify: CLAUDE.md

  • Step 1: Tooling Прил. Н — §4.39–4.42 (9-атрибутные блоки)

Прочитать §4.36 (finance plugin) как канонический шаблон 9-attribute блока, реплицировать структуру для 4 узлов со значениями:

  • §4.39 #64 Rector — name@source: Rector+rector-laravel @ rectorphp/rector + driftingly/rector-laravel (Composer dev-dep); category: backend-tooling (off-phase, 16-я); install: composer require rector/rector driftingly/rector-laravel --dev + app/rector.php; activation: gate-постура Task 1 (lefthook job 16 если N≈0, иначе composer+CI); conflicts: BT1/BT2/BT3 (ADR-013); dormant: false; routing-trigger: «обнови/почини/рефактори backend-код», апгрейд Laravel-версии, dead-code; cost: 0 LLM.
  • §4.40 #65 PHP Insights — @ nunomaduro/phpinsights (Composer dev-dep); backend-tooling; install: composer require nunomaduro/phpinsights --dev + app/phpinsights.php; activation: on-demand/CI (composer insights), НЕ lefthook (BT9); conflicts: BT4 (ADR-013); dormant: false; routing-trigger: «оцени качество/сложность кода», «где код запутан», аудит; cost: 0 LLM.
  • §4.41 #66 laravel-backend-patterns — @ self-authored (.claude/skills/); backend-tooling; install: project skill auto-discovered; activation: trigger-based; conflicts: BT5/BT6 (ADR-013); dormant: false; routing-trigger: «как писать контроллер/сервис/джоб в Лидерре», scaffolding backend-фичи; cost: skill inference.
  • §4.42 #67 NightOwl — name@source: NightOwl(self-hosted) @ lemed99/nightowl-agent + laravel/nightwatch; backend-tooling; install: composer require laravel/nightwatch --dev + nightowl-agent → PG; activation: active READ-ONLY, access-path per Task 3; conflicts: BT7/BT8 (ADR-013); dormant: false; routing-trigger: «почему медленно/падает в runtime», коррелированный трейс request↔job↔query; cost: 0 LLM.

§0 счётчик: 63 → 67; добавить 16-ю off-phase подкатегорию «backend-tooling». Header Прил. Н: v2.18 → v2.19 + наследие-строка.

  • Step 2: PSR_v1 — R10.1 +4 строки + header

R10.1 Блок 1/3: +4 строки (#6467, категория backend-tooling, не UI → вне R6/R14). Header v3.18 → v3.19 + наследие.

  • Step 3: Pravila — §13.2 +абзац + header

§13.2: +абзац «Off-phase backend-tooling» (#64 Rector / #65 PHP Insights / #66 laravel-backend-patterns / #67 NightOwl — 16-я подкатегория; счётчики — пин на Tooling Прил. Н §0). Header v1.34 → v1.35 + §10 changelog.

  • Step 4: CLAUDE.md — §3.3 + §6 + §9 + header

  • §3.3: +4 строки #64–67 (однострочный индекс, пин на Tooling §4.394.42).

  • §6: +абзац «2026-05-20 A1 backend-tooling integration» сверху.

  • §9: +запись v2.22.

  • §0 cross-refs: Pravila v1.35 / PSR_v1 v3.19 / Tooling Прил.Н v2.19.

  • Header: v2.21 → v2.22. (Прямой Edit — worktree-эксцепшн §5 п.10.)

  • Step 5: Verify cross-refs локально перед коммитом

Run (root):

node tools/cross-ref-checker.mjs
node tools/l1-watcher.mjs

Expected: оба чисто (нет version drift; NightOwl MCP формализован/aliased).

  • Step 6: Атомарный commit (все 4 файла вместе)
git add docs/Tooling_v8_3.md docs/Plugin_stack_rules_v1.md docs/Pravila_raboty_Claude_v1_1.md CLAUDE.md
git commit -m "docs(normative): A1 backend-tooling #64-67 — Tooling v2.19/PSR v3.19/Pravila v1.35/CLAUDE v2.22"

Phase 7 — Карта

Task 12: automation-graph-data.js +4 узла + рёбра + версии

Files:

  • Modify: docs/automation-graph-data.js

  • Step 1: Добавить 4 узла в NODES + NODE_SECTION (все A1)

Прочитать блок finance (finance_plugin/billing_audit/ru_tax) как образец. Добавить узлы rector, php_insights, backend_patterns, nightowl в NODES (group по типу: lefthook/agents/mcp/skills_proj) + в NODE_SECTION все 4 → 'A1'. Reuse-кросс-рефы в NODE_SECTION_SECONDARY если есть (напр. backend_patterns → секция C6? нет — оставить только A1).

  • Step 2: Добавить рёбра

Рёбра L14-цепочки (rector→php_insights→larastan/deptrac) + reuse-связи (backend_patterns↔billing_audit, nightowl↔mcp_sentry/mcp_boost). Обновить версии-метки шапки карты (v1.35/v2.22/v3.19/v2.19) + счётчики узлов/рёбер.

  • Step 3: Browser-smoke карты

Открыть docs/automation-graph.html через Playwright MCP, проверить: 4 новых узла рендерятся в секторе A1, рёбра присутствуют, нет JS-ошибок в консоли. Скриншот.

  • Step 4: Commit
git add docs/automation-graph-data.js
git commit -m "feat(map): +4 A1 backend-tooling nodes + L14 chain (137→141 nodes)"

Phase 8 — Финал

Task 13: Полная регрессия + finishing

Files: (нет правок)

  • Step 1: Полная регрессия

Run (root app/):

composer pint -- --test
composer stan
php vendor/bin/pest --parallel --recreate-databases

Запустить Vitest если затронут frontend (не затронут — пропустить). Expected: Pint 0, Larastan 0 above baseline, Pest GREEN (выписать точные числа passed/failed с file:line при падении).

  • Step 2: Pre-push проверки

Run (root):

./bin/gitleaks.exe detect --source . --no-banner --config .gitleaks.toml --redact
./bin/lychee.exe --config .lychee.toml "docs/**/*.md" "*.md"

Expected: gitleaks 0; lychee 0 broken (untracked spike-доки — если ломают, добавить в exclude или закоммитить).

  • Step 3: finishing-a-development-branch

Использовать superpowers:finishing-a-development-branch — представить заказчику опции (push в main / PR / cleanup). Push паттерн git push origin <ветка>:main (memory reference_github).


Self-Review (исполнено при написании плана)

Spec coverage:

  • Спека §2 (4 узла + out-of-scope) → Tasks 1/2/6/8 (узлы), out-of-scope зафиксирован в ADR Task 9.
  • Спека §3 (детали узлов + границы) → Tasks 4/5/6/8 + ADR Task 9.
  • Спека §4 (роутер) → Task 10.
  • Спека §5 (наблюдатель: 9-атрибуты + C1/C2) → Task 11 (9-атрибуты §4.39-42, C1/C2 verify Step 5).
  • Спека §6 (нормативка атомарно) → Task 11.
  • Спека §7 (карта) → Task 12.
  • Спека §8 (BT1BT9) → Task 9 ADR.
  • Спека §9 (spikes) → Tasks 1/2/3 + verify.
  • Спека §10 (worktree subagent-driven) → Pre-flight + execution handoff.

Placeholder scan: <N>/<Q>/<C>/<A> — намеренные spike-выходы (заполняются в Task 1/2), не placeholder-долги. Условные шаги (Task 4 Step 4, Task 8 Step 3/4) явно помечены ветвлением по spike-результату.

Type consistency: имена узлов карты (rector/php_insights/backend_patterns/nightowl), номера (#6467), §4.394.42, версии (v1.35/v3.19/v2.19/v2.22), коды BT1BT9, связка L14 — единообразны across задач.