crdt-op
Чеклист добавления или изменения операции CRDT доски (стикеры, перемещение, группы, голоса) в packages/crdt — семантика конфликтов, дельта, слияние, обязательные property-тесты, валидация на сервере,
Files1
View on GitHubSKILL.md.claude/skills/crdt-op/SKILL.md
GitHubcrdt-op — новая операция над доской
Сходимость доски доказывается свойствами merge. Одна операция, нарушившая их, ломает доказательство для всего проекта, поэтому чеклист проходится целиком.
Чеклист
- Семантика. У каждого нового или изменённого поля есть строка в таблице §1.4
docs/spec/consistency-model.md(Kind/Field/Значения/Политика: «все варианты» или «победитель по метке»). Разные поля разрешаются независимо — отдельной попарной таблицы конфликтов операций в модели нет, см. § 2. Нет нужной строки — сначала/write-spec. - Протокол. zod-схема дельты в
packages/protocol; лимиты размера (длина текста, числоsupersedes) заданы в схеме. - Дельта.
packages/crdt/src/ops/<op>.ts: чистая функция(state, params, clock) → delta. Время, ID и случайность приходят параметрами. - Слияние. Только через существующие примитивы полурешётки (MV-регистр, 2P-set, объединение по dot). Новый примитив → ADR и отдельный полный набор свойств для него.
- Материализация. Обход коллекций — после сортировки по ключу. Победитель —
max(lamport, actorId). Никакой зависимости от порядка вставки вMap/Set. - Генераторы. Операция добавлена в
packages/crdt/test/arbitraries.ts— иначе property-тесты её не видят. - Обязательные свойства (общие наборы параметризованы генераторами, проверить, что новая операция в них участвует):
lattice.prop— коммутативность, ассоциативность, идемпотентностьmerge;convergence.prop— перестановки, дубли, задержки → одинаковыйmaterialize;no-loss.prop— dot каждой операции присутствует в состоянии;materialize.prop— независимость от порядка вставки;compact.prop—materialize(compact(s)) == materialize(s).
- Сервер. Валидация в обработчике: матрица прав (
docs/security/permissions.md), фаза, лимиты. Если проверка не нужна — комментарий с причиной. - Симулятор. Операция добавлена в генератор операций
packages/sim. - Прогон.
npm run test:prop && npm run test:sim, затемnpm run check.
Типичные ошибки
Date.now()/crypto.randomUUID()внутриpackages/crdt.Object.keys/for...ofпоMapбез сортировки вmaterialize.- Удаление, которое физически убирает запись: одновременная правка «воскрешает» стикер или теряется. Удаление — только отдельное значение в регистре
deleted. - Доверие
actorIdиlamportиз сообщения клиента на сервере. - Упавший property-тест «починен» уменьшением генератора. Правильно: seed и минимальный контрпример → регрессионный тест → исправление.