# Claude Brain Extraction 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:** Извлечь «мозг Claude» (правила + хуки + плагины + MCP) из Лидерры в независимый репозиторий `claude-brain` с воспроизводимым sync-механизмом.

**Architecture:** Bootstrap создаёт новый git repo `c:\моя\проекты\claude-brain` с двумя каналами: `project-files/` копируется в consumer-проекты (Лидерра), `user-level-files/` в `~/.claude/` + `~/.claude.json`. 7 скриптов реализуют sync (install/verify/extract + 4 lib helper'а) с TDD-покрытием. Plugin layer pin'ит 4 плагина с gitCommitSha, MCP layer масштабирует API_KEY через placeholder + interactive prompt. Gitleaks self-scan — обязательный gate перед первым commit'ом.

**Tech Stack:** Bash (Git Bash на Windows) / Python 3.10+ для hook-тестов / jq для JSON merge / git + gh CLI / gitleaks для secret scanning / Claude Code CLI для plugin install.

**Спека:** [docs/superpowers/specs/2026-05-10-claude-brain-extraction-design.md](../specs/2026-05-10-claude-brain-extraction-design.md) (776 строк, version extended A)

---

## Структура файлов (создаются за весь план)

### Brain repo `c:\моя\проекты\claude-brain\`

```
claude-brain/
├── .gitignore                              # Task 1.3
├── .brain-version                          # Task 8.2 (self-marker)
├── README.md                               # Task 5.3
├── CLAUDE.md                               # Task 5.1 (meta для brain)
├── manifest.json                           # Task 5.2 (sha256 + versions)
├── CHANGELOG.md                            # Task 5.4
│
├── project-files/                          # Task 1.2 (mkdir)
│   ├── CLAUDE.md.template                  # Task 2.1
│   ├── .mcp.json.template                  # Task 2.9
│   ├── README.md                           # Task 5.6 (помещено там же)
│   └── docs/
│       ├── Pravila_raboty_Claude.template.md   # Task 2.2a
│       ├── Plugin_stack_rules.template.md       # Task 2.2b
│       ├── Tooling.template.md                  # Task 2.2c
│       ├── CHANGELOG_claude_md.template.md      # Task 2.2d
│       └── visualizations/
│           └── hooks-skills-plugins-map.html    # Task 2.3
│
├── user-level-files/                       # Task 1.2 (mkdir)
│   ├── hooks/                              # 10 файлов из Task 2.4
│   │   ├── skill-marker.py
│   │   ├── skill-check.py
│   │   ├── economy-mode.py
│   │   ├── economy-mode-test.py
│   │   ├── economy-self-check.py
│   │   ├── economy-self-check-test.py
│   │   ├── economy-state-guard.py
│   │   ├── economy-state-guard-test.py
│   │   ├── economy-postcompact.py
│   │   └── economy-verifier.py
│   ├── settings-fragment.json              # Task 2.5
│   ├── marketplaces.json                   # Task 2.6
│   ├── plugins-manifest.json               # Task 2.7
│   ├── mcp-user.template.json              # Task 2.8
│   └── README.md                           # Task 5.6 (часть)
│
├── experiments/
│   ├── README.md                           # Task 1.2 (placeholder)
│   └── .gitkeep                            # Task 1.2
│
├── scripts/                                # Tasks 3.x, 4.x
│   ├── install.sh                          # Task 4.2
│   ├── verify.sh                           # Task 4.1
│   ├── extract.sh                          # Task 4.3
│   ├── tests/                              # все *-test.sh файлы
│   │   ├── common-test.sh                  # Task 3.1
│   │   ├── merge-settings-test.sh          # Task 3.2
│   │   ├── merge-mcp-test.sh               # Task 3.3
│   │   ├── setup-secrets-test.sh           # Task 3.4
│   │   ├── install-plugins-test.sh         # Task 3.5
│   │   ├── verify-test.sh                  # Task 4.1
│   │   ├── install-test.sh                 # Task 4.2
│   │   └── extract-test.sh                 # Task 4.3
│   ├── fixtures/                           # тестовые JSON-данные
│   │   ├── sample-settings.json            # Task 3.2
│   │   ├── sample-claude-json.json         # Task 3.3
│   │   └── sample-mcp.json                 # Task 3.3
│   └── lib/
│       ├── common.sh                       # Task 3.1
│       ├── merge-settings.sh               # Task 3.2
│       ├── merge-mcp.sh                    # Task 3.3
│       ├── setup-secrets.sh                # Task 3.4
│       └── install-plugins.sh              # Task 3.5
│
├── docs/                                   # Tasks 5.x
│   ├── architecture.md                     # Task 5.5
│   ├── how-to-use-brain.md                 # Task 5.6
│   ├── how-to-experiment.md                # Task 5.7
│   ├── secrets-and-tokens.md               # Task 5.8
│   └── consumer-projects.md                # Task 5.9
│
└── .github/                                # Task 6.1
    └── workflows/
        └── ci.yml
```

### Liderra (модификация)

```
c:\моя\проекты\портал crm\Документация\
└── .brain-version                          # Task 10.1 (новый файл)
```

### Test consumer (временный)

```
c:\tmp\test-consumer\
└── .brain-version                          # Task 9.2 (создаётся install.sh)
```

---

## Phase 0: Pre-bootstrap discovery

**Цель:** Верифицировать prerequisites (CLI команды, инструменты, jq поведение, secret rotation) ПЕРЕД любым extraction. Закрывает unverified-пункты из spec §13.

---

### Task 0.1: Verify Claude Code CLI plugin commands exist

**Files:** none (read-only discovery)

- [ ] **Step 1: Check `claude` CLI availability**

Run: `command -v claude && claude --version`
Expected: путь к binary + версия

Если `claude` не в PATH — это known issue (VSCode extension не всегда экспортирует `claude` в PATH). Документировать в plan progress: «CLI команды нельзя использовать, fallback на прямое редактирование JSON-конфигов (Q14 fallback из spec)».

- [ ] **Step 2: Check plugin subcommands**

Run: `claude plugin --help 2>&1 | tee /tmp/claude-plugin-help.txt`
Expected: список команд (`install`, `list`, `info` и т.п.) или error

Если нет subcommand `plugin` — установить в memory как fact: «brain v1.0 fallback mode — править installed_plugins.json + known_marketplaces.json + enabledPlugins напрямую, инструкция в setup-secrets.sh».

- [ ] **Step 3: Check marketplace subcommand**

Run: `claude marketplace --help 2>&1 | tee /tmp/claude-marketplace-help.txt`
Expected: `add`, `list`, или error

- [ ] **Step 4: Record findings in plan progress file**

Write to `c:/tmp/brain-discovery-results.md`:

```markdown
# Brain Bootstrap Discovery — <ISO timestamp>

## Claude Code CLI
- claude available: <yes/no>
- claude plugin install: <yes/no>
- claude plugin list: <yes/no>
- claude plugin info --json: <yes/no>
- claude marketplace add: <yes/no>
- claude marketplace list: <yes/no>

## Fallback decision
<if any CLI command unavailable: explicit fallback strategy>
```

---

### Task 0.2: Verify jq / python3 / git / gitleaks

**Files:** none (read-only discovery)

- [ ] **Step 1: Check jq**

Run: `command -v jq && jq --version`
Expected: путь + версия (≥1.6 рекомендована для `*` deep-merge stability)

Если jq не установлен на Windows — установить через `choco install jq` или `winget install jqlang.jq`. Записать в discovery-results.

- [ ] **Step 2: Check python3**

Run: `command -v python3 || command -v python; python --version`
Expected: Python ≥3.10 (manifest.json min-python-version будет ставить эту планку)

- [ ] **Step 3: Check git + gh**

Run: `git --version && command -v gh && gh --version 2>&1 || echo "gh not installed (optional)"`
Expected: git ≥2.x обязательно; gh опционально (для шага создания GitHub repo)

- [ ] **Step 4: Check gitleaks**

Run: `command -v gitleaks || ls "c:/моя/проекты/портал crm/Документация/bin/gitleaks.exe" 2>&1`
Expected: либо global gitleaks, либо локальный `bin/gitleaks.exe` Лидерры

Если ни того ни другого — установить через `choco install gitleaks` или скачать binary в `c:/моя/проекты/claude-brain/bin/`.

- [ ] **Step 5: Append findings to discovery-results.md**

```markdown
## Prerequisites
- jq: <version or MISSING>
- python: <version or MISSING>
- git: <version>
- gh CLI: <version or MISSING - optional>
- gitleaks: <path or MISSING>
```

---

### Task 0.3: Test jq deep-merge behavior on ~/.claude.json

**Files:** `c:/tmp/jq-merge-test/` (создаётся для теста)

- [ ] **Step 1: Create test fixtures**

```bash
mkdir -p c:/tmp/jq-merge-test
cat > c:/tmp/jq-merge-test/existing.json <<'EOF'
{
  "mcpServers": {
    "laravel-boost": {
      "command": "php",
      "args": ["app/artisan", "boost:mcp"]
    },
    "magic": {
      "type": "stdio",
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@21st-dev/magic@latest", "API_KEY=OLD_KEY"]
    }
  },
  "otherKey": "preserved"
}
EOF
cat > c:/tmp/jq-merge-test/brain.json <<'EOF'
{
  "mcpServers": {
    "magic": {
      "type": "stdio",
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@21st-dev/magic@latest", "API_KEY=<<MAGIC_API_KEY>>"]
    }
  }
}
EOF
```

- [ ] **Step 2: Test shallow merge with `*` operator**

Run: `jq -s '.[0].mcpServers * .[1].mcpServers' c:/tmp/jq-merge-test/existing.json c:/tmp/jq-merge-test/brain.json`

Expected output:

```json
{
  "laravel-boost": { "command": "php", "args": ["app/artisan", "boost:mcp"] },
  "magic": { "type": "stdio", "command": "cmd", "args": ["/c", "npx", "-y", "@21st-dev/magic@latest", "API_KEY=<<MAGIC_API_KEY>>"] }
}
```

**Critical check:** `magic` должен быть **заменён** brain'овской версией (с placeholder), `laravel-boost` — **сохранён**. Если `*` сохраняет старый magic (с OLD_KEY), это shallow merge не то поведение что нам нужно — придётся использовать explicit replace.

- [ ] **Step 3: Test alternative — explicit replacement**

Run: `jq -s '.[0] | .mcpServers = (.mcpServers + .[1].mcpServers)' c:/tmp/jq-merge-test/existing.json c:/tmp/jq-merge-test/brain.json`

Expected: тот же результат, но с гарантией что новые ключи добавляются, существующие — заменяются.

- [ ] **Step 4: Decide algorithm in merge-mcp.sh**

Записать в `c:/tmp/brain-discovery-results.md` под заголовком `## jq merge behavior`:

- Какая команда даёт ожидаемый результат
- Какая используется в `merge-mcp.sh` (зафиксировать в коде Task 3.3)

- [ ] **Step 5: Cleanup**

Run: `rm -rf c:/tmp/jq-merge-test`

---

### Task 0.4: Rotate compromised MAGIC_API_KEY (user manual action)

**Files:** none (manual user action на 21st.dev)

- [ ] **Step 1: Open 21st.dev dashboard**

User вручную: https://21st.dev → settings → API keys

Текущий ключ `da9dbfbdd4ad1594d4a6d95f7df6506f93b80d74c17d7567ebcae6546745cd04` (виден в `~/.claude.json:544`) — формально дискомпрометирован показом в логах текущей сессии. Ротация обязательна перед extraction.

- [ ] **Step 2: Generate new API key**

User вручную: кликнуть «Generate new key», скопировать в KeePass / Bitwarden.

- [ ] **Step 3: Update `~/.claude.json` локально (НЕ commit)**

User вручную: открыть `c:/Users/Administrator/.claude.json:544`, заменить старый `API_KEY=...` на новый. Сохранить.

- [ ] **Step 4: Verify new key working**

В Claude Code session: запросить любой Magic MCP tool (`mcp__magic__21st_magic_component_search` с пустым query — должен вернуть error/empty, не auth-error).

Если auth-error — ключ не подхватился, нужен restart Claude Code.

- [ ] **Step 5: Revoke old key on 21st.dev**

User вручную: revoke старый ключ через 21st.dev UI.

- [ ] **Step 6: Record in discovery-results.md**

```markdown
## Secret rotation
- MAGIC_API_KEY rotated: <yes/skipped+reason>
- Date: <ISO timestamp>
- Old key revoked: <yes/no>
```

---

### Task 0.5: Scan ~/.claude/backups/ for historical secrets

**Files:** none (read-only scan)

- [ ] **Step 1: Locate backup files**

Run: `find "$HOME/.claude/backups" -type f -name "*.json" 2>&1 | head -20`
Expected: список (возможно пустой) JSON-бэкапов settings.json / .claude.json

- [ ] **Step 2: Scan каждый backup на API_KEY**

Run:

```bash
for f in "$HOME/.claude/backups"/*.json "$HOME/.claude/settings.json.backup-pre-economy-hardening"; do
  [ -f "$f" ] || continue
  if grep -l 'API_KEY=[a-f0-9]\{40,\}' "$f" 2>/dev/null; then
    echo "FOUND in $f"
    grep -n 'API_KEY=' "$f"
  fi
done
```

Expected: список файлов содержащих API_KEY (старый ключ)

- [ ] **Step 3: Document scope leak**

В `c:/tmp/brain-discovery-results.md`:

```markdown
## ~/.claude/backups/ leak scope
- Files containing OLD_API_KEY: <count>
- Remediation: ротация (Task 0.4) делает старый ключ невалидным; backups можно оставить (uselless)
- Optional cleanup: `rm $HOME/.claude/backups/*.json` (если есть желание; для бренда не критично)
```

---

### Task 0.6: Phase 0 gate — Commit discovery results

**Files:**

- Create: `c:/tmp/brain-discovery-results.md` (созданный в Tasks 0.1-0.5)

- [ ] **Step 1: Final review discovery-results.md**

Прочитать файл целиком; убедиться что для каждого Task 0.x есть заполненная секция; убедиться что все blocker'ы решены или explicit fallback зафиксирован.

- [ ] **Step 2: Copy discovery-results.md в Лидерра как memory backup**

Run: `cp c:/tmp/brain-discovery-results.md "c:/моя/проекты/портал crm/Документация/docs/superpowers/specs/2026-05-10-brain-bootstrap-discovery-results.md"`

- [ ] **Step 3: Commit в Лидерре**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git add docs/superpowers/specs/2026-05-10-brain-bootstrap-discovery-results.md
git commit -m "$(cat <<'EOF'
docs: brain bootstrap discovery results (Phase 0 of brain extraction)

Captures pre-bootstrap verification: Claude CLI commands availability,
prerequisites (jq/python/git/gitleaks), jq deep-merge behavior, secret
rotation status, ~/.claude/backups/ leak scope.

Required reading before Phase 1 (brain repo skeleton creation).

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

Expected: `1 file changed, N insertions(+)`.

---

## Phase 1: Brain repo skeleton

**Цель:** Создать пустую структуру brain repo с .gitignore и initial empty commit (так чтобы Phase 2 коммитил уже в существующий repo).

---

### Task 1.1: Create brain repo directory + git init

**Files:**

- Create: `c:\моя\проекты\claude-brain\` (directory)
- Create: `c:\моя\проекты\claude-brain\.git\` (git init artifact)

- [ ] **Step 1: Pre-flight check — directory не существует**

Run: `ls "c:/моя/проекты/claude-brain" 2>&1 || echo "directory does not exist (good)"`
Expected: «does not exist (good)» — если directory уже есть, ABORT и спросить пользователя.

- [ ] **Step 2: Create directory**

Run: `mkdir -p "c:/моя/проекты/claude-brain"`
Expected: 0 exit code.

- [ ] **Step 3: git init**

Run: `cd "c:/моя/проекты/claude-brain" && git init`
Expected: «Initialized empty Git repository...»

- [ ] **Step 4: Configure git for brain repo**

```bash
cd "c:/моя/проекты/claude-brain"
git config user.name "Дмитрий"
git config user.email "eclips9363@gmail.com"
```

Expected: 0 exit codes (значения из текущей Лидерры).

- [ ] **Step 5: Verify**

Run: `ls -la "c:/моя/проекты/claude-brain/.git" | head -5`
Expected: видны `HEAD`, `config`, `objects`, `refs/`.

---

### Task 1.2: Create directory tree

**Files:**

- Create: `c:\моя\проекты\claude-brain\project-files\docs\visualizations\`
- Create: `c:\моя\проекты\claude-brain\user-level-files\hooks\`
- Create: `c:\моя\проекты\claude-brain\experiments\`
- Create: `c:\моя\проекты\claude-brain\scripts\lib\`
- Create: `c:\моя\проекты\claude-brain\scripts\tests\`
- Create: `c:\моя\проекты\claude-brain\scripts\fixtures\`
- Create: `c:\моя\проекты\claude-brain\docs\`
- Create: `c:\моя\проекты\claude-brain\.github\workflows\`

- [ ] **Step 1: Create all directories**

```bash
cd "c:/моя/проекты/claude-brain"
mkdir -p \
  project-files/docs/visualizations \
  user-level-files/hooks \
  experiments \
  scripts/lib scripts/tests scripts/fixtures \
  docs \
  .github/workflows
```

Expected: 0 exit code.

- [ ] **Step 2: Create placeholder файлы для пустых директорий (git tracking)**

```bash
cd "c:/моя/проекты/claude-brain"
echo "# Experiments — work-in-progress, not synced to consumers" > experiments/README.md
touch experiments/.gitkeep
```

- [ ] **Step 3: Verify tree**

Run: `find "c:/моя/проекты/claude-brain" -type d | sort`
Expected (output):

```
c:/моя/проекты/claude-brain
c:/моя/проекты/claude-brain/.git
c:/моя/проекты/claude-brain/.github
c:/моя/проекты/claude-brain/.github/workflows
c:/моя/проекты/claude-brain/docs
c:/моя/проекты/claude-brain/experiments
c:/моя/проекты/claude-brain/project-files
c:/моя/проекты/claude-brain/project-files/docs
c:/моя/проекты/claude-brain/project-files/docs/visualizations
c:/моя/проекты/claude-brain/scripts
c:/моя/проекты/claude-brain/scripts/fixtures
c:/моя/проекты/claude-brain/scripts/lib
c:/моя/проекты/claude-brain/scripts/tests
c:/моя/проекты/claude-brain/user-level-files
c:/моя/проекты/claude-brain/user-level-files/hooks
```

---

### Task 1.3: Write .gitignore

**Files:**

- Create: `c:\моя\проекты\claude-brain\.gitignore`

- [ ] **Step 1: Write .gitignore**

```bash
cat > "c:/моя/проекты/claude-brain/.gitignore" <<'EOF'
# Python
__pycache__/
*.pyc
*.pyo
*.pyd

# Experiments — work-in-progress, not synced to consumers
experiments/*
!experiments/README.md
!experiments/.gitkeep

# Secret resolution artifacts (post-install)
*-resolved.json
.brain-deferred-secrets.txt

# OS
.DS_Store
Thumbs.db

# Editor
.vscode/
.idea/
*.swp
*~

# Logs
*.log
EOF
```

- [ ] **Step 2: Verify content**

Run: `cat "c:/моя/проекты/claude-brain/.gitignore" | wc -l`
Expected: ≥18 lines (примерно 22 строки с пустыми).

---

### Task 1.4: Initial commit (empty skeleton)

**Files:** все из Tasks 1.1-1.3

- [ ] **Step 1: Stage everything tracked**

```bash
cd "c:/моя/проекты/claude-brain"
git add .gitignore experiments/README.md experiments/.gitkeep
```

- [ ] **Step 2: Verify status**

Run: `cd "c:/моя/проекты/claude-brain" && git status`
Expected: 3 файла в staging (`.gitignore`, `experiments/README.md`, `experiments/.gitkeep`)

- [ ] **Step 3: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git commit -m "$(cat <<'EOF'
chore: initial brain repo skeleton

Empty repo with directory tree:
- project-files/ (for consumer-repo sync)
- user-level-files/ (for ~/.claude/ sync)
- experiments/ (sandbox, gitignored)
- scripts/ (sync tooling)
- docs/

Next: extract brain artifacts from Liderra + ~/.claude/.

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

Expected: 1 commit, 3 files changed.

- [ ] **Step 4: Verify**

Run: `cd "c:/моя/проекты/claude-brain" && git log --oneline`
Expected: 1 line — initial commit.

---

## Phase 2: Extract brain artifacts

**Цель:** Скопировать/извлечь все 6 markdown templates + 10 hooks + 1 visualization + 4 plugin/MCP JSON-конфига из Лидерры + `~/.claude/` в правильные места brain repo.

---

### Task 2.1: Copy CLAUDE.md as template

**Files:**

- Create: `c:\моя\проекты\claude-brain\project-files\CLAUDE.md.template`
- Source: `c:\моя\проекты\портал crm\Документация\CLAUDE.md`

- [ ] **Step 1: Copy file**

```bash
cp "c:/моя/проекты/портал crm/Документация/CLAUDE.md" \
   "c:/моя/проекты/claude-brain/project-files/CLAUDE.md.template"
```

- [ ] **Step 2: Verify 100% identical**

Run: `diff -q "c:/моя/проекты/портал crm/Документация/CLAUDE.md" "c:/моя/проекты/claude-brain/project-files/CLAUDE.md.template"`
Expected: пустой вывод (0 differences); exit code 0.

- [ ] **Step 3: Verify line count**

Run: `wc -l "c:/моя/проекты/claude-brain/project-files/CLAUDE.md.template"`
Expected: 266 lines (как в Лидерре).

---

### Task 2.2: Copy Pravila / Plugin_stack_rules / Tooling / CHANGELOG as templates

**Files:**

- Create: `project-files/docs/Pravila_raboty_Claude.template.md`
- Create: `project-files/docs/Plugin_stack_rules.template.md`
- Create: `project-files/docs/Tooling.template.md`
- Create: `project-files/docs/CHANGELOG_claude_md.template.md`

- [ ] **Step 1: Copy 4 files**

```bash
SRC="c:/моя/проекты/портал crm/Документация/docs"
DST="c:/моя/проекты/claude-brain/project-files/docs"

cp "$SRC/Pravila_raboty_Claude_v1_1.md" "$DST/Pravila_raboty_Claude.template.md"
cp "$SRC/Plugin_stack_rules_v1.md" "$DST/Plugin_stack_rules.template.md"
cp "$SRC/Tooling_v8_3.md" "$DST/Tooling.template.md"
cp "$SRC/CHANGELOG_claude_md.md" "$DST/CHANGELOG_claude_md.template.md"
```

- [ ] **Step 2: Verify line counts match source**

```bash
SRC="c:/моя/проекты/портал crm/Документация/docs"
DST="c:/моя/проекты/claude-brain/project-files/docs"
diff <(wc -l "$SRC/Pravila_raboty_Claude_v1_1.md") <(wc -l "$DST/Pravila_raboty_Claude.template.md" | sed 's|.template||') || echo "Mismatch in Pravila"
diff <(wc -l "$SRC/Plugin_stack_rules_v1.md") <(wc -l "$DST/Plugin_stack_rules.template.md" | sed 's|.template||') || echo "Mismatch in Plugin_stack"
diff <(wc -l "$SRC/Tooling_v8_3.md") <(wc -l "$DST/Tooling.template.md" | sed 's|.template||') || echo "Mismatch in Tooling"
```

Expected: 720, 916, 613 строк (Pravila, Plugin_stack, Tooling); CHANGELOG — variable.

---

### Task 2.3: Copy visualization HTML

**Files:**

- Create: `project-files/docs/visualizations/hooks-skills-plugins-map.html`

- [ ] **Step 1: Copy**

```bash
cp "c:/моя/проекты/портал crm/Документация/docs/visualizations/hooks-skills-plugins-map.html" \
   "c:/моя/проекты/claude-brain/project-files/docs/visualizations/hooks-skills-plugins-map.html"
```

- [ ] **Step 2: Verify diff = 0**

Run: `diff -q "c:/моя/проекты/портал crm/Документация/docs/visualizations/hooks-skills-plugins-map.html" "c:/моя/проекты/claude-brain/project-files/docs/visualizations/hooks-skills-plugins-map.html"`
Expected: empty (exit 0).

- [ ] **Step 3: Verify size**

Run: `wc -l "c:/моя/проекты/claude-brain/project-files/docs/visualizations/hooks-skills-plugins-map.html"`
Expected: 3122 lines.

---

### Task 2.4: Copy 10 hook scripts

**Files:**

- Create: `user-level-files/hooks/skill-marker.py` (710 B)
- Create: `user-level-files/hooks/skill-check.py` (2521 B)
- Create: `user-level-files/hooks/economy-mode.py` (15081 B)
- Create: `user-level-files/hooks/economy-mode-test.py` (6882 B)
- Create: `user-level-files/hooks/economy-self-check.py` (2191 B)
- Create: `user-level-files/hooks/economy-self-check-test.py` (4244 B)
- Create: `user-level-files/hooks/economy-state-guard.py` (3872 B)
- Create: `user-level-files/hooks/economy-state-guard-test.py` (3597 B)
- Create: `user-level-files/hooks/economy-postcompact.py` (2138 B)
- Create: `user-level-files/hooks/economy-verifier.py` (1329 B)

- [ ] **Step 1: Copy all 10 files**

```bash
cp "$HOME/.claude/hooks"/*.py "c:/моя/проекты/claude-brain/user-level-files/hooks/"
```

- [ ] **Step 2: Verify 10 files**

Run: `ls "c:/моя/проекты/claude-brain/user-level-files/hooks/" | wc -l`
Expected: 10.

- [ ] **Step 3: Verify each file size matches source**

```bash
for f in "$HOME/.claude/hooks"/*.py; do
  basename=$(basename "$f")
  src_size=$(wc -c < "$f")
  dst_size=$(wc -c < "c:/моя/проекты/claude-brain/user-level-files/hooks/$basename")
  if [ "$src_size" != "$dst_size" ]; then
    echo "MISMATCH: $basename (src=$src_size, dst=$dst_size)"
  fi
done
```

Expected: 0 mismatches.

- [ ] **Step 4: Run Python syntax check on all 10**

```bash
for f in "c:/моя/проекты/claude-brain/user-level-files/hooks"/*.py; do
  python -m py_compile "$f" && echo "OK: $(basename $f)" || echo "SYNTAX ERROR: $(basename $f)"
done
```

Expected: 10 OK lines.

---

### Task 2.5: Extract settings-fragment.json (jq filter)

**Files:**

- Create: `user-level-files/settings-fragment.json`
- Source: `~/.claude/settings.json` (145 строк)

- [ ] **Step 1: Run jq filter**

```bash
jq '{enabledPlugins, permissions, hooks}' "$HOME/.claude/settings.json" \
  > "c:/моя/проекты/claude-brain/user-level-files/settings-fragment.json"
```

- [ ] **Step 2: Verify JSON valid**

Run: `jq empty "c:/моя/проекты/claude-brain/user-level-files/settings-fragment.json" && echo "VALID JSON"`
Expected: «VALID JSON».

- [ ] **Step 3: Verify expected keys present**

```bash
jq -r 'keys[]' "c:/моя/проекты/claude-brain/user-level-files/settings-fragment.json"
```

Expected output (3 строки):

```
enabledPlugins
hooks
permissions
```

- [ ] **Step 4: Verify enabledPlugins has 4 plugins**

```bash
jq '.enabledPlugins | keys[]' "c:/моя/проекты/claude-brain/user-level-files/settings-fragment.json"
```

Expected (4 строки):

```
"claude-md-management@claude-plugins-official"
"frontend-design@claude-plugins-official"
"superpowers@superpowers-dev"
"ui-ux-pro-max@ui-ux-pro-max-skill"
```

- [ ] **Step 5: Verify no theme/editorMode/statusLine leaked**

Run: `grep -E '"(theme|editorMode|statusLine)"' "c:/моя/проекты/claude-brain/user-level-files/settings-fragment.json" || echo "OK no user-machine keys"`
Expected: «OK no user-machine keys».

---

### Task 2.6: Copy marketplaces.json

**Files:**

- Create: `user-level-files/marketplaces.json`
- Source: `~/.claude/plugins/known_marketplaces.json`

- [ ] **Step 1: Copy**

```bash
cp "$HOME/.claude/plugins/known_marketplaces.json" \
   "c:/моя/проекты/claude-brain/user-level-files/marketplaces.json"
```

- [ ] **Step 2: Verify JSON valid + 3 marketplaces**

```bash
jq -r 'keys[]' "c:/моя/проекты/claude-brain/user-level-files/marketplaces.json"
```

Expected (3 строки):

```
claude-plugins-official
superpowers-dev
ui-ux-pro-max-skill
```

---

### Task 2.7: Copy plugins-manifest.json

**Files:**

- Create: `user-level-files/plugins-manifest.json`
- Source: `~/.claude/plugins/installed_plugins.json`

- [ ] **Step 1: Copy**

```bash
cp "$HOME/.claude/plugins/installed_plugins.json" \
   "c:/моя/проекты/claude-brain/user-level-files/plugins-manifest.json"
```

- [ ] **Step 2: Verify 4 plugins with gitCommitSha**

```bash
jq -r '.plugins | keys[]' "c:/моя/проекты/claude-brain/user-level-files/plugins-manifest.json"
```

Expected (4 строки):

```
claude-md-management@claude-plugins-official
frontend-design@claude-plugins-official
superpowers@superpowers-dev
ui-ux-pro-max@ui-ux-pro-max-skill
```

- [ ] **Step 3: Verify each plugin has gitCommitSha**

```bash
jq -r '.plugins | to_entries[] | "\(.key): \(.value[0].gitCommitSha) (v\(.value[0].version))"' \
  "c:/моя/проекты/claude-brain/user-level-files/plugins-manifest.json"
```

Expected:

```
claude-md-management@claude-plugins-official: 76b35e91d1c99c090b1a08dade53bcc5e352c1b2 (v1.0.0)
frontend-design@claude-plugins-official: 76b35e91d1c99c090b1a08dade53bcc5e352c1b2 (vunknown)
superpowers@superpowers-dev: f2cbfbefebbfef77321e4c9abc9e949826bea9d7 (v5.1.0)
ui-ux-pro-max@ui-ux-pro-max-skill: b7e3af80f6e331f6fb456667b82b12cade7c9d35 (v2.5.0)
```

---

### Task 2.8: Extract mcp-user.template.json with API_KEY masking

**Files:**

- Create: `user-level-files/mcp-user.template.json`
- Source: `~/.claude.json` (section `.mcpServers`)

- [ ] **Step 1: Run jq with masking transform**

```bash
jq '{
  mcpServers: (.mcpServers | with_entries(
    .value.args |= (if . then map(
      if test("API_KEY=") then 
        sub("API_KEY=.*"; "API_KEY=<<MAGIC_API_KEY>>") 
      else . 
      end
    ) else . end)
  ))
}' "$HOME/.claude.json" > "c:/моя/проекты/claude-brain/user-level-files/mcp-user.template.json"
```

- [ ] **Step 2: Verify JSON valid**

Run: `jq empty "c:/моя/проекты/claude-brain/user-level-files/mcp-user.template.json" && echo "VALID"`
Expected: «VALID».

- [ ] **Step 3: Verify placeholder present**

Run: `grep -o '<<MAGIC_API_KEY>>' "c:/моя/проекты/claude-brain/user-level-files/mcp-user.template.json"`
Expected: `<<MAGIC_API_KEY>>` (минимум 1 совпадение).

- [ ] **Step 4: Verify NO real API_KEY leaked**

Run: `grep -E 'API_KEY=[a-f0-9]{30,}' "c:/моя/проекты/claude-brain/user-level-files/mcp-user.template.json" && echo "LEAK DETECTED" || echo "OK no leak"`
Expected: «OK no leak».

- [ ] **Step 5: Verify magic server present**

```bash
jq '.mcpServers.magic' "c:/моя/проекты/claude-brain/user-level-files/mcp-user.template.json"
```

Expected: блок с `command: "cmd"`, args содержит `API_KEY=<<MAGIC_API_KEY>>`.

---

### Task 2.9: Extract .mcp.json.template (universal only, drop laravel-boost)

**Files:**

- Create: `project-files/.mcp.json.template`
- Source: `c:\моя\проекты\портал crm\Документация\.mcp.json`

- [ ] **Step 1: Run jq filter (drop laravel-boost)**

```bash
jq 'del(.mcpServers["laravel-boost"])' \
  "c:/моя/проекты/портал crm/Документация/.mcp.json" \
  > "c:/моя/проекты/claude-brain/project-files/.mcp.json.template"
```

- [ ] **Step 2: Verify JSON valid**

Run: `jq empty "c:/моя/проекты/claude-brain/project-files/.mcp.json.template" && echo "VALID"`
Expected: «VALID».

- [ ] **Step 3: Verify 3 universal servers present**

```bash
jq -r '.mcpServers | keys[]' "c:/моя/проекты/claude-brain/project-files/.mcp.json.template"
```

Expected (3 строки):

```
github
playwright
semgrep
```

- [ ] **Step 4: Verify laravel-boost удалён**

Run: `grep -q "laravel-boost" "c:/моя/проекты/claude-brain/project-files/.mcp.json.template" && echo "LEAK" || echo "OK"`
Expected: «OK».

---

### Task 2.10: Commit Phase 2 — extracted artifacts

**Files:** все из Tasks 2.1-2.9

- [ ] **Step 1: Stage**

```bash
cd "c:/моя/проекты/claude-brain"
git add project-files/ user-level-files/
```

- [ ] **Step 2: Verify status**

Run: `cd "c:/моя/проекты/claude-brain" && git status --short`
Expected: ~18 файлов в staging (6 markdown + 10 hooks + 1 viz + 4 JSON).

- [ ] **Step 3: Gitleaks pre-commit check (R13 mitigation early)**

Run:

```bash
GITLEAKS="$(command -v gitleaks || echo 'c:/моя/проекты/портал crm/Документация/bin/gitleaks.exe')"
"$GITLEAKS" detect --source="c:/моя/проекты/claude-brain" --no-git --verbose
```

Expected: «no leaks found» (exit 0).

Если обнаружены leaks — **ABORT**: вернуться к Task 2.8 и проверить masking. Не делать commit.

- [ ] **Step 4: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git commit -m "$(cat <<'EOF'
feat: extract brain artifacts from Liderra + ~/.claude/

project-files/:
- CLAUDE.md.template (266 lines)
- docs/Pravila_raboty_Claude.template.md (720 lines)
- docs/Plugin_stack_rules.template.md (916 lines)
- docs/Tooling.template.md (613 lines)
- docs/CHANGELOG_claude_md.template.md
- docs/visualizations/hooks-skills-plugins-map.html (3122 lines)
- .mcp.json.template (universal: playwright/github/semgrep; laravel-boost dropped)

user-level-files/:
- hooks/ (10 Python files: skill-marker, skill-check, economy-* x8)
- settings-fragment.json (enabledPlugins + permissions + hooks only)
- marketplaces.json (3 sources)
- plugins-manifest.json (4 plugins pinned with gitCommitSha)
- mcp-user.template.json (magic with <<MAGIC_API_KEY>> placeholder)

Gitleaks scan: 0 findings.

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

Expected: 18 files changed, +5637+ insertions.

---

## Phase 3: Common library scripts (TDD)

**Цель:** Написать 5 lib-скриптов через TDD. Каждый — failing test первым, минимальная реализация для green.

---

### Task 3.1: scripts/lib/common.sh (helpers) + tests

**Files:**

- Create: `scripts/lib/common.sh`
- Create: `scripts/tests/common-test.sh`

**Назначение common.sh:** shared helpers — `log_info` / `log_warn` / `log_error` / `require_cmd` / `make_backup_dir`. Используется всеми остальными скриптами.

- [ ] **Step 1: Write failing test**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/common-test.sh" <<'EOF'
#!/usr/bin/env bash
# Tests for scripts/lib/common.sh
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    local expected="$1" actual="$2" name="$3"
    if [ "$expected" = "$actual" ]; then
        echo "PASS: $name"
    else
        echo "FAIL: $name (expected '$expected', got '$actual')"
        FAILURES=$((FAILURES + 1))
    fi
}

# Test 1: log_info writes to stderr
output=$(log_info "test message" 2>&1 1>/dev/null)
case "$output" in
    *"test message"*) assert_eq "ok" "ok" "log_info goes to stderr" ;;
    *) assert_eq "ok" "fail" "log_info goes to stderr" ;;
esac

# Test 2: require_cmd succeeds for existing command
require_cmd ls >/dev/null 2>&1
assert_eq "0" "$?" "require_cmd ls returns 0"

# Test 3: require_cmd fails for missing command
require_cmd this_command_definitely_does_not_exist_12345 >/dev/null 2>&1
result=$?
[ "$result" -ne 0 ] && assert_eq "0" "0" "require_cmd missing returns non-zero" || assert_eq "0" "1" "require_cmd missing returns non-zero"

# Test 4: make_backup_dir creates dir
tmpdir=$(mktemp -d)
backup=$(make_backup_dir "$tmpdir")
[ -d "$backup" ] && assert_eq "yes" "yes" "make_backup_dir creates directory" || assert_eq "yes" "no" "make_backup_dir creates directory"
rm -rf "$tmpdir"

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/common-test.sh"
```

- [ ] **Step 2: Run test — должен FAIL**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/common-test.sh"`
Expected: FAIL (lib/common.sh не существует, source падает).

- [ ] **Step 3: Implement common.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/lib/common.sh" <<'EOF'
#!/usr/bin/env bash
# Shared helpers for brain scripts
# Source guard
[ -n "${__BRAIN_COMMON_LOADED:-}" ] && return 0
__BRAIN_COMMON_LOADED=1

log_info()  { printf "[INFO]  %s\n" "$*" >&2; }
log_warn()  { printf "[WARN]  %s\n" "$*" >&2; }
log_error() { printf "[ERROR] %s\n" "$*" >&2; }

require_cmd() {
    local cmd="$1"
    if ! command -v "$cmd" >/dev/null 2>&1; then
        log_error "Required command not found: $cmd"
        return 1
    fi
    return 0
}

make_backup_dir() {
    local target="$1"
    local ts
    ts=$(date +%Y%m%d-%H%M%S)
    local backup="${target%/}/.brain-backup-${ts}"
    mkdir -p "$backup"
    printf "%s" "$backup"
}
EOF
```

- [ ] **Step 4: Run test — должен PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/common-test.sh"`
Expected: 4 PASS, 0 FAIL, exit 0.

- [ ] **Step 5: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/lib/common.sh scripts/tests/common-test.sh
git commit -m "feat(scripts): common.sh helpers (log_*, require_cmd, make_backup_dir)

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

---

### Task 3.2: scripts/lib/merge-settings.sh + tests

**Files:**

- Create: `scripts/lib/merge-settings.sh`
- Create: `scripts/tests/merge-settings-test.sh`
- Create: `scripts/fixtures/sample-settings.json`

**Назначение:** merge brain'овский settings-fragment.json в существующий `~/.claude/settings.json` сохраняя `theme`/`editorMode`/`statusLine`, заменяя `enabledPlugins`/`permissions`/`hooks`.

- [ ] **Step 1: Create fixture (sample consumer's settings.json)**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/fixtures/sample-settings.json" <<'EOF'
{
  "theme": "dark",
  "editorMode": "vscode",
  "statusLine": "compact",
  "enabledPlugins": {
    "old-plugin@old-marketplace": true
  },
  "permissions": {
    "allow": ["Bash(old:*)"],
    "deny": [],
    "ask": []
  },
  "hooks": {
    "SessionStart": []
  }
}
EOF
```

- [ ] **Step 2: Write failing test**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/merge-settings-test.sh" <<'EOF'
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    local expected="$1" actual="$2" name="$3"
    if [ "$expected" = "$actual" ]; then
        echo "PASS: $name"
    else
        echo "FAIL: $name (expected '$expected', got '$actual')"
        FAILURES=$((FAILURES + 1))
    fi
}

# Setup: temp consumer settings + brain fragment
tmpdir=$(mktemp -d)
cp "$SCRIPT_DIR/fixtures/sample-settings.json" "$tmpdir/settings.json"
cat > "$tmpdir/fragment.json" <<EOF2
{
  "enabledPlugins": {
    "new-plugin@new-mp": true
  },
  "permissions": {
    "allow": ["Bash(new:*)"],
    "deny": ["Bash(rm:*)"],
    "ask": []
  },
  "hooks": {
    "SessionStart": [{"hooks": [{"type": "command", "command": "echo new"}]}]
  }
}
EOF2

# Run merge
bash "$SCRIPT_DIR/lib/merge-settings.sh" "$tmpdir/settings.json" "$tmpdir/fragment.json"

# Test 1: theme preserved
theme=$(jq -r '.theme' "$tmpdir/settings.json")
assert_eq "dark" "$theme" "theme preserved"

# Test 2: editorMode preserved
em=$(jq -r '.editorMode' "$tmpdir/settings.json")
assert_eq "vscode" "$em" "editorMode preserved"

# Test 3: enabledPlugins replaced (not merged)
plugins=$(jq -r '.enabledPlugins | keys[]' "$tmpdir/settings.json")
assert_eq "new-plugin@new-mp" "$plugins" "enabledPlugins replaced with brain version"

# Test 4: permissions.deny populated from fragment
deny=$(jq -r '.permissions.deny[0]' "$tmpdir/settings.json")
assert_eq "Bash(rm:*)" "$deny" "permissions.deny from fragment"

# Test 5: hooks replaced
hook_cmd=$(jq -r '.hooks.SessionStart[0].hooks[0].command' "$tmpdir/settings.json")
assert_eq "echo new" "$hook_cmd" "hooks replaced with brain version"

# Cleanup
rm -rf "$tmpdir"

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/merge-settings-test.sh"
```

- [ ] **Step 3: Run test — FAIL (script not exists)**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/merge-settings-test.sh"`
Expected: FAIL.

- [ ] **Step 4: Implement merge-settings.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/lib/merge-settings.sh" <<'EOF'
#!/usr/bin/env bash
# Merge brain settings-fragment.json into consumer's settings.json
# Replaces: enabledPlugins, permissions, hooks
# Preserves: theme, editorMode, statusLine, all other keys
#
# Usage: merge-settings.sh <consumer-settings.json> <brain-fragment.json>
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/common.sh"

target="$1"
fragment="$2"

require_cmd jq || exit 1
[ -f "$fragment" ] || { log_error "Fragment not found: $fragment"; exit 1; }

# If target doesn't exist, just copy fragment
if [ ! -f "$target" ]; then
    log_info "Target settings.json missing, creating from fragment"
    cp "$fragment" "$target"
    exit 0
fi

# Backup
backup="${target}.bak.$(date +%s)"
cp "$target" "$backup"

# Merge: target.* overridden by fragment.{enabledPlugins, permissions, hooks}
tmp="${target}.tmp"
jq -s '.[0] * {enabledPlugins: .[1].enabledPlugins, permissions: .[1].permissions, hooks: .[1].hooks}' \
    "$target" "$fragment" > "$tmp"

# Validate output JSON
jq empty "$tmp" || { log_error "Merge produced invalid JSON"; rm "$tmp"; exit 1; }

mv "$tmp" "$target"
log_info "settings.json merged (backup: $backup)"
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/lib/merge-settings.sh"
```

- [ ] **Step 5: Run test — PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/merge-settings-test.sh"`
Expected: 5 PASS, 0 FAIL, exit 0.

- [ ] **Step 6: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/lib/merge-settings.sh scripts/tests/merge-settings-test.sh scripts/fixtures/sample-settings.json
git commit -m "feat(scripts): merge-settings.sh — jq merge with preservation of theme/editorMode

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

---

### Task 3.3: scripts/lib/merge-mcp.sh + tests

**Files:**

- Create: `scripts/lib/merge-mcp.sh`
- Create: `scripts/tests/merge-mcp-test.sh`
- Create: `scripts/fixtures/sample-claude-json.json`
- Create: `scripts/fixtures/sample-mcp.json`

**Назначение:** merge brain MCP-template в consumer's `~/.claude.json:mcpServers` (user-mode) или `<repo>/.mcp.json:mcpServers` (project-mode). Сохраняет consumer-specific servers (laravel-boost).

- [ ] **Step 1: Create fixtures**

```bash
# Consumer's ~/.claude.json fixture (с laravel-boost)
cat > "c:/моя/проекты/claude-brain/scripts/fixtures/sample-claude-json.json" <<'EOF'
{
  "mcpServers": {
    "laravel-boost": {
      "command": "php",
      "args": ["app/artisan", "boost:mcp"]
    },
    "magic": {
      "type": "stdio",
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@21st-dev/magic@latest", "API_KEY=OLD_VALUE"]
    }
  },
  "preserveMe": "yes"
}
EOF

# Consumer's project .mcp.json fixture (с laravel-boost)
cat > "c:/моя/проекты/claude-brain/scripts/fixtures/sample-mcp.json" <<'EOF'
{
  "$schema": "https://raw.githubusercontent.com/anthropics/claude-code/main/schemas/mcp.json",
  "mcpServers": {
    "laravel-boost": {
      "command": "php",
      "args": ["app/artisan", "boost:mcp"]
    }
  }
}
EOF
```

- [ ] **Step 2: Write failing test**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/merge-mcp-test.sh" <<'EOF'
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    if [ "$1" = "$2" ]; then echo "PASS: $3"; else echo "FAIL: $3 (expected '$1', got '$2')"; FAILURES=$((FAILURES + 1)); fi
}

# Test 1: user-mode merge — magic replaced, laravel-boost preserved
tmpdir=$(mktemp -d)
cp "$SCRIPT_DIR/fixtures/sample-claude-json.json" "$tmpdir/.claude.json"
cat > "$tmpdir/brain-mcp.json" <<EOF2
{
  "mcpServers": {
    "magic": {
      "type": "stdio",
      "command": "cmd",
      "args": ["/c", "npx", "-y", "@21st-dev/magic@latest", "API_KEY=<<MAGIC_API_KEY>>"]
    }
  }
}
EOF2

bash "$SCRIPT_DIR/lib/merge-mcp.sh" --mode=user "$tmpdir/.claude.json" "$tmpdir/brain-mcp.json"

# magic args should now contain placeholder
magic_api_key=$(jq -r '.mcpServers.magic.args[-1]' "$tmpdir/.claude.json")
assert_eq "API_KEY=<<MAGIC_API_KEY>>" "$magic_api_key" "user-mode: magic API_KEY replaced with placeholder"

# laravel-boost preserved
lb_cmd=$(jq -r '.mcpServers["laravel-boost"].command' "$tmpdir/.claude.json")
assert_eq "php" "$lb_cmd" "user-mode: laravel-boost preserved"

# preserveMe key still present (other keys unchanged)
preserve=$(jq -r '.preserveMe' "$tmpdir/.claude.json")
assert_eq "yes" "$preserve" "user-mode: other top-level keys preserved"

rm -rf "$tmpdir"

# Test 2: project-mode merge — playwright/github/semgrep added, laravel-boost preserved
tmpdir=$(mktemp -d)
cp "$SCRIPT_DIR/fixtures/sample-mcp.json" "$tmpdir/.mcp.json"
cat > "$tmpdir/brain-mcp.json" <<EOF3
{
  "mcpServers": {
    "playwright": {"command": "npx", "args": ["-y", "@playwright/mcp"]},
    "github": {"type": "http", "url": "https://api.githubcopilot.com/mcp"},
    "semgrep": {"command": "npx", "args": ["-y", "semgrep-mcp"]}
  }
}
EOF3

bash "$SCRIPT_DIR/lib/merge-mcp.sh" --mode=project "$tmpdir/.mcp.json" "$tmpdir/brain-mcp.json"

# Should have 4 servers total
count=$(jq '.mcpServers | length' "$tmpdir/.mcp.json")
assert_eq "4" "$count" "project-mode: 4 servers after merge"

# laravel-boost preserved
lb=$(jq -r '.mcpServers["laravel-boost"].command' "$tmpdir/.mcp.json")
assert_eq "php" "$lb" "project-mode: laravel-boost preserved"

# playwright added
pw=$(jq -r '.mcpServers.playwright.command' "$tmpdir/.mcp.json")
assert_eq "npx" "$pw" "project-mode: playwright added"

rm -rf "$tmpdir"

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/merge-mcp-test.sh"
```

- [ ] **Step 3: Run — FAIL**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/merge-mcp-test.sh"`
Expected: FAIL.

- [ ] **Step 4: Implement merge-mcp.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/lib/merge-mcp.sh" <<'EOF'
#!/usr/bin/env bash
# Merge brain MCP template into consumer's claude.json or project .mcp.json
# Mode: user (merge into ~/.claude.json:mcpServers) or project (merge into <repo>/.mcp.json:mcpServers)
# Preserves consumer-specific servers; replaces brain-managed servers.
#
# Usage: merge-mcp.sh --mode=user|project <target> <brain-mcp.json>
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/common.sh"

mode=""
case "${1:-}" in
    --mode=user) mode="user"; shift ;;
    --mode=project) mode="project"; shift ;;
    *) log_error "First arg must be --mode=user or --mode=project"; exit 1 ;;
esac

target="$1"
brain_mcp="$2"

require_cmd jq || exit 1
[ -f "$brain_mcp" ] || { log_error "Brain MCP file not found: $brain_mcp"; exit 1; }

# If target missing, copy brain template
if [ ! -f "$target" ]; then
    log_info "Target $target missing, creating from brain template"
    cp "$brain_mcp" "$target"
    exit 0
fi

# Backup
backup="${target}.bak.$(date +%s)"
cp "$target" "$backup"

# Merge: target.mcpServers + brain.mcpServers (brain overrides on collision)
tmp="${target}.tmp"
jq -s '.[0] | .mcpServers = ((.mcpServers // {}) + .[1].mcpServers)' \
    "$target" "$brain_mcp" > "$tmp"

# Validate
jq empty "$tmp" || { log_error "Merge produced invalid JSON"; rm "$tmp"; exit 1; }

mv "$tmp" "$target"
log_info "MCP ($mode mode) merged (backup: $backup)"
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/lib/merge-mcp.sh"
```

- [ ] **Step 5: Run — PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/merge-mcp-test.sh"`
Expected: 6 PASS, 0 FAIL, exit 0.

- [ ] **Step 6: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/lib/merge-mcp.sh scripts/tests/merge-mcp-test.sh scripts/fixtures/sample-claude-json.json scripts/fixtures/sample-mcp.json
git commit -m "feat(scripts): merge-mcp.sh — preserves laravel-boost, replaces brain-managed MCP

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

---

### Task 3.4: scripts/lib/setup-secrets.sh + tests

**Files:**

- Create: `scripts/lib/setup-secrets.sh`
- Create: `scripts/tests/setup-secrets-test.sh`

**Назначение:** заменить `<<MAGIC_API_KEY>>` placeholder в файле на реальное значение. Поддержка `--secret=KEY=VALUE` (CLI) и interactive prompt (manual).

- [ ] **Step 1: Write failing test**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/setup-secrets-test.sh" <<'EOF'
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    if [ "$1" = "$2" ]; then echo "PASS: $3"; else echo "FAIL: $3 (expected '$1', got '$2')"; FAILURES=$((FAILURES + 1)); fi
}

# Test 1: --secret=KEY=VALUE replaces placeholder
tmpdir=$(mktemp -d)
cat > "$tmpdir/config.json" <<EOF2
{
  "mcpServers": {
    "magic": {
      "args": ["API_KEY=<<MAGIC_API_KEY>>"]
    }
  }
}
EOF2

bash "$SCRIPT_DIR/lib/setup-secrets.sh" --secret=MAGIC_API_KEY=resolved_value "$tmpdir/config.json"

result=$(jq -r '.mcpServers.magic.args[0]' "$tmpdir/config.json")
assert_eq "API_KEY=resolved_value" "$result" "non-interactive: placeholder replaced"

# Test 2: --skip-unresolved leaves placeholder + creates deferred file
cat > "$tmpdir/config2.json" <<EOF3
{
  "args": ["API_KEY=<<MAGIC_API_KEY>>", "TOKEN=<<UNKNOWN_TOKEN>>"]
}
EOF3
bash "$SCRIPT_DIR/lib/setup-secrets.sh" --skip-unresolved --secret=MAGIC_API_KEY=val "$tmpdir/config2.json"
remaining=$(jq -r '.args[1]' "$tmpdir/config2.json")
assert_eq "TOKEN=<<UNKNOWN_TOKEN>>" "$remaining" "skip-unresolved: leaves unknown placeholder"

# Test 3: list-unresolved shows placeholders without replacing
cat > "$tmpdir/config3.json" <<EOF4
{"k1": "<<A>>", "k2": "<<B>>", "k3": "<<A>>"}
EOF4
output=$(bash "$SCRIPT_DIR/lib/setup-secrets.sh" --list-unresolved "$tmpdir/config3.json" 2>&1)
case "$output" in
    *"<<A>>"*"<<B>>"*) assert_eq "ok" "ok" "list-unresolved finds both" ;;
    *) assert_eq "ok" "fail" "list-unresolved finds both" ;;
esac
# Verify file untouched
unchanged=$(jq -r '.k1' "$tmpdir/config3.json")
assert_eq "<<A>>" "$unchanged" "list-unresolved: file untouched"

rm -rf "$tmpdir"

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/setup-secrets-test.sh"
```

- [ ] **Step 2: Run — FAIL**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/setup-secrets-test.sh"`
Expected: FAIL.

- [ ] **Step 3: Implement setup-secrets.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/lib/setup-secrets.sh" <<'EOF'
#!/usr/bin/env bash
# Resolve secret placeholders <<NAME>> in target file
# Modes:
#   --secret=NAME=VALUE  (non-interactive substitution)
#   --list-unresolved   (find <<*>> placeholders, no changes)
#   --skip-unresolved   (don't prompt for unresolved; leave + write to .brain-deferred-secrets.txt)
#   (default)           interactive prompt for each placeholder
#
# Usage: setup-secrets.sh [--secret=NAME=VALUE ...] [--skip-unresolved | --list-unresolved] <target-file>
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/common.sh"

declare -A secrets=()
skip_unresolved=0
list_only=0
target=""

while [ $# -gt 0 ]; do
    case "$1" in
        --secret=*)
            kv="${1#--secret=}"
            name="${kv%%=*}"
            value="${kv#*=}"
            secrets["$name"]="$value"
            ;;
        --skip-unresolved) skip_unresolved=1 ;;
        --list-unresolved) list_only=1 ;;
        *) target="$1" ;;
    esac
    shift
done

[ -n "$target" ] || { log_error "Target file required"; exit 1; }
[ -f "$target" ] || { log_error "Target not found: $target"; exit 1; }

# Find all placeholders
placeholders=$(grep -oE '<<[A-Z_][A-Z0-9_]*>>' "$target" 2>/dev/null | sort -u || true)

if [ "$list_only" -eq 1 ]; then
    if [ -z "$placeholders" ]; then
        log_info "No unresolved placeholders in $target"
    else
        log_info "Unresolved placeholders in $target:"
        echo "$placeholders"
    fi
    exit 0
fi

deferred_file="$(dirname "$target")/.brain-deferred-secrets.txt"
deferred=""

for p in $placeholders; do
    name="${p#<<}"
    name="${name%>>}"
    
    if [ -n "${secrets[$name]:-}" ]; then
        value="${secrets[$name]}"
        # sed-replace via temp + mv (Windows-safe)
        sed "s|<<$name>>|$value|g" "$target" > "$target.tmp"
        mv "$target.tmp" "$target"
        log_info "Resolved <<$name>>"
    elif [ "$skip_unresolved" -eq 1 ]; then
        deferred="$deferred$name\n"
        log_warn "Skipped <<$name>> (deferred)"
    else
        # Interactive prompt
        printf "Enter value for <<%s>> (or empty to skip): " "$name" >&2
        read -r value
        if [ -n "$value" ]; then
            sed "s|<<$name>>|$value|g" "$target" > "$target.tmp"
            mv "$target.tmp" "$target"
            log_info "Resolved <<$name>>"
        else
            deferred="$deferred$name\n"
            log_warn "Skipped <<$name>>"
        fi
    fi
done

if [ -n "$deferred" ]; then
    printf "%b" "$deferred" > "$deferred_file"
    log_warn "Deferred secrets recorded: $deferred_file"
fi
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/lib/setup-secrets.sh"
```

- [ ] **Step 4: Run — PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/setup-secrets-test.sh"`
Expected: 4 PASS, 0 FAIL, exit 0.

- [ ] **Step 5: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/lib/setup-secrets.sh scripts/tests/setup-secrets-test.sh
git commit -m "feat(scripts): setup-secrets.sh — placeholder resolution with --secret/--skip/--list modes

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

---

### Task 3.5: scripts/lib/install-plugins.sh + tests

**Files:**

- Create: `scripts/lib/install-plugins.sh`
- Create: `scripts/tests/install-plugins-test.sh`

**Назначение:** для каждого marketplace в `marketplaces.json` — добавить (если нет); для каждого плагина в `plugins-manifest.json` — установить через `claude plugin install`. Verify SHA pinning (warn on mismatch).

**Note:** если Phase 0 Task 0.1 показал что CLI команды `claude plugin install` недоступны — этот скрипт fallback'ится на прямое редактирование `~/.claude/plugins/installed_plugins.json` + `~/.claude/plugins/known_marketplaces.json` + `~/.claude/settings.json:enabledPlugins`, и просит пользователя restart Claude Code.

- [ ] **Step 1: Write failing test (use mock `claude` binary)**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/install-plugins-test.sh" <<'EOF'
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    if [ "$1" = "$2" ]; then echo "PASS: $3"; else echo "FAIL: $3 (expected '$1', got '$2')"; FAILURES=$((FAILURES + 1)); fi
}

# Setup: temp dir with fake `claude` CLI
tmpdir=$(mktemp -d)
mkdir "$tmpdir/bin"
cat > "$tmpdir/bin/claude" <<'CLAUDE_EOF'
#!/usr/bin/env bash
# Mock claude CLI: records calls to /tmp/claude-calls.log
echo "claude $@" >> /tmp/claude-calls.log
case "$1 $2" in
    "marketplace list")
        # Print existing marketplaces (none)
        ;;
    "marketplace add")
        # Always succeed
        exit 0
        ;;
    "plugin install")
        # Always succeed
        exit 0
        ;;
    "plugin info")
        # Return fake SHA matching expected
        if [ "$2" = "info" ] && [ "$4" = "--json" ]; then
            echo '{"gitCommitSha": "f2cbfbefebbfef77321e4c9abc9e949826bea9d7"}'
        fi
        ;;
esac
exit 0
CLAUDE_EOF
chmod +x "$tmpdir/bin/claude"

# Create fixtures
cat > "$tmpdir/marketplaces.json" <<EOF2
{
  "superpowers-dev": {
    "source": {"source": "github", "repo": "obra/superpowers"}
  }
}
EOF2

cat > "$tmpdir/plugins-manifest.json" <<EOF3
{
  "version": 2,
  "plugins": {
    "superpowers@superpowers-dev": [
      {
        "scope": "user",
        "version": "5.1.0",
        "gitCommitSha": "f2cbfbefebbfef77321e4c9abc9e949826bea9d7"
      }
    ]
  }
}
EOF3

rm -f /tmp/claude-calls.log
PATH="$tmpdir/bin:$PATH" bash "$SCRIPT_DIR/lib/install-plugins.sh" \
    --marketplaces="$tmpdir/marketplaces.json" \
    --manifest="$tmpdir/plugins-manifest.json"

# Test 1: marketplace add called
grep -q "marketplace add obra/superpowers" /tmp/claude-calls.log
assert_eq "0" "$?" "marketplace add called"

# Test 2: plugin install called
grep -q "plugin install superpowers@superpowers-dev" /tmp/claude-calls.log
assert_eq "0" "$?" "plugin install called"

rm -rf "$tmpdir" /tmp/claude-calls.log

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/install-plugins-test.sh"
```

- [ ] **Step 2: Run — FAIL**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/install-plugins-test.sh"`
Expected: FAIL.

- [ ] **Step 3: Implement install-plugins.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/lib/install-plugins.sh" <<'EOF'
#!/usr/bin/env bash
# Install Claude Code plugins from brain manifest
# Adds marketplaces, installs plugins, warns on SHA mismatch
#
# Usage: install-plugins.sh --marketplaces=<path> --manifest=<path>
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/common.sh"

marketplaces=""
manifest=""

while [ $# -gt 0 ]; do
    case "$1" in
        --marketplaces=*) marketplaces="${1#--marketplaces=}" ;;
        --manifest=*) manifest="${1#--manifest=}" ;;
        *) log_error "Unknown arg: $1"; exit 1 ;;
    esac
    shift
done

[ -f "$marketplaces" ] || { log_error "Marketplaces file: $marketplaces not found"; exit 1; }
[ -f "$manifest" ] || { log_error "Manifest file: $manifest not found"; exit 1; }

require_cmd jq || exit 1

if ! command -v claude >/dev/null 2>&1; then
    log_warn "claude CLI not found — fallback: edit JSON configs manually and restart"
    log_info "Required edits:"
    log_info "  1. Copy $marketplaces → ~/.claude/plugins/known_marketplaces.json"
    log_info "  2. Copy $manifest → ~/.claude/plugins/installed_plugins.json"
    log_info "  3. Update ~/.claude/settings.json:enabledPlugins"
    log_info "  4. Restart Claude Code"
    exit 0
fi

# Add marketplaces
for mp in $(jq -r 'keys[]' "$marketplaces"); do
    repo=$(jq -r ".[\"$mp\"].source.repo" "$marketplaces")
    if claude marketplace list 2>/dev/null | grep -q "$mp"; then
        log_info "Marketplace $mp already added"
    else
        log_info "Adding marketplace: $repo"
        claude marketplace add "$repo" || { log_error "marketplace add failed: $repo"; exit 6; }
    fi
done

# Install plugins
for plugin in $(jq -r '.plugins | keys[]' "$manifest"); do
    expected_sha=$(jq -r ".plugins[\"$plugin\"][0].gitCommitSha" "$manifest")
    expected_ver=$(jq -r ".plugins[\"$plugin\"][0].version" "$manifest")
    
    log_info "Installing $plugin (pinned v$expected_ver, SHA $expected_sha)"
    claude plugin install "$plugin" || { log_error "plugin install failed: $plugin"; exit 6; }
    
    actual_sha=$(claude plugin info "$plugin" --json 2>/dev/null | jq -r '.gitCommitSha // "unknown"')
    if [ "$actual_sha" = "$expected_sha" ]; then
        log_info "  SHA match: $actual_sha"
    else
        log_warn "  SHA mismatch (expected $expected_sha, got $actual_sha) — marketplace may have updated"
    fi
done
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/lib/install-plugins.sh"
```

- [ ] **Step 4: Run — PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/install-plugins-test.sh"`
Expected: 2 PASS, 0 FAIL, exit 0.

- [ ] **Step 5: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/lib/install-plugins.sh scripts/tests/install-plugins-test.sh
git commit -m "feat(scripts): install-plugins.sh — marketplace add + plugin install + SHA verify

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

---

## Phase 4: Main scripts (install, verify, extract)

---

### Task 4.1: scripts/verify.sh + tests

**Files:**

- Create: `scripts/verify.sh`
- Create: `scripts/tests/verify-test.sh`

**Назначение:** проверка целостности после install — `.brain-version` валиден, sha256 файлов совпадают с manifest.json, settings.json валиден, hooks Python syntax OK.

- [ ] **Step 1: Write failing test (минимальный)**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/verify-test.sh" <<'EOF'
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    if [ "$1" = "$2" ]; then echo "PASS: $3"; else echo "FAIL: $3 (expected '$1', got '$2')"; FAILURES=$((FAILURES + 1)); fi
}

# Test 1: missing .brain-version → exit 1
tmpdir=$(mktemp -d)
bash "$SCRIPT_DIR/verify.sh" --target="$tmpdir" >/dev/null 2>&1
assert_eq "1" "$?" "missing .brain-version returns exit 1"
rm -rf "$tmpdir"

# Test 2: valid .brain-version → exit 0 (минимальный manifest пустой)
tmpdir=$(mktemp -d)
echo "brain-v1.0" > "$tmpdir/.brain-version"
echo "sha: 0000000000000000000000000000000000000000" >> "$tmpdir/.brain-version"
# Создаём минимальный manifest в brain
brain_dir=$(mktemp -d)
echo '{"version": "brain-v1.0", "files": {}}' > "$brain_dir/manifest.json"
BRAIN_ROOT="$brain_dir" bash "$SCRIPT_DIR/verify.sh" --target="$tmpdir" >/dev/null 2>&1
assert_eq "0" "$?" "valid .brain-version returns exit 0"
rm -rf "$tmpdir" "$brain_dir"

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/verify-test.sh"
```

- [ ] **Step 2: Run — FAIL**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/verify-test.sh"`
Expected: FAIL.

- [ ] **Step 3: Implement verify.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/verify.sh" <<'EOF'
#!/usr/bin/env bash
# Verify brain installation integrity
# Checks: .brain-version, sha256 from manifest.json, settings.json validity, hooks syntax
#
# Usage: verify.sh --target=<path> [--strict-secrets]
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

# Determine brain root: env BRAIN_ROOT or script's parent
BRAIN_ROOT="${BRAIN_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"

target=""
strict_secrets=0

while [ $# -gt 0 ]; do
    case "$1" in
        --target=*) target="${1#--target=}" ;;
        --strict-secrets) strict_secrets=1 ;;
        *) log_error "Unknown: $1"; exit 1 ;;
    esac
    shift
done

[ -n "$target" ] || { log_error "--target required"; exit 1; }

# Check 1: .brain-version exists
bv="$target/.brain-version"
[ -f "$bv" ] || { log_error ".brain-version not found in $target"; exit 1; }

# Parse version + sha
version=$(head -1 "$bv")
sha_line=$(grep '^sha:' "$bv" || echo "")
[ -n "$version" ] || { log_error ".brain-version: missing version line"; exit 1; }

log_info "Found .brain-version: $version"

# Check 2: manifest.json exists in brain root
manifest="$BRAIN_ROOT/manifest.json"
[ -f "$manifest" ] || { log_error "manifest.json missing in BRAIN_ROOT=$BRAIN_ROOT"; exit 1; }

# Check 3: sha256 per file in manifest (если manifest содержит files)
files_count=$(jq -r '(.files // {}) | length' "$manifest")
if [ "$files_count" -gt 0 ]; then
    log_info "Verifying $files_count file hashes..."
    while IFS= read -r entry; do
        rel_path=$(echo "$entry" | jq -r '.key')
        expected_sha=$(echo "$entry" | jq -r '.value')
        actual_path="$target/$rel_path"
        
        if [ ! -f "$actual_path" ]; then
            log_error "Missing: $rel_path"
            exit 2
        fi
        
        if command -v sha256sum >/dev/null 2>&1; then
            actual_sha=$(sha256sum "$actual_path" | cut -d' ' -f1)
        else
            actual_sha=$(certutil -hashfile "$actual_path" SHA256 | sed -n '2p' | tr -d ' \r')
        fi
        
        if [ "$actual_sha" != "$expected_sha" ]; then
            log_error "SHA mismatch: $rel_path (expected $expected_sha, got $actual_sha)"
            exit 2
        fi
    done < <(jq -c '(.files // {}) | to_entries[]' "$manifest")
fi

# Check 4: strict secrets — no unresolved <<*>> placeholders
if [ "$strict_secrets" -eq 1 ]; then
    if grep -rE '<<[A-Z_]+>>' "$target" 2>/dev/null | grep -v '.brain-backup' | head -1; then
        log_error "Unresolved placeholders found"
        exit 7
    fi
fi

log_info "Verification passed"
exit 0
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/verify.sh"
```

- [ ] **Step 4: Run — PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/verify-test.sh"`
Expected: 2 PASS, 0 FAIL.

- [ ] **Step 5: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/verify.sh scripts/tests/verify-test.sh
git commit -m "feat(scripts): verify.sh — .brain-version + sha256 + strict-secrets check

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

---

### Task 4.2: scripts/install.sh (orchestrator) + tests

**Files:**

- Create: `scripts/install.sh`
- Create: `scripts/tests/install-test.sh`

**Назначение:** orchestrator: detect target mode (project/user) → backup → copy files → merge settings/MCP → install plugins → write .brain-version → run verify.

- [ ] **Step 1: Write failing integration test**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/install-test.sh" <<'EOF'
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    if [ "$1" = "$2" ]; then echo "PASS: $3"; else echo "FAIL: $3 (expected '$1', got '$2')"; FAILURES=$((FAILURES + 1)); fi
}

# Test 1: --dry-run does not modify target
tmpdir=$(mktemp -d)
mkdir "$tmpdir/docs"
echo "marker" > "$tmpdir/marker.txt"

bash "$SCRIPT_DIR/install.sh" --target="$tmpdir" --version=brain-v1.0 --dry-run --with-plugins=no --with-mcp=no --skip-secrets >/dev/null 2>&1

# marker.txt should still exist
[ -f "$tmpdir/marker.txt" ] && assert_eq "yes" "yes" "dry-run preserves target" || assert_eq "yes" "no" "dry-run preserves target"

rm -rf "$tmpdir"

# Test 2: missing --target → exit 1
bash "$SCRIPT_DIR/install.sh" --version=brain-v1.0 >/dev/null 2>&1
assert_eq "1" "$?" "missing --target returns exit 1"

# Test 3: install to fresh project target — files copied
tmpdir=$(mktemp -d)
mkdir "$tmpdir/docs"  # detect as project mode (has docs/)
# Эмулируем brain repo с минимальным manifest
brain_dir=$(mktemp -d)
mkdir -p "$brain_dir/project-files/docs" "$brain_dir/scripts"
echo "# template" > "$brain_dir/project-files/CLAUDE.md.template"
echo '{"version":"brain-v1.0","files":{}}' > "$brain_dir/manifest.json"
cp "$SCRIPT_DIR/install.sh" "$brain_dir/scripts/"
cp "$SCRIPT_DIR/verify.sh" "$brain_dir/scripts/"
mkdir -p "$brain_dir/scripts/lib"
cp "$SCRIPT_DIR/lib/common.sh" "$brain_dir/scripts/lib/"
# Также делаем чтобы install.sh видел свой BRAIN_ROOT — переопределяем через env
BRAIN_ROOT="$brain_dir" bash "$brain_dir/scripts/install.sh" --target="$tmpdir" --version=brain-v1.0 --with-plugins=no --with-mcp=no --skip-secrets --force >/dev/null 2>&1

# Should have CLAUDE.md
[ -f "$tmpdir/CLAUDE.md" ] && assert_eq "yes" "yes" "project mode: CLAUDE.md copied" || assert_eq "yes" "no" "project mode: CLAUDE.md copied"
# Should have .brain-version
[ -f "$tmpdir/.brain-version" ] && assert_eq "yes" "yes" "project mode: .brain-version written" || assert_eq "yes" "no" "project mode: .brain-version written"

rm -rf "$tmpdir" "$brain_dir"

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/install-test.sh"
```

- [ ] **Step 2: Run — FAIL**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/install-test.sh"`
Expected: FAIL.

- [ ] **Step 3: Implement install.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/install.sh" <<'EOF'
#!/usr/bin/env bash
# Install brain artifacts to target (project consumer or user-level ~/.claude)
#
# Usage:
#   install.sh --target=<path> --version=<tag>
#              [--dry-run] [--force]
#              [--with-plugins=yes|no] [--with-mcp=yes|no] [--skip-secrets]
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

BRAIN_ROOT="${BRAIN_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"

target=""
version=""
dry_run=0
force=0
with_plugins="default"
with_mcp="yes"
skip_secrets=0

while [ $# -gt 0 ]; do
    case "$1" in
        --target=*) target="${1#--target=}" ;;
        --version=*) version="${1#--version=}" ;;
        --dry-run) dry_run=1 ;;
        --force) force=1 ;;
        --with-plugins=*) with_plugins="${1#--with-plugins=}" ;;
        --with-mcp=*) with_mcp="${1#--with-mcp=}" ;;
        --skip-secrets) skip_secrets=1 ;;
        *) log_error "Unknown arg: $1"; exit 1 ;;
    esac
    shift
done

[ -n "$target" ] || { log_error "--target required"; exit 1; }
[ -n "$version" ] || { log_error "--version required"; exit 1; }

require_cmd jq || exit 1
require_cmd git || exit 1

# Detect mode
mode=""
if [ "$target" = "$HOME/.claude" ] || [ -d "$target/hooks" ] || [ -f "$target/settings.json" ]; then
    mode="user"
elif [ -d "$target/.git" ] || [ -d "$target/docs" ]; then
    mode="project"
else
    log_error "Cannot detect mode for: $target (expected ~/.claude/ or project dir with docs/)"
    exit 4
fi
log_info "Detected mode: $mode"

# Default --with-plugins per mode
if [ "$with_plugins" = "default" ]; then
    [ "$mode" = "user" ] && with_plugins="yes" || with_plugins="no"
fi

# Checkout version (skip if BRAIN_ROOT override — tests)
if [ -z "${BRAIN_ROOT_OVERRIDE:-}" ] && [ -d "$BRAIN_ROOT/.git" ]; then
    cd "$BRAIN_ROOT"
    git tag | grep -q "^$version$" || { log_error "Tag $version not found"; exit 3; }
    git diff --quiet || { log_error "Brain repo dirty"; exit 2; }
fi

if [ "$dry_run" -eq 1 ]; then
    log_info "DRY RUN — would install $version to $target ($mode mode)"
    exit 0
fi

# Backup
if [ "$force" -eq 0 ]; then
    backup=$(make_backup_dir "$target")
    log_info "Backup: $backup"
fi

# Copy files per mode
if [ "$mode" = "project" ]; then
    src="$BRAIN_ROOT/project-files"
    [ -d "$src" ] && cp -r "$src"/* "$target/" 2>/dev/null || true
    # Special: .mcp.json from template (если ещё нет)
    if [ -f "$src/.mcp.json.template" ]; then
        if [ -f "$target/.mcp.json" ] && [ "$with_mcp" = "yes" ]; then
            bash "$SCRIPT_DIR/lib/merge-mcp.sh" --mode=project "$target/.mcp.json" "$src/.mcp.json.template"
        elif [ ! -f "$target/.mcp.json" ] && [ "$with_mcp" = "yes" ]; then
            cp "$src/.mcp.json.template" "$target/.mcp.json"
        fi
    fi
elif [ "$mode" = "user" ]; then
    src="$BRAIN_ROOT/user-level-files"
    # Hooks
    [ -d "$src/hooks" ] && mkdir -p "$target/hooks" && cp "$src/hooks"/*.py "$target/hooks/" 2>/dev/null || true
    # settings.json merge
    if [ -f "$src/settings-fragment.json" ]; then
        bash "$SCRIPT_DIR/lib/merge-settings.sh" "$target/settings.json" "$src/settings-fragment.json"
    fi
    # MCP merge (user-level: ~/.claude.json)
    if [ "$with_mcp" = "yes" ] && [ -f "$src/mcp-user.template.json" ]; then
        claude_json="$(dirname "$target")/.claude.json"
        bash "$SCRIPT_DIR/lib/merge-mcp.sh" --mode=user "$claude_json" "$src/mcp-user.template.json"
        if [ "$skip_secrets" -eq 0 ]; then
            bash "$SCRIPT_DIR/lib/setup-secrets.sh" "$claude_json" || log_warn "Some secrets unresolved"
        fi
    fi
    # Plugins
    if [ "$with_plugins" = "yes" ]; then
        if [ -f "$src/marketplaces.json" ] && [ -f "$src/plugins-manifest.json" ]; then
            bash "$SCRIPT_DIR/lib/install-plugins.sh" \
                --marketplaces="$src/marketplaces.json" \
                --manifest="$src/plugins-manifest.json" || exit 6
        fi
    fi
fi

# Write .brain-version
brain_sha="unknown"
if [ -d "$BRAIN_ROOT/.git" ]; then
    brain_sha=$(cd "$BRAIN_ROOT" && git rev-parse "$version" 2>/dev/null || echo "unknown")
fi
{
    echo "$version"
    echo "sha: $brain_sha"
} > "$target/.brain-version"

# Run verify
BRAIN_ROOT="$BRAIN_ROOT" bash "$SCRIPT_DIR/verify.sh" --target="$target" || {
    log_error "Verification failed after install"
    exit 5
}

log_info "Install complete: $version → $target ($mode mode)"
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/install.sh"
```

- [ ] **Step 4: Run test — PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/install-test.sh"`
Expected: 3 PASS, 0 FAIL.

- [ ] **Step 5: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/install.sh scripts/tests/install-test.sh
git commit -m "feat(scripts): install.sh — orchestrates project/user mode sync with plugins+MCP

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

---

### Task 4.3: scripts/extract.sh + tests

**Files:**

- Create: `scripts/extract.sh`
- Create: `scripts/tests/extract-test.sh`

**Назначение:** reverse sync — показать diff между consumer-файлом и brain template, спросить apply/reject.

- [ ] **Step 1: Write failing test**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/tests/extract-test.sh" <<'EOF'
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

FAILURES=0
assert_eq() {
    if [ "$1" = "$2" ]; then echo "PASS: $3"; else echo "FAIL: $3 (expected '$1', got '$2')"; FAILURES=$((FAILURES + 1)); fi
}

# Test: identical content → exit 0 (no diff)
tmpdir=$(mktemp -d)
brain="$tmpdir/brain"
consumer="$tmpdir/consumer"
mkdir -p "$brain/project-files" "$consumer"
echo "same content" > "$brain/project-files/CLAUDE.md.template"
echo "same content" > "$consumer/CLAUDE.md"

BRAIN_ROOT="$brain" bash "$SCRIPT_DIR/extract.sh" --source="$consumer" --file=CLAUDE.md --dry-run >/dev/null 2>&1
assert_eq "0" "$?" "identical content returns exit 0"

# Test: different content → exit non-zero
echo "consumer different" > "$consumer/CLAUDE.md"
BRAIN_ROOT="$brain" bash "$SCRIPT_DIR/extract.sh" --source="$consumer" --file=CLAUDE.md --dry-run >/dev/null 2>&1
result=$?
[ "$result" -ne 0 ] && assert_eq "0" "0" "different content returns non-zero" || assert_eq "0" "1" "different content returns non-zero"

rm -rf "$tmpdir"

echo "---"
echo "Failures: $FAILURES"
exit $FAILURES
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/tests/extract-test.sh"
```

- [ ] **Step 2: Run — FAIL**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/extract-test.sh"`
Expected: FAIL.

- [ ] **Step 3: Implement extract.sh**

```bash
cat > "c:/моя/проекты/claude-brain/scripts/extract.sh" <<'EOF'
#!/usr/bin/env bash
# Reverse sync: show diff between consumer-file and brain template, optionally apply
#
# Usage: extract.sh --source=<consumer-path> --file=<relative-path> [--dry-run]
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

BRAIN_ROOT="${BRAIN_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"

source_dir=""
file=""
dry_run=0

while [ $# -gt 0 ]; do
    case "$1" in
        --source=*) source_dir="${1#--source=}" ;;
        --file=*) file="${1#--file=}" ;;
        --dry-run) dry_run=1 ;;
        *) log_error "Unknown: $1"; exit 1 ;;
    esac
    shift
done

[ -n "$source_dir" ] || { log_error "--source required"; exit 1; }
[ -n "$file" ] || { log_error "--file required"; exit 1; }

consumer_file="$source_dir/$file"
[ -f "$consumer_file" ] || { log_error "Not found: $consumer_file"; exit 1; }

# Find brain template (try with and without .template suffix)
brain_file=""
if [ -f "$BRAIN_ROOT/project-files/$file.template" ]; then
    brain_file="$BRAIN_ROOT/project-files/$file.template"
elif [ -f "$BRAIN_ROOT/project-files/docs/$(basename $file).template$([ "$file" = "${file%.md}" ] || echo .md)" ]; then
    # Heuristic for docs/
    brain_file="$BRAIN_ROOT/project-files/docs/$(basename $file)"
elif [ -f "$BRAIN_ROOT/project-files/$file" ]; then
    brain_file="$BRAIN_ROOT/project-files/$file"
else
    log_error "Brain template not found for: $file"
    exit 1
fi

log_info "Comparing $consumer_file ↔ $brain_file"
if diff -q "$brain_file" "$consumer_file" >/dev/null; then
    log_info "Identical, no changes needed"
    exit 0
fi

log_warn "Files differ:"
diff -u "$brain_file" "$consumer_file" || true

if [ "$dry_run" -eq 1 ]; then
    exit 2
fi

# Interactive prompt
printf "Action [a]pply / [r]eject / [q]uit: " >&2
read -r action
case "$action" in
    a|apply)
        cp "$consumer_file" "$brain_file"
        log_info "Applied. Don't forget to commit brain repo + bump version."
        ;;
    r|reject)
        log_info "Rejected. Brain template unchanged."
        ;;
    *)
        log_info "Quit. No changes."
        ;;
esac
EOF
chmod +x "c:/моя/проекты/claude-brain/scripts/extract.sh"
```

- [ ] **Step 4: Run — PASS**

Run: `bash "c:/моя/проекты/claude-brain/scripts/tests/extract-test.sh"`
Expected: 2 PASS, 0 FAIL.

- [ ] **Step 5: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add scripts/extract.sh scripts/tests/extract-test.sh
git commit -m "feat(scripts): extract.sh — reverse sync diff/apply for brain templates

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

---

## Phase 5: Brain meta documents

---

### Task 5.1: Write meta CLAUDE.md (для brain repo)

**Files:**

- Create: `c:\моя\проекты\claude-brain\CLAUDE.md`

- [ ] **Step 1: Write file**

```bash
cat > "c:/моя/проекты/claude-brain/CLAUDE.md" <<'EOF'
# CLAUDE.md — Brain Repository

**Что это:** независимый репозиторий «мозга Claude» — переиспользуемого набора правил, хуков, плагинов и MCP-серверов для консьюмер-проектов (Лидерра и будущие).

**Версия:** brain-v1.0 от 11.05.2026

---

## Что лежит в этом репозитории

- `project-files/` — копируется в consumer-проекты (CLAUDE.md.template, Pravila, Tooling, Plugin_stack_rules, .mcp.json.template, visualization)
- `user-level-files/` — копируется в `~/.claude/` (10 hooks, settings-fragment, marketplaces, plugins-manifest, mcp-user.template)
- `scripts/` — инструменты sync (install.sh, verify.sh, extract.sh + 4 lib helper'а)
- `experiments/` — песочница, не синкается
- `docs/` — документация brain'а самого (architecture, how-to-use, how-to-experiment, secrets, consumer-projects)

## Когда использовать какой скрипт

- **install.sh** — синкать brain в consumer (Лидерра или новый проект) или в `~/.claude/`
- **verify.sh** — проверить целостность после install
- **extract.sh** — обратный rescue если consumer'е сделали правку и она потерялась бы при следующем install

## Источник истины

- Архитектура: [docs/architecture.md](docs/architecture.md) (копия из spec'а Лидерры на момент bootstrap)
- Spec на момент создания: `c:/моя/проекты/портал crm/Документация/docs/superpowers/specs/2026-05-10-claude-brain-extraction-design.md`

## Что НЕ редактировать прямо в этом репо

- Скопированные template'ы — это installed copies brain v1.0. Когда хочется править — править здесь, делать bump и rerun install.sh в Лидерре.
- Plugin/MCP конфиги — bump через update manifest, не редактирование cache.

## Безопасность

- API_KEY никогда в repo (используется placeholder `<<MAGIC_API_KEY>>`)
- gitleaks scan — CI workflow на каждый push
- Подробности: [docs/secrets-and-tokens.md](docs/secrets-and-tokens.md)
EOF
```

- [ ] **Step 2: Verify**

Run: `wc -l "c:/моя/проекты/claude-brain/CLAUDE.md"`
Expected: ~30-40 строк.

---

### Task 5.2: Write manifest.json

**Files:**

- Create: `c:\моя\проекты\claude-brain\manifest.json`

- [ ] **Step 1: Compute sha256 для всех artifact'ов**

```bash
cd "c:/моя/проекты/claude-brain"

compute_sha() {
    if command -v sha256sum >/dev/null 2>&1; then
        sha256sum "$1" | cut -d' ' -f1
    else
        certutil -hashfile "$1" SHA256 | sed -n '2p' | tr -d ' \r'
    fi
}

# Сначала — собрать all relative paths
find project-files user-level-files -type f | sort > /tmp/brain-files.txt
```

- [ ] **Step 2: Generate manifest.json**

```bash
cd "c:/моя/проекты/claude-brain"

# Build JSON via jq
{
    echo '{'
    echo '  "version": "brain-v1.0",'
    echo '  "created": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",'
    echo '  "min_python_version": "3.10",'
    echo '  "required_tools": ["jq", "python3", "git"],'
    echo '  "optional_tools": ["gh", "gitleaks", "claude"],'
    echo '  "files": {'
    
    first=1
    while IFS= read -r f; do
        sha=$(compute_sha "$f")
        if [ $first -eq 1 ]; then first=0; else echo ","; fi
        printf '    "%s": "%s"' "$f" "$sha"
    done < /tmp/brain-files.txt
    
    echo ''
    echo '  }'
    echo '}'
} > manifest.json

# Validate
jq empty manifest.json && echo "Valid JSON"
```

- [ ] **Step 3: Verify manifest has expected files**

Run: `jq -r '.files | length' "c:/моя/проекты/claude-brain/manifest.json"`
Expected: ≥18 (6 markdown + 10 hooks + 1 viz + ~4 JSON + 1 mcp template).

---

### Task 5.3: Write README.md (root brain)

**Files:**

- Create: `c:\моя\проекты\claude-brain\README.md`

- [ ] **Step 1: Write README**

```bash
cat > "c:/моя/проекты/claude-brain/README.md" <<'EOF'
# Claude Brain

Переиспользуемый «мозг Claude» — правила, хуки, плагины и MCP-серверы — для подключения к проектам.

## Quick start

### Установить мозг в новый или существующий consumer-проект

```bash
cd c:/моя/проекты/claude-brain
./scripts/install.sh --target=/path/to/my-project --version=brain-v1.0
```

### Установить мозг в `~/.claude/` (user-level хуки + плагины + MCP)

```bash
cd c:/моя/проекты/claude-brain
./scripts/install.sh --target=$HOME/.claude --version=brain-v1.0
```

При первом запуске будет prompt для `MAGIC_API_KEY` (21st.dev). Используй `--skip-secrets` для CI.

### Проверить целостность

```bash
./scripts/verify.sh --target=/path/to/my-project
```

## Структура

См. [CLAUDE.md](CLAUDE.md) для деталей.

## Документация

- [docs/architecture.md](docs/architecture.md) — архитектура brain'а
- [docs/how-to-use-brain.md](docs/how-to-use-brain.md) — workflow использования
- [docs/how-to-experiment.md](docs/how-to-experiment.md) — песочница experiments/
- [docs/secrets-and-tokens.md](docs/secrets-and-tokens.md) — управление секретами
- [docs/consumer-projects.md](docs/consumer-projects.md) — список known consumer projects

## Prerequisites

- `git` ≥2.x
- `jq` ≥1.6
- `python3` ≥3.10
- `bash` (Git Bash на Windows работает)
- Optional: `gh` (для GitHub repo create), `gitleaks` (CI), `claude` CLI (для plugin install)
EOF

```

---

### Task 5.4: Write CHANGELOG.md

- [ ] **Step 1: Write CHANGELOG**

```bash
cat > "c:/моя/проекты/claude-brain/CHANGELOG.md" <<'EOF'
# Changelog

## brain-v1.0 — 2026-05-11 (planned)

### Extracted artifacts

**project-files/** (для consumer-репозиториев):
- CLAUDE.md.template (Лидерра v1.86, 266 строк)
- docs/Pravila_raboty_Claude.template.md (v1.10, 720 строк)
- docs/Plugin_stack_rules.template.md (v1.7, 916 строк)
- docs/Tooling.template.md (v1.15, 613 строк)
- docs/CHANGELOG_claude_md.template.md
- docs/visualizations/hooks-skills-plugins-map.html (3122 строки)
- .mcp.json.template (playwright + github + semgrep; laravel-boost dropped — project-specific)

**user-level-files/** (для `~/.claude/`):
- 10 hook-скриптов (skill-marker, skill-check, economy-mode×4, economy-state-guard×2, economy-postcompact, economy-verifier, economy-self-check×2)
- settings-fragment.json (enabledPlugins + permissions + hooks)
- marketplaces.json (3 marketplace: anthropics/claude-plugins-official, obra/superpowers, nextlevelbuilder/ui-ux-pro-max-skill)
- plugins-manifest.json (4 плагина с pinned gitCommitSha)
- mcp-user.template.json (magic с `<<MAGIC_API_KEY>>` placeholder)

**scripts/** (sync tooling):
- install.sh — orchestrator (project/user mode + plugins + MCP)
- verify.sh — sha256 integrity + Python syntax
- extract.sh — reverse sync (consumer → brain)
- lib/common.sh, merge-settings.sh, merge-mcp.sh, setup-secrets.sh, install-plugins.sh

### Security

- API_KEY (21st.dev) masking при extraction (placeholder + interactive prompt)
- gitleaks self-scan — обязательный gate перед первым commit'ом
- CI workflow с gitleaks на каждый push

### Known limitations

- Plugin SHA pinning через `claude plugin install` — best-effort (warn on mismatch, не fail)
- На VSCode-extension Claude Code команды `claude plugin install` могут быть недоступны — fallback на прямое редактирование JSON
EOF
```

---

### Task 5.5: Write docs/architecture.md

- [ ] **Step 1: Copy spec content as architecture doc**

```bash
cp "c:/моя/проекты/портал crm/Документация/docs/superpowers/specs/2026-05-10-claude-brain-extraction-design.md" \
   "c:/моя/проекты/claude-brain/docs/architecture.md"
```

- [ ] **Step 2: Add header note**

Edit `c:/моя/проекты/claude-brain/docs/architecture.md` — добавить в начало:

```bash
# Используем sed для вставки header'а после первой строки
{
    head -1 "c:/моя/проекты/claude-brain/docs/architecture.md"
    echo ""
    echo "**Источник:** этот документ — копия design spec'а из Лидерры (2026-05-10-claude-brain-extraction-design.md) на момент bootstrap brain v1.0. Hard-link для future-reference."
    tail -n +2 "c:/моя/проекты/claude-brain/docs/architecture.md"
} > "c:/моя/проекты/claude-brain/docs/architecture.md.tmp"
mv "c:/моя/проекты/claude-brain/docs/architecture.md.tmp" "c:/моя/проекты/claude-brain/docs/architecture.md"
```

---

### Task 5.6: Write docs/how-to-use-brain.md

- [ ] **Step 1: Write file**

```bash
cat > "c:/моя/проекты/claude-brain/docs/how-to-use-brain.md" <<'EOF'
# How to use Brain

## Сценарий 1: Подключить brain к новому проекту

```bash
cd c:/моя/проекты/claude-brain
./scripts/install.sh --target=/path/to/new-project --version=brain-v1.0
```

После этого в `new-project/` появятся:

- `CLAUDE.md` (правила Claude)
- `docs/Pravila_*.md`, `docs/Plugin_stack_rules.md`, `docs/Tooling.md`
- `docs/visualizations/hooks-skills-plugins-map.html`
- `.mcp.json` (playwright + github + semgrep MCP)
- `.brain-version` (маркер)

## Сценарий 2: Обновить brain в существующем проекте

```bash
cd c:/моя/проекты/claude-brain
git pull
./scripts/install.sh --target=/path/to/existing-project --version=brain-v1.1
```

Backup `<target>/.brain-backup-<timestamp>/` создаётся автоматически.

## Сценарий 3: Обновить хуки в `~/.claude/`

```bash
./scripts/install.sh --target=$HOME/.claude --version=brain-v1.1
```

При первом запуске prompt для `MAGIC_API_KEY`. После — Claude Code требует restart для подхвата новых хуков (раз).

## Сценарий 4: Откатить sync

Восстановить из backup:

```bash
ls /path/to/project/.brain-backup-*
cp -r /path/to/project/.brain-backup-<ts>/* /path/to/project/
```

EOF

```

---

### Task 5.7: Write docs/how-to-experiment.md

- [ ] **Step 1: Write file**

```bash
cat > "c:/моя/проекты/claude-brain/docs/how-to-experiment.md" <<'EOF'
# How to experiment

`experiments/` — песочница, **не синкается** в consumer-проекты (`.gitignore` excludes).

## Эксперимент: новый хук

```bash
cd c:/моя/проекты/claude-brain
mkdir experiments/2026-05-20-my-new-hook
# Прототипировать в experiments/2026-05-20-my-new-hook/hook.py
python experiments/2026-05-20-my-new-hook/hook.py < test-input.json

# Тестировать на live ~/.claude/ — через symlink (Windows: mklink)
# Или через add-hook flag в settings.json указывая полный путь к experiments/...
```

## Промоут эксперимента → user-level-files

Когда хук готов:

```bash
git mv experiments/2026-05-20-my-new-hook/hook.py user-level-files/hooks/my-new-hook.py
# Обновить manifest.json — добавить sha256 нового файла
# Обновить CHANGELOG.md
git commit -m "feat: promote my-new-hook from experiments"
git tag brain-v1.1
```

После — `./scripts/install.sh --target=$HOME/.claude --version=brain-v1.1` в нужном моменте.

## Эксперимент: новая редакция Pravila

```bash
mkdir experiments/2026-05-20-pravila-v2-draft
cp project-files/docs/Pravila_raboty_Claude.template.md experiments/2026-05-20-pravila-v2-draft/
# Редактировать draft независимо
# Когда готов — заменить template + bump version
```

## Гарантия

`experiments/*` в `.gitignore` (кроме `README.md` и `.gitkeep`). Никакие изменения там не попадают в consumer'ы.
EOF

```

---

### Task 5.8: Write docs/secrets-and-tokens.md

- [ ] **Step 1: Write file**

```bash
cat > "c:/моя/проекты/claude-brain/docs/secrets-and-tokens.md" <<'EOF'
# Secrets and Tokens

## Список секретов

| Секрет | Где используется | Откуда взять |
|---|---|---|
| `MAGIC_API_KEY` | `~/.claude.json:mcpServers.magic.args` | 21st.dev → settings → API keys |
| `GITHUB_TOKEN` | `.mcp.json:mcpServers.github.headers` | GitHub → settings → Personal Access Tokens (fine-grained, repo+read:org) |

## Где НЕ хранить

- ❌ В brain repo (даже private)
- ❌ В commit history
- ❌ В CLAUDE.md / docs / README
- ❌ В скриншотах сессий

## Где хранить

- ✅ В KeePass / Bitwarden / 1Password
- ✅ Как env-vars в shell profile (для `GITHUB_TOKEN`)
- ✅ Inline в `~/.claude.json` локально (после resolve через `setup-secrets.sh`)

## Workflow при первой установке

```bash
./scripts/install.sh --target=$HOME/.claude --version=brain-v1.0
# Скрипт промптит:
# > Enter value for <<MAGIC_API_KEY>> (or empty to skip):
# Вводишь значение из KeePass
```

## Workflow в CI

```bash
./scripts/install.sh --target=$HOME/.claude --version=brain-v1.0 \
    --skip-secrets
# Placeholder'ы остаются; .brain-deferred-secrets.txt создан
```

Затем — resolve через GH Actions secret + `setup-secrets.sh --secret=MAGIC_API_KEY=$MAGIC_API_KEY ...`.

## Ротация при компрометации

1. На 21st.dev: revoke + создать новый
2. Обновить локально через `setup-secrets.sh --secret=MAGIC_API_KEY=newvalue ~/.claude.json`
3. Никаких изменений в brain repo не нужно — placeholder остаётся

## gitleaks scan

В brain repo — pre-commit hook и CI workflow проверяют:

```bash
gitleaks detect --source=. --no-git
```

Если 0 findings — OK. Любой finding — **немедленный фикс** (mask API_KEY, force-push, ротация key).
EOF

```

---

### Task 5.9: Write docs/consumer-projects.md

- [ ] **Step 1: Write file**

```bash
cat > "c:/моя/проекты/claude-brain/docs/consumer-projects.md" <<'EOF'
# Consumer Projects

Реестр проектов, которые подключают brain.

| Проект | Brain version | Путь | Дата подключения | Status |
|---|---|---|---|---|
| Лидерра | brain-v1.0 | `c:/моя/проекты/портал crm/Документация/` | 2026-05-11 | active |

## Как зарегистрировать новый проект

1. `./scripts/install.sh --target=/path/to/new-project --version=brain-vX.Y`
2. В `new-project/` появится `.brain-version`
3. Добавить строку в эту таблицу
4. Commit + push brain repo

## Reverse — отключить проект

1. В `<consumer>/` удалить brain'овские файлы (по списку из manifest.json)
2. Удалить `.brain-version`
3. Удалить строку из таблицы
EOF
```

---

### Task 5.10: Write user-level-files/README.md и project-files/README.md

- [ ] **Step 1: Write user-level-files README**

```bash
cat > "c:/моя/проекты/claude-brain/user-level-files/README.md" <<'EOF'
# user-level-files/

Содержимое для копирования в `~/.claude/` (user-level config Claude Code).

## Файлы

- `hooks/` — 10 Python hook-скриптов
- `settings-fragment.json` — секции `enabledPlugins` + `permissions` + `hooks` для merge в `~/.claude/settings.json`
- `marketplaces.json` — 3 marketplace для `~/.claude/plugins/known_marketplaces.json`
- `plugins-manifest.json` — 4 плагина с pinned versions для `~/.claude/plugins/installed_plugins.json`
- `mcp-user.template.json` — MCP `magic` с placeholder для merge в `~/.claude.json:mcpServers`

## Sync

Не редактировать здесь напрямую. Все правки — в brain repo + `./scripts/install.sh --target=$HOME/.claude --version=...`.
EOF
```

- [ ] **Step 2: Write project-files README**

```bash
cat > "c:/моя/проекты/claude-brain/project-files/README.md" <<'EOF'
# project-files/

Содержимое для копирования в consumer-репозитории.

## Файлы

- `CLAUDE.md.template` — оперативная карта Claude Code (переименовывается в `CLAUDE.md` в consumer'е)
- `.mcp.json.template` — universal MCP-сервера (playwright, github, semgrep)
- `docs/Pravila_raboty_Claude.template.md` — правила работы Claude
- `docs/Plugin_stack_rules.template.md` — правила plugin stack
- `docs/Tooling.template.md` — реестр инструментов
- `docs/CHANGELOG_claude_md.template.md` — история правок
- `docs/visualizations/hooks-skills-plugins-map.html` — интерактивная карта мозга

## Sync

Не редактировать здесь напрямую. Все правки — в brain repo + `./scripts/install.sh --target=<consumer-path> --version=...`.
EOF
```

---

### Task 5.11: Commit Phase 5 (meta documents)

```bash
cd "c:/моя/проекты/claude-brain"
git add CLAUDE.md manifest.json README.md CHANGELOG.md \
        docs/ user-level-files/README.md project-files/README.md
git commit -m "$(cat <<'EOF'
docs: brain meta documentation + manifest.json

- CLAUDE.md (brain repo meta)
- README.md (root quick start)
- CHANGELOG.md (brain-v1.0 release notes)
- manifest.json (sha256 + min-python + required tools)
- docs/architecture.md (copy of Liderra spec)
- docs/how-to-use-brain.md
- docs/how-to-experiment.md
- docs/secrets-and-tokens.md
- docs/consumer-projects.md
- user-level-files/README.md
- project-files/README.md

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

---

## Phase 6: CI

---

### Task 6.1: Write .github/workflows/ci.yml

**Files:**

- Create: `c:\моя\проекты\claude-brain\.github\workflows\ci.yml`

- [ ] **Step 1: Write CI workflow**

```bash
cat > "c:/моя/проекты/claude-brain/.github/workflows/ci.yml" <<'EOF'
name: Brain CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-and-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'

      - name: Python syntax check (hooks)
        run: |
          for f in user-level-files/hooks/*.py; do
            python -m py_compile "$f"
          done

      - name: Install jq
        run: sudo apt-get install -y jq

      - name: Validate JSON files
        run: |
          for f in $(find . -name '*.json' -not -path './.git/*'); do
            jq empty "$f" || { echo "Invalid JSON: $f"; exit 1; }
          done

      - name: Run script tests
        run: |
          bash scripts/tests/common-test.sh
          bash scripts/tests/merge-settings-test.sh
          bash scripts/tests/merge-mcp-test.sh
          bash scripts/tests/setup-secrets-test.sh
          bash scripts/tests/install-plugins-test.sh
          bash scripts/tests/verify-test.sh
          bash scripts/tests/install-test.sh
          bash scripts/tests/extract-test.sh

      - name: Run Python hook tests
        run: |
          python user-level-files/hooks/economy-mode-test.py
          python user-level-files/hooks/economy-self-check-test.py
          python user-level-files/hooks/economy-state-guard-test.py

      - name: Gitleaks scan
        uses: gitleaks/gitleaks-action@v2

      - name: Markdownlint
        run: |
          npm install -g markdownlint-cli2
          markdownlint-cli2 "**/*.md" "#node_modules"
EOF
```

- [ ] **Step 2: Commit**

```bash
cd "c:/моя/проекты/claude-brain"
git add .github/workflows/ci.yml
git commit -m "ci: GitHub Actions workflow — Python syntax + JSON valid + script tests + gitleaks + markdownlint

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

---

## Phase 7: Pre-release verification

---

### Task 7.1: Run gitleaks self-scan

**Files:** none (read-only scan)

- [ ] **Step 1: Run gitleaks**

```bash
cd "c:/моя/проекты/claude-brain"
GITLEAKS="$(command -v gitleaks || echo 'c:/моя/проекты/портал crm/Документация/bin/gitleaks.exe')"
"$GITLEAKS" detect --source=. --no-git --verbose
```

Expected: `no leaks found`, exit 0.

Если findings — **STOP**, фикс masking, re-stage, re-commit, повтор.

---

### Task 7.2: Run all script unit tests

- [ ] **Step 1: Run all tests in sequence**

```bash
cd "c:/моя/проекты/claude-brain"
total=0
failed=0
for t in scripts/tests/*-test.sh; do
    total=$((total + 1))
    if bash "$t"; then
        echo "OK: $(basename $t)"
    else
        failed=$((failed + 1))
        echo "FAIL: $(basename $t)"
    fi
done
echo "---"
echo "Total: $total, Failed: $failed"
[ "$failed" -eq 0 ] || exit 1
```

Expected: `Total: 8, Failed: 0`.

---

### Task 7.3: Run Python hook tests

- [ ] **Step 1: Run all 3 hook tests**

```bash
cd "c:/моя/проекты/claude-brain"
python user-level-files/hooks/economy-mode-test.py
python user-level-files/hooks/economy-self-check-test.py
python user-level-files/hooks/economy-state-guard-test.py
```

Expected: каждый — 0 failures, exit 0.

---

### Task 7.4: Run install.sh --dry-run on Лидерра

- [ ] **Step 1: Dry-run в project mode на Лидерре**

```bash
cd "c:/моя/проекты/claude-brain"
./scripts/install.sh --target="c:/моя/проекты/портал crm/Документация" \
                     --version=brain-v1.0 \
                     --dry-run \
                     --with-plugins=no \
                     --with-mcp=no \
                     --skip-secrets
```

Expected: `[INFO]  Detected mode: project` + `[INFO]  DRY RUN — would install brain-v1.0 to ...`. Exit 0.

---

## Phase 8: First release

---

### Task 8.1: Final commit + tag brain-v1.0

- [ ] **Step 1: Verify everything staged**

Run: `cd "c:/моя/проекты/claude-brain" && git status`
Expected: `working tree clean` (всё уже было закоммичено в Phases 1-7).

- [ ] **Step 2: Create tag**

```bash
cd "c:/моя/проекты/claude-brain"
git tag -a brain-v1.0 -m "$(cat <<'EOF'
Brain v1.0 — initial release

First release of Claude Brain — extracted from Liderra project.

Includes:
- 6 markdown/HTML templates (CLAUDE.md, Pravila v1.10, Plugin_stack_rules v1.7, Tooling v1.15, CHANGELOG, visualization)
- 10 Python hooks (skill-marker, skill-check, economy-mode × 8 variants)
- 4 plugin pin (superpowers 5.1.0, claude-md-management 1.0.0, frontend-design, ui-ux-pro-max 2.5.0)
- 3 marketplace (anthropics/claude-plugins-official, obra/superpowers, nextlevelbuilder/ui-ux-pro-max-skill)
- 4 MCP servers (universal: playwright, github, semgrep; user-level: magic with placeholder)
- 7 sync scripts (install/verify/extract + 4 lib helpers)
- CI: gitleaks + markdownlint + Python syntax + JSON validation + script tests

Consumer: Liderra project (c:/моя/проекты/портал crm/Документация/).

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

- [ ] **Step 3: Verify tag**

Run: `cd "c:/моя/проекты/claude-brain" && git tag`
Expected: `brain-v1.0`.

- [ ] **Step 4: Log SHA для использования в .brain-version**

Run: `cd "c:/моя/проекты/claude-brain" && git rev-parse brain-v1.0`
Expected: 40-char hex. Запомнить — нужен в Phase 10.

---

### Task 8.2: (Optional) Create GitHub repo + push

**Skip if:** заказчик не хочет публиковать в GitHub на этом этапе. Локального brain repo достаточно для всех остальных Phase.

- [ ] **Step 1: Verify gh CLI auth**

Run: `gh auth status`
Expected: `Logged in to github.com account ...`

Если нет — `gh auth login` (manual user action).

- [ ] **Step 2: Create private repo**

```bash
cd "c:/моя/проекты/claude-brain"
gh repo create CoralMinister/claude-brain --private --source=. --remote=origin
```

Expected: «Created repository» + URL.

- [ ] **Step 3: Push main + tags**

```bash
cd "c:/моя/проекты/claude-brain"
git push -u origin main
git push origin brain-v1.0
```

Expected: успешные pushes.

- [ ] **Step 4: Verify on GitHub**

Run: `gh repo view CoralMinister/claude-brain --web`
Browser opens; verify visible files, tag, CI status.

---

## Phase 9: Self-test on test consumer

---

### Task 9.1: Create test consumer

- [ ] **Step 1: Create temp consumer dir**

```bash
mkdir -p c:/tmp/test-consumer
cd c:/tmp/test-consumer
git init
mkdir docs  # тригер detection как project mode
echo "# Test Consumer" > README.md
git add . && git commit -m "initial test consumer"
```

---

### Task 9.2: Install brain v1.0 to test consumer (project mode)

- [ ] **Step 1: Run install**

```bash
cd "c:/моя/проекты/claude-brain"
./scripts/install.sh --target=/c/tmp/test-consumer \
                     --version=brain-v1.0 \
                     --with-plugins=no \
                     --with-mcp=yes \
                     --skip-secrets
```

Expected: успех, файлы в `c:/tmp/test-consumer/`.

- [ ] **Step 2: Verify files**

```bash
ls c:/tmp/test-consumer/
ls c:/tmp/test-consumer/docs/
cat c:/tmp/test-consumer/.brain-version
```

Expected:

- `CLAUDE.md` exists
- `.mcp.json` exists
- `.brain-version` содержит `brain-v1.0` + SHA из Task 8.1 step 4.

- [ ] **Step 3: Run verify.sh**

```bash
cd "c:/моя/проекты/claude-brain"
./scripts/verify.sh --target=/c/tmp/test-consumer
```

Expected: `Verification passed`, exit 0.

---

### Task 9.3: Cleanup test consumer

- [ ] **Step 1: Remove temp dir**

```bash
rm -rf c:/tmp/test-consumer
```

---

## Phase 10: Liderra marker

---

### Task 10.1: Create .brain-version in Liderra

- [ ] **Step 1: Get brain SHA**

```bash
BRAIN_SHA=$(cd "c:/моя/проекты/claude-brain" && git rev-parse brain-v1.0)
echo "Brain SHA: $BRAIN_SHA"
```

- [ ] **Step 2: Write .brain-version в Лидерре**

```bash
cd "c:/моя/проекты/портал crm/Документация"
{
    echo "brain-v1.0"
    echo "sha: $BRAIN_SHA"
} > .brain-version
```

- [ ] **Step 3: Verify**

Run: `cat "c:/моя/проекты/портал crm/Документация/.brain-version"`
Expected: 2 lines, version + sha.

---

### Task 10.2: Commit .brain-version in Liderra

- [ ] **Step 1: Stage + commit**

```bash
cd "c:/моя/проекты/портал crm/Документация"
git add .brain-version
git commit -m "$(cat <<'EOF'
chore: declare brain v1.0 installed

Marker file for the new Claude Brain repository at c:/моя/проекты/claude-brain/.
Brain artifacts (CLAUDE.md / Pravila / Tooling / Plugin_stack_rules / hooks /
settings / plugin manifest / MCP templates) are now versioned independently
and synced into this project via:

  cd c:/моя/проекты/claude-brain
  ./scripts/install.sh --target=<this-repo> --version=brain-vX.Y

Future edits to brain artifacts: edit in claude-brain repo, then re-run install.

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

Expected: 1 file changed, 2 insertions.

- [ ] **Step 2: Verify Лидерра не пострадала**

Run:

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

Expected: top commit = «declare brain v1.0 installed»; предыдущие — unchanged.

---

### Task 10.3: Update memory — record brain v1.0 deployment

- [ ] **Step 1: Update memory project_state.md**

Read: `C:\Users\Administrator\.claude\projects\c---------------------crm-------------\memory\project_state.md`

Add new line at top about brain v1.0:

```bash
# В файле memory/project_state.md — заменить шапку
# (через Edit tool на конкретную строку)
```

Edit: добавить запись о brain v1.0 bootstrap в начало шапки.

- [ ] **Step 2: Update memory MEMORY.md index**

Edit: `C:\Users\Administrator\.claude\projects\c---------------------crm-------------\memory\MEMORY.md` — добавить новую строку:

```
- [Claude Brain v1.0 architecture](project_claude_brain.md) — extracted brain repo at c:/моя/проекты/claude-brain/; install.sh для consumer sync
```

- [ ] **Step 3: Create memory project_claude_brain.md**

```bash
cat > "$HOME/.claude/projects/c---------------------crm-------------/memory/project_claude_brain.md" <<'EOF'
---
name: Claude Brain v1.0 architecture
description: Extracted brain repo with sync mechanism — Liderra is first consumer
type: project
---

**11.05.2026 brain-v1.0 extracted** из Лидерры. Path: `c:/моя/проекты/claude-brain/`. Tag `brain-v1.0` SHA: see `cd c:/моя/проекты/claude-brain && git rev-parse brain-v1.0`.

**Архитектура:**
- `project-files/` → копируется в consumer (Лидерра)
- `user-level-files/` → копируется в `~/.claude/` + `~/.claude.json` merge
- 7 sync скриптов (install/verify/extract + 4 lib helpers)
- 4 плагина pinned по gitCommitSha (superpowers 5.1.0, claude-md-management 1.0.0, frontend-design, ui-ux-pro-max 2.5.0)
- MAGIC_API_KEY masked through `<<MAGIC_API_KEY>>` placeholder
- Gitleaks scan — pre-commit и CI gates

**Workflow правок (post-bootstrap):**
1. Открыть `c:/моя/проекты/claude-brain/`
2. Править template в `project-files/` или хук в `user-level-files/hooks/`
3. Update `manifest.json` (sha256)
4. Bump `CHANGELOG.md`
5. `git commit && git tag brain-vX.Y`
6. `./scripts/install.sh --target=<consumer> --version=brain-vX.Y`
7. В consumer'e: `git add .brain-version && git commit -m "chore: bump brain to vX.Y"`

**Why:** изолировать развитие «мозга» от content Лидерры — sandbox-friendly экспериментирование, переиспользование на новых проектах.
EOF
```

- [ ] **Step 4: Verify memory written**

Run: `ls "$HOME/.claude/projects/c---------------------crm-------------/memory/" | grep brain`
Expected: `project_claude_brain.md`.

---

## Self-review (по writing-plans checklist)

### Spec coverage check

| Spec section | Task(s) implementing |
|---|---|
| §1 Цели | Бутстрап выполняет 4 цели через Phases 1-10 |
| §2.1 Inventory (6 markdown + 10 hooks + 4 JSON + 2 MCP) | Tasks 2.1-2.9 |
| §2.2 Out-of-scope | Не копируется (cache/sessions/telemetry — manifest.json `files` явно ограничен) |
| §2.3 Спорные кейсы | Tasks 2.8 (masking), 2.9 (laravel-boost drop), 5.2 (manifest gitCommitSha) |
| §3 Архитектура | Phases 1-2 строят brain repo (артефакт A), Phase 10 ставит маркер в Лидерре (B), Phase 9 user-level (C) |
| §4 Структура brain repo | Tasks 1.2 + tree упомянут в Files-секциях каждой Task |
| §5 Bootstrap | Phases 1-10 = 32 spec шагов в expanded TDD form |
| §6 Скрипты | Tasks 3.1-3.5 (lib) + 4.1-4.3 (main) с TDD |
| §7 Brain dev workflow | docs/how-to-use-brain.md (Task 5.6), docs/how-to-experiment.md (Task 5.7) |
| §8 Matrix | Описана в spec; план следует matrix — никаких прямых правок brain-файлов в Лидерре |
| §9 Risks R1-R18 | R1 (backup) — все install.sh; R13 (API_KEY) — Tasks 2.8 masking + 7.1 gitleaks; R14 (plugin install fail) — Task 3.5 exit 6; R15 (MCP conflict) — Task 3.3 preserve laravel-boost |
| §10 Success criteria | Phase 7 + Phase 9 verify all conditions |
| §11 Multi-project future | Phase 9 self-test уже доказывает (test-consumer) |
| §12 Open Q | Q1 (GitHub) — Task 8.2 optional; Q11 (API rotation) — Task 0.4 |
| §13 Unverified | Phase 0 (Tasks 0.1-0.3) discovery |
| §15 Self-review | Этот раздел |

### Placeholder scan

Scan plan for: TBD / TODO / FIXME / "fill later" / "similar to N" — none found in plan body.

### Type/name consistency

- `merge-settings.sh` signature: `(target, fragment)` — used consistently in Task 3.2, install.sh Task 4.2
- `merge-mcp.sh` signature: `--mode=user|project <target> <brain-mcp>` — used consistently in Tasks 3.3, 4.2
- `setup-secrets.sh` flags: `--secret=KEY=VAL`, `--skip-unresolved`, `--list-unresolved` — consistent
- `install-plugins.sh` flags: `--marketplaces=`, `--manifest=` — consistent
- `BRAIN_ROOT` env-var override pattern used in tests — consistent

---

## Execution Handoff

Plan complete and saved to `docs/superpowers/plans/2026-05-10-claude-brain-extraction.md`.

**Two execution options:**

**1. Subagent-Driven (recommended)** — Я диспатчу свежий subagent на каждую Task, two-stage review (spec compliance + code quality) между Tasks, быстрая итерация. Каждый Task запускается с полным контекстом из этого plan'а; subagent не видит conversation history.

**2. Inline Execution** — выполняем Tasks в этой же сессии через executing-plans skill, batch с checkpoints на конце каждой Phase.

**Какой подход?**
