diff --git a/audit/2026-05-06-objects-audit.md b/audit/2026-05-06-objects-audit.md index eeff08f..404aac6 100644 --- a/audit/2026-05-06-objects-audit.md +++ b/audit/2026-05-06-objects-audit.md @@ -3,16 +3,16 @@ date: 2026-05-06 type: audit source: scripts/kb-objects-audit.py tags: [audit, objects, frontmatter, links] -score: 84 +score: 6 --- # KB objects audit — 2026-05-06 -**Score (меньше = лучше): `84`** +**Score (меньше = лучше): `6`** - Проектов с frontmatter: **12/12** (0 проблем) - NetBird online-пиров без проектной карточки: **3** -- Битых wiki-ссылок `[[...]]`: **26** +- Битых wiki-ссылок `[[...]]`: **0** ## Frontmatter в projects/ @@ -34,29 +34,4 @@ score: 84 ## Битые wiki-ссылки -- [CLAUDE.md](CLAUDE.md) — `[[двойные скобки]` → нет такого файла -- [snippets/invoice-template.md](snippets/invoice-template.md) — `[[projects/dttb/znamenskoye-log.md]` → нет такого файла -- [decisions/2026-04-30-niikn-culture-gov-fakeip-fix.md](decisions/2026-04-30-niikn-culture-gov-fakeip-fix.md) — `[[notes/govru-diagnosis]` → нет такого файла -- [decisions/2026-05-02-apple-id-tj-via-residential-proxy.md](decisions/2026-05-02-apple-id-tj-via-residential-proxy.md) — `[[../snippets/clients/]` → нет такого файла -- [decisions/2026-04-29-rustdesk-client-deployment-package.md](decisions/2026-04-29-rustdesk-client-deployment-package.md) — `[[../snippets/clients/]` → нет такого файла -- [decisions/2026-04-28-niikn-uookn-sev-gov-fakeip-fix.md](decisions/2026-04-28-niikn-uookn-sev-gov-fakeip-fix.md) — `[[notes/govru-diagnosis]` → нет такого файла -- [decisions/2026-04-30-openwrt-homelab-agh-podkop-chain.md](decisions/2026-04-30-openwrt-homelab-agh-podkop-chain.md) — `[[../claude-memory/podkop]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[таргет]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[notes/govru-diagnosis]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[../snippets/clients/]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[../claude-memory/podkop]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[../snippets/clients/]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[notes/govru-diagnosis]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[../../../knowledge-base/feedback_lxc_loadavg]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[feedback_finland_security]` → нет такого файла -- [audit/2026-05-03-health.md](audit/2026-05-03-health.md) — `[[..]` → нет такого файла -- [projects/dttb/rustdesk.md](projects/dttb/rustdesk.md) — `[[../../../knowledge-base/feedback_lxc_loadavg]` → нет такого файла -- [projects/lipki/README.md](projects/lipki/README.md) — `[[../znamenskoye/]` → нет такого файла -- [projects/lipki/README.md](projects/lipki/README.md) — `[[../znamenskoye/]` → нет такого файла -- [projects/lipki/README.md](projects/lipki/README.md) — `[[../znamenskoye/]` → нет такого файла -- [projects/sergey/README.md](projects/sergey/README.md) — `[[../znamenskoye/]` → нет такого файла -- [projects/dttb/graphify-out/GRAPH_REPORT.md](projects/dttb/graphify-out/GRAPH_REPORT.md) — `[[_COMMUNITY_Community 0|` → нет такого файла -- [projects/dttb/graphify-out/GRAPH_REPORT.md](projects/dttb/graphify-out/GRAPH_REPORT.md) — `[[_COMMUNITY_Community 1|` → нет такого файла -- [projects/dttb/graphify-out/GRAPH_REPORT.md](projects/dttb/graphify-out/GRAPH_REPORT.md) — `[[_COMMUNITY_Community 2|` → нет такого файла -- [projects/dttb/graphify-out/GRAPH_REPORT.md](projects/dttb/graphify-out/GRAPH_REPORT.md) — `[[_COMMUNITY_Community 3|` → нет такого файла -- [snippets/clients/yaroslav-amnezia-setup.md](snippets/clients/yaroslav-amnezia-setup.md) — `[[feedback_finland_security]` → нет такого файла +✅ битых ссылок не найдено diff --git a/decisions/2026-04-28-niikn-uookn-sev-gov-fakeip-fix.md b/decisions/2026-04-28-niikn-uookn-sev-gov-fakeip-fix.md index 4fce220..bb2a86e 100644 --- a/decisions/2026-04-28-niikn-uookn-sev-gov-fakeip-fix.md +++ b/decisions/2026-04-28-niikn-uookn-sev-gov-fakeip-fix.md @@ -12,7 +12,7 @@ tags: [decision, niikn, network, dns, podkop] ## Диагноз -По алгоритму [[notes/govru-diagnosis]]: +По алгоритму [[../projects/niikn/govru-quickfix-playbook]]: | Точка | HTTP | Real IP | |-------|------|---------| diff --git a/decisions/2026-04-29-rustdesk-client-deployment-package.md b/decisions/2026-04-29-rustdesk-client-deployment-package.md index b3a1b54..4a93841 100644 --- a/decisions/2026-04-29-rustdesk-client-deployment-package.md +++ b/decisions/2026-04-29-rustdesk-client-deployment-package.md @@ -117,7 +117,7 @@ RustDesk при первом запуске парсит своё имя фай ## TODO / следующие шаги -- [ ] Олег создаёт public share-link в Nextcloud (с паролем), кладёт ссылку в [[../snippets/clients/]] +- [ ] Олег создаёт public share-link в Nextcloud (с паролем), кладёт ссылку в `snippets/clients/` - [ ] Подготовить **one-liner-скрипты** на сервере (NPM static path `/install/` → S3 или rustdesk-api resources/public) - [ ] **Configuration Strategy** в админке lejianwen-api — push config existing peers - [ ] Скачать `rustdesk-utils` 2.x (lejianwen-pro) для генерации `rustdesk-licensed-*.exe` — single-file deployment без скриптов diff --git a/decisions/2026-04-30-niikn-culture-gov-fakeip-fix.md b/decisions/2026-04-30-niikn-culture-gov-fakeip-fix.md index 6b05bc4..9d18ee3 100644 --- a/decisions/2026-04-30-niikn-culture-gov-fakeip-fix.md +++ b/decisions/2026-04-30-niikn-culture-gov-fakeip-fix.md @@ -12,7 +12,7 @@ tags: [decision, niikn, network, dns, podkop] ## Диагноз -По алгоритму [[notes/govru-diagnosis]]: +По алгоритму [[../projects/niikn/govru-quickfix-playbook]]: | Точка | HTTP | Real IP | |-------|------|---------| diff --git a/decisions/2026-04-30-openwrt-homelab-agh-podkop-chain.md b/decisions/2026-04-30-openwrt-homelab-agh-podkop-chain.md index da76302..bb4b2b6 100644 --- a/decisions/2026-04-30-openwrt-homelab-agh-podkop-chain.md +++ b/decisions/2026-04-30-openwrt-homelab-agh-podkop-chain.md @@ -75,6 +75,6 @@ ssh root@10.0.0.1 "cp /etc/adguardhome.yaml.bak.20260430_001129 /etc/adguardhome ## Ссылки - [[../projects/dttb/openwrt-router]] — карточка роутера -- [[../claude-memory/podkop]] — справка по подкопу (схемы AGH, fakeip 198.18.0.0/15) +- [[2026-04-17-peredelki-podkop-stability-fix]] — справка по подкопу (схемы AGH, fakeip 198.18.0.0/15) - https://podkop.net/docs/adguard/ - https://podkop.net/docs/dont-touch-my-dhcp/ diff --git a/decisions/2026-05-02-apple-id-tj-via-residential-proxy.md b/decisions/2026-05-02-apple-id-tj-via-residential-proxy.md index 0771985..ec5739a 100644 --- a/decisions/2026-05-02-apple-id-tj-via-residential-proxy.md +++ b/decisions/2026-05-02-apple-id-tj-via-residential-proxy.md @@ -148,4 +148,4 @@ Grizzlysms TJ-pool **полностью забанен** Apple на текущи - [[../README]] — индекс vault - TODO в MEMORY был «отложено с 2026-04-23», теперь активирован. -- Решение по [[../snippets/clients/]] для US Apple ID на RU iPhone — структурно тот же подход (proxy + foreign SMS). +- Решение по `snippets/clients/` для US Apple ID на RU iPhone — структурно тот же подход (proxy + foreign SMS). diff --git a/projects/dttb/rustdesk.md b/projects/dttb/rustdesk.md index 5db2284..d6dadc6 100644 --- a/projects/dttb/rustdesk.md +++ b/projects/dttb/rustdesk.md @@ -157,7 +157,7 @@ Pre-production audit (2026-04-30) с найденными уязвимостям - **NPM streams через UI/API не публикуются наружу docker-контейнера.** Нужно править compose-файл и пересоздавать контейнер. Compose лежит в `/data/compose/2/docker-compose.yml` на host LXC 103 (мы его положили туда, ранее Portainer хранил только в своём volume). При обновлении stack ВАЖНО: `cd /data/compose/2 && docker compose -p npm up -d` — relative `./data` resolve в `/data/compose/2/data` (где реальные данные NPM). НЕ обновляй stack через Portainer UI — он работает со своей копией compose в `/var/lib/docker/volumes/portainer_data/_data/compose/2/`, может перезаписать. Текущий compose содержит ports: 80, 81, 443, 21115-21119 (TCP+UDP где надо). - **WebClient в браузере** работает на инфра-уровне (wss://remot.dttb.ru:21118/ws/id и :21119/ws/relay → 101 Switching Protocols). TLS termination для 21118/21119 через `/data/compose/2/data/nginx/custom/stream.conf` (custom stream block в NPM с `listen 21118 ssl` + `ssl_certificate /etc/letsencrypt/live/npm-41/...`). Streams 21115/21117/21116-tcp/udp идут через обычные NPM streams (id 38, 39, 40, 43). Чтобы реально использовать — нужны online peers с api-server login. Подключение Mac→Mac через WebClient невозможно (это и есть `MUST_LOGIN`-style ошибка "не удалось подключиться к серверу ретрансляции"). - **community-script может пытаться обновить пакеты** — `apt-mark hold` защищает hbbs/hbbr, но если запустить полный re-run скрипта community-scripts, могут быть сюрпризы. Не запускать без необходимости. -- **`/proc/loadavg` в LXC = нагрузка хоста**, не контейнера ([[../../../knowledge-base/feedback_lxc_loadavg]] в memory). +- **`/proc/loadavg` в LXC = нагрузка хоста**, не контейнера (`feedback_lxc_loadavg` (user memory) в memory). ## Развёртывание клиентов diff --git a/projects/lipki/README.md b/projects/lipki/README.md index f083006..7e962f4 100644 --- a/projects/lipki/README.md +++ b/projects/lipki/README.md @@ -69,7 +69,7 @@ WAN — белый IP, прямой DNAT возможен без хаба `swtes ## Связанные -- [[../znamenskoye/]] — соседний «куст» в Истре, **не путать** +- [[../znamenskoye/README]] — соседний «куст» в Истре, **не путать** - [[../../claude-memory/znamenskoye-ohothozyistvo]] — соседний OpenWrt 100.70.63.67 (Охотхозяйство) - [[../dttb/openwrt-router]] — homelab-роутер, тот же стек (OpenWrt 24.10.3, 1qaz!QAZ) @@ -82,11 +82,11 @@ WAN — белый IP, прямой DNAT возможен без хаба `swtes - [ ] LAN-подсеть и DHCP-диапазон - [ ] Пароль/ключ доступа на сам OpenWrt - [ ] Есть ли DNAT через VPS-хаб или доступ только через NetBird -- [ ] Почему отдельный объект, не часть [[../znamenskoye/]] +- [ ] Почему отдельный объект, не часть [[../znamenskoye/README]] ## Связанные -- [[../znamenskoye/]] — другой объект-«куст» в Истре, **не путать** +- [[../znamenskoye/README]] — другой объект-«куст» в Истре, **не путать** - [[../../claude-memory/znamenskoye-ohothozyistvo]] — соседний OpenWrt 100.70.63.67 (Охотхозяйство) - [[../dttb/netbird-inventory]] — единственный пока источник по Липкам diff --git a/projects/sergey/README.md b/projects/sergey/README.md index 91ba475..9d2b537 100644 --- a/projects/sergey/README.md +++ b/projects/sergey/README.md @@ -25,7 +25,7 @@ aliases: [Sergey, sergey, OpenWrt_Sergey, Одинцово] - [ ] Кто такой Сергей — клиент / друг / семья? - [ ] Точный адрес и контакт -- [ ] Тот ли это Сергей, что управляющий [[../znamenskoye/]] (вероятно НЕТ — там объекты в Истре, этот в Одинцово) +- [ ] Тот ли это Сергей, что управляющий [[../znamenskoye/README]] (вероятно НЕТ — там объекты в Истре, этот в Одинцово) - [ ] Что роутер обслуживает (камеры / IoT / рабочие места) - [ ] LAN, провайдер, белый WAN или CGNAT - [ ] Пароль/ключ доступа diff --git a/scripts/kb-objects-audit.py b/scripts/kb-objects-audit.py index 29754c9..ce5c8fd 100644 --- a/scripts/kb-objects-audit.py +++ b/scripts/kb-objects-audit.py @@ -77,32 +77,42 @@ def check_project_frontmatter(objects: list) -> list[str]: def check_broken_wikilinks(files: list[Path]) -> list[tuple[str, str, str]]: - """Возвращает [(source, link, reason)] для битых [[...]] ссылок.""" + """Возвращает [(source, link, reason)] для битых [[...]] ссылок. + + Проверка только полноценных wiki-ссылок [[...]] (двойная скобка с обеих сторон).""" issues = [] all_basenames = {f.stem for f in files} all_relpaths = {str(f.relative_to(VAULT)).replace(".md", "") for f in files} - pat = re.compile(r"\[\[([^\]\|#]+?)(?:\||#|\])") + # match [[target]] / [[target|alias]] / [[target#anchor]] + pat = re.compile(r"\[\[([^\]\|#\n]+?)(?:[\|#][^\]\n]*)?\]\]") for f in files: + # пропускаем graphify-плагин output и весь audit/ (само-цитирование, autogen) + rel = f.relative_to(VAULT) + if "graphify-out" in rel.parts: + continue + if rel.parts[0] == "audit": + continue + if str(rel) == "CLAUDE.md": + continue # обучающие placeholder'ы вроде [[двойные скобки]] try: text = f.read_text() except Exception: continue for m in pat.finditer(text): - target = m.group(1).strip().rstrip("/") - if not target: + target = m.group(1).strip().rstrip("/").removesuffix(".md") + if not target or target in (".", ".."): continue - # Allow absolute by relpath, or basename match, or relative-resolved + # Allow absolute by relpath, basename, or relative-to-source if target in all_relpaths: continue base = target.split("/")[-1] if base in all_basenames: continue - # try relative to source src_dir = f.parent.relative_to(VAULT) resolved = str(src_dir / target).replace("./", "") if resolved in all_relpaths: continue - issues.append((str(f.relative_to(VAULT)), m.group(0), "→ нет такого файла")) + issues.append((str(rel), m.group(0), "→ нет такого файла")) return issues diff --git a/snippets/clients/yaroslav-amnezia-setup.md b/snippets/clients/yaroslav-amnezia-setup.md index 3237527..933cefd 100644 --- a/snippets/clients/yaroslav-amnezia-setup.md +++ b/snippets/clients/yaroslav-amnezia-setup.md @@ -163,7 +163,7 @@ vpn://AAAIYXjanVVdcpswEH7PKTyevjl1QNiAM5MH100T4vwY06ZpQscjg-yoIYKAbMfN5Ay9RI_Qh8 ### Как отозвать у Ярослава -1. SSH на сервер (см. [[../../projects/dttb/vpn-clients]] → Finland → [[feedback_finland_security]]) +1. SSH на сервер (см. [[../../projects/dttb/vpn-clients]] → Finland → `feedback_finland_security` (user memory)) 2. Найти peer Ярослава в `/opt/amnezia/…/wg0.conf` или в amnezia-docker-контейнере 3. Удалить `[Peer]` блок → `wg syncconf wg0 <(wg-quick strip wg0)` 4. Отметить в таблице: «Отозван: YYYY-MM-DD»