From ed8ba09226e309c451e7956788ba3fafbfd0e7f1 Mon Sep 17 00:00:00 2001 From: Michael Chus Date: Sun, 1 Mar 2026 17:15:32 +0300 Subject: [PATCH] Add module versioning contract Co-Authored-By: Claude Sonnet 4.6 --- rules/patterns/module-versioning/contract.md | 120 +++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 rules/patterns/module-versioning/contract.md diff --git a/rules/patterns/module-versioning/contract.md b/rules/patterns/module-versioning/contract.md new file mode 100644 index 0000000..ebb20ee --- /dev/null +++ b/rules/patterns/module-versioning/contract.md @@ -0,0 +1,120 @@ +# Contract: Module Versioning + +## Purpose + +Единое правило версионирования внутренних слоёв приложения: +плагины, парсеры, API-клиенты, адаптеры и прочие условные модули. + +Модули — это логические слои внутри одного репозитория, не отдельные пакеты. + +--- + +## Формат версии + +``` +N.M +``` + +- `N` — мажорная версия (целое число, начинается с 1) +- `M` — минорная версия (кратна 0.1, начинается с 0) + +Примеры: `1.0`, `2.0`, `2.1`, `2.3` + +--- + +## Правила инкремента + +### N+1 — любая функциональная правка + +Поднимаем мажор при **любом изменении функциональности**: + +- добавление новой функции, метода, поля +- изменение существующего поведения +- удаление функциональности +- рефакторинг, меняющий структуру модуля +- изменение интерфейса взаимодействия с другими слоями + +При инкременте мажора минор **сбрасывается в 0**: `2.3 → 3.0` + +### N+0.1 — исправление бага + +Поднимаем минор при **коротком точечном багфиксе**: + +- исправление некорректного поведения без изменения интерфейса +- правка крайнего случая (edge case) +- исправление опечатки в логике + +Функциональность при этом **не меняется**. + +--- + +## Где хранить версию + +Версия фиксируется в одном месте внутри модуля. Выбрать один из вариантов: + +**Go** — константа в пакете: +```go +const Version = "2.1" +``` + +**Файл** — заголовок contract.md или README модуля: +``` +Version: 2.1 +``` + +**JSON/YAML конфиг** — поле `version`: +```json +{ "version": "2.1" } +``` + +Не дублировать версию в нескольких местах одного модуля. + +--- + +## Git-тег (опционально) + +Если модуль выпускается как отдельная поставка, тег ставится в формате: + +``` +/v +``` + +Примеры: `parser/v2.0`, `api-client/v1.3` + +Тег ставится только на коммит, в котором обновлена версия внутри модуля. +Тег без обновления версии в коде — ошибка. + +--- + +## Стартовая версия + +Новый модуль начинается с `1.0`. +Версия `0.x` не используется. + +--- + +## Инструкция для агентов (Codex, Claude) + +**Обязательно при каждом коммите:** + +1. Определи, к какому модулю относятся изменения. +2. Прочитай текущую версию модуля из канонического места (константа, заголовок, конфиг). +3. Выбери инкремент по правилу: + - Изменяется поведение, добавляется или удаляется функциональность → **N+1**, минор сбросить в 0 + - Только исправление бага, поведение не меняется → **N+0.1** +4. Обнови версию в коде до коммита. +5. Включи новую версию в сообщение коммита: `feat(parser): add csv dialect — v2.0` + +**Агент не должен делать коммит без обновления версии затронутого модуля.** + +### Дерево решений + +``` +Изменения в модуле? +│ +├── Да — это багфикс (логика была неверной, интерфейс не менялся)? +│ ├── Да → N+0.1 +│ └── Нет → N+1, сброс минора в 0 +│ +└── Нет изменений в модуле → версия не меняется +```