From 68a8291500c9480d165b99260dd43adb5e32a0a9 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Wed, 13 May 2026 00:57:52 +0600 Subject: [PATCH] [2026-05-13] obsidian sync docs: obsidian-sync.md created, kraken plan updated, truenas-infra + architecture cross-referenced --- family/how-to/obsidian-sync.md | 110 ++++++++++++++++++++++++ family/how-to/openmediavault-rpi5.md | 94 ++++++++------------ family/how-to/truenas-infrastructure.md | 35 ++++++++ wiki/personal-os-architecture.md | 35 +++++++- 4 files changed, 211 insertions(+), 63 deletions(-) create mode 100644 family/how-to/obsidian-sync.md diff --git a/family/how-to/obsidian-sync.md b/family/how-to/obsidian-sync.md new file mode 100644 index 00000000..7313ffa1 --- /dev/null +++ b/family/how-to/obsidian-sync.md @@ -0,0 +1,110 @@ +--- +tags: + - obsidian + - sync + - git + - how-to +created: '2026-05-13' +updated: '2026-05-13' +status: active +--- +# Obsidian Sync — Eagle ↔ Taiga ↔ Kraken + +**Статус:** ✅ работает на всех 3 узлах (протестировано 2026-05-13, двусторонний sync с конфликтами) + +## Архитектура + +``` +Eagle (Mac, ~/obsidian — полный vault) + │ push/pull via SSH + ▼ +TrueNAS bare repo +mallexxx.duckdns.org:/mnt/RED_2TB/storage/git/obsidian-vault.git + │ + ├── Taiga (sparse: personal/ family/) + │ vault: /mnt/RED_2TB/docker/hermes/vault + │ скрипт на хосте TrueNAS: ~/sync-vault.sh + │ + └── Kraken (sparse: personal/ family/) + vault: ~/obsidian + скрипт: ~/scripts/sync-vault.sh +``` + +## Узлы + +| Узел | Vault путь | Scope | Скрипт | Крон | +|------|-----------|-------|--------|------| +| Eagle | `~/obsidian` | full vault | `~/scripts/sync-vault.sh` | `0 * * * *` (Hermes cron job) | +| Kraken | `~/obsidian` | sparse: `personal/ family/` | `~/scripts/sync-vault.sh` | `0 * * * *` (crontab) | +| Taiga | `/mnt/RED_2TB/docker/hermes/vault` | sparse: `personal/ family/` | `~/sync-vault.sh` (на хосте!) | `0 * * * *` (Hermes cron job) | + +> ⚠️ **Taiga**: скрипт запускается на **хосте TrueNAS** (не внутри контейнера hermes-taiga). +> Причина: ZFS ACL дают доступ к bare repo только пользователю `truenas_admin`. +> Vault примонтирован в контейнер как `/vault:rw` из `/mnt/RED_2TB/docker/hermes/vault`. + +## Логика sync (одинакова на всех 3) + +``` +1. git stash (если есть локальные изменения) +2. git fetch origin main +3. git merge origin/main --no-edit + └─ при конфликте: git add -A, PULL_OK=conflict +4. git stash pop (если был stash) + └─ при конфликте pop: git add -A +5. git add -A && git commit (если есть изменения — staged ИЛИ unstaged ИЛИ untracked) +6. git push origin main +``` + +**Конфликты:** не теряются — остаются в файлах как conflict markers, коммитятся с пометкой `"conflict markers present"`. Ручного разрешения не требуется для текстовых заметок. + +## Скрипты — детали + +### Eagle: `~/scripts/sync-vault.sh` +- Дополнительно: генерирует commit message через `claude -p` (если claude доступен) +- Remote name: `nas` (не `origin`) +- git user: глобальный (`admin@eagle`) + +### Kraken: `~/scripts/sync-vault.sh` +- git user задан в скрипте: `kraken@hermes` / `Kraken` +- Переменные: `VAULT_DIR` (default: `~/obsidian`), `REMOTE_URL` (default: `origin`) +- Sparse checkout: `personal/ family/` (задан при инициализации vault) + +### Taiga: `~/sync-vault.sh` +- git user задан в скрипте: `taiga@hermes` / `Taiga` +- `git config core.fileMode false` — ZFS не сохраняет exec bits +- Hardcoded paths: vault=`/mnt/RED_2TB/docker/hermes/vault`, remote=`file:///mnt/RED_2TB/storage/git/obsidian-vault.git` + +## SSH ключи + +| Узел | Ключ | Добавлен в authorized_keys | +|------|------|--------------------------| +| Eagle | `~/.ssh/id_rsa` | ✅ TrueNAS (`truenas_admin`) | +| Kraken | `~/.ssh/id_rsa` | ✅ TrueNAS (`truenas_admin`) | +| Taiga | file:// (локальный) | — (не нужен) | + +## Obsidian MCP + +| Узел | Команда | Vault | +|------|---------|-------| +| Eagle | `/opt/homebrew/bin/obsidian-mcp ~/obsidian` | full | +| Kraken | `npx obsidian-mcp /home/kraken/obsidian` | sparse | +| Taiga | `npx obsidian-mcp /vault` | sparse (контейнерный путь) | + +## Диагностика + +```bash +# Проверить последний sync +ssh kraken@192.168.1.14 "tail -5 /tmp/vault-sync.log" +ssh truenas_admin@mallexxx.duckdns.org "tail -5 /tmp/vault-sync.log" + +# Запустить sync вручную +ssh kraken@192.168.1.14 "bash ~/scripts/sync-vault.sh" +ssh truenas_admin@mallexxx.duckdns.org "bash ~/sync-vault.sh" + +# Посмотреть историю коммитов в bare repo +ssh truenas_admin@mallexxx.duckdns.org "git -C /mnt/RED_2TB/storage/git/obsidian-vault.git log --oneline -10" +``` + +## Связанные заметки +- [[openmediavault-rpi5]] — Kraken NAS setup (шаги 11–12) +- [[truenas-infrastructure]] — TrueNAS инфраструктура, bare repo, ACL diff --git a/family/how-to/openmediavault-rpi5.md b/family/how-to/openmediavault-rpi5.md index e9dd7506..1986946c 100644 --- a/family/how-to/openmediavault-rpi5.md +++ b/family/how-to/openmediavault-rpi5.md @@ -28,8 +28,8 @@ ip: 192.168.1.14 | 8 — Контейнеры | ✅ | Все через отдельные docker compose, конфиги на HDD (см. ниже) | | 9 — Time Machine share | ✅ | `mbentley/timemachine:smb`, расписание 10:00-22:00 GMT+6, HDD/timemachine | | 10 — Перенос данных | 🔲 | | -| 11 — Hermes агент Кракен | 🚧 | Билд готов, entrypoint проблема решается, нужно: HA token (отложено), docker compose up | -| 12 — Obsidian sync (Taiga↔Kraken↔Eagle) | 🚧 | Скрипты готовы, cron Eagle запущен (hourly). Кракен/Тайга — деплой pending | +| 11 — Hermes агент Кракен | ✅ | Запущен, Telegram @kraken_htpc_bot живой, obsidian-mcp подключён | +| 12 — Obsidian sync (Taiga↔Kraken↔Eagle) | ✅ | Все 3 узла работают, кроны активны, двусторонний sync протестирован | | 13 — Vault wiki (llm-wiki) | 🔲 | Eagle: scheduled wiki-curation job, Karpathy-style | --- @@ -243,93 +243,69 @@ rsync -avh --progress /path/to/movies/ kraken@kraken.local:/srv/.../media/movies ## Шаг 11 — Hermes агент Кракен +**Статус: ✅ запущен (2026-05-12)** + ### Файлы ``` /home/kraken/hermes/ Dockerfile — образ на базе node:20-slim + hermes-agent + obsidian-mcp - docker-compose.yml — restart: unless-stopped, network_mode: host - .env — API ключи (заполнить вручную) - config.yaml → копируется в /srv/.../docker/hermes/config/config.yaml + docker-compose.yml — restart: unless-stopped, network_mode: host, HERMES_ALLOW_ROOT=1 + .env — API ключи + config.yaml → /srv/.../docker/hermes/config/config.yaml ``` -### Модели (проверено 2026-05-12) -Бесплатные модели с tool calling на OpenRouter: +### Модели (актуально 2026-05-12) | Модель | Статус | |--------|--------| -| `nvidia/nemotron-3-super-120b-a12b:free` | ✅ работает | -| `openrouter/free` | ✅ fallback (авто-роутинг) | -| `deepseek/deepseek-chat-v3-0324:free` | ❌ 404 | -| `qwen/qwen3-235b-a22b:free` | ❌ 404 | -| `google/gemma-4-31b-it:free` | ❌ 429 rate limit | - -**Primary**: `nvidia/nemotron-3-super-120b-a12b:free` (262K ctx, tools ✅) -**Auxiliary/Fallback**: `openrouter/free` -**Рекомендуется**: добавить `GOOGLE_API_KEY` → Gemini Flash как auxiliary +| `openai/gpt-oss-120b:free` | ✅ primary | +| `minimax/minimax-m2.5:free` | ✅ fallback | ### Telegram бот -- Имя: Кракен -- Bot: [@kraken_htpc_bot](https://t.me/kraken_htpc_bot) -- Token: `8750114596:AAH625OBSdb_Bn7ZSwshjDD3mbENnkSRYag` +- Имя: Кракен / Bot: [@kraken_htpc_bot](https://t.me/kraken_htpc_bot) ### Toolsets -`hermes-cli, terminal, file, web, web_crawler, memory, spotify, homeassistant` +`hermes-cli, terminal, file, web, memory, spotify, homeassistant` -### Деплой (после заполнения .env) +### MCP серверы +| Server | Команда | Vault | +|--------|---------|-------| +| obsidian | `npx obsidian-mcp /home/kraken/obsidian` | `~/obsidian` (sparse: personal/ + family/) | + +### Деплой ```bash -# Заполнить ключи: -nano /home/kraken/hermes/.env -# OPENROUTER_API_KEY=sk-or-... -# GOOGLE_API_KEY=... -# HASS_TOKEN=... (создать в HA UI → Profile → Long-Lived Access Tokens) - -# Собрать и запустить: cd /home/kraken/hermes -sudo docker compose build +sudo docker compose build # ~82 сек на RPi5 sudo docker compose up -d - -# Проверить: sudo docker logs hermes-kraken --tail 20 ``` ### TODO -- [ ] Заполнить .env (OPENROUTER_API_KEY, GOOGLE_API_KEY) -- [ ] Настроить HA → создать Long-Lived token → вписать в HASS_TOKEN -- [ ] Собрать и запустить контейнер -- [ ] Настроить obsidian-mcp (vault path = /vault) -- [ ] Перенести Spotify auth с Eagle (или запарить заново) +- [ ] Настроить HA → создать Long-Lived token → вписать в HASS_TOKEN в .env +- [ ] Перенести Spotify auth (или запарить заново) --- ## Шаг 12 — Obsidian sync (Eagle ↔ Taiga ↔ Kraken) -**Схема:** Git bare repo на TrueNAS как центральный хаб. +**Статус: ✅ работает на всех 3 узлах (протестировано 2026-05-13)** +Подробная документация: [[obsidian-sync]] + +**Схема:** ``` -Eagle (полный vault) ──push/pull──┐ -Taiga (personal/ family/) ────────├── TrueNAS bare repo (git) -Kraken (personal/ family/) ────────┘ +Eagle (полный vault ~/obsidian) ──push/pull──┐ +Taiga (sparse: personal/ family/) ────────────├── TrueNAS bare repo +Kraken (sparse: personal/ family/) ───────────┘ mallexxx.duckdns.org:/mnt/RED_2TB/storage/git/obsidian-vault.git ``` -**Скрипты:** -- Eagle: `~/scripts/sync-vault.sh` — full vault, pull→stash→push каждый час -- Taiga/Kraken: `~/scripts/sync-vault.sh` (partial) — sparse checkout `personal/ family/`, та же схема +**Скрипты и кроны:** +| Узел | Скрипт | Крон | Vault | +|------|--------|------|-------| +| Eagle | `~/scripts/sync-vault.sh` | `0 * * * *` | `~/obsidian` (full) | +| Kraken | `~/scripts/sync-vault.sh` | `0 * * * *` | `~/obsidian` (sparse) | +| Taiga | `~/sync-vault.sh` (на хосте!) | Hermes cron `0 * * * *` | `/mnt/RED_2TB/docker/hermes/vault` (sparse) | -**Логика конфликтов:** -1. `git stash` локальных изменений -2. `git pull` (merge) -3. При конфликте — оставить conflict markers, `git stash pop` -4. Коммит с пометкой "conflict markers present" -5. `git push` - -**Eagle cron:** job `b8d6cd6c97f6` (`sync-vault`), каждый час, `0 * * * *` — ✅ активен - -**Taiga/Kraken:** `~/scripts/sync-vault.sh` — деплой pending (нужен SSH ключ крякена на TrueNAS) - -**TODO:** -- [ ] Добавить SSH ключ Кракена в authorized_keys на TrueNAS -- [ ] Деплой sync-vault.sh на Кракен + cron (hourly) -- [ ] Деплой sync-vault.sh на Тайгу + cron (hourly) -- [ ] Инициализировать sparse checkout на Кракене: `VAULT_DIR=/vault REMOTE_URL=ssh://truenas_admin@mallexxx.duckdns.org/mnt/RED_2TB/storage/git/obsidian-vault.git bash sync-vault.sh` +> ⚠️ Тайга: скрипт запускается на **хосте TrueNAS** (не внутри контейнера) — только truenas_admin имеет ZFS ACL доступ к bare repo. ## Шаг 13 — Vault wiki (llm-wiki / Karpathy approach) diff --git a/family/how-to/truenas-infrastructure.md b/family/how-to/truenas-infrastructure.md index 0fab0075..fa26852b 100644 --- a/family/how-to/truenas-infrastructure.md +++ b/family/how-to/truenas-infrastructure.md @@ -115,6 +115,41 @@ TrueNAS использует **NFSv4 ACL**, а не стандартный POSIX | cam.mallexxx.duckdns.org | Камера :8090 | | docs.mallexxx.duckdns.org | Docs :8000 | +## Hermes-Taiga агент + +| Параметр | Значение | +|----------|----------| +| Контейнер | `hermes-taiga` | +| Telegram | через общий токен | +| Vault (хост) | `/mnt/RED_2TB/docker/hermes/vault` | +| Vault (контейнер) | `/vault:rw` | +| obsidian-mcp | `npx obsidian-mcp /vault` | +| Scope | sparse: `personal/ + family/` | + +## Obsidian Sync (Taiga) + +**Скрипт:** `~/sync-vault.sh` (запускается на **хосте**, не в контейнере) +**Крон:** Hermes cron job `0 * * * *` +**Bare repo:** `file:///mnt/RED_2TB/storage/git/obsidian-vault.git` +**Лог:** `/tmp/vault-sync.log` + +```bash +# Запустить sync вручную: +bash ~/sync-vault.sh + +# Посмотреть лог: +tail -20 /tmp/vault-sync.log + +# История коммитов: +git -C /mnt/RED_2TB/storage/git/obsidian-vault.git log --oneline -10 +``` + +> ⚠️ Скрипт запускается от `truenas_admin` — только этот пользователь имеет ZFS ACL доступ к bare repo и vault папке. + +Подробности: [[obsidian-sync]] + ## Связанные заметки - [[truenas-access]] — SSH-доступ - [[truenas-rclone-backup]] — система бэкапов +- [[obsidian-sync]] — Obsidian sync Eagle ↔ Taiga ↔ Kraken +- [[openmediavault-rpi5]] — Kraken NAS (Hermes агент, sync) diff --git a/wiki/personal-os-architecture.md b/wiki/personal-os-architecture.md index 2325a1ce..67cae32b 100644 --- a/wiki/personal-os-architecture.md +++ b/wiki/personal-os-architecture.md @@ -26,7 +26,32 @@ See: `personal-os-purpose.md` - Logs corrections to `corrections_log` table (SQL INSERT, silently on pushback) - **Never accesses Asana API directly** — only reads pre-rendered markdown and DB -### Ретроспектор (Retrospector) — Friday pattern analysis +### Кракен (Kraken) — home NAS agent +- Hermes на RPi 5, Telegram @kraken_htpc_bot +- Toolsets: `hermes-cli, terminal, file, web, memory, spotify, homeassistant` +- Models: `openai/gpt-oss-120b:free` (primary), `minimax/minimax-m2.5:free` (fallback) +- obsidian-mcp: `npx obsidian-mcp /home/kraken/obsidian` → sparse vault `personal/ + family/` +- Vault sync: `~/scripts/sync-vault.sh`, cron `0 * * * *`, pulls/pushes via SSH → TrueNAS bare repo +- Config: `/home/kraken/hermes/`, data on HDD `/srv/dev-disk-by-uuid-49e8f586-.../docker/hermes/` + +### Тайга (Taiga) — TrueNAS agent +- Hermes в Docker контейнере `hermes-taiga` на TrueNAS +- obsidian-mcp: `npx obsidian-mcp /vault` → sparse vault `personal/ + family/` +- Vault sync: `~/sync-vault.sh` на **хосте** TrueNAS (не в контейнере), cron `0 * * * *` +- Vault (хост): `/mnt/RED_2TB/docker/hermes/vault`, (контейнер): `/vault:rw` + +### Vault Sync Pipeline +``` +Eagle ~/obsidian (full) ──SSH push/pull──┐ +Taiga /vault (sparse) ──file:// ───────├── TrueNAS bare repo +Kraken ~/obsidian (sparse) ──SSH ────────┘ /mnt/RED_2TB/storage/git/obsidian-vault.git +``` +- Все 3 узла: stash → fetch → merge → stash pop → commit → push (hourly) +- Конфликты: сохраняются как markers, не теряются +- Eagle commit message: генерируется через `claude -p` +- Подробности: `family/how-to/obsidian-sync.md` + + - Runs as separate Hermes cron at 17:30 Friday → `#retrospector` - Sources: corrections_log table, status.md subtask counts, obsidian git log, activity_daily quadrants, stories visibility metric - Prompt: `~/Developer/personal-os/agent/prompts/retrospector.md` @@ -123,9 +148,11 @@ Executor runs ## MCP Servers **Hermes agents:** -| Name | Command | Used for | -|------|---------|---------| -| obsidian | `/opt/homebrew/bin/obsidian-mcp ~/obsidian` | Vault search, read, write | +| Name | Command | Used for | Node | +|------|---------|---------|------| +| obsidian | `/opt/homebrew/bin/obsidian-mcp ~/obsidian` | Vault search, read, write | Eagle | +| obsidian | `npx obsidian-mcp /home/kraken/obsidian` | Vault search, read, write | Kraken | +| obsidian | `npx obsidian-mcp /vault` | Vault search, read, write | Taiga | **Claude Code / `claude -p` sessions:** | Name | Command | Used for |