# 为 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 OR Apache-2.0** 下发布
(由用户选择),与本仓库的其余部分相同。