Merge checkbox state on pull instead of overwriting it #12

Closed
opened 2026-08-09 19:48:13 +00:00 by claude · 0 comments
Collaborator

Summary

При pull объединять состояние чекбоксов вместо перезаписи: для строк-чекбоксов
с совпадающим текстом [x] с любой стороны выигрывает. Остальное тело
по-прежнему затирается целиком.

Spec

none

Depends on

  • tick-in-body-checkboxes-from-a-domain-script — разбор чекбоксов живёт в
    доменном слое, слой sync его импортирует, а не переопределяет

Motivation

Галочка теряется в обе стороны. Pull пишет тело сервера как есть
(skills/sync/scripts/pull.py:191), push шлёт локальное тело как есть
(skills/sync/scripts/map.py:171), и кто записал последним, тот и прав:
отметил в вебе — потерял на первом push.py --update; отметил локально —
потерял на первом pull.

Обычный ответ на это — отслеживание drift и слияние, от которых репозиторий
отказался осознанно (skills/sync/SKILL.md:193). Здесь он и не нужен.
Тик монотонен: пункт едет только из [ ] в [x], поэтому объединение
двух сторон — это объединение множеств, а не разрешение конфликта. Правило на
один тип строки заменяет весь механизм, и «стор не зеркало» остаётся в силе.

Отказаться от объединения — значит запретить отмечать в веб-интерфейсе, а
отмечают там, где читают. Запрет, который невозможно проверить, выполняться не
будет.

Цену признаём явно: снятие галочки монотонности не подчиняется, поэтому снятая
в вебе галочка вернётся следующим pull. Снимать — локально, потом push.

Acceptance criteria

  • при pull для чекбокс-строки, текст которой совпадает со строкой в
    локальной копии, состояние [x] сохраняется, с какой бы стороны оно ни
    стояло
  • строка, текст которой в локальной копии не нашёлся, берётся с сервера
    как есть — включая её состояние
  • всё остальное тело перезаписывается как раньше: правило действует только
    на строки-чекбоксы, проза не сливается
  • pull в пустой стор (локального файла нет) пишет тело сервера без
    изменений и не падает
  • --cached поведения не меняет: пропущенный issue не читается и не
    сливается
  • разбор чекбоксов импортируется из skills/issue/, в skills/sync/ не
    дублируется
  • skills/sync/SKILL.md описывает правило и его цену: снятая в вебе
    галочка возвращается следующим pull, снимать надо локально и пушить
  • skills/issue/ не изменён

Constraints

  • Не входит в объём: любое другое слияние тела. Проза, заголовки и метаданные
    затираются pull'ом как раньше.
  • Не входит в объём: отслеживание drift, предупреждения об изменившемся
    upstream, трёхсторонний merge с базовой версией.
  • Не входит в объём: обратная передача галочек отдельным запросом — тело и так
    уезжает целиком в push.py --update.
## Summary При pull объединять состояние чекбоксов вместо перезаписи: для строк-чекбоксов с совпадающим текстом `[x]` с любой стороны выигрывает. Остальное тело по-прежнему затирается целиком. ## Spec none ## Depends on - tick-in-body-checkboxes-from-a-domain-script — разбор чекбоксов живёт в доменном слое, слой sync его импортирует, а не переопределяет ## Motivation Галочка теряется в обе стороны. Pull пишет тело сервера как есть (`skills/sync/scripts/pull.py:191`), push шлёт локальное тело как есть (`skills/sync/scripts/map.py:171`), и кто записал последним, тот и прав: отметил в вебе — потерял на первом `push.py --update`; отметил локально — потерял на первом pull. Обычный ответ на это — отслеживание drift и слияние, от которых репозиторий отказался осознанно (`skills/sync/SKILL.md:193`). Здесь он и не нужен. **Тик монотонен**: пункт едет только из `[ ]` в `[x]`, поэтому объединение двух сторон — это объединение множеств, а не разрешение конфликта. Правило на один тип строки заменяет весь механизм, и «стор не зеркало» остаётся в силе. Отказаться от объединения — значит запретить отмечать в веб-интерфейсе, а отмечают там, где читают. Запрет, который невозможно проверить, выполняться не будет. Цену признаём явно: снятие галочки монотонности не подчиняется, поэтому снятая в вебе галочка вернётся следующим pull. Снимать — локально, потом push. ## Acceptance criteria - [x] при pull для чекбокс-строки, текст которой совпадает со строкой в локальной копии, состояние `[x]` сохраняется, с какой бы стороны оно ни стояло - [x] строка, текст которой в локальной копии не нашёлся, берётся с сервера как есть — включая её состояние - [x] всё остальное тело перезаписывается как раньше: правило действует только на строки-чекбоксы, проза не сливается - [x] pull в пустой стор (локального файла нет) пишет тело сервера без изменений и не падает - [x] `--cached` поведения не меняет: пропущенный issue не читается и не сливается - [x] разбор чекбоксов импортируется из `skills/issue/`, в `skills/sync/` не дублируется - [x] `skills/sync/SKILL.md` описывает правило и его цену: снятая в вебе галочка возвращается следующим pull, снимать надо локально и пушить - [x] `skills/issue/` не изменён ## Constraints - Не входит в объём: любое другое слияние тела. Проза, заголовки и метаданные затираются pull'ом как раньше. - Не входит в объём: отслеживание drift, предупреждения об изменившемся upstream, трёхсторонний merge с базовой версией. - Не входит в объём: обратная передача галочек отдельным запросом — тело и так уезжает целиком в `push.py --update`.
claude added this to the Issue's in-body ticks milestone 2026-08-09 19:48:13 +00:00
claude added the comp/sync
type
task
labels 2026-08-09 19:48:13 +00:00
claude changed reference from feat/issue-cache-scripts to feat/issue-cache-scripts 2026-08-10 10:58:18 +00:00
Sign in to join this conversation.