# Perplexity Pack — План 1 (v9, floor-safe): перенос конфигурации

> **For agentic workers:** REQUIRED SUB-SKILL: superpowers:executing-plans (inline). Steps use checkbox syntax.

**Goal:** Аддитивно перенести три блока серверов research-слоя в main `.mcp.json` floor-safe способом, с проверкой наличия ключей, байт-в-байт бэкапом (`cp -n`) и защитой бэкапа в .gitignore.

**Architecture:** Вет (research-vet.md) и дом-README уже на диске (plan-v6). Этот план — только перенос. Сначала проверяется присутствие платных API-ключей в env (без утечки значения, идиома `${VAR:+set}`); затем gitignore бэкапа → байт-в-байт бэкап `cp -n` → Edit `.mcp.json` (+3 блока). Все операции floor-safe (Edit/Write + `echo`/`cp` — не arbitrary-exec, не destructive).

**Tech Stack:** харнес Write/Edit, `echo`/`cp` (coreutils), JSON config `.mcp.json`.

## Цель

Доделать перенос конфигурации Perplexity Pack в main floor-safe способом. Реализует якорь
спеки {#D3} (перенос конфигурации) из
`docs/superpowers/specs/2026-06-14-perplexity-pack-research-tooling-design-v3.md`.

## Платные API — предупреждение исполнителю (cost)

Все три сервера ходят в **платные API** (Perplexity sonar-* / Exa / Firecrawl). Дисциплина:
- **Расхода при переносе и загрузке серверов НЕТ** — деньги тратятся ТОЛЬКО при явном вызове
  tool (perplexity_ask / web_search_exa / firecrawl_scrape) после перезапуска.
- Cost-ceiling на уровне MCP не enforce'ится; митигация — дисциплина: использовать точечно
  на крупных/абстрактных задачах, **никогда в автономных циклах**, не дёргать пачками.
- Нет ключа → сервер падает gracefully (как Sentry), сессию не ломает. Step 1 фиксирует наличие.

```skills-json
[]
```

```steps-json
[
  {"op":"Bash","object":"echo \"keys: PERPLEXITY=${PERPLEXITY_API_KEY:+set} EXA=${EXA_API_KEY:+set} FIRECRAWL=${FIRECRAWL_API_KEY:+set}\"","ref":"D3"},
  {"op":"Edit","object":".gitignore","ref":"D3"},
  {"op":"Bash","object":"cp -n .mcp.json .mcp.json.bak-perplexity-pack-20260614","ref":"D3"},
  {"op":"Edit","object":".mcp.json","ref":"D3"}
]
```

```verified-context-json
[
  {"id":"vc1","kind":"EXTRACTED","ref":".mcp.json","anchor":"\"$schema\": \"https://raw.githubusercontent.com/anthropics/claude-code/main/schemas/mcp.json\""},
  {"id":"vc2","kind":"EXTRACTED","ref":"docs/security/research-vet.md","anchor":"Провенанс-вет research-tooling"},
  {"id":"vc3","kind":"EXTRACTED","ref":"tools/cost-pricing.mjs","anchor":"export const PRICING = Object.freeze("}
]
```

---

## Task 3: Floor-safe перенос блоков в main `.mcp.json`

**Files:** Modify `.gitignore`, `.mcp.json`; Create `.mcp.json.bak-perplexity-pack-20260614` (`cp -n`).

- [ ] **Step 1: Проверка наличия ключей (без утечки значения)** — Run: `echo "keys: PERPLEXITY=${PERPLEXITY_API_KEY:+set} EXA=${EXA_API_KEY:+set} FIRECRAWL=${FIRECRAWL_API_KEY:+set}"` — Expected: `keys: PERPLEXITY=set EXA=set FIRECRAWL=set` (идиома `:+set` печатает «set», НЕ значение). Если какой-то `=` пуст — ключ отсутствует; перенос всё равно безопасен (fail-graceful), но отметить в отчёте.
- [ ] **Step 2: Защитить бэкап в .gitignore** — Read `.gitignore` (авторизовано планом), затем Edit: добавить `.mcp.json.bak-*`, если её нет.
- [ ] **Step 3: Байт-в-байт бэкап** — Run: `cp -n .mcp.json .mcp.json.bak-perplexity-pack-20260614` — Expected: бэкап побайтно средствами ОС (`-n` не затирает существующий).
- [ ] **Step 4: Добавить три блока серверов** — Read `.mcp.json` (авторизовано), затем Edit: перед ключом `_disabled_marketing_servers_note` добавить три блока `mcpServers` по образцу `openapi`/`sentry`:
  - `perplexity` → `@perplexity-ai/mcp-server`, env `PERPLEXITY_API_KEY`, comment (research; ПРИНЯТ; SLSA-provenance; MIT; платный sonar-*; ключ user env).
  - `exa` → `exa-mcp-server`, env `EXA_API_KEY`, comment (нейро-поиск; ПРИНЯТ; MIT; license-поле npm пусто — research-vet; платный).
  - `firecrawl` → `firecrawl-mcp`, env `FIRECRAWL_API_KEY`, comment (глубокое чтение/обход; ПРИНЯТ; MIT; платный).
  Все три ПРИНЯТ (`docs/research/research-vet.md`). Существующие блоки не трогать. JSON валиден.

---

## Безопасность правки (floor-safe)

- **Ключи** — Step 1 (presence-check `:+set`, без утечки значения).
- **Бэкап** — Step 3 `cp -n` (байт-в-байт ОС, не LLM-память — закрывает замечание судьи к v7; идемпотентно). gitignored Step 2.
- **Валидация JSON** — программный `node -e JSON.parse` пол блокирует (правило 8); floor-safe:
  пост-Edit Read `.mcp.json` + структурная сверка; MCP-серверы валидируют JSON при загрузке после
  перезапуска (битый JSON → серверы не стартуют — заметно сразу).
- **Откат** — `cp .mcp.json.bak-perplexity-pack-20260614 .mcp.json` либо владелец `git checkout -- .mcp.json` (tracked). Правка аддитивная.

## Self-Review

- Покрытие: Task 3 → {#D3}. {#D2} (вет) сделан в plan-v6. {#D4}-{#D9} — Планы 2 и 3.
- Floor-safe: Edit/Write + `echo`/`cp -n` (не arbitrary-exec, не destructive) → ни floor, ни Δ7+ не блокируют.
- Закрыты прошлые замечания судьи: бэкап байт-в-байт (cp, не память), идемпотентность (cp -n),
  gitignore бэкапа, проверка ключей + cost-warning (платные API).

## Примечания

- Перенос только ПРИНЯТ-пакетов (все три) из `docs/research/research-vet.md`.
- Live-smoke — после переноса + перезапуска владельцем.
- Регрессия vitest + реестр/нормативка/роутер — Планы 2 и 3.
