# CTO-19 Lucide icon migration — 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.

**Goal:** Закрыть CTO-19 ⏸ через установку `lucide-vue-next` и регистрацию custom Vuetify IconSet с 78-entry mapping `mdi-*` → Lucide components. Views НЕ touched.

**Architecture:** Single core change в [`app/resources/js/plugins/vuetify.ts`](../../../app/resources/js/plugins/vuetify.ts) — добавление `icons` config с custom `IconSet`, где `component` function принимает Vuetify icon prop (`mdi-plus`/etc.) и рендерит Lucide component через `h()`. Fallback `HelpCircle` для unmapped. 51 Vue/TS файл с `icon="mdi-*"` invariant.

**Tech Stack:** Vue 3.5 + Vuetify 3.12 + `lucide-vue-next` (~0.460.0+). Vite tree-shaking → ~25-30 KB gzip bundle delta.

**Spec:** [docs/superpowers/specs/2026-05-13-cto-19-lucide-icon-migration-design.md](../specs/2026-05-13-cto-19-lucide-icon-migration-design.md) (approved 13.05.2026 path α).

---

## File Structure

| Файл | Responsibility |
|---|---|
| `app/package.json` | +1 dep `lucide-vue-next` |
| `app/package-lock.json` | auto-generated `npm install` |
| `app/resources/js/plugins/vuetify.ts` | +icons config (~80 строк добавлений: Lucide imports, lucideMap 78 entries, liderraLucideSet IconSet, registration в `createVuetify`) |
| `docs/Открытые_вопросы_v8_3.md` | CTO-19 §3 строка ⏸ → ✅; Сводка §0 counters (CTO 17 ✅ → 18 ✅ / 1 ⏸ → 0 ⏸); header v1.82 → v1.83 + changelog; footer v1.83 |
| `CLAUDE.md` | §0 row «Открытые вопросы» v1.82 → v1.83 |
| Memory `reference_archive.md` + `MEMORY.md` index | version refs sync v1.82 → v1.83 (post-push) |

---

## Task 1: Install lucide-vue-next

**Files:**

- Modify: `app/package.json` (+1 dependency)
- Modify: `app/package-lock.json` (auto)

- [ ] **Step 1.1: Install package**

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
npm install lucide-vue-next
```

Expected output: `added 1 package` (или `added N packages` если есть transitive). Exit 0.

- [ ] **Step 1.2: Verify installed**

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
grep -A1 lucide-vue-next package.json
```

Expected: `"lucide-vue-next": "^0.460.X"` (где X — actual version) в `"dependencies"` секции.

- [ ] **Step 1.3: Snapshot baseline tests (PRE-modification)**

Зафиксировать baseline ДО изменения vuetify.ts:

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
./vendor/bin/pest --parallel --recreate-databases 2>&1 | tail -3
```

Expected: `{"tool":"pest","result":"passed","tests":742,"passed":739,"assertions":2243,"duration_ms":~55000,"skipped":3}`.

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
npm run test:vue 2>&1 | tail -5
```

Expected: `Test Files  88 passed (88) | Tests  683 passed | 3 skipped (686)`.

**NB:** не commit'ить package.json одиночным коммитом — Task 2 объединит с vuetify.ts в один atomic commit.

---

## Task 2: Update vuetify.ts — register Lucide IconSet

**Files:**

- Modify: `app/resources/js/plugins/vuetify.ts` (lines 1-75 → расширяется до ~155 строк)

- [ ] **Step 2.1: Read current vuetify.ts полностью**

```bash
cd "/c/моя/проекты/портал crm/Документация"
cat app/resources/js/plugins/vuetify.ts
```

Зафиксировать существующую структуру (theme, defaults block) — НЕ менять.

- [ ] **Step 2.2: Add Lucide imports + lucideMap + IconSet**

Edit `app/resources/js/plugins/vuetify.ts`:

Заменить первые 3 строки imports:

```ts
// @ts-expect-error vuetify/styles — CSS-импорт без d.ts
import 'vuetify/styles';
import { createVuetify } from 'vuetify';
import type { ThemeDefinition } from 'vuetify';
```

На:

```ts
// @ts-expect-error vuetify/styles — CSS-импорт без d.ts
import 'vuetify/styles';
import { h, type Component } from 'vue';
import { createVuetify } from 'vuetify';
import type { ThemeDefinition, IconSet, IconProps } from 'vuetify';
import {
  Activity, AlertCircle, AlertTriangle, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowRightLeft,
  ArrowUp, Bell, BellOff, Camera, Check, CheckCircle, ChevronRight, CircleStop, Clock, Code,
  Columns3, Copy, CreditCard, Download, Edit, Eye, EyeOff, FilterX, FileText, FlaskConical,
  Folder, Folders, Globe, HelpCircle, Key, KeyRound, LayoutDashboard, List, LogOut, Mail,
  Megaphone, MessageSquare, MessageSquareText, MoreVertical, Pause, Pencil, Phone, Play, Plus,
  PlusCircle, Puzzle, ReceiptText, RefreshCw, RotateCcw, RotateCw, RussianRuble, Save, Search,
  Settings, Shield, ShieldCheck, ShieldOff, Tag, Trash2, User, UserCheck, UserCog, UserPlus,
  Users, Wallet, Webhook, X, XCircle,
} from 'lucide-vue-next';
```

Затем добавить ПЕРЕД `export const vuetify = createVuetify({` (после блока ThemeDefinition):

```ts
/**
 * Liderra Lucide IconSet (CTO-19 closure, v1.83).
 * Spec: docs/superpowers/specs/2026-05-13-cto-19-lucide-icon-migration-design.md
 *
 * Maps 78 mdi-* semantic-ID strings (used across 51 Vue/TS files in resources/js/)
 * to Lucide Vue components for rendering. Views НЕ touched — mdi-* строки остаются
 * как semantic identifiers, рендерятся через Lucide stroke-based SVG icons.
 *
 * CLAUDE.md §2 «Иконки: Lucide» — бренд-spec compliance.
 */
const lucideMap: Record<string, Component> = {
  'mdi-account-arrow-right-outline': UserCheck,
  'mdi-account-group-outline': Users,
  'mdi-account-outline': User,
  'mdi-account-plus-outline': UserPlus,
  'mdi-account-switch': UserCog,
  'mdi-alert-circle': AlertCircle,
  'mdi-alert-circle-outline': AlertCircle,
  'mdi-alert-outline': AlertTriangle,
  'mdi-api': Webhook,
  'mdi-archive': Archive,
  'mdi-arrow-down': ArrowDown,
  'mdi-arrow-left': ArrowLeft,
  'mdi-arrow-up': ArrowUp,
  'mdi-autorenew': RotateCw,
  'mdi-bell-off-outline': BellOff,
  'mdi-bell-outline': Bell,
  'mdi-bullhorn-outline': Megaphone,
  'mdi-camera': Camera,
  'mdi-cash-plus': PlusCircle,
  'mdi-chart-box-outline': LayoutDashboard,
  'mdi-check': Check,
  'mdi-check-circle': CheckCircle,
  'mdi-check-circle-outline': CheckCircle,
  'mdi-chevron-right': ChevronRight,
  'mdi-clock-check-outline': Clock,
  'mdi-clock-outline': Clock,
  'mdi-close': X,
  'mdi-close-circle': XCircle,
  'mdi-cog-outline': Settings,
  'mdi-comment-outline': MessageSquare,
  'mdi-content-copy': Copy,
  'mdi-content-save-outline': Save,
  'mdi-credit-card-outline': CreditCard,
  'mdi-currency-rub': RussianRuble,
  'mdi-delete-outline': Trash2,
  'mdi-dots-vertical': MoreVertical,
  'mdi-download': Download,
  'mdi-email-outline': Mail,
  'mdi-eye': Eye,
  'mdi-eye-off': EyeOff,
  'mdi-eye-outline': Eye,
  'mdi-file-pdf-box': FileText,
  'mdi-filter-off': FilterX,
  'mdi-folder-multiple-outline': Folders,
  'mdi-folder-outline': Folder,
  'mdi-format-list-bulleted': List,
  'mdi-key': Key,
  'mdi-lock-reset': KeyRound,
  'mdi-logout': LogOut,
  'mdi-magnify': Search,
  'mdi-message-text': MessageSquareText,
  'mdi-pause': Pause,
  'mdi-pencil': Pencil,
  'mdi-pencil-outline': Pencil,
  'mdi-phone': Phone,
  'mdi-play': Play,
  'mdi-plus': Plus,
  'mdi-plus-circle-outline': PlusCircle,
  'mdi-progress-clock': Clock,
  'mdi-pulse': Activity,
  'mdi-puzzle-outline': Puzzle,
  'mdi-receipt-text-check-outline': ReceiptText,
  'mdi-refresh': RefreshCw,
  'mdi-restore': RotateCcw,
  'mdi-shield-account-outline': ShieldCheck,
  'mdi-shield-key': Shield,
  'mdi-shield-lock-outline': ShieldCheck,
  'mdi-shield-off': ShieldOff,
  'mdi-stop-circle-outline': CircleStop,
  'mdi-swap-horizontal': ArrowRightLeft,
  'mdi-tag-arrow-right': Tag,
  'mdi-test-tube': FlaskConical,
  'mdi-trash-can-outline': Trash2,
  'mdi-view-column-outline': Columns3,
  'mdi-view-dashboard-outline': LayoutDashboard,
  'mdi-wallet-outline': Wallet,
  'mdi-web': Globe,
  'mdi-xml': Code,
};

const liderraLucideSet: IconSet = {
  component: (props: IconProps) => {
    const Icon = lucideMap[String(props.icon)] || HelpCircle;
    return h(Icon, { size: 20, strokeWidth: 1.75 });
  },
};
```

Затем в `createVuetify({...})` call, ПОСЛЕ блока `theme: { ... }` и ПЕРЕД блоком `defaults: { ... }`, добавить:

```ts
    icons: {
        defaultSet: 'liderra',
        sets: { liderra: liderraLucideSet },
    },
```

**Финальная структура файла:**

```
1: import 'vuetify/styles';
2: import { h, type Component } from 'vue';
3: import { createVuetify } from 'vuetify';
4: import type { ThemeDefinition, IconSet, IconProps } from 'vuetify';
5-12: import { Activity, AlertCircle, ... } from 'lucide-vue-next';
14-32: theme liderraForest (UNCHANGED)
34-110: lucideMap (78 entries) + liderraLucideSet
112-155: createVuetify({ theme, icons, defaults })
```

- [ ] **Step 2.3: Type-check**

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
npm run type-check 2>&1 | tail -10
```

Expected: `0 errors`. Если есть ошибки про unused imports — удалить unused Lucide components из import statement.

- [ ] **Step 2.4: Run Vitest**

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
npm run test:vue 2>&1 | tail -5
```

Expected: `Test Files  88 passed (88) | Tests  683 passed | 3 skipped (686)`. Идентично pre-modification baseline.

Если есть failures — falsify 3 гипотезы:

1. **H1**: Lucide import name неверен (имя компонента у Lucide отличается) → grep test failure для component name → проверить в `lucide-vue-next/dist/index.d.ts`.
2. **H2**: IconSet API mismatch (Vuetify ожидает другой shape) → проверить Vuetify docs / type definition.
3. **H3**: Test stub mismatch (Vitest stubs `<v-icon>` per test setup) → проверить тест setup в `app/vitest.config.ts` / `app/tests/setup.ts`.

Falsify каждую перед фиксом.

- [ ] **Step 2.5: Vite build**

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
npm run build 2>&1 | tail -10
```

Expected: `✓ built in ~2-3s`, exit 0. App.js / chunks slightly bigger (~25-30 KB gzip Lucide chunk).

---

## Task 3: Visual smoke на 5 ключевых views (Playwright MCP)

**Files:** (no file changes — verification only)

- [ ] **Step 3.1: Start dev server**

```bash
cd "/c/моя/проекты/портал crm/Документация/app"
npm run dev &
```

Wait until `Local: http://127.0.0.1:5173/` появится в output.

- [ ] **Step 3.2: Login через Playwright MCP**

Navigate to `http://127.0.0.1:5173/login`. Fill email `admin@demo.local` / password `password`. Click «Войти».

- [ ] **Step 3.3: Visual smoke /dashboard**

Navigate to `http://127.0.0.1:5173/dashboard`. Take screenshot. Verify visually:

- KPI-cards: icons видны (mdi-cash-plus → PlusCircle, mdi-account-group-outline → Users etc.)
- Notification bell видна (mdi-bell-outline → Bell)
- Action buttons имеют glyph'ы.

Acceptance: 0 пустых icon mounts.

- [ ] **Step 3.4: Visual smoke /projects**

Navigate to `http://127.0.0.1:5173/projects`. Screenshot. Verify:

- Search input magnify (mdi-magnify → Search)
- Clearable X (mdi-close-circle → XCircle)
- Action menu MoreVertical (mdi-dots-vertical)
- Status pill icons

Acceptance: 0 пустых icon mounts.

- [ ] **Step 3.5: Visual smoke /settings**

Navigate to `http://127.0.0.1:5173/settings`. Tab через 8 tabs. Verify:

- Tab icons (если есть)
- Save buttons (mdi-content-save-outline → Save)
- Security cards icons (Key, Shield, ShieldCheck)
- Eye toggle (mdi-eye / mdi-eye-off → Eye/EyeOff)

Acceptance: 0 пустых icon mounts.

- [ ] **Step 3.6: Visual smoke /admin/billing**

Navigate to `http://127.0.0.1:5173/admin/billing`. Verify:

- Sidebar navigation icons
- Table action icons
- Dropdown chevrons (mdi-chevron-right → ChevronRight)
- CreditCard / Wallet visible

Acceptance: 0 пустых icon mounts.

- [ ] **Step 3.7: Visual smoke /no-such-404**

Navigate to `http://127.0.0.1:5173/no-such-404`. Verify ErrorView icons (если есть в illustration). Acceptance: page renders, 0 console errors related to icon resolution.

- [ ] **Step 3.8: Stop dev server**

```bash
# Если запущен через background — найти и убить
ps -ef | grep -i "vite" | grep -v grep
# kill <PID>
```

- [ ] **Step 3.9: A11y re-scan (axe-core CDN inject через Playwright)**

Re-run scan на `/dashboard` + `/admin/billing` per quirk 70 pattern (CDN inject + `setTimeout 500ms` + `axe.run()`). Acceptance: 0 новых violations по iconography rules (`aria-hidden-focus`, `image-alt`).

---

## Task 4: Confirm «закрываем CTO-19» from user

**Files:** (no file changes — gating question)

- [ ] **Step 4.1: Ask user via AskUserQuestion**

Pravila §2.2 / §7.1 — закрытие CTO-19 в реестре требует explicit «закрываем» от заказчика. Сформулировать через `AskUserQuestion`:

```
question: "CTO-19 ⏸ → ✅ — закрываем? Visual smoke на 5 views прошёл; иконки рендерятся через Lucide; tests baseline match."
options:
  - "Да, закрываем CTO-19 как ✅"
  - "Нет, отложить closure до дополнительной проверки"
  - "Откатить migration"
```

- [ ] **Step 4.2: Записать ответ**

Если ответ ≠ «Да, закрываем» — НЕ переходить к Task 5/6/7. Возврат к user для дополнительных действий.

Если «Да, закрываем» — proceed к Task 5.

---

## Task 5: Registry v1.82 → v1.83 — CTO-19 ✅ closure + Сводка §0 update

**Files:**

- Modify: `docs/Открытые_вопросы_v8_3.md` (CTO-19 строка §3, Сводка §0 row CTO, Итого row, header version, footer version)

- [ ] **Step 5.1: Locate CTO-19 entry**

```bash
cd "/c/моя/проекты/портал crm/Документация"
grep -n "CTO-19" docs/Открытые_вопросы_v8_3.md | head -3
```

Expected: 1 match строки в section §3 «CTO / архитектор» (line ~2266 после v1.82 bump, +offset от v1.82 inserts).

- [ ] **Step 5.2: Edit CTO-19 entry — ⏸ → ✅**

Edit `docs/Открытые_вопросы_v8_3.md`:

Заменить (значение `⏸ **CTO-19**` start of entry):

```
| ⏸ **CTO-19** | **Иконочная система портала не подключена — все `mdi-*` рендерятся пустыми.**
```

На:

```
| ✅ **CTO-19** | **Иконочная система — Lucide migration через Vuetify custom IconSet (закрыто 13.05.2026).** В `app/resources/js/plugins/vuetify.ts` добавлен custom `IconSet` (`liderraLucideSet`) с 78-entry mapping `mdi-*` → Lucide components. Все 51 Vue/TS файл с `icon="mdi-*"` остаются untouched — mdi-имена работают как semantic-ID для Lucide рендеринга. `npm i lucide-vue-next` selective tree-shakable imports ~25-30 KB gzip. CLAUDE.md §2 «Иконки: Lucide» — бренд-spec compliance. **Spec:** docs/superpowers/specs/2026-05-13-cto-19-lucide-icon-migration-design.md. **Plan:** docs/superpowers/plans/2026-05-13-cto-19-lucide-icon-migration.md. **Прежний контент:** Vuetify-конфиг создавал `<i class="mdi-...">` (default MDI), но CSS-пакет `@mdi/font` в `package.json` отсутствовал → `document.fonts` не содержит `Material Design Icons`, `::before content: none`. Затронуты все места с `prepend-icon`/`append-icon`/`icon`/`clearable` в Vue-views: «+ Создать проект» (mdi-plus → Plus), поле поиска (mdi-magnify → Search), clearable v-select/v-text-field (mdi-close-circle → XCircle), notification bell, dropdown chevron'ы. Локальный workaround клиентский для clearable-крестика в `ProjectsView.vue` (`::after content '✕'`) применён 12.05.2026 — может быть убран в отдельной post-CTO-19 hygiene-task. | Закрыт 13.05.2026 |
```

- [ ] **Step 5.3: Update Сводка §0 row CTO**

Edit `docs/Открытые_вопросы_v8_3.md`:

Заменить:

```
| CTO / архитектор | **18** | **17** (CTO-1..16 + CTO-20 v1.81 ICU collation) | 0 | **1** (CTO-19 v1.79 ⏸ иконочная система `@mdi/font`) | 0 | 0 | 1 [?] |
```

На:

```
| CTO / архитектор | **18** | **18** (CTO-1..16 + CTO-19 v1.83 Lucide migration + CTO-20 v1.81 ICU collation) | 0 | 0 | 0 | 0 | 0 |
```

- [ ] **Step 5.4: Update Сводка §0 Итого row**

Edit `docs/Открытые_вопросы_v8_3.md`:

Заменить:

```
| **Итого продуктовых** | **87** | **70 ✅** | **5 🟦** | **12 ⏸** | **1 P0** | **5 P1** | **3 P2** + 2 P3 (Биз-29, Биз-30) + 1 P2 [?] (CTO-19, priority TBD) |
```

На:

```
| **Итого продуктовых** | **87** | **71 ✅** | **5 🟦** | **11 ⏸** | **1 P0** | **5 P1** | **3 P2** + 2 P3 (Биз-29, Биз-30) |
```

- [ ] **Step 5.5: Update «Истинные P0-блокеры»**

В блоке "Истинные P0-блокеры" — обновить дату: «на 13.05.2026 (после v1.82)» → «на 13.05.2026 (после v1.83)». Контент сохранить.

- [ ] **Step 5.6: Bump header v1.82 → v1.83**

Заменить на line 5 первый блок:

```
**Версия:** 1.82 от 13.05.2026 (day) — **Catch-up bump v1.77 → v1.82** после обнаружения hidden inconsistency
```

На:

```
**Версия:** 1.83 от 13.05.2026 (day, +1) — **CTO-19 ✅ closed** через Lucide migration: `npm i lucide-vue-next` + custom Vuetify IconSet (`liderraLucideSet`) в `app/resources/js/plugins/vuetify.ts` с 78-entry mapping `mdi-*` → Lucide components. Views (51 файл) untouched. Спец [docs/superpowers/specs/2026-05-13-cto-19-lucide-icon-migration-design.md](superpowers/specs/2026-05-13-cto-19-lucide-icon-migration-design.md) + plan [docs/superpowers/plans/2026-05-13-cto-19-lucide-icon-migration.md](superpowers/plans/2026-05-13-cto-19-lucide-icon-migration.md). Сводка §0 update: CTO **18/17✅/1⏸ → 18/18✅/0⏸**; Итого продуктовых **87/70✅/12⏸ → 87/71✅/11⏸**. Регрессия: Pest 742/739/0/3 ✅ + Vitest 88 files / 683 passed + 3 skipped + Vite build exit 0 + bundle Lucide +~25-30 KB gzip. CLAUDE.md §2 «Иконки: Lucide» — бренд-spec compliance achieved. Заказчик 13.05.2026: «E. CTO-19 fix — иконочная система» + «ii. Правильный — Lucide migration» + явное «закрываем» на Task 4. Path α (aliases-only). Path (i) @mdi/font REJECTED (250 KB CSS, против бренда). Path β rename strings REJECTED (большой diff 51 файл, не нужен). Через `superpowers:brainstorming` → `superpowers:writing-plans` → `superpowers:executing-plans` + manual Edit. Предыдущая v1.82 — catch-up bump.
```

Затем добавить **NEW** «Что изменилось в v1.83 относительно v1.82:» block перед существующим «Что изменилось v1.82 относительно v1.77»:

```
**Что изменилось в v1.83 относительно v1.82:**

- **CTO-19 ⏸ → ✅ closed** через Lucide migration. Custom Vuetify IconSet (`liderraLucideSet`) в `app/resources/js/plugins/vuetify.ts`. 78-entry mapping `mdi-*` semantic-ID → Lucide components (Plus, Search, Bell, AlertCircle, etc.). 51 Vue/TS файл с `icon="mdi-*"` invariant. `npm i lucide-vue-next` (~25-30 KB gzip tree-shakable).
- **Сводка §0 counter update**: CTO 17✅ → 18✅, 1⏸ → 0⏸; Итого 70✅ → 71✅, 12⏸ → 11⏸. P2 [?] (CTO-19 priority TBD) убрано.
- **Регрессия зелёная**: Pest --parallel 742/739/0/3 ✅, Vitest 88 files / 683 passed + 3 skipped, Vite build exit 0, lychee 248 OK, gitleaks 0.
- **Brand alignment**: CLAUDE.md §2 «Иконки: Lucide» — теперь visually реализован (был declaratory только в спеке).

---

```

- [ ] **Step 5.7: Update footer**

Заменить на line ~2810 (после v1.82 bump):

```
*Версия: 1.82 от 13.05.2026 (day) — Catch-up bump v1.77 → v1.82 после обнаружения hidden inconsistency
```

На:

```
*Версия: 1.83 от 13.05.2026 (day, +1) — CTO-19 ✅ closed через Lucide migration. `npm i lucide-vue-next` + Vuetify custom IconSet с 78-entry mapping. Views untouched (51 файл invariant). Сводка §0: CTO 17✅ → 18✅, 0⏸; Итого 70✅ → 71✅, 11⏸. Brand alignment CLAUDE.md §2. Регрессия Pest 742/Vitest 683/Vite 2.67s/lychee 248 OK/gitleaks 0. Через `superpowers:brainstorming` → `superpowers:writing-plans` → `superpowers:executing-plans`. Path α (aliases-only); paths (i)/(β) REJECTED. Предыдущая v1.82 — catch-up.*
```

---

## Task 6: CLAUDE.md §0 sync — registry version v1.82 → v1.83

**Files:**

- Modify: `CLAUDE.md` (line ~20 — §0 «Открытые вопросы» row)

- [ ] **Step 6.1: Read current row**

```bash
cd "/c/моя/проекты/портал crm/Документация"
grep -n "Открытые_вопросы_v8_3.md" CLAUDE.md | head -1
```

Зафиксировать текущую строку (v1.82 row from registry catch-up commit `9bc0419`).

- [ ] **Step 6.2: Edit row — bump v1.82 → v1.83**

Edit `CLAUDE.md`:

Заменить:

```
| Открытые вопросы | [docs/Открытые_вопросы_v8_3.md](docs/Открытые_вопросы_v8_3.md) (**v1.82 от 13.05.2026 (day) — Catch-up bump** v1.77 → v1.82 после hidden inconsistency: header заявлял v1.77, footer накопил v1.78/v1.79/v1.80/v1.81. Содержит v1.78 Plan 4 +7 Биз-25..31 ⏸ (section ## 14), v1.79 CTO-19 ⏸ иконочная система, v1.80 CTO-20 ⏸ ICU collation, v1.81 CTO-20 ✅ closed, v1.82 — post-Plan-4 context (Plan 5 frontend / Quiet Luxury / Q.DEFER closures audit-internal / R15 merge — не Q-items). **Сводка §0 после v1.82: 87 продуктовых / 70 ✅ / 5 🟦 / 12 ⏸ / 1 P0 + 5 P1 + 3 P2 + 2 P3 + 1 P2 [?]**. **Регрессия: Pest --parallel 742/739/0/3 / Vitest 88 files / 683 passed + 3 skipped / Vite build 2.67s / lychee 248 OK / gitleaks 0 (367 commits)**. v1.77 baseline — Sprint 4 «Audit tail» (Pest 421 / Vitest 416). Section ## 13 collision fixed: Plan 4 → ## 14, Аудит C сохраняется ## 13) |
```

На:

```
| Открытые вопросы | [docs/Открытые_вопросы_v8_3.md](docs/Открытые_вопросы_v8_3.md) (**v1.83 от 13.05.2026 (day, +1) — CTO-19 ✅ closed** через Lucide migration: `npm i lucide-vue-next` + custom Vuetify IconSet с 78-entry `mdi-*` → Lucide mapping. CLAUDE.md §2 «Иконки: Lucide» бренд-spec compliance achieved. Spec/plan в docs/superpowers/. **Сводка §0: 87 продуктовых / 71 ✅ / 5 🟦 / 11 ⏸ / 1 P0 + 5 P1 + 3 P2 + 2 P3**. v1.82 baseline — Catch-up bump v1.77 → v1.82. v1.77 — Sprint 4 «Audit tail» (Pest 421 / Vitest 416). Section ## 13 collision fixed: Plan 4 → ## 14, Аудит C ## 13) |
```

**NB CLAUDE.md §5 п.10:** прямой Edit per approved plan rationale «registry version sync» (single-line update, не content authoring). Зафиксировать в commit message.

---

## Task 7: Verification — full pre-commit lefthook + test baseline

**Files:** (verification only)

- [ ] **Step 7.1: Stage files**

```bash
cd "/c/моя/проекты/портал crm/Документация"
git add app/package.json app/package-lock.json app/resources/js/plugins/vuetify.ts docs/Открытые_вопросы_v8_3.md CLAUDE.md
git status --short
```

Expected: 5 файлов в staged area (M все 5).

- [ ] **Step 7.2: Full pre-commit hook run через `git commit`**

```bash
cd "/c/моя/проекты/портал crm/Документация"
git commit -m "$(cat <<'EOF'
feat(icons): CTO-19 ✅ closed via Lucide migration (Vuetify custom IconSet)

Закрывает CTO-19 ⏸ из реестра v1.79 — иконочная система портала
была не подключена (`@mdi/font` отсутствовал в `package.json`,
все `mdi-*` рендерились пустыми).

PATH α (aliases-only, approved заказчиком 13.05.2026 через brainstorming):
— `npm i lucide-vue-next` (~25-30 KB gzip tree-shakable bundle)
— `app/resources/js/plugins/vuetify.ts`: +icons config c `liderraLucideSet`
  custom IconSet и 78-entry `lucideMap` (`mdi-plus` → Plus, `mdi-magnify`
  → Search, `mdi-bell-outline` → Bell, ... всего 78 entries)
— Fallback `HelpCircle` для unmapped
— 51 Vue/TS файл с `icon="mdi-*"` НЕ touched — mdi-имена работают как
  semantic-ID для Lucide рендеринга

CLAUDE.md §2 «Иконки: Lucide» — бренд-spec compliance achieved.

Реестр:
— CTO-19 ⏸ → ✅ closed (явное «закрываем» от заказчика на Task 4)
— Сводка §0 CTO: 17✅/1⏸ → 18✅/0⏸
— Сводка §0 Итого: 70✅/12⏸ → 71✅/11⏸
— Header v1.82 → v1.83 + новый changelog block
— Footer v1.83 (match header)

CLAUDE.md §0 row «Открытые вопросы» — v1.82 → v1.83 sync. Прямой
Edit per approved plan rationale «registry version sync», не content
authoring (CLAUDE.md §5 п.10).

Spec: docs/superpowers/specs/2026-05-13-cto-19-lucide-icon-migration-design.md
Plan: docs/superpowers/plans/2026-05-13-cto-19-lucide-icon-migration.md

Path (i) `npm i @mdi/font` REJECTED (250 KB CSS, против бренда).
Path β rename all `mdi-*` strings REJECTED (большой diff 51 файл).

Регрессия зелёная:
— Pest --parallel 742/739/0/3 ✅ (после --recreate-databases)
— Vitest 88 files / 683 passed + 3 skipped (baseline match)
— Vite build exit 0
— lychee 248 OK / 0 errors
— gitleaks 0 leaks

Memory updates (отдельный шаг, git-untracked):
— reference_archive.md description (registry v1.82 → v1.83)
— MEMORY.md index line 7 sync

Через `superpowers:brainstorming` → `superpowers:writing-plans` →
`superpowers:executing-plans` + ручной Edit (vuetify.ts / реестр).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
```

Expected: lefthook prints `gitleaks ✅ + markdownlint ✅ + cspell ✅` (possibly +eslint-vue/larastan если staged JS/TS файлы). Exit 0.

Если cspell упадёт на новых словах (например, lucide component names в комментариях) — добавить в `cspell-words.txt`, re-stage, re-commit.

Если eslint-vue упадёт на vuetify.ts unused import — удалить unused, re-commit.

Если markdownlint упадёт на registry edit — auto-fix или manual fix per output, re-commit.

- [ ] **Step 7.3: Post-commit verification**

```bash
cd "/c/моя/проекты/портал crm/Документация"
git log -1 --stat
git status
```

Expected: commit visible, working tree clean.

---

## Task 8: Push + pre-push hooks

**Files:** (push only)

- [ ] **Step 8.1: Push to origin**

```bash
cd "/c/моя/проекты/портал crm/Документация"
git push origin plan5-frontend-projects 2>&1
```

Expected: lefthook pre-push prints `gitleaks-full-history ✅` (369 commits / +1 from this push) + `lychee-links ✅` (~248 OK). Push success: `9bc0419..<new-sha>  plan5-frontend-projects -> plan5-frontend-projects`.

- [ ] **Step 8.2: Verify remote sync**

```bash
cd "/c/моя/проекты/портал crm/Документация"
git rev-parse HEAD
git rev-parse origin/plan5-frontend-projects
git rev-list --left-right --count plan5-frontend-projects...origin/main
```

Expected: local HEAD == remote HEAD. Counters: 116 ahead / 0 behind (или similar +1 от 115).

---

## Task 9: Memory updates (post-push, git-untracked)

**Files:**

- Modify: `C:\Users\Administrator\.claude\projects\c---------------------crm-------------\memory\reference_archive.md`
- Modify: `C:\Users\Administrator\.claude\projects\c---------------------crm-------------\memory\MEMORY.md`

- [ ] **Step 9.1: Update reference_archive.md description**

Edit `memory/reference_archive.md`:

Заменить в description (line 3) — registry version reference:

```
реестр **v1.82** (13.05.2026 day catch-up bump: v1.77→v1.82 после hidden inconsistency header vs footer-trail v1.78/v1.79/v1.80/v1.81 + post-Plan-4 context; section ## 13 collision fix Plan 4 → ## 14; Сводка §0 counters update 78→87 продуктовых / 4→12 ⏸ / 3→5 P1 / 0→3 P2; Pravila §2.2 строго: Биз-25..31 + CTO-19 остаются ⏸)
```

На:

```
реестр **v1.83** (13.05.2026 day +1: CTO-19 ✅ closed через Lucide migration — `npm i lucide-vue-next` + Vuetify custom IconSet c 78-entry `mdi-*`→Lucide mapping; views untouched. CLAUDE.md §2 brand-spec compliance. Сводка §0: CTO 18✅/0⏸ / Итого 71✅/11⏸. v1.82 — catch-up bump v1.77→v1.82)
```

- [ ] **Step 9.2: Update MEMORY.md index line 7**

Edit `memory/MEMORY.md` line 7 (reference_archive description):

Заменить:

```
**реестр v1.82** (catch-up bump: v1.78 Plan 4 +7 Биз-25..31 ⏸ / v1.79 CTO-19 ⏸ / v1.80-v1.81 CTO-20 cycle / v1.82 post-Plan-4 context; section ## 13 collision fix Plan 4→## 14; Сводка §0 87 продуктовых / 70 ✅ / 12 ⏸)
```

На:

```
**реестр v1.83** (13.05.2026 day +1: CTO-19 ✅ closed via Lucide migration; Сводка §0 87 продуктовых / 71 ✅ / 11 ⏸; CLAUDE.md §2 brand-spec compliance achieved; v1.82 baseline — catch-up bump)
```

---

## Task 10: Final verification — invoke superpowers:verification-before-completion

**Files:** (gating verification only)

- [ ] **Step 10.1: Invoke skill**

Invoke `superpowers:verification-before-completion` через Skill tool.

- [ ] **Step 10.2: Run fresh verification suite**

```bash
cd "/c/моя/проекты/портал crm/Документация"
echo "=== HEAD sync ===" && git rev-parse HEAD && git rev-parse origin/plan5-frontend-projects
echo "=== ahead/behind ===" && git rev-list --left-right --count plan5-frontend-projects...origin/main
echo "=== registry version ===" && head -5 docs/Открытые_вопросы_v8_3.md | grep Версия | head -c 100
echo "=== footer version ===" && tail -5 docs/Открытые_вопросы_v8_3.md | grep "^\*Версия" | head -c 100
echo "=== Сводка Итого ===" && grep "Итого продуктовых" docs/Открытые_вопросы_v8_3.md | head -c 200
echo "=== CTO-19 status ===" && grep -A1 "CTO-19" docs/Открытые_вопросы_v8_3.md | head -3
echo "=== CLAUDE.md ref ===" && grep "Открытые_вопросы_v8_3.md" CLAUDE.md | head -c 200
echo "=== vuetify.ts has IconSet ===" && grep -c "liderraLucideSet" app/resources/js/plugins/vuetify.ts
echo "=== lucide-vue-next installed ===" && grep -c "lucide-vue-next" app/package.json
```

Expected (все pass):

- HEAD == remote HEAD
- 116 ahead / 0 behind
- header v1.83 + footer v1.83 match
- Итого продуктовых: 87 / 71 ✅ / 5 🟦 / 11 ⏸
- CTO-19 строка начинается с `✅ **CTO-19**`
- CLAUDE.md row содержит «v1.83»
- vuetify.ts grep `liderraLucideSet` count: 2+ (один в definition, один в `sets:`)
- package.json grep `lucide-vue-next` count: 1+

- [ ] **Step 10.3: Final report to user**

Report (per Pravila §3.2) — concise summary:

```
CTO-19 ✅ closed via Lucide migration. Реестр v1.82 → v1.83.

— vuetify.ts: liderraLucideSet IconSet с 78-entry mdi-* → Lucide map
— bundle: +~25-30 KB gzip (tree-shaken Lucide selective imports)
— views untouched (51 файл с icon="mdi-*" invariant)
— регрессия: Pest 742/Vitest 683/Vite OK/lychee 248 OK/gitleaks 0
— Сводка §0: CTO 18/18✅/0⏸; Итого 87/71✅/11⏸

Branch HEAD: <new-sha> (116 ahead / 0 behind origin/main).
```

---

## Self-Review

Per writing-plans skill — quick fresh-eyes check после written plan.

**1. Spec coverage:** Spec §2.1-2.5 (architecture) → Task 1+2. Spec §3 (bundle) → Task 1.3 baseline + Task 2.5 build. Spec §4 (testing) → Task 2.4 + Task 3 + Task 10.2. Spec §5 (risks) → addressed inline (Step 2.4 hypothesis falsification, Step 7.2 cspell/eslint fallback). Spec §6 (closure plan) → Task 4 + Task 5 + Task 6 + Task 9. ✅ All sections covered.

**2. Placeholder scan:** Lucide component names в Step 2.2 import — все listed; mapping table 78 entries — все listed. No TBDs. Commit messages — fully drafted. ✅

**3. Type consistency:** `liderraLucideSet` (Step 2.2 definition) → used в `sets: { liderra: liderraLucideSet }` (Step 2.2 createVuetify call) → verified in Task 10.2 grep (count 2+). ✅

---

## Execution Handoff

Plan complete and saved to `docs/superpowers/plans/2026-05-13-cto-19-lucide-icon-migration.md`. Two execution options:

**1. Subagent-Driven (recommended)** — `superpowers:subagent-driven-development` dispatches fresh subagent per task, review between tasks, fast iteration.

**2. Inline Execution** — `superpowers:executing-plans` execute tasks in this session с batch checkpoints для review.

**Which approach?**
