# Вклад в Ktav
**Languages:** [English](CONTRIBUTING.md) · **Русский** · [简体中文](CONTRIBUTING.zh.md)
Спасибо, что заглянули. Ktav — намеренно маленький формат, и планка
для принятия изменений сознательно поднята высоко. Эта планка — **не**
«было бы классно добавить». Планка такая: **делает ли это изменение
Ktav меньше, проще или целостнее?**
Документ описывает (1) что относится к спецификации, (2) что нет,
(3) как устроен процесс версионирования и релизов и (4) как подавать.
## Что уместно здесь
Этот репозиторий — сам формат. Здесь приземляются три вида изменений:
### 1. Редакторские — bump `PATCH`
Исправления, которые не меняют поведения соответствующего парсера.
Опечатки, переформулированные абзацы, более ясные примеры, лучшие
имена тестов, новые *conformance*-тесты (новые углы к существующим
правилам, а не новые правила).
Отправляйте PR напрямую. Однострочное описание в коммите, обновлённая
версия в заголовке `versions/<v>/spec.md` и в `CHANGELOG.md`.
### 2. Аддитивные — bump `MINOR`
Обратно совместимые расширения. Новое ключевое слово, новая
примитивная форма, новый вариант многострочной строки — то, что
старые парсеры отвергли бы, но отсутствие чего не ломает существующие
документы.
Сначала откройте issue. В issue нужно ответить, по порядку:
1. **Что это позволяет пользователям делать, чего они сейчас не могут?**
Покажите реальный конфиг, не синтетический пример.
2. **Какова цена?** Каждое добавленное правило — это правило, которое
должен верно реализовать каждый реализатор, и правило, которое
должен знать каждый читатель.
3. **Можно ли выразить то же самое в существующей грамматике?** Если
да — обычно это и есть правильный ответ.
Дополнения выходят как новая директория `versions/<x>.(y+1)/` с
собственной спецификацией и тестами. Предыдущая версия остаётся
замороженной — реализации продолжают закрепляться за той версией,
которую поддерживают.
### 3. Ломающие — bump `MAJOR`
Изменение грамматики или семантики, делающее некоторые
ранее-валидные документы невалидными или меняющее их смысл. Они
редки. Процесс тот же, что для аддитивных, плюс migration note,
описывающая, что меняется и почему.
Ломающие изменения приземляются в новой директории
`versions/(x+1).0/`. Предыдущие мажорные версии остаются
опубликованными навсегда — реализации, ориентированные на них, не
устаревают.
## Что здесь неуместно
- **Трюки парсера** — если это нельзя выразить в документе
спецификации, это забота реализации. Открывайте issue в репозитории
соответствующей реализации (`ktav-lang/rust` и т. д.).
- **Утверждения о производительности** — тоже на уровне реализации.
- **Интеграции** (как Ktav общается с вашим любимым DI-фреймворком,
валидатором схем и т. п.) — находятся за пределами спецификации.
- **Треды «почему бы не взять YAML / TOML / JSON»** — сравнительная
таблица в README и есть весь поддерживаемый нами ответ.
## Принципы дизайна
Каждое предложение взвешивается по следующим принципам, в порядке
приоритета:
1. **Локальность.** Смысл строки не должен зависеть от объявления в
другом месте файла или в другом файле.
2. **Одно предложение.** Новое правило должно формулироваться одним
предложением спецификации. Если требуется абзац — это, скорее
всего, два правила.
3. **Нечувствительность к пробелам** (кроме переносов строк). Ktav
строчно-ориентирован; выравнивание по колонкам никогда не несёт
смысла.
4. **Никаких магических типов.** Строки — это строки; числа — это
строки на уровне Value. Типизация — задача потребителя (через
serde, через схему, через код).
5. **Явное предпочтительнее хитрого.** `::` многословен намеренно —
редкий случай, когда нужен литерал, должен быть и тем, что стоит
лишних символов, а не повседневным случаем.
Предложение, жертвующее любым из этих принципов, требует
соразмерно большого обоснования.
## Версионирование, конкретно
```
x . y . z
│ │ └── PATCH — editorial; parsers unaffected
│ └────── MINOR — additive; old docs still valid
└────────── MAJOR — breaking
```
- `versions/<x>.<y>/` — источник истины для данной версии.
- `CHANGELOG.md` в корне репозитория отслеживает историю по всем версиям.
- `versions.ktav` — машиночитаемый индекс.
- Каждый релиз помечается git-тегом с **полной**
`MAJOR.MINOR.PATCH`: `v0.1.0`, `v0.1.1`, `v0.2.0`, … Имя директории
(`versions/0.1/`) опускает PATCH по соглашению — PATCH-бамп
обновляет ту же директорию, а не создаёт соседнюю, — но везде в
остальных местах version string остаётся трёхсоставной.
## Подача
1. Fork, ветка, коммит с описательным сообщением (английский или
русский оба принимаются).
2. Если изменение затрагивает `versions/<v>/`, обновите версию в
заголовке и добавьте запись в `CHANGELOG.md` под правильным
разделом.
3. Добавьте conformance-тест в `versions/<v>/tests/` — либо в
`valid/` (новая форма парсится корректно), либо в `invalid/`
(новое ограничение отклоняет правильный вход). Один тест — одна
концепция.
4. Откройте PR со ссылкой на issue (для аддитивных/ломающих
изменений). Редакторским PR предварительный issue не нужен.
5. CI в нижележащих реализациях проверит, что парсер по-прежнему
согласуется с обновлённым набором тестов.
## Ревью
Майнтейнеры смотрят:
- Проходит ли изменение пять принципов выше?
- Есть ли тест, который падал бы при неправильной реализации?
- Правило из одного предложения — действительно одно предложение?
- Хорошо ли читается пример вне контекста?
Маленькие хирургические PR мержатся быстро. Большие рефакторинги
текста спецификации «раз уж я здесь» отклоняются — разбивайте их.
## Языковая политика
Организация `ktav-lang` ведёт каждый prose-документ в трёх
параллельных языках: английский (канонический), русский и
упрощённый китайский. Именование файлов:
`<name>.md` / `<name>.ru.md` / `<name>.zh.md`. Изменяя любой
prose-файл, **обновляйте все три версии в одном коммите** —
расхождение переводов это главная болячка многоязычных документов.
Если вы не владеете одним из языков, пометьте нетронутые файлы
комментарием `<!-- TODO: sync with <name>.md -->` в начале и
откройте PR как есть; мейнтейнер или участник сообщества закроет
пробел до мерджа.
`versions/<v>/spec.md` нормативен на английском; переводы RU / ZH —
**информативные** (полезны не-англоязычным читателям, но не
авторитетный источник). Ключевые слова RFC 2119 (MUST, SHOULD, MAY,
…) сохраняются в английских капсах во всех переводах — это
технические термины.
Полная политика — в org-level
[`.github/AGENTS.md`](https://github.com/ktav-lang/.github/blob/main/AGENTS.md).
## Лицензия
Внося вклад, вы соглашаетесь, что ваш вклад лицензируется под
MIT License, так же как и остальная часть репозитория.