From d163f43e122575b1e5f77844c2de21808025b556 Mon Sep 17 00:00:00 2001 From: claude code agent 227 Date: Wed, 24 Jun 2026 04:16:01 +0300 Subject: [PATCH] =?UTF-8?q?docs(git-sync):=20thin-meta=20design=20?= =?UTF-8?q?=E2=80=94=20identity=20must=20travel=20with=20the=20file=20(B/C?= =?UTF-8?q?)=20+=20link-sync=20phase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Captures the design discussion: a path-keyed sidecar is NOT a safe source of truth (a git-undetected rename loses the page), so the id must travel WITH the file — either as a slugId suffix in the filename (B) or a minimal YAML frontmatter `id:` (C); both robust, B/C is the open UX decision (author leans C for clean names). The sidecar may remain an optional path->id cache. Adds phase 6 — link sync between notes: Docmost links are by pageId (survive rename), vault markdown links are by path (rewrite on rename, Obsidian-style); independent of B/C and the format phases. Co-Authored-By: Claude Opus 4.8 --- docs/backlog/git-sync-thin-meta.md | 48 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/backlog/git-sync-thin-meta.md b/docs/backlog/git-sync-thin-meta.md index 303ff306..5236fe95 100644 --- a/docs/backlog/git-sync-thin-meta.md +++ b/docs/backlog/git-sync-thin-meta.md @@ -18,12 +18,37 @@ ## Решённые принципы -1. **Идентичность — pageId, не имя файла.** (Уже подпёрто фиксом 5133bb34: страница - с известным pageId, чей файл переехал, никогда не удаляется — только move.) -2. **Вся мета — в `.gitmost/index.json`.** Файлы `.md` — без меты. +1. **Идентичность — стабильный id, не имя файла и не путь.** (Подпёрто фиксом + 5133bb34: страница с известным id, чей файл переехал, никогда не удаляется — + только move.) `pageId` нужен как durable мост файл↔Docmost-страница: title, + путь, parent — всё мутабельно, id — нет; без него re-clone/rename плодят дубли. +2. **id ЕДЕТ ВМЕСТЕ С ФАЙЛОМ.** Критично: path-keyed сайдкар (`index.json` по + пути) НЕ годится источником истины — если git не распознал rename (контент + менялся вместе с именем, наш кейс), путь-ключ протухает и страница теряется. + Поэтому id хранится так, что переживает любой move: + - **Вариант B** — slugId суффиксом в ИМЕНИ файла (`Заметка ~Cj7YX7.md`). + Ноль меты в контенте; имена «грязные»; адопция переименовывает файл юзера. + - **Вариант C** — минимальный YAML-frontmatter `id:` в начале файла. Имена + чистые; frontmatter скрыт в Obsidian; адопция имя не трогает (только дописывает). + - **ОТКРЫТО:** B или C (см. ниже). Обе устойчивы. Сайдкар может остаться как + опциональный КЭШ path→id, но не источник истины. + Всё остальное (title/parent/spaceId/version) из файла убираем — выводимо. 3. **Папка = страница-родитель**, дерево зеркальное 1:1. 4. **Контент родителя — внутри его папки**, файлом-индексом (folder-note). +## Открытое решение: B vs C (носитель id) + +Различие свелось к UX, устойчивость равная (id в обоих едет с файлом): +- **B (id в имени):** проще в реализации (парс суффикса), ноль меты в контенте, но + Obsidian показывает ` ~slug` как заголовок заметки, и адопция переименовывает + голый файл (→ может поехать `[[ссылка]]`). +- **C (frontmatter `id:`):** чистые имена, скрытый нативный YAML, адопция имя не + трогает (дописывает строку). Цена — одна строка «меты» в файле. +- Рекомендация автора — **C** (чистые имена важнее, frontmatter идиоматичен), но + это вкусовщина, решает владелец. +- NB: ссылки между заметками ломаются при rename в ЛЮБОМ варианте (title=имя + файла) — это не различает B/C, это отдельная фаза (см. ниже). + ## Формат волта ``` @@ -129,6 +154,23 @@ Obsidian-подобный клиент → появляются страницы. 5. **Чистка**: удалить `docmost:meta` из формата (оставить только фолбэк-парсер), `.gitignore` для `.obsidian/`. +6. **Синк ссылок между заметками** (см. ниже) — отдельный кусок, после формата. + +## Ссылки между заметками (фаза 6) + +Поднял владелец: `title = имя файла`, значит при переименовании страницы ссылки на +неё в волте протухают. + +- **В Docmost** ссылки — по pageId (mention/reference node редактора), переименование + ПЕРЕЖИВАЮТ, не ломаются. Эта сторона безопасна. +- **В волте** markdown-ссылки — по пути/имени (`[t](rel/path.md)` или `[[Имя]]`), + при rename/move файла протухают. +- Решение: при rename/move файла движок ПЕРЕПИСЫВАЕТ цель ссылок во всех файлах, + что на него ссылались (Obsidian «update links on rename»). Альтернатива — + хранить ссылки в волте по стабильному id (но это уже не человекочитаемый md; + отвергаем для дружбы со сторонними редакторами). +- Конвертер Docmost-mention ↔ markdown-link (обе стороны) — часть этой фазы. +- Не влияет на выбор B/C и на фазы формата 1–5; выносим отдельно. ## Риски