a0e169e9b4
Корневая причина: при pull конфликт объявлялся по условию `dirty && remoteUpdatedAt !== prev.remote_updated_at`, где `dirty` определяется сравнением raw-байтового sha файла с content_etag_local. Серверные метки времени (updated_at/created_at) входят и во frontmatter файла, и в etag. Когда сервер бьёт _updated_at родителя при дочерней мутации (создание/удаление issue/story), etag в индексе расходится с файлом ровно на строку updated_at — файл считается «грязным», а при изменившемся remote_updated_at pull пишет маркеры слияния на весь файл, хотя содержательно текст идентичен. Подтверждено: подстановка remote_updated_at в файл воспроизводит etag байт-в-байт (58 записей на проде voskhod). Фикс: в syncEntityFile перед записью маркеров сравниваем локальный и серверный тексты в каноне без updated_at/created_at. Если совпадают — это не конфликт: принимаем серверную версию и лечим etag, без маркеров. Реальная правка тела/заголовка по-прежнему даёт маркеры. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>