# 从结构化事实生成三语 Release Notes

用一个封闭事实源生成 zh、zh-hant、en 三份发布说明，并用不变量和 SHA-256 阻止事实漂移。

发布说明经常需要多语言，但不能因为翻译而改变版本号、配额、接口或产品边界。这个 Recipe 用同一个结构化事实文件生成简体中文、繁体中文和英文 Markdown，并对每份产物做确定性校验。

## 事实源

默认输入 `examples/soyaos-cloud-v0.2.0.json` 来自官方 v0.2.0 Release。它记录：

- 产品、版本、发布时间、状态和官方链接；
- 每条事实的唯一 ID、类型、原文；
- 必须逐字保留的接口、模型名、数字和技术标识。

SoyaOS Cloud 只能翻译标题、摘要和事实正文，不能添加 URL、数字或新事实。版本、日期和链接由渲染器直接取自事实文件。

## 准备和运行

安装 Node.js 22 或更高版本，并按 [Cloud 快速上手](/zh/docs/cloud-quickstart)创建 API Key。Key 是 opaque string，只放在当前终端的环境变量里。

```bash
git clone https://github.com/soyaos/cloud-recipes.git
cd cloud-recipes
export SOYA_API_KEY='your-soyaos-api-key'
npm run run:multilingual-release-notes
```

默认产物目录：

```text
output/soyaos-cloud-v0.2.0-release-notes/
├── zh.md
├── zh-hant.md
├── en.md
└── manifest.json
```

## 为什么使用封闭事实集

一般的“请帮我写 Release Notes”会让模型同时承担事实发现、判断和翻译，错误很难定位。这里先由人或可信自动化把事实固化成 JSON，再让 Cloud 完成最适合模型的语言工作。

校验器要求：

1. locale 必须恰好是 `zh`、`zh-hant`、`en`；
2. 每个语种必须包含完全相同且顺序一致的事实 ID；
3. 每条事实的不变量必须逐字存在；
4. 模型不得增加未批准的数字或任何 URL；
5. 英文不得混入中文正文，繁体中文必须具有繁体文本特征。

模型第一次输出不合格时只允许修复一次，第二次仍失败就关闭式终止。

## Manifest 与质量门禁

`manifest.json` 记录版本身份、事实清单、Cloud `requestIds`，以及三个 Markdown 文件各自的 SHA-256。写入后修改任何正文都会造成哈希校验失败。

五类门禁分别检查内容、Markdown 结构、语种、Manifest 完整性和安全性。所有门禁通过后，Recipe 才把临时目录原子重命名为最终目录，不会留下半成品。

## 生成新版本

复制示例 JSON，按同一 schema 写入新版本的官方事实，再运行：

```bash
node recipes/multilingual-release-notes/run.mjs \
  --input examples/your-release.json \
  --output output/your-release-notes
```

不要把未经核验的营销文案直接当作事实，也不要把 API Key 写进输入文件。

## 常见错误

- `invalid_facts`：输入不符合结构、URL 带凭证，或事实 ID 重复。
- `locale_mismatch`：模型没有返回完整的三个语种。
- `invariant_changed`：技术标识、配额或其他不变量被改写。
- `invented_number` / `invented_url`：模型增加了事实集之外的数字或链接。
- `quality_gate_failed`：语言、结构、哈希或安全校验失败。

源码与测试：[soyaos/cloud-recipes](https://github.com/soyaos/cloud-recipes)

---

Canonical HTML: https://soyaos.ai/zh/docs/cloud-recipes/multilingual-release-notes
