---
name: kn-map
description: >
  Сгенерировать knowledge map — два дополняющих ракурса на wiki: UMAP-карту
  по семантической близости и force-directed граф по wikilink-связям.
  Wrapper над `bin/knowledge_map.py`. Обе карты рендерятся через Cytoscape.js
  (vendored в `bin/vendor/`). Создаёт три версионированных артефакта: два
  интерактивных HTML в `_attachments/` плюс markdown-страницу со статистикой,
  Louvain-диагностикой и обоими iframe-embed в `wiki/meta/kn-maps/`.
  Триггеры: /kn-map, kn-map, knowledge map, "карта знаний", "сделай карту знаний",
  "обнови карту", "визуализируй wiki", "knowledge map snapshot", "umap wiki".
---

# kn-map: визуализация wiki

Скилл — тонкая обёртка над `bin/knowledge_map.py`. Сам Python-скрипт делает всю работу:
читает `wiki/meta/embeddings.json`, проецирует 4096-мерные эмбеддинги в 2D через UMAP,
рендерит обе карты через Cytoscape.js (`bin/wiki_graph.py`), считает Louvain
сообщества + bridge nodes + sparse-метрики, собирает markdown-обёртку.

Два HTML — **не дубликат**, а разные ракурсы на одном движке:

- `knowledge-map-*.html` (Cytoscape, layout=preset, координаты — UMAP):
  близость на экране = **семантическая** близость (по эмбеддингам). Compound-облака
  отключены — Louvain-кластеры на семантической карте искажают чтение.
- `wiki-graph-*.html` (Cytoscape, layout=fcose): близость на экране = **топологическая**
  связность (плотность wikilinks). Сообщества Louvain — compound nodes (полупрозрачные
  облака), узлы-мосты — звезда с золотым свечением.

В обеих картах: hover на узле подсвечивает его 1-hop соседей и затемняет остальное.

Расхождения между двумя картами и есть самое интересное (страница семантически близка
к одному кластеру, но цитируется в другом — кандидат для cross-link или re-domain).

Скилл нужен только для: (1) маршрутизации запроса к скрипту, (2) подачи результата пользователю.

**Свежесть эмбеддингов — не забота скилла.** `wiki/meta/embeddings.json` поддерживается актуальным через Stop-hook (`python3 bin/embed.py update` после каждого turn'а агента). Скилл просто потребляет последний снимок.

---

## Команда и флаги

| Команда | Поведение |
|---|---|
| `/kn-map` | Полная генерация: оба HTML + markdown-обёртка. Дефолтный `--seed 42`. |
| `/kn-map --no-edges` | Без wikilink-граней на UMAP-карте (если перегружено). Cytoscape-граф не затрагивается. |
| `/kn-map --no-graph` | Пропустить Cytoscape-граф (только UMAP + markdown). |
| `/kn-map --no-page` | Только HTML-артефакты, без markdown в `wiki/meta/kn-maps/`. Для одноразовой проверки. |
| `/kn-map --seed N` | Другой UMAP random_state — даёт другую укладку точек (используй, если дефолтная плохо разделяет кластеры). |

Под капотом — `python3 bin/knowledge_map.py [флаги]`. Плюс `--out-dir <DIR>` если нужен другой каталог для HTML (по умолчанию `_attachments/`).

---

## Поток

```
1. python3 bin/knowledge_map.py [флаги]   # генерация
2. Парсинг stdout: пути к артефактам + сводная статистика
3. Сообщение пользователю — пути обоими wikilink'ами + ключевые цифры
```

Если `wiki/meta/embeddings.json` отсутствует — скрипт упадёт. Это означает, что Stop-hook ещё ни разу не успешно отработал (например, embedder недоступен). Сообщи пользователю — это разовая проблема окружения, не задача скилла.

---

## Output для пользователя

После успешного прогона — короткое сообщение:

```
🗺️ Карта обновлена.

- UMAP (семантика): [[_attachments/knowledge-map-YYYY-MM-DD.html]]
- Граф (топология): [[_attachments/wiki-graph-YYYY-MM-DD.html]]
- Markdown-обёртка с обоими iframe + статистикой и Louvain-диагностикой:
  [[wiki/meta/kn-maps/knowledge-map-YYYY-MM-DD]]

Сводка: <страниц всего>, <доменов>, <wikilink-граней>, <сирот>, <Q сообществ>.
```

Если генерация графа была пропущена (`--no-graph` или Cytoscape-зависимости отсутствуют), не упоминай его в выводе. Если в stdout есть строки с warnings (например, страницы без эмбеддинга, fallback на серый цвет) — упомяни их.

---

## Что скилл не делает

- **Не редактирует content-файлы** (`wiki/ideas/`, `wiki/entities/`). Артефакты пишутся только в `_attachments/` и `wiki/meta/kn-maps/`.
- **Не учитывается в `wiki_hash` lint'а** — папка `wiki/meta/kn-maps/` исключена в `bin/static_lint.py` (см. lint SKILL, секция Skip-check). Поэтому `/kn-map` не триггерит fresh-audit при следующем `/lint`.
- **Не запускает embedder.** Свежесть `wiki/meta/embeddings.json` — забота Stop-hook'а в `.claude/settings.json`. Если эмбеддингов нет, скрипт падает — пользователь сам разбирается с окружением.
- **Не удаляет старые snapshot'ы.** История `knowledge-map-*.md` в `kn-maps/` накапливается специально — это диахронический срез эволюции wiki (как `lint-report-*.md`).

---

## Когда вызывать проактивно

После крупного ingest (≥5 новых страниц) или batch-ingest — упомянуть в финальном отчёте: «можно обновить карту знаний через `/kn-map`». Не запускать без явного запроса — генерация занимает 10-30 секунд и тратит память на UMAP.

Для иллюстраций ВКР — карта это самый зрелищный артефакт, у пользователя могут быть запросы вида «сделай свежий снимок до защиты».
