Files
knowledge-base/decisions/2026-05-06-kb-search-overhaul.md
dttb 1748562756 Decision: сводка по перестройке KB-поиска (8 фаз)
Один артефакт-агрегатор: метрики до/после, грабли, отложенное, ссылки
на все промежуточные decisions/snippets. Чтобы не прыгать по разным
файлам — единая точка входа для повторного чтения.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 16:46:05 +03:00

102 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
date: 2026-05-06
type: decision
tags: [kb, openclaw, search, fts, infra, summary]
status: applied
---
# Перестройка KB-поиска и синхронизации (8 фаз за один день)
## Что было до
Запрос «OpenWRT Липки» Максимке возвращал `netbird-inventory.md`, потому что:
- слова «Липки» во всём vault'е была одна строка в табличке инвентаря,
- слово «OpenWRT» статистически перевешивали НИИКН-документы (`govru-quickfix`, `niikn-openwrt-awg-fix`),
- кросс-ссылок и aliases не было, embeddings не было,
- лаг push→бот доходил до 16 минут (cron `*/5` Mac→Gitea + cron `*/15` Gitea→openclaw).
Пользователь жаловался: «бот путает, я ему про Липки, он мне про НИИКН».
## Что сделано
| Фаза | Эффект |
|---|---|
| 1. Embeddings (ollama+bge-m3) | ⛔ откачено — openclaw 2026.5.2 при `provider: ollama` шлёт inputs целиком, ollama тратит >5 мин/запрос, undici fetch валится по headers timeout. ollama на LXC 132 готова (uptime, bge-m3 1024d), но сторона openclaw нуждается в фиксе chunking |
| 2. Webhook + auto-reindex | Gitea push→listener (HMAC SHA-256)→`kb-pull.sh``openclaw memory index`. **push→FTS: 15 мин → 50 c**. См. [[../snippets/openclaw-kb-webhook]] и [[2026-05-06-openclaw-kb-webhook-deployment]] |
| 3. objects-map.json + _index.md | Скрипт `scripts/kb-objects-map.py` парсит netbird-inventory + frontmatter и пишет JSON для бота + human-readable [[../projects/_index]]. Базовый структурный слой |
| 4. Stubs + frontmatter | Создано 6 README (`znamenskoye`, `mmfb`, `lipki` уже был, + 4 stub'а клиентских OpenWrt). Обогащён frontmatter в `niikn`, `dttb`, `glavtorg`, `krasnogorsk`, `zelenograd` с aliases для netbird-имён. **38 → 14 orphan-пиров** |
| 5.1. Слить дубли видео | Удалён `dttb/video-surveillance-report.md` (297 строк, неполная копия), canonical `videonablyudenie-znam.md` обогащён aliases |
| 5.2. Архив audit/ | 18 устаревших drift-отчётов 2026-04-* перенесены в `audit/archive/`, в active остались 7 свежих |
| 6. Recall + dreaming | `openclaw memory promote --apply`: 17/39 коротких воспоминаний переехали в долгую. `dreaming.enabled=true` (cron `0 3 * * *`). Weekly cron на promote |
| 7. Расширенный kb-audit | Скрипт `scripts/kb-objects-audit.py` пишет еженедельный отчёт с score: проверяет frontmatter, online-orphans, битые wiki-ссылки. Первый запуск — score=84 (12/12 frontmatter ✓, 3 online orphan, 26 битых wiki) |
| 8. UX бота | `memorySearch.query.minScore=0.4`, IDENTITY.md разводит двух Максимок (homelab vs НИИКН), INFRASTRUCTURE.md переписан как навигатор по vault'у |
## Метрики до / после
| Параметр | До | После |
|---|---|---|
| «OpenWRT Липки» top-1 | `netbird-inventory.md` ❌ | `projects/lipki/README.md` ✅ |
| «Антон клиент Звенигород» top-1 | ничего | `projects/lipki/README.md` ✅ |
| «AgentDVR ЧОП Знаменское» top-1 | три дубля | `videonablyudenie-znam.md` ✅ |
| «Константин Вишневый сад» top-1 | `netbird-inventory.md` | `projects/vishnevyy-sad/README.md` ✅ |
| Лаг push → видно боту | 516 мин | **~50 секунд** |
| Проектов с netbird-привязкой | 0 | **9** |
| Структурный объект-граф | нет | `objects-map.json` (34 entries) |
| Online orphan-пиров | ~30+ | **3** |
| Auto-reindex после pull | нет | есть |
| Recall promoted | 0 (mёртв 16 дней) | 17 + weekly cron |
| Dreaming | off | on (ночной cron) |
| FTS-шум audit/ | 24 файла | 7 active + 18 в archive |
## Грабли (для будущей памяти)
1. **Gitea SSRF-protection.** Без `webhook.ALLOWED_HOST_LIST` в `app.ini` Gitea silently отказывает доставлять webhook на private IP. В docker-логах: `webhook can only call allowed HTTP servers, deny '10.0.0.239'`. Listener при этом получает 0 запросов, journal пустой.
2. **`flock -n` теряет двойные push.** Если webhook прилетел во время pull/reindex — non-blocking lock молча выходит. Заменить на `flock -w 180`.
3. **openclaw 2026.5.2 ollama-провайдер игнорирует chunking.** При `provider: ollama` шлёт файлы целиком в `/api/embed`, ollama buffer растёт до 700 MB, обработка >5 мин, fetch валится. Не лечится `chunking.tokens=512`, `nonBatchConcurrency=1`, `batch.enabled=false`. Bug либо в openclaw, либо неочевидный конфиг-флаг.
4. **substring matching → false positives.** Alias `cloud` подхватывал `Cloud-NIIKN New niikn.com`. Перешли на exact-match с нормализацией `ye→e`. Aliases теперь должны содержать **полные** имена пиров как в netbird-inventory.
5. **Heredoc через ssh с backticks** — bash интерпретирует backticks как command-substitution внутри пути файла. Для записи структурных markdown'ов с inline-кодом — пушить через base64 или scp/pct push, не heredoc.
6. **`git commit` без `-a` или явного `git add`** забирает только staged. Удаление через `git rm` помечается автоматом, а modify — нет. Один коммит может оставить часть правок несинхронизированными — дополнительный коммит лечит.
## Что отложено
| Задача | Причина | Когда возвращаться |
|---|---|---|
| Векторный поиск через ollama | bug в openclaw 2026.5.2 ollama-провайдере | при апгрейде openclaw, или попробовать `provider: local` (transformers.js встроен в openclaw) |
| 14 orphan-пиров (Денис Тихая, DESKTOP-2IOQS54 Saransk, KOMPUTER, MastaNotebook, …) | нужны факты от Олега чьи это машины | по мере выяснения — добавлять в aliases подходящих проектов |
| 26 битых wiki-ссылок | автоматический фикс не всегда возможен (некоторые цели реально удалены) | semi-auto проход: показать список, для очевидных — починить, остальное — оставить TODO |
| Singleton-проекты (`projects/*.md`) без frontmatter | не критично — они top-level note'ы | при касании |
## Артефакты в vault
- [[../projects/lipki/README]], [[../projects/znamenskoye/README]], [[../projects/mmfb/README]]
- [[../projects/sergey/README]], [[../projects/benilux/README]], [[../projects/vishnevyy-sad/README]], [[../projects/openwrt-4/README]]
- [[../projects/_index]] — авто-генерированный реестр
- `audit/objects-map.json` — машинно-читаемый граф
- [[../audit/2026-05-06-objects-audit]] — первый health-check
- `scripts/kb-objects-map.py`, `scripts/kb-objects-audit.py`
- [[../snippets/openclaw-kb-webhook]]
- [[2026-05-06-openclaw-kb-webhook-deployment]]
- frontmatter добавлен в `projects/{niikn,dttb,glavtorg,krasnogorsk,zelenograd}/README.md`
## Артефакты вне vault
**LXC 137 (openclaw):**
- `/usr/local/bin/kb-pull-webhook.py` (Python listener, HMAC)
- `/etc/systemd/system/kb-pull-webhook.service`
- Обновлённый `/usr/local/bin/kb-pull.sh` (`flock -w 180`, hash-diff, auto-reindex)
- Cron `0 4 * * 1` weekly memory promote
- Config: `memorySearch.query.minScore=0.4`, `dreaming.enabled=true`, ollama-провайдер откачен (бэкап `/root/.openclaw/openclaw.json.bak.embed-2026-05-06-112441`)
- Переписаны `/root/clawd/IDENTITY.md`, `INFRASTRUCTURE.md`
**LXC 136 (Gitea):**
- `webhook.ALLOWED_HOST_LIST = 10.0.0.0/24,*.dttb.ru,private` в `/opt/gitea/data/gitea/conf/app.ini`
- Webhook id=1 на репо `oleg/knowledge-base`
**LXC 132 (code-server):**
- ollama systemd override `OLLAMA_HOST=0.0.0.0:11434, KEEP_ALIVE=24h` (для будущего возврата к embeddings)