obsidian-sync.ru.md
docs/i18n/integrations/obsidian-sync.ru.md
Двусторонняя синхронизация с Obsidian — предлагаемый дизайн
<!-- translations:start -->
English · 한국어 · 中文 · 日本語 · Español · Français · Deutsch
<!-- translations:end -->
Статус: поставлено (Tier 1, v0.5.0). Описанные ниже читатель оверлея, зоны добавления пользовательских заметок, режим watch и чистка сирот живут за
tesserae vault sync. Эта страница служит одновременно обоснованием дизайна и руководством пользователя. Мультихранилищная федерация (Tier 3) остаётся вне рамок.
Экспорт Obsidian раньше был строго односторонним: типизированный граф в .tesserae/graph.json проецируется в vault, а project compile перезаписывает проецируемые файлы. obsidian-sync добавляет обратное направление — отредактируйте описание в Obsidian, и оно переживает перекомпиляцию.
Этот документ расписывает, как это работает, не делая модель данных бессвязной.
Стратегический сдвиг, сказанный прямо
Текущий README отказывается от живого редактирования:
Tesserae выбирает compile-from-source вместо живого редактирования. Если хотите редактировать заметки в UI, используйте Logseq или Obsidian.
Двусторонняя синхронизация меняет этот контракт для подмножества полей. Стоит быть осознанным. Цель не «Obsidian становится редактором» — а «Obsidian-правки пользователя не уничтожаются молча при перекомпиляции».
Ключевая идея: оверлеи, а не слияния
Вместо попыток слить две расходящиеся копии одного узла — трактовать vault как слой диффа над проекцией:
source markdown ──extract──▶ base_graph
+
vault_overrides ◀── computed from vault
↓
final_graph ──project──▶ vault (.md files)
vault_overrides.json живёт в .tesserae/ и вычисляется, а не пишется вручную. При каждой компиляции Tesserae обходит vault, сравнивает каждую проецируемую страницу с тем, что записала предыдущая проекция, и фиксирует каждое внесённое пользователем изменение как запись оверлея. Итоговый граф — это base_graph с применёнными оверлеями. Следующая проекция записывает результат обратно на диск.
Стабильно по кругу. Перекомпиляция того же vault без изменений на стороне источников не производит диффов.
Владение по полям
У каждого поля узла есть владелец. Владение решает, что происходит, когда источник и vault расходятся.
| Поле | Владеет источник | Vault может переопределить | Заметки |
|---|---|---|---|
id, type | да | нет | Контролируется схемой; владеет экстрактор |
name | изначально | да | Пользователь часто знает каноническое имя лучше экстрактора |
aliases | изначально | да | Только-добавление из vault; записи vault всегда сохраняются |
description | изначально | да | Самая частая Obsidian-правка |
source_path | да | нет | Provenance; нельзя отредактировать прочь |
metadata (объявленные ключи) | изначально | да | Например arxiv_id, github_repo — пользователь может поправить |
metadata.user.* | n/a | да | Зарезервированный неймспейс для только-пользовательских ключей; экстрактор никогда не пишет |
| Исходящие рёбра (типизированные) | да | нет | Рёбра живут в онтологии, не в vault |
| Новые wikilink-и, набранные пользователем | n/a | да | Отображаются как edge_type=user_link, пишутся в граф |
Блок тела <!-- user-notes --> | никогда не пишется | всегда сохраняется | Зона только-добавления, которую проектор никогда не трогает |
Конфликтные случаи и дефолты
| Случай | Дефолт | Почему |
|---|---|---|
description в vault отличается от переизвлечённого из источника description | Vault выигрывает, лог в .tesserae/lint-report.md под «diverged fields» | Уважение к правкам пользователя: пользователь явно хотел эту правку. Аудиторский след позволяет пересмотреть позже. |
| Файл источника удалён, проецируемая страница всё ещё в vault | Удалить узел из графа, перечислить в .tesserae/orphans.md | Источник авторитетен для существования; журнал сирот позволяет решить, восстановить или принять |
| Пользователь написал wikilink на несуществующий slug | Создать узел-надгробие (тип Stub), показать в lint-отчёте | Не терять намерение пользователя; пометить для чистки |
| Пользователь добавил ключ фронтматтера, не известный схеме | Сохранить как metadata.user.<key>, никогда не перезаписывать | Совместимо вперёд, не загрязняя типизированный граф |
| Два vault на разных машинах правят один узел, оба синхронизируются через Obsidian Sync | Вне рамок v1. Последний писатель выигрывает на уровне файловой системы. | Настоящая мультихранилищная федерация — Tier 3; отложить до реального сценария |
Зона добавления пользовательских заметок
Каждая проецируемая страница получает огороженную зону, которую проектор никогда не трогает:
> [!quote] Paper
> Headline contribution and method sketch projected from the graph...
<!-- user-notes:start -->
Your notes here. Anything between the markers survives recompile forever.
Wikilinks here become `user_link` edges in the graph on the next pull.
<!-- user-notes:end -->
## Outgoing
- ...
Два практических эффекта:
- Пользователи могут аннотировать любую страницу (например «см. главу 4 моих заметок»), не теряя это при пересборке.
- Проход pull сканирует блок пользовательских заметок на wikilink-и и отображает их как онтологически типизированные рёбра
user_link, давая им достижимость в графе без загрязнения формальных типов рёбер.
Удалённый транспорт — явная не-цель
Tesserae не строит сервер синхронизации, слой аутентификации, демон разрешения конфликтов или хостинг vault. «Двусторонний» здесь означает «компиляция читает из vault» — как vault попадает на машину, делающую компиляцию, — проблема пользователя, решаемая уже существующими инструментами:
| Стек | Стоимость | Заметки |
|---|---|---|
| Obsidian Sync | Платно, $4-8/мес | E2E-шифрование, официально, предельно просто |
| iCloud / Dropbox / OneDrive | Идёт с ОС | Работает, но UX конфликтов враждебен |
| Syncthing | Бесплатно, self-hosted | Лучшее для одиночки на нескольких устройствах |
| Git (vault под коммитами) | Бесплатно | UX конфликтов лучше всего для технических пользователей |
| LiveSync (плагин CouchDB) | Бесплатно, нужен сервер | Реальное время, много устройств |
Все пять совместимы с моделью оверлеев, потому что Tesserae видит vault как файлы-на-диске, а не как поток мутаций.
Поверхность CLI
tesserae vault sync применяет правки vault на типизированный граф и перепроецирует:
# Apply the overlay once: pull user edits, re-project to the vault.
tesserae vault sync
# Inspect what would change first. Writes .tesserae/diverged-fields.md and
# does NOT apply or re-project.
tesserae vault sync --dry-run
# Point at a specific vault for this call (resolution order:
# --vault > config.obsidian.vault_path > .tesserae/obsidian_vault/).
tesserae vault sync --vault ~/Documents/tesserae-vault
# Make that vault path the default for future commands.
tesserae vault sync --vault ~/Documents/tesserae-vault --persist-vault
# Long-running watch: re-apply the overlay every time the vault changes.
# Ctrl-C to stop; tune the poll cadence with --interval (default 1.5s).
tesserae vault sync --watch --interval 1.5
# Delete projected pages whose source node no longer exists (the projector
# only overwrites, never deletes). Pages with user-notes are kept unless you
# also pass --force-prune-with-notes.
tesserae vault sync --prune-orphans
tesserae vault sync --prune-orphans --force-prune-with-notes
Слэш-команда /tesserae:obsidian-sync оборачивает это, а tesserae refresh (плюс макрос /tesserae:refresh) запускает оверлей последним шагом своей цепочки import → compile → sync.
Статус поставки
| Tier | Объём | Статус |
|---|---|---|
| 1a | Читатель оверлея: обход vault, построение vault_overrides.json, применение при sync. Расхождения ложатся в .tesserae/diverged-fields.md. | Поставлено |
| 1b | Зоны добавления пользовательских заметок: проектор никогда не трогает блоки <!-- user-notes:start --> ... <!-- user-notes:end -->. | Поставлено |
| 2 | Режим watch: долгоживущий obsidian-sync --watch перезапускает оверлей в опросном цикле по мере изменений vault. | Поставлено |
| 3 | Мультихранилищная федерация: граф хранит provenance по vault, поддерживает конкурентные правки между синхронизируемыми vault-ами. | Отложено до реального сценария |
Не-цели (явно)
- Сервер синхронизации / auth / хостинг-бэкенд.
- Совместное редактирование в реальном времени внутри Obsidian (используйте LiveSync, если это нужно).
- Переписывание экстрактора для round-trip каждого поля — исходный markdown остаётся каноническим для всего вне таблицы переопределений.
- Синхронизация статического HTML-сайта (
build-siteостаётся только-проекцией).
Разрешённые решения
Это были открытые вопросы на этапе дизайна; поставленная реализация Tier 1–2 разрешила их так:
- Форма lint-отчёта. Разошедшиеся поля отображаются как выделенный файл
.tesserae/diverged-fields.md(пишется--dry-runи при каждом применении), чтобы его можно было диффать в git, а не как секцияlint-report.md. - Тип узла-надгробия. Добавить
Stubкак настоящий тип схемы или подсесть наOpenQuestionс дискриминатором_kind: stub? Предложено: настоящий тип с именемStub, скрытый из публичных индексов. - Дефолт pull-on-compile. По умолчанию ON или OFF? Предложено: ON, когда vault существует по настроенному пути, с одноразовым подтверждением при первой активации, чтобы пользователи подключались осознанно.
- Что считается «предыдущей проекцией» для диффа? Снапшот, хранимый в
.tesserae/vault_snapshot.json, или перепроекция на лету при каждой компиляции? Предложено: снапшот, записываемый в конце каждой компиляции. Дешевле и не даёт недетерминизму экстрактора протекать в оверлей. - Мультиязычная проекция vault. Сегодняшняя проекция одноязычна (язык источника). Должны ли оверлеи быть locale-aware (например, правка
descriptionв корейском vault-оверлее применяется только к корейской проекции)? Предложено: вне рамок v1; vault одноязычен и соответствует основному языку проекта.
Как это отражается в obsidian.md
Пользовательское руководство остаётся сфокусированным на «вы можете читать и запрашивать vault», а затем ссылается сюда за историей round-trip с однострочной сводкой: «Редактируйте поля в Obsidian — они переживают перекомпиляцию. Полную модель см. в obsidian-sync.md».