From 787ad01cffb1aa5b786bc18292b30cab4a295abb Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 15 Sep 2026 11:37:04 +0600 Subject: [PATCH] =?UTF-8?q?[2026-09-15]=20vault-sync:=20=D0=BE=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=20README.md=20(?= =?UTF-8?q?=D0=BA=D0=B0=D0=BA=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5?= =?UTF-8?q?=D1=82,=20=D0=BA=D0=B0=D0=BA=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D1=82=D1=8C=20=D1=81=D0=B8=D0=BD=D0=BA=20=D1=80?= =?UTF-8?q?=D1=83=D0=BA=D0=B0=D0=BC=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2026-09-14-cron-api-timeout-sync-outage.md | 1 + family/documents/vault-sync/README.md | 129 ++++++++++++++++++ family/how-to/ha-automations.md | 1 + family/how-to/home-automation.md | 1 + family/how-to/vault-sync-pipeline.md | 128 +++++++++++++++++ 5 files changed, 260 insertions(+) create mode 100644 family/documents/vault-sync/README.md create mode 100644 family/how-to/vault-sync-pipeline.md diff --git a/family/documents/vault-sync/2026-09-14-cron-api-timeout-sync-outage.md b/family/documents/vault-sync/2026-09-14-cron-api-timeout-sync-outage.md index 8f1e4d2c..8d7e5b20 100644 --- a/family/documents/vault-sync/2026-09-14-cron-api-timeout-sync-outage.md +++ b/family/documents/vault-sync/2026-09-14-cron-api-timeout-sync-outage.md @@ -102,5 +102,6 @@ EOF **Вывод:** это аргумент за `--no-agent --script` (пункт 1 ниже) — LLM в петле не только блокирует очередь таймаутами, но и в ~6 % случаев просто не вызывает команду. ## Связанные заметки +- [[family/how-to/vault-sync-pipeline]] — архитектура трёх звеньев, ручной прогон, питфолл `origin → /vault.git` - [[2026-09-02-dubious-ownership-and-merge-cleanup]] — предыдущий инцидент sync (dubious ownership /vault.git) - [[2026-08-31-syncthing-truenas-incident]] diff --git a/family/documents/vault-sync/README.md b/family/documents/vault-sync/README.md new file mode 100644 index 00000000..f6fbc2cf --- /dev/null +++ b/family/documents/vault-sync/README.md @@ -0,0 +1,129 @@ +--- +title: "🔄 Vault sync — как работает и как запустить" +tags: [vault-sync, infrastructure, obsidian, syncthing, taiga] +updated: 2026-09-15 +--- + +# 🔄 Vault sync — как работает и как запустить + +> **Операционный документ.** Как правка из vault доезжает до телефона и что делать, если не доехала. +> Инциденты — в этой же папке `family/documents/vault-sync/`. + +--- + +## 1. Архитектура + +``` + Mac ~/obsidian ──git push──▶ bare: /mnt/RED_2TB/storage/git/obsidian-vault.git + (IS the remote, /vault.git внутри контейнера) + │ + │ git merge + ▼ + ┌──────────────────────────────────────────────────────────┐ + │ контейнер hermes-taiga · /opt/data/sync-vault.sh │ + │ ТРИ фазы: │ + │ ① taiga → /vault = .../storage/obsidian │ + │ ② syncthing → /obsidian-syncthing ← SyncThing → 📱 │ + │ ③ syncthing-out → push обратно в bare │ + └──────────────────────────────────────────────────────────┘ +``` + +**Спайс:** `/vault` — sparse-checkout (`personal/`, `family/`, `.obsidian/`). Пуш из taiga-фазы — только эти пути. + +| Путь | Что это | +|---|---| +| `~/obsidian` (Mac) | рабочий клон vault (править тут) | +| `/mnt/RED_2TB/storage/git/obsidian-vault.git` | **bare-репозиторий = remote** | +| `/mnt/RED_2TB/storage/obsidian` | `/vault` — taiga-воркtree (sparse) | +| `/mnt/RED_2TB/storage/obsidian-syncthing` | **раздаётся SyncThing'ом на телефон** | +| `/opt/data/sync-vault.sh` (в контейнере) | сам скрипт синка | + +--- + +## 2. 🔴 ГЛАВНОЕ: `git push` НЕ доводит правку до телефона + +**Факт, стоивший времени 2026-09-15.** Пуш на bare — это только полдела. До телефона доводит **cron-скрипт `sync-vault.sh` внутри контейнера `hermes-taiga`**. + +Если после правки телефона не видно — **причина почти всегда в этом**: синк не прогонялся. + +--- + +## 3. Запустить синк вручную + +```bash +ssh truenas_admin@mallexxx.duckdns.org \ + 'docker exec hermes-taiga bash /opt/data/sync-vault.sh 2>&1 | tail -20' +``` + +**Признак успеха** — три строки: +``` +[] [taiga] ... Pushed ✓ +[] [syncthing] Syncthing: synced with bare repo ✓ / Pushed ✓ +[] [syncthing-out] Pushed ✓ +``` + +**Если не видишь — SyncThing раздаст в течение минуты.** + +--- + +## 4. Cron-задача + +| Параметр | Значение | +|---|---| +| Название | `sync-vault` | +| id | `29851c413903` | +| Расписание | `*/5 * * * *` | +| prompt | `bash /opt/data/sync-vault.sh >> /tmp/vault-sync.log 2>&1` | +| Живёт | в контейнере `hermes-taiga` (не на Mac!) | +| Лог | `/tmp/vault-sync.log` (в контейнере) | + +> ⚠️ Задача оформлена как **prompt** (LLM-раунд), поэтому наследует риски провайдера: таймауты блокируют очередь, а ~6 % тиков завершаются `completed` **без запуска скрипта**. Данные не теряются (git идемпотентен), но каденция ниже номинала. Разбор — [[2026-09-14-cron-api-timeout-sync-outage]]. + +**Смотреть лог:** +```bash +ssh truenas_admin@mallexxx.duckdns.org 'docker exec hermes-taiga tail -12 /tmp/vault-sync.log' +``` + +--- + +## 5. Проверить, что всё сошлось + +Все три репозитория должны быть на **одном коммите**: + +```bash +ssh truenas_admin@mallexxx.duckdns.org ' +cd /mnt/RED_2TB/storage/obsidian-syncthing && echo -n "syncthing: " && git log --oneline -1 +cd /mnt/RED_2TB/storage/obsidian && echo -n "vault: " && git log --oneline -1 +cd /mnt/RED_2TB/storage/git/obsidian-vault.git && echo -n "bare: " && git log --oneline -1 main +' +``` + +На Mac: `cd ~/obsidian && git log --oneline -1` + +**Рабочие деревья должны быть чистыми:** `git status --porcelain` → пусто. + +--- + +## 6. Скрипт `sync-vault-taiga.sh` (локальная копия) + +Локальная копия для чтения: `~/.hermes/hermes-whale/sync-vault-taiga.sh` (3342 б, 2026-05-29). +Описание из шапки скрипта: +- `taiga@hermes` — пушит Hermes-агент +- `syncthing@hermes` — пушит телефон через SyncThing +- `core.fileMode false` (иначе chmod-варнинги root vs UID 950 на ZFS) + +**Что делает по шагам:** +1. **taiga:** коммит локальных изменений → `git merge main` (сюда пушит Eagle) → коммит → push в bare. +2. **syncthing:** коммит локальных (от телефона) → `git fetch origin main` → `merge origin/main` → `push origin main`. +3. **syncthing-out:** финальный push. + +Конфликты скрипт **не разрешает** — оставляет маркеры и коммитит (осознанное решение). + +--- + +## Связанные + +- [[family/documents/vault-sync/2026-09-14-cron-api-timeout-sync-outage]] — разрыв синка из-за таймаутов LLM +- [[family/documents/vault-sync/2026-09-04-git-identity-loss-silent-commit-failure]] — потеря git-identity +- [[family/documents/vault-sync/2026-08-31-syncthing-truenas-incident]] — инцидент SyncThing +- [[family/how-to/truenas-infrastructure]] — инфраструктура TrueNAS diff --git a/family/how-to/ha-automations.md b/family/how-to/ha-automations.md index fc406116..70978422 100644 --- a/family/how-to/ha-automations.md +++ b/family/how-to/ha-automations.md @@ -122,3 +122,4 @@ curl -s -X POST -H @/tmp/h1 -H "Content-Type: application/json" \ - [[family/how-to/home-automation]] — единый справочник: топология, железо, Zigbee, Modbus, команды, сценарии, питфоллы - [[family/documents/home-automation-wishlist]] — роадмап идей и приоритетов +- [[family/how-to/vault-sync-pipeline]] — правки в vault не доедут до телефона без прогона sync-петли diff --git a/family/how-to/home-automation.md b/family/how-to/home-automation.md index 2c3fe026..3e91f697 100644 --- a/family/how-to/home-automation.md +++ b/family/how-to/home-automation.md @@ -9,6 +9,7 @@ updated: 2026-09-15 > **Единственный справочник по домашней автоматизации.** Всё: топология, железо, Zigbee, Modbus, доступ, команды, сценарии, питфоллы. > **Автоматизации** (16 шт., логика, дефекты) — [[family/how-to/ha-automations]]. +> 📄 Правка этой доки не появится на телефоне после `git push` — нужен прогон sync-петли: [[family/how-to/vault-sync-pipeline]]. --- diff --git a/family/how-to/vault-sync-pipeline.md b/family/how-to/vault-sync-pipeline.md new file mode 100644 index 00000000..644e63d8 --- /dev/null +++ b/family/how-to/vault-sync-pipeline.md @@ -0,0 +1,128 @@ +--- +title: "Vault sync — архитектура и ручной прогон" +aliases: [vault-sync, синк vault, sync-vault.sh, телефон не видит vault] +tags: [family, how-to, vault, sync, syncthing, cron] +created: 2026-09-15 +updated: 2026-09-15 +--- + +# Vault sync — архитектура и ручной прогон + +> **Зачем документ:** правки в vault (Obsidian) на Mac **не появляются на телефоне сами по себе**. Есть отдельная петля синхронизации с тремя фазами, которая гоняется cron-задачей. Без прогона этой петли телефон правку не увидит. +> **Инциденты синка** (таймауты LLM, «тик completed но скрипт не запущен») — [[family/documents/vault-sync/2026-09-14-cron-api-timeout-sync-outage]]. + +--- + +## 1. Три звена (не путать!) + +| Звено | Что это | Кто驱动 | +|---|---|---| +| **1. Рабочий клон Mac** | `/Users/admin/obsidian` — где правит агент | агент (git add/commit/push) | +| **2. Bare-репозиторий** | `/mnt/RED_2TB/storage/git/obsidian-vault.git` на NAS (`mallexxx.duckdns.org`) | приём push от Mac | +| **3. SyncThing-папка** | `/mnt/RED_2TB/storage/obsidian-syncthing` на NAS | **раздаёт на телефон** через SyncThing | + +> ⚠️ **ГЛАВНАЯ ОШИБКА:** думать, что `git push` с Mac = правка на телефоне. +> **`git push` доезжает только до bare (звено 2).** Телефон читает **звено 3** — `obsidian-syncthing`. Между ними — петля `sync-vault.sh`, которая делает pull в звено 3. + +### Проверка расхождения (диагностика «телефон не видит») + +```bash +# Mac +cd /Users/admin/obsidian && git log --oneline -1 + +# NAS: все клоны должны быть на ТОМ ЖЕ коммите, что Mac +ssh truenas_admin@mallexxx.duckdns.org ' + cd /mnt/RED_2TB/storage/git/obsidian-vault.git && echo -n "bare: " && git log --oneline -1 main + cd /mnt/RED_2TB/storage/obsidian-syncthing && echo -n "syncthing: " && git log --oneline -1 + cd /mnt/RED_2TB/storage/obsidian && echo -n "obsidian: " && git log --oneline -1' +``` + +**Если `syncthing:` отстаёт** — телефон правку не увидит, пока не прогонится sync-петля. + +--- + +## 2. sync-vault.sh — три фазы + +**Скрипт:** `/opt/data/sync-vault.sh` — живёт **в окружении Hermes (контейнер)**, НЕ на NAS. +На NAS его нет (`ls /opt/data/sync-vault.sh` → нет файла), поэтому пулль «руками оттуда» не выйдет. +**Лог:** `/tmp/vault-sync.log` (тоже в контейнере). + +Скрипт печатает по три timestamped строки `Pushed ✓` — по одной на фазу: + +| Фаза | Что делает | +|---|---| +| `[syncthing]` | стягивает изменения с Eagle/Кракена, коммитит и пушит | +| `[taiga-vault]` | пушит изменения из `vault/` | +| `[syncthing-out]` | пушит в SyncThing-папку → **то, что увидит телефон** | + +> **Признак успеха:** три строки `Pushed ✓`. Если в логе за тик **ноль строк** — скрипт вообще не запускался (см. инцидент 2026-09-14, «второй режим отказа»). + +--- + +## 3. Как прогнать синк вручную + +**Cron-задача Hermes:** `sync-vault`, **id `29851c413903`**, расписание `*/5 * * * *`, prompt = `bash /opt/data/sync-vault.sh >> /tmp/vault-sync.log 2>&1`. + +```bash +# 1) Найти задачу +cronjob action='list' + +# 2) Прогнать принудительно +cronjob action='run' job_id='29851c413903' +``` + +**⚠️ Питфолл:** задача оформлена как **prompt**, а не как `--script`, поэтому её исполняет LLM-раунд. Последствия: +- провайдер не отвечает → тик висит до 600 с, очередь блокируется на 30–57 мин; +- агент может ответить текстом **без вызова инструмента** → статус `completed`, но скрипт **не запущен** (~6,6 % тиков). +**Правильный фикс (не сделан, требует решения Alex):** `--no-agent --script