# Вклад в 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, так же как и остальная часть репозитория.
