16.1 KB · updated 2026-07-31 · md

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 отличается от переизвлечённого из источника descriptionVault выигрывает, лог в .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
- ...

Два практических эффекта:

  1. Пользователи могут аннотировать любую страницу (например «см. главу 4 моих заметок»), не теряя это при пересборке.
  2. Проход 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 разрешила их так:

  1. Форма lint-отчёта. Разошедшиеся поля отображаются как выделенный файл .tesserae/diverged-fields.md (пишется --dry-run и при каждом применении), чтобы его можно было диффать в git, а не как секция lint-report.md.
  2. Тип узла-надгробия. Добавить Stub как настоящий тип схемы или подсесть на OpenQuestion с дискриминатором _kind: stub? Предложено: настоящий тип с именем Stub, скрытый из публичных индексов.
  3. Дефолт pull-on-compile. По умолчанию ON или OFF? Предложено: ON, когда vault существует по настроенному пути, с одноразовым подтверждением при первой активации, чтобы пользователи подключались осознанно.
  4. Что считается «предыдущей проекцией» для диффа? Снапшот, хранимый в .tesserae/vault_snapshot.json, или перепроекция на лету при каждой компиляции? Предложено: снапшот, записываемый в конце каждой компиляции. Дешевле и не даёт недетерминизму экстрактора протекать в оверлей.
  5. Мультиязычная проекция vault. Сегодняшняя проекция одноязычна (язык источника). Должны ли оверлеи быть locale-aware (например, правка description в корейском vault-оверлее применяется только к корейской проекции)? Предложено: вне рамок v1; vault одноязычен и соответствует основному языку проекта.

Как это отражается в obsidian.md

Пользовательское руководство остаётся сфокусированным на «вы можете читать и запрашивать vault», а затем ссылается сюда за историей round-trip с однострочной сводкой: «Редактируйте поля в Obsidian — они переживают перекомпиляцию. Полную модель см. в obsidian-sync.md».