# ADR-019: Off-phase research-tooling (Perplexity Pack) **Status:** Accepted **Date:** 2026-06-14 **Контекст:** эпик «Perplexity Pack», spec `docs/superpowers/specs/2026-06-14-perplexity-pack-research-tooling-design-v3.md`, провенанс-вет `docs/research/research-vet.md`. ## Context В тулчейне Лидерры не было выделенного слоя веб-разведки. Существующие узлы дают знания узких типов: `context7` (#60) — документация библиотек/SDK; `openapi`-mcp (#47) — интроспекция нашего REST-API; `Laravel Boost` (#10) — Laravel-экосистема и runtime-запросы; `Sentry`/`Redis` MCP (#34/#35) — runtime-факты прод-системы; `graphify` (#86) — внутренний граф проекта; `GitHub` MCP (#3) — операции с репозиторием. Ни один не покрывает **открытый веб**: актуальные практики, нормативные требования, фич-разведку конкурентов, deep-research с цитатами. Три зрелых MCP-сервера закрывают этот пробел: **perplexity** (ранжированный ответ-с-источниками поверх sonar), **exa** (нейро/семантическое обнаружение источников), **firecrawl** (глубокое чтение и обход страниц). Все три присутствовали только в ветке `worktree-perplexity-pack`; main и нормативка их не знали. Аналогичный паттерн «новый off-phase слой» закрывался ранее: A8 infosec (ADR-014), C1 marketing (ADR-015), knowledge-graph (ADR-017). Дисциплина та же: провенанс-вет IS9 → перенос конфигурации в main → формализация в нормативке → реестр узлов. **Риск ecosystem.** Все три — внешние пакеты с платными API-ключами. Snyk/SentinelOne «ToxicSkills» 2025: ≈13% маркетплейс-артефактов содержат критичные дефекты. Провенанс-гейт IS9 (прецедент A8/C1) обязателен ДО формализации; вет завершён — `docs/research/research-vet.md`, все три **ПРИНЯТ**. **Решение заказчика (зафиксировано):** платные API приняты владельцем (owner waiver, Вариант 2); ключи (`PERPLEXITY_API_KEY` / `EXA_API_KEY` / `FIRECRAWL_API_KEY`) живут только в пользовательском окружении, никогда в репозитории. ## Decision Принят слой **research-tooling** — новая **20-я off-phase подкатегория**, номера Tooling **#87–#89**, классификация роутера `research`. | # | Узел | Источник | Тип | Назначение | |---|---|---|---|---| | 87 | perplexity MCP | `@perplexity-ai/mcp-server` | внешний MCP, READ-ONLY | ранжированный ответ-с-источниками (search/ask/research/reason; sonar) | | 88 | exa MCP | `exa-mcp-server` (exa-labs) | внешний MCP, READ-ONLY | семантическое/нейро обнаружение источников (web_search_exa/web_fetch_exa) | | 89 | firecrawl MCP | `firecrawl-mcp` (Firecrawl/Mendable) | внешний MCP, READ-ONLY (read-тяжёлый) | глубокое чтение и обход (scrape/batch/map/search/crawl/extract + agent) | **Детали решений:** 1. **#87 perplexity** — первичный «дай ответ-с-источниками». Четыре инструмента поверх sonar-моделей: `perplexity_search` (ранжированный web), `perplexity_ask` (sonar-pro real-time), `perplexity_research` (sonar-deep-research, медленный 30s+), `perplexity_reason` (sonar-reasoning-pro). READ-ONLY. Базовый URL через AITUNNEL-прокси (`PERPLEXITY_BASE_URL`). 2. **#88 exa** — обнаружение того, что keyword-поиск пропускает: семантический `web_search_exa` плюс `web_fetch_exa`. READ-ONLY. 3. **#89 firecrawl** — прочитать страницу целиком/обойти сайт/извлечь структурированное; `firecrawl_agent` — автономный web-research. READ-ONLY (read-тяжёлый режим). **Gate-постура (реализована, commit `bfc1f575`):** все инструменты трёх серверов (`mcp__perplexity__*` / `mcp__exa__*` / `mcp__firecrawl__*`) классифицированы как **read_only** в `tools/mcp-tool-classifier.mjs` (+тест). Это не намерение, а зафиксированный факт: router-gate пускает их без approve, мутаций они не несут. ## Boundaries (конфликт-аудит) - **RT1 — ↔ context7 (#60):** разные слои знаний. context7 = документация библиотек/SDK (vendor docs известного пакета); research-tooling = открытый веб — практики, нормы, конкуренты, новости. context7 первый для «как настроить пакет X»; research для «что индустрия делает с Y». - **RT2 — ↔ openapi-mcp (#47):** разный объект. openapi = наш REST-спек (introspection endpoints/схем); research = внешние источники в вебе. - **RT3 — ↔ Laravel Boost (#10):** разный масштаб. Boost = Laravel-экосистема и runtime-запросы в app/; research = веб вне проекта. - **RT4 — ↔ Sentry (#34) / Redis (#35):** разная плоскость. Sentry/Redis = runtime-факты прод-системы (ошибки/очереди/кэш); research = внешние знания. - **RT5 — ↔ graphify (#86):** направление. graphify = внутренний граф проекта (наружу не ходит); research = наружу, в открытый веб. Post-mortem: graphify даёт blast radius внутри, research приносит внешний контекст. - **RT6 — ↔ GitHub MCP (#3):** разный канал. GitHub = операции с репозиторием/issues/PR; research = открытый веб. - **RT7 — внутренние слои (anti-overlap внутри пака):** хотя все три «ищут в вебе», роли не пересекаются. **perplexity** = ранжированный ответ-с-источниками; **exa** = семантическое обнаружение источников по смыслу; **firecrawl** = глубокое чтение/обход конкретных страниц. Канонический порядок — связка L17: perplexity (ответ) → exa (обнаружение) → firecrawl (глубокое чтение). - **RT8 — платные API + запрет авто-трат:** все три держат платные ключи (прецедент MKT8 / READ-ONLY Sentry/Redis). Ключи только в пользовательском окружении; без авто-расхода без нужды; gitleaks стережёт утечку в репозиторий. - **RT9 — классификация `research` ≠ analysis/knowledge_graph_query/planning:** `research` = разведка широты во внешнем вебе на крупных/абстрактных задачах. Не перехватывает `analysis` (статанализ кода — Semgrep/ToB), `knowledge_graph_query` (внутренний граф — graphify), `planning` (Superpowers/CCPM). Разграничение — триггер-ключевые слова + настоящий ADR. ## Alternatives Considered - **Только WebSearch/WebFetch (встроенные)** — отклонено: дают сырой список/одну страницу, без ранжированного ответа-с-источниками, без семантического обнаружения, без глубокого обхода. research-tooling — качественный апгрейд. - **Один сервер вместо трёх** — отклонено: роли не дублируются (RT7); ответ ≠ обнаружение ≠ глубокое чтение. Один сервер не закрывает все три потребности. - **DEFERRED до Б-1** — отклонено: владелец принял платные API сейчас (owner waiver); слой полезен немедленно для разведки практик/норм при проектировании. ## Consequences **Positive:** - Закрыт пробел «открытый веб»: 0 → 3 узла research-разведки. - Новая **20-я off-phase подкатегория research-tooling**; номера #87–#89. - Связка **L17** research chain (`brainstorming` → perplexity → exa → firecrawl) в routing-off-phase.md (canonical chain). - Провенанс-вет IS9 всех трёх пройден ДО формализации — ни одного FAIL. - Gate-постура read_only зафиксирована в коде (не декларация): мутаций нет. **Neutral / Cautionary:** - Платные API: расход контролируется дисциплиной (без авто-вызовов без нужды); ключи в env. - Bulk-load MCP-инструментов исторически ронял субагентов API-ошибкой; +3 сервера увеличивают суммарное число инструментов — митигация через deferred-tools (схемы по запросу), риск помечен в дом-README раздела. - `perplexity_research` медленный (30s+) — для глубоких задач, не для быстрых вопросов. ## Related Decisions - **ADR-014** — A8 infosec-tooling; IS9-провенанс-дисциплина, прецедент платных/внешних. - **ADR-015** — C1 marketing-tooling; паттерн «пустой/новый слой → наполнение», MKT8 (READ-ONLY + запрет авто-трат) — прямой предок RT8. - **ADR-017** — knowledge-graph-tooling; граница «внутрь vs наружу» (graphify ↔ research, RT5). ## Enforcement Граница research-tooling против смежных узлов (RT1–RT9) проверяется при маршрутизации: задача «открытый веб / практики / нормы / конкуренты» → research-узлы (#87–#89); задача «документация библиотеки» → context7 (#60); «наш API» → openapi (#47); «внутренний граф» → graphify (#86); «runtime прод» → Sentry/Redis (#34/#35). Read-only-постура трёх серверов закреплена в `tools/mcp-tool-classifier.mjs` (+тест в `tools/mcp-tool-classifier.test.mjs`) — router-gate пускает их без approve и блокирует любую не-read_only попытку по умолчанию. Ключи API только в пользовательском окружении; gitleaks (pre-commit/pre-push) блокирует утечку в репозиторий. Узлы #87–#89 живут в `docs/registry/nodes.yaml` (`subcategory: research-tooling`, `triggers.classification: research`); инвариант покрытия карточками (Машина 3-E) требует контракт-карточку на каждый узел (`docs/registry/contracts/{perplexity,exa,firecrawl}-mcp.contract.json`). ## References - `docs/superpowers/specs/2026-06-14-perplexity-pack-research-tooling-design-v3.md` — design (D1–D9). - `docs/research/research-vet.md` — IS9 провенанс-вет (#87/#88/#89, все ПРИНЯТ). - `docs/research/README.md` — дом раздела research-tooling. - `docs/Tooling_v8_3.md` §4.60–§4.62 — 9-атрибутные блоки узлов #87–#89. - `docs/Plugin_stack_rules_v1.md` R10.1 Блок 3 + R15.6 — реестр ролей MCP-серверов. - `docs/Pravila_raboty_Claude_v1_1.md` §13.2 — Off-phase research-tooling абзац. - `docs/routing-off-phase.md` — связка L17 (research chain) + routing #87–#89. - `.mcp.json` — три блока mcpServers (perplexity/exa/firecrawl); commit `bfc1f575` (gate read_only).