# 为 Ktav 做贡献

**Languages:** [English](CONTRIBUTING.md) · [Русский](CONTRIBUTING.ru.md) · **简体中文**

感谢关注。Ktav 是一份有意保持克制的小格式——接纳改动的门槛被
刻意抬高，而这道门槛**不是**「这个特性要是有就好了」。门槛是：
**这个改动是否让 Ktav 更小、更简单或更自洽？**

本文涵盖：(1) 什么应当进入规范，(2) 什么不应，(3) 版本与发布流程
是怎样运作的，以及 (4) 如何提交。

## 属于这里的内容

本仓库就是格式本身。进入仓库的改动分为三类：

### 1. 编辑性——`PATCH` 递进

不改变符合规范的解析器行为的修订：错字、重写的段落、更清楚的示例、
更好的测试命名、新的*一致性*测试（针对已有规则的新角度——而非新
规则）。

直接提 PR。提交信息一行概括，同时更新 `versions/<v>/spec.md` 头部
的版本号以及 `CHANGELOG.md`。

### 2. 新增性——`MINOR` 递进

向后兼容的扩展：一个新关键字、一种新的原始形式、一种新的多行字符串
变体——旧解析器会拒绝它，但缺失它不会破坏既有文档。

请先开 issue。该 issue 必须按顺序回答：

1. **它让用户能做哪些现在做不到的事？** 请出示真实的配置，而非
   合成示例。
2. **代价是什么？** 每新增一条规则，都是每个实现者都必须做对的
   规则，也是每个读者都必须知道的规则。
3. **能否用现有语法表达同一件事？** 如果能，那通常才是更好的答案。

新增以新目录 `versions/<x>.(y+1)/` 发布，附带自身的规范与测试。
上一版本保持冻结——实现继续锁定到它们所支持的版本。

### 3. 破坏性——`MAJOR` 递进

会让此前有效的文档变得无效、或改变其语义的语法/语义变更。这类改动
很罕见。流程与新增性一致，另加一份迁移说明，描述改了什么、为何而改。

破坏性变更落到新目录 `versions/(x+1).0/`。旧的主要版本将永久保留
发布——面向它们的实现不会被作废。

## 不属于这里的内容

- **解析器的小把戏**——如果规范文档无法表达，就是实现层面的事。
  请到对应的实现仓库（`ktav-lang/rust` 等）去报告。
- **性能声称**——同样属于实现层面。
- **集成问题**（Ktav 如何配合你钟爱的 DI 框架、Schema 校验器等）
  ——属于规范下游。
- **「为什么不用 YAML / TOML / JSON」式讨论**——README 的对比表
  就是我们维护的全部回答。

## 设计原则

每份提案按以下原则依优先级衡量：

1. **局部性。** 一行的语义不得依赖于文件别处或其它文件里的声明。
2. **一句话可表述。** 新规则必须能用规范里的一个句子陈述完。
   如果要写一整段，它多半其实是两条规则。
3. **对空白不敏感**（换行除外）。Ktav 是以行为单位的；列对齐
   永远不承担语义。
4. **拒绝类型魔法。** 字符串就是字符串；数字在 Value 层仍是字符串。
   类型处理是消费方的职责（通过 serde、通过 Schema、通过代码）。
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 递进是就地更新同一目录，而非新建相邻目
  录——但其它所有地方的版本字符串仍保持三段式。

## 提交

1. Fork、开分支，提交时写出描述性 commit 信息（英文或俄文均可）。
2. 若改动涉及 `versions/<v>/`，请同步更新头部版本号，并在
   `CHANGELOG.md` 对应标题下增加一条。
3. 在 `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` 以英语版为规范源（normative）；俄语 / 中文
译本为**informative** —— 对非英语读者有帮助，但不作为权威依据。
RFC 2119 关键字（MUST、SHOULD、MAY ……）在所有译本中保持英语大写
—— 它们是技术术语，不是英文单词。

完整政策见组织级别的
[`.github/AGENTS.md`](https://github.com/ktav-lang/.github/blob/main/AGENTS.md)。

## 许可证

一旦贡献，您即同意您的贡献在 MIT License 下许可，与本仓库的其余
部分相同。
