# Obsidian Untangle Knot

> Разгрузка hub-заметки с высоким in-degree: под-MOC под категории хаба, перепривязка входящих ссылок ресурсных заметок; оригинал остаётся точкой входа. Срабатывай на «распутай клубок», «разгрузи MOC X», «карта стала помойкой», «перепривязать заметки».

- Skill: `jtprogru/obsidian-untangle-knot-2` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add jtprogru/obsidian-untangle-knot-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jtprogru/obsidian-untangle-knot-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: jtprogru (https://skillmd.com/u/jtprogru)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/jtprogru/obsidian-untangle-knot-2

---


# obsidian-untangle-knot

## Базовая идея

На общие MOC ссылаются десятки заметок: проще сослаться на `[[DevOps]]`, чем искать подкарту. In-links растут стихийно, out-links — медленно, поэтому сигнал клубка — **высокий in-degree**, не out.

Скилл считает in/out хаба, использует **существующую структуру** hub (подзаголовки, категории) как готовые точки приземления, создаёт под-MOC и — **главное действие** — переключает входящие ссылки ресурсных заметок на подходящий под-MOC. Оригинал **остаётся** точкой входа «не знаю точнее куда»: не удаляем, один hub за прогон, файлы между папками PARA не двигаем — перевязываем связи, а не структуру.

Правила хранилища — `.agents/rules/`, загружаются автоматически. `obsidian-split-note` разбивает **содержимое** заметки на атомарки; здесь разбиваем **связи** — атомарки не создаются.

---

## Алгоритм

### 1. Выбор hub-заметки

**Точечный** — пользователь назвал заметку: `fd -t f "DevOps.md" .`; несколько совпадений — спроси. **Discovery** — «найди мои hub-заметки»: прогон по `03. Ресурсы/07. Карты/` (или другой папке), top-10 по `in + out`, спроси какую разгружать:

```bash
for f in "03. Ресурсы/07. Карты/"*.md; do
  out=$(rg -o '\[\[[^\]]+\]\]' "$f" | wc -l); echo "$out  $f"
done | sort -rn | head -10
rg -c -F "[[Имя заметки]]" .   # in-links
```

### 2. Подсчёт ссылок и диагностика

**In-links — три потока с разной стратегией:**

| Поток | Что это | Перепривязка |
|-------|---------|--------------|
| **A. Out-соседи hub** | Заметки, на которые ссылается hub (тело или `down`) | Итерация 1 |
| **B. Up-children** | Заметки с `up: [[Hub]]`, не упомянутые в теле hub | Итерация 1 — **не пропускай**, самая «забытая» нагрузка |
| **C. In-links в телах** | Упоминания `[[Hub]]` в телах (`rg -l -F`, плюс pipe-вариант `[[Hub|`) | Итерация 2 (опциональная) |

Поток B ищи **только по полю `up:`** — грубый grep ловит `[[Hub]]` в `other`/`links`/`category`/`sources`, а это другая семантика. Точный парсинг:

```bash
python3 - <<'PY'
import os, re
n = 0
for dp, _, fns in os.walk('.'):
    for fn in fns:
        if not fn.endswith('.md'): continue
        try: c = open(os.path.join(dp, fn), encoding='utf-8').read(4000)
        except: continue
        m = re.match(r'^---\n(.*?)\n---', c, re.DOTALL)
        if not m: continue
        fm = m.group(1)
        b = re.search(r'^up:\s*\n(.*?)(?=^[a-zA-Z_]+:|\Z)', fm, re.M|re.S)
        s = re.search(r'^up:\s*(.+)$', fm, re.M)
        if (b and re.search(r'-\s*"?\[\[Hub\]\]"?', b.group(1))) or (s and '[[Hub]]' in s.group(1)): n += 1
print(n)
PY
```

**Поля frontmatter:** трогаем только `up` (поток B) и `down` hub-а. `other`, `links`, `category`, `sources` (никогда) — не трогаем.

**Порог по in-degree:** ≥ 100 — распутываем; 50–100 — спроси; 20–50 — прирост невелик; < 20 — рано. **Out-degree:** N < 5 — лепить не из чего, откажись; 5–10 — 2–3 категории, если намечены подзаголовками; > 10 — нормальная категоризация.

### 3. Чтение соседей (без изменений)

Для каждого out-соседа — короткий read (frontmatter + первая осмысленная строка): существует ли файл (dangling — не сосед, в отдельный список), тезис, структурный тег, `confidence`, и главное — **значение `up`** (определяет ветку в 6.2).

Типы: атомарка/MOC — стандартная перепривязка (MOC также в `down` под-MOC); **упоминание** (`#person`, компания, инструмент) — не категоризуется, остаётся контекстной ссылкой в hub; `02. Сферы/05. Медийность/` — свой жизненный цикл, `up` не трогаем; сосед с `up` на существующий альтернативный под-MOC — уже категоризован, оставляем.

### 4. Категоризация

**Под-MOC — точки приземления будущих in-links.** **Есть `##`-подзаголовки — используй их как готовые категории**, не выдумывай оси: сохраняй ментальную модель автора. Нет — подбери ось: домен знаний, уровень абстракции (принципы/инструменты/опыт/источники), тип артефакта, зрелость (`confidence`), существующие теги.

Размер: минимум 2 заметки, если категория намечена структурой; минимум 3 — если выдумана; > 20 — дроби внутри (`Hub → группа → под-MOC`). Одиночки — в «Прочее» hub-а, без под-MOC. Имя — claim-based по `file-naming.md`; семейство от одного родителя — `<Родитель> – <Категория>`.

**Валидация выдуманных осей** через `myvault_search` по соседям hub (параметры гибридного поиска — см. CLAUDE.md): в топе планируемые соседи → ось рабочая; разброс по чужим заметкам → переформулируй; пусто → категория выдумана, откажись. Дополнительный сигнал, первичен графовый анализ.

**Стоп-сигнал:** ни одна ось не даёт категорий → материал монолитный, это центр темы, а не клубок. Скажи прямо, предложи `obsidian-note-critic` или `obsidian-split-note`.

### 5. План разгрузки → подтверждение

**Две итерации; реальное падение in-degree приходит только во второй — не обещай чудес после первой.**

**Итерация 1 (каркас, безопасная):** создать под-MOC; перепривязать `up` у потоков A и B (объединяются; при up-children > 50 — батчи по 10–20); минимально обновить тело hub. **Итерация 2 (опциональная):** перенаправить поток C — нужен контекст каждой ссылки; применимо только где `[[Hub]]` — центральная тема заметки; может оказаться почти не нужной.

План: числа in/out, dangling out-links, соседи на альтернативных картах, создаваемые под-MOC с числом заметок, число перепривязок, действия с телом hub, ожидаемый эффект по итерациям. Подтверждение **на каждую итерацию отдельно**; итерации не объединять.

### 6. Выполнение

#### 6.1. Создать под-MOC

В `00. Входящие/` по `Шаблон карты.md` (после ревью → `03. Ресурсы/07. Карты/`), файл заводи через Templater — см. навык `/note-templates`, раздел «Как применить шаблон технически». Wikilink резолвится по имени файла — перепривязка работает, пока под-MOC в инбоксе. Блок ниже — что должно получиться после заполнения:

```yaml
---
aliases: []
tags:
  - MapOfContent
  - review
up:
  - "[[Оригинальный hub]]"
down: []
links: []
other: []
contradicts: []
summary: "Какие темы собирает под-MOC и для какой задачи — 1–3 предложения, plain text"
ai_generated: true
---
```

Тело: описание категории (1–2 предложения), `## Заметки` (ссылки с аннотациями), `## Связанные карты` (соседи-MOC; сюда и в `other` — обнаруженный альтернативный под-MOC: не дублируем чужую категоризацию, а ссылаемся).

Описание категории — именно 1–2 предложения: под-MOC это навигация, а не пересказ собранных заметок (`note-density.md`). Аннотация к ссылке отвечает «зачем сюда идти», а не повторяет `summary` заметки. После создания — `python3 .agents/scripts/check_note_density.py "00. Входящие"`.

#### 6.2. Перепривязать `up` у соседей — ветки

- **`up` содержит `[[Hub]]`** → заменить на `[[Под-MOC]]`; других родителей не трогать.
- **`up` пустой** → добавить `[[Под-MOC]]` (не hub).
- **`up` содержит dangling wikilink** → намерение автора категоризовать: замени dangling на актуальный под-MOC.
- **`up` содержит существующий альтернативный под-MOC** → **не трогаем**; в плане «остаётся на альт. карте», альтернатива — в `other`/«Связанные карты» нового под-MOC.
- **Сосед-упоминание** (`#person`, компания, инструмент) → `up` не трогаем.
- **Telegram/контентные** (`02. Сферы/05. Медийность/`) → `up` не трогаем.
- **Есть более точный родитель, `[[Hub]]` лишний** (например `up: [[SRE]], [[DevOps]]` у заметки про SRE) → **удалить hub из `up`**, не перепривязывать. Признак: ни один под-MOC не подходит семантически, а другой родитель точнее. Не путать с альтернативным под-MOC: там другая категоризация той же темы, здесь — другая тема.

Попутно: dangling wikilinks старой категоризации в телах можно заменить на актуальные. Сохраняй YAML-формат исходника. `sources` не трогаем; меняешь `up` литературного источника — синхронизируй по политике «up + sources». `links`/`other` не очищаем — замене подлежит только `up`.

#### 6.3. Перенаправить in-links в телах (итерация 2)

`rg -l -F "[[Имя hub]]" --type md .` → перепривязываем **только ресурсные папки** (`03. Ресурсы/01…05, 07`). **Не трогаем** `01. Проекты/`, `02. Сферы/`, `05. Дневник/`, `04. Архив/`, `00. Входящие/` — там ссылки на общий MOC намеренны (точка входа, исторический контекст); инбокс — для `obsidian-refactor-inbox`.

Для каждой заметки: контекст ссылки (1–2 строки вокруг) → категория определима — замени на `[[Под-MOC]]`; нет или контекст общий — оставь оригинал (это правильно). Несколько ссылок в заметке — по отдельности, могут уйти в разные под-MOC. **Не трогай** ссылки в callout-блоках (`> [!quote]`, `> [!note]`, «Ревью») и в `sources`. Спорные — оставь оригинал, в «Под вопросом».

#### 6.4. Минимально обновить тело hub

**Не переписывай целиком.** Есть подзаголовки — первой строкой после каждого вынесенного добавь pointer `→ Подкарта: [[DevOps – Управление инфраструктурой]]`; существующие out-links под заголовком не трогай. Плоский список — сгруппируй по категориям, сохраняя порядок и формулировки. Frontmatter hub-а: в `down` добавить под-MOC; `up`, `aliases`, `links`, `other`, `tags`, Bases/Dataview — не трогать.

#### 6.5. Заполнить `down` у под-MOC

Списком заметок, у которых теперь `up: [[Под-MOC]]` — из плана, без повторного скана.

### 7. Отчёт

После **итерации 1**: in до/после (точные и pipe-варианты отдельно), созданные под-MOC с их in, число перепривязанных `up`, «Под вопросом» — и **обязательное предупреждение**: in-degree упал слабо, перепривязан только frontmatter, реальный эффект — после итерации 2. Затем вопрос: идти ли во вторую. После **итерации 2**: падение in, разбивка «N из M» по папкам, что сохранено as-is, «Под вопросом» с выбором по каждой. Выявилось новое (соседний hub, противоречие соседей, дубликаты) — упомяни, не лезь в той же итерации.

---

## Особые случаи

**Concept-hub** (атомарка обросла in-links, типа `Kubernetes`) — спроси пользователя при выборе hub: (1) превратить в MOC — `#thought` → `#MapOfContent`, frontmatter по `Шаблон карты.md`, переместить в `03. Ресурсы/07. Карты/`, backlinks Obsidian обновит; (2) оставить концептом и создать `Kubernetes – MOC.md` рядом — in-links идут на MOC, концепт остаётся узким «определение/идея».

**Out-клубок** (низкий in, высокий out — свежесобранная карта): перепривязка не нужна; главное — переписать тело hub в оглавление по под-MOC. Спроси, какой эффект нужен (навигация vs graph view).

**Двусторонние ссылки** (заметка и в `up`, и в `down` оригинала) — симптом запутанности: покажи явно, спроси какое направление оставить; по умолчанию общая — в `up`, частная — в `down`.

