# 验收自检（ACCEPTANCE）

> **本仓库就是提交内容。** 验收按 git 仓库在 **2026-09-30 24:00 的快照**进行，直接依据仓库
> 内容评估，**没有独立的材料提交环节** —— 所以这份自检表放在仓库里，并从两个 README 的
> 顶部链接过来。

本文件把**五份口径**逐条对照，每个结论都指向仓库内可复现的证据：

| 口径 | 条数 | 本节 |
|---|---|---|
| 章程阶段三「项目验收」 | **9 条**（第 9 条含两个子句 → 按 10 行自检） | [§一](#一章程阶段三项目验收9-条--10-行) |
| 章程第七章「开源与成果提交要求」 | **10 条** | [§二](#二章程第七章开源与成果提交要求10-条) |
| 官网「验收标准」 | **6 条** | [§三](#三官网验收标准6-条) |
| 组委会初审邮件补充的评估维度 | **4 个** | [§四](#四组委会初审邮件补充的-4-个评估维度) |
| 本人申报书承诺的范围 | **7 条核心功能 + 3 个使用场景** | [§五](#五与申报书的一致性对照) |

**一句话结论**：五份口径全部满足。申报书承诺的核心功能全部交付；其中申报书写明
「本期暂不实现」的**两项反而做完了**，已单列为**增量**（[§5.3](#53-申报书写明本期暂不实现的四项)）；
对照中查出的一处**承诺不实**（CLI 退出码可作 CI 门禁）**已修复并验证**（[§5.2](#52-三个预期使用场景)）。

所有指标都由仓库内脚本产出，一条命令可全部复现：

```bash
bash check-all.sh          # 闸门 + 全部测量，报告写入 .final-check/
```

---

## 一、章程阶段三「项目验收」（9 条 → 10 行）

> 说明：章程阶段三是 **9 条**。第 9 条含两个子句（OSI 许可证 / 参考移植合规），
> 下表把它拆成两行，所以是 **9 条 → 10 行**，并非另有一条要求。

| # | 章程要求 | 状态 | 证据位置 |
|---|---|---|---|
| 1 | 项目以 **MoonBit 为主要实现语言** | ✅ | `src/` **6,749 行**（6 个库包）+ `cmd/main` 601 行 + `examples/` 958 行，**全部 MoonBit**；库包无 `extern`、无 C、无 FFI。仓库内唯一 C 是 CLI 的 46 行 stdin 垫片（原因见 [README](README.md#native-code)） |
| 2 | GitHub 仓库**公开可访问**，提交记录清晰 | ✅ | https://github.com/Careylq/spell.mbt ；提交按功能分组、连续可追溯；`DEVLOG.md` 逐日记录（Day 1–14） |
| 3 | 源代码结构清晰，**能完成声明的核心功能** | ✅ | `src/aff`（.aff 解析）· `src/dic`（.dic 解析）· `src/affix`（条件匹配）· `src/spell`（判定引擎）· `src/suggest`（建议引擎）· `src/api`（公开 API）· `cmd/main`（CLI） |
| 4 | 提供 **README**：项目目标 / 安装方式 / 使用方法 / 示例 / **可复现** | ✅ | [`README.mbt.md`](README.mbt.md)（英文，权威）+ [`README.zh.mbt.md`](README.zh.mbt.md)（中文）；两版都是 `.mbt.md`，代码块受 `moon check` 编译。含安装（含 `moon.pkg` 写法）、Quick start、CLI、以及一条命令的全量复现 |
| 5 | **使用持续集成工具，覆盖检查、构建、测试流程** | ✅ | [`.github/workflows/ci.yml`](.github/workflows/ci.yml) **14 步**：`moon check` / `build` / `test --target all` / 跨后端构建 / 符合率报告 / **本仓库自身文档的拼写门禁** / 退出码契约自检。另有手动触发的 `bench.yml` |
| 6 | 提供**至少一个可运行示例**或最小使用样例 | ✅ | 三个：[`examples/basic`](examples/basic)（`moon run examples/basic` 直接跑）· [`examples/doccheck`](examples/doccheck)（用本库检查本仓库文档）· [`examples/ci-gate`](examples/ci-gate)（**离线**证明退出码可作 CI 门禁） |
| 7 | 提供**完整测试，覆盖核心功能路径** | ✅ | `moon test --target all` → **182 个测试**（native **186 个**），四后端全通过；测试代码 3,323 行；另有符合率框架 `conformance/` |
| 8 | **发布到 mooncakes.io** | ✅ | `Careylq/spell@0.9.5`（`build_status: success`）· https://mooncakes.io/docs/Careylq/spell |
| 9 | 采用 **OSI 认可的开源许可证** | ✅ | [`LICENSE`](LICENSE) = Apache-2.0（OSI 认证） |
| 10 | 如参考/移植其他开源项目，符合原项目许可证要求 | ✅ | [`NOTICE`](NOTICE)：参考 Hunspell（LGPL-2.1）的**格式规范与可观察行为**，未复制源码；测试语料与词典**不随仓库分发**，均由脚本运行时拉取 |

---

## 二、章程第七章「开源与成果提交要求」（10 条）

| # | 章程要求 | 状态 | 证据位置 |
|---|---|---|---|
| 1 | 项目须在 GitHub 或赛事组认可的平台**公开发布** | ✅ | https://github.com/Careylq/spell.mbt （public）；并发布到 mooncakes.io |
| 2 | 仓库须包含**完整源代码** | ✅ | `src/` + `cmd/` + `examples/` 全为源码；无编译产物入库（`_build/`、`.mooncakes/` 均在 `.gitignore`） |
| 3 | 仓库须保留**合理开发历史记录** | ✅ | 提交按功能分组且连续；[`DEVLOG.md`](DEVLOG.md) 逐日记录设计取舍；`.githooks/pre-commit` |
| 4 | 仓库须包含 **README** | ✅ | [`README.mbt.md`](README.mbt.md)（`README.md` 为符号链接）+ 中文版 |
| 5 | 项目须选择 **OSI 认证许可证** | ✅ | Apache-2.0 |
| 6 | 如移植或参考其他开源项目，应在 **README 或专门文档**中注明原项目**名称、链接、许可证和参考范围** | ✅ | [`NOTICE`](NOTICE) 逐项列明：Hunspell / 链接 / LGPL-2.1 / 参考范围；README 也指向它 |
| 7 | 项目须遵守**第三方依赖及参考项目的许可证**要求 | ✅ | 依赖仅 `moonbitlang/x`（纯 MoonBit）；Hunspell 仅参考规范未复制源码；语料与词典运行时拉取、用完即删 |
| 8 | 不得侵犯他人知识产权，不得提交**未经授权的私有/闭源/商业代码** | ✅ | 全部实现为本期从零编写；无来源不明代码 |
| 9 | 如包含**生成代码、测试数据或样例文件**，应保证其**来源合法合规** | ✅ | 见下方专述 |
| 10 | 同意主办方在保留署名前提下用于**赛事宣传、官网展示、社区文章、技术分享** | ✅ | 已知悉并同意（亦为章程第九条参赛前提） |

> **第 9 条专述**：本项目开发过程使用了 AI 辅助，因此「代码来源可核验」是关键。
> 可核验材料全部在仓库内：[`DEVLOG.md`](DEVLOG.md) 逐日记了**哪些部分由 AI 生成、
> 以及每一处是如何被验证的**；[`docs/MOONBIT_GOTCHAS.md`](docs/MOONBIT_GOTCHAS.md)
> 收录 **43 条由编译器或运行时实测**的 MoonBit 陷阱；[`CHANGELOG.md`](CHANGELOG.md) 记录
> 每个版本的改动与理由；`examples/` 中的样例词典均为本仓库现写并注明来源，
> 未使用任何第三方测试数据。第三方语料只在脚本运行时拉取，不随仓库分发。

---

## 三、官网「验收标准」（6 条）

| # | 官网标准 | 我们的情况 |
|---|---|---|
| 1 | **MoonBit 为主** —— 以 MoonBit 作为项目主要实现语言 | 见 [§一](#一章程阶段三项目验收9-条--10-行) 第 1 条；库包零 FFI |
| 2 | **仓库公开** —— 保留连续、可追踪的提交与开发记录 | 见 §一 第 2 条 |
| 3 | **能够运行** —— 提供清晰 README、可运行示例与必要测试 | 见 §一 第 4、6、7 条；README 的安装与 Quick start 已按**全新消费者项目**实测（`moon new` → `moon add Careylq/spell` → 照抄文档可跑通） |
| 4 | **工作有效** —— 已有项目须含本期实质新增工作 | 本项目本期**从零建成**，全部为新增工作 |
| 5 | **开源合规** —— 使用认可的开源许可证，并说明移植或参考来源 | 见 §一 第 9、10 条与 §二 第 5–8 条 |
| 6 | **AI 可解释** —— 可以使用 AI 辅助，但目标、路径与质量必须由参赛者掌握 | 见 §二 第 9 条专述 |

---

## 四、组委会初审邮件补充的 4 个评估维度

初审通过邮件写明：最终验收根据**项目完成度、代码质量、开源合规性、与 MoonBit 生态的相关性**评估。

| 维度 | 结论 | 证据 |
|---|---|---|
| **项目完成度** | Hunspell `.aff`/`.dic` 的**解析 → 词缀推导 → 判定 → 建议**全链路打通。官方语料 `.good` **99.2%**、`.wrong` **99.7%**；真实词典上与 C++ Hunspell 判定基本一致（235,976 词上分歧 **0.084%**） | [§六](#六已实测指标每条都可用仓库内脚本复现) |
| **代码质量** | **182 / 186** 个测试 × 四后端全通过；`moon check --deny-warn --target all` **0 warning**；`moon fmt --check` 干净；`.mbti` 公开接口 diff 为空；CI 14 步全绿；每个实测数字都有脚本，且**每个未通过用例都逐条列明并解释为什么不猜** | `check-all.sh`；[README](README.md#conformance) |
| **开源合规性** | Apache-2.0；`NOTICE` 声明参考范围并隔离 LGPL-2.1；语料与词典不分发；依赖唯一且为纯 MoonBit | [`NOTICE`](NOTICE)；[§二](#二章程第七章开源与成果提交要求10-条) |
| **与 MoonBit 生态的相关性** | 填补生态空缺（申报前实测 7 个相关关键词在 mooncakes.io **0 命中**）；四后端可用；公开 API 全部带 `///` 文档；可直接 `moon add` 作为依赖；并有**吃自己狗粮**的 `doccheck` | [README · Ecosystem relevance](README.md#ecosystem-relevance) |

---

## 五、与申报书的一致性对照

> 对照基准：本人通过官方表单提交的《spell.mbt 项目申报书》。
> 章程约束是**单向**的 —— 多做了不算违背，**少做了才算**（L227「应完成申报阶段约定的
> 主要功能」、L245「未完成申报 Proposal 中的主要目标」、L247「与申报内容明显不符」）。

### 5.1 核心功能范围（申报书 §核心功能范围）—— 全部交付

| # | 申报书原文要求 | 状态 | 证据 |
|---|---|---|---|
| 1 | `.aff` 解析：覆盖 `SET` `FLAG` `AF`/`AM` `PFX`/`SFX` `REP` `TRY` `KEY` `IGNORE` `WORDCHARS` `COMPOUND*` 及 `NOSUGGEST` `KEEPCASE` 等特殊 flag | ✅ | `src/aff/`；官方语料 `.good` **841/848 = 99.2%** |
| 2 | 「未实现的指令会**统一记录不直接丢弃**」 | ✅ | `AffFile.unrecognized : Array[UnknownDirective]`；有测试断言其 `name`/`args`/`line` |
| 3 | 「解析出错**标注对应行号**」 | ✅ | `AffParseError(line~, message~)`，`to_string()` 即 `"line N: message"` |
| 4 | `.dic` 解析：词条计数、单词与 flag 映射、转义字符、**四种 flag 格式**（单字符 / long / num / UTF-8） | ✅ | `src/dic/`；各有专门测试 |
| 5 | 词缀引擎：条件匹配语法、前缀锚定词首、后缀锚定词尾、**所有字符按 Unicode 码点处理** | ✅ | `src/affix/`；按 `to_array()`/`char_length()` 处理，含非 BMP 字符测试 |
| 6 | `spell()` 判定：词典直接命中、词缀推导命中、大小写规则适配、各类特殊 flag | ✅ | `src/spell/`；49,568 条真实词典自测与 `hunspell 1.7.3` 判定完全一致 |
| 7 | 配套工具：命令行工具 + 可运行示例 + 基于官方语料的通过率统计 + **数据脚本实测并在 README 公开** | ✅ | `cmd/main`、`examples/`×3、`conformance/`、`bench/`、[`check-all.sh`](check-all.sh) |

### 5.2 三个预期使用场景

| 场景 | 申报书要求 | 状态 | 核实方式 |
|---|---|---|---|
| 1 | 编辑器 / IDE 拼写检查：输出「不在词典内、也无法通过词缀规则推导的单词**和位置**」 | ✅ | `doccheck` 输出形如 `README.mbt.md:42: delibberate`（词 + 文件:行） |
| 2 | 提交前 / CI 文档校对：输入 Markdown 文件或目录，输出可疑词清单**与退出码**，「可以嵌在流程里**自动拦截**拼写错误」 | ✅ | 退出码 `0` 干净 / `1` 发现拼写错误 / `2` 用法或 I/O 错误（wrapper 另有 `3` = 取不到词典）。[`examples/ci-gate`](examples/ci-gate) 离线断言这组契约；本仓库 CI 已用它作为**阻塞步骤** |
| 3 | 用户输入校验：输入单个单词，返回判定结果（是直接收录在词典里，还是能通过词缀规则推导出来） | ✅ | 两种命中均已实现；`check` 对二者都返回 `true`。该括号是对「判定通过」的解释说明，公开 API 不区分「命中来源」 |

> **⚠️ 对照中查出的一处承诺不实，已修复（0.9.2）**
> 场景 2 承诺「退出码可自动拦截」，但对照时实测发现 `examples/doccheck` **无论发现多少
> 拼写错误都返回 0** —— 当时的非零退出码只用于参数错误与读文件失败，**根本没有
> 「发现拼写错误 → 非零」这条路径**，也就是说那句承诺当时**并不成立**。
> 已改为上述 `0/1/2` 契约并加 `--no-fail` 逃生阀，用 5 个用例 + 真实 shell `if` 验证门禁成立。
> 这正是逐条对照申报书的价值：**它能查出一句自己写下的、听起来合理、却从未真正实现的话。**
>
> 附带说明：库的 CLI（`moon run cmd/main -- check ...`）**刻意保持被拒词也退出 0** ——
> 它输出逐行判定流，符合率与基准 harness 都读这个流，被拒词让进程非零会使基准判为
> 「测量失败」。**门禁是 `doccheck` 的职责。**

### 5.3 申报书写明「本期暂不实现」的四项

| 申报书声明 | 实际结果 | 判定 |
|---|---|---|
| 拼写建议引擎 `suggest()` | **已实现**：`REP`、编辑距离 1、有界距离 2、大小写变体、拆分两词、`MAP`、`PHONE`、`ph:`、`KEY`/`TRY` 排序；官方语料 **141/173 = 81.5%** | 🟢 **超出申报书承诺的增量** |
| 完整复合词规则（申报书仅承诺 `COMPOUNDMIN` / `COMPOUNDFLAG` 基础场景） | **远超基础**：德语式复合词、`COMPOUNDRULE`、`COMPOUNDWORDMAX`、`COMPOUNDSYLLABLE`、`COMPLEXPREFIXES`、`CHECKCOMPOUNDPATTERN`、`COMPOUNDFORBIDFLAG` | 🟢 **超出申报书承诺的增量** |
| Hunspell C++ 库 FFI 绑定（声明全程纯 MoonBit） | 未做，且**保持不做** —— 全部库包无 FFI | ✅ 与承诺一致 |
| 编辑器插件与图形界面 | 未做 | ✅ 与承诺一致 |

> **为什么单列**：这两项不是「申报书要求的功能」，而是**申报书主动声明不做、最终却做完了**
> 的部分。验收口径是「完成约定的主要功能」，所以它们属于**加分**，但必须标注清楚归属，
> 否则按申报书逐条对照时会被误读为「项目描述与申报书对不上」。

### 5.4 申报书基本信息的一致性

| 申报书填写 | 交付物实际 | 一致 |
|---|---|---|
| 项目名称：spell.mbt —— MoonBit 的 Hunspell 兼容拼写检查库 | README 与包描述同 | ✅ |
| GitHub 仓库：`https://github.com/Careylq/spell.mbt` | 同 | ✅ |
| 项目方向：工具库（文本处理基础库） | mooncakes.io 归类 `spellcheck`/`hunspell`/`dictionary`/`affix`/`text`/`nlp` | ✅ |
| 是否为移植项目：**否**（参考格式规范从零实现，没有移植源码） | `NOTICE` 同样声明 | ✅ |
| 本项目许可证：Apache-2.0 | `LICENSE` / `moon.mod` | ✅ |
| 仓库需含**不少于 10 个有效 commits** | 远超，且按功能分组、无空提交 | ✅ |

### 5.5 结论

- 申报书承诺的**核心功能 7 条**与**使用场景 3 条全部成立**；唯一一处承诺不实（场景 2 退出码）
  已修复并验证。
- **两项「声明不做却做完了」** 单列为增量，计入实际产出但不计入承诺。
- **两项「声明不做且确实没做」**（FFI、编辑器插件）与承诺一致，无风险。

---

## 六、已实测指标（每条都可用仓库内脚本复现）

### 6.1 官方语料符合率

`bash conformance/run.sh` —— 154 个测试套件、848 个 `.good` 判定：

| 指标 | 通过 | 总数 | 通过率 |
|---|---|---|---|
| `.good`（必须接受） | **841** | 848 | **99.2%** |
| `.wrong`（必须拒绝） | **611** | 613 | **99.7%** |
| `.sug`（期望首选建议被产出） | **141** | 173 | **81.5%** |

未通过的 `.good` **正好 7 个**，全部落在 [§七](#七诚信说明刻意未实现的部分) 已列明的未实现项上：
ALL-CAPS 输入匹配混合大小写词条（6 个判定、4 个不同拼写：`OPENOFFICE.ORG` `UNICEF'S`
`L'AFRIQUE` `IPOD`）、匈牙利 `LANG hu` 的 moving rule（`forróvíz-tartály`）。
未通过的 `.wrong` 只有 2 个：`allcaps2` 的 `iPodos` 与 `limit-multiple-compounding` 的 `foobarbaz`。

> **一个被修正的度量 bug（97.3% → 99.2%）**：早期 harness 用 `paste -d' '` 按**位置**配对
> 输入流与判定流，于是任何**含空格的语料行都会错位并被无条件记为失败**
> （`morph.good` 有 16 行 `drink eat` 这种）。改成「每个非空输入行一个判定、直接计数」后
> 得到 841/848；`841 − 825 = 16` 正是该假象的大小。**引擎行为一个字都没变** ——
> 全量测试与差分测试的结果都逐字未变。

### 6.2 与真实 hunspell 的差分测试

`bash conformance/differential.sh` —— en_US + `/usr/share/dict/words`：

235,976 个词上，与原生 `hunspell 1.7.3` 的判定差异 **199 个（0.084%）**：
「该拒绝却接受」**198 个**，「该接受却拒绝」**1 个**（`Jean-Christophe`）。
这 198 个是 Hunspell 由派生规则承认、本库派生规则尚未覆盖的形态（`-er`/`-ing`/`-ness`/`-ly`
造词），且**不是回归** —— 在引入复合词引擎之前的提交上重跑同一测量，得到完全相同的 198/1。

### 6.3 建议质量口径

`bash conformance/suggest.sh` —— 37 个 `.sug` 文件、173 行非空期望。
`.sug` 只记录**产生了建议的词**，未产生建议的整行省略，因此**无法按行位置配对**。三个口径全部公开：

| 口径 | 结果 |
|---|---|
| 期望的首选建议被产出（按输入顺序做最大单调配对） | **141/173 = 81.5%** |
| 期望首选建议**就是我们的第一条** | **124/173 = 71.7%** |
| 完整复现整个 `.sug` 文件（**Hunspell 自己的判据**） | **7/37 套** |

### 6.4 性能（原生二进制对原生二进制）

`bash bench/run.sh` —— 同一份 `.aff`/`.dic`、同一份词表：

| 指标 | 本库 | Hunspell 1.7.3 | 倍数 |
|---|---|---|---|
| 进程启动 | 0.0020 s | 0.0030 s | 0.67×（略快） |
| 词典加载（49,568 词条） | 0.030 s | 0.007 s | 慢 4.29× |
| **直接命中，仅查找** | **0.34–0.38 µs/词** | 0.36–0.38 µs/词 | **0.89×–1.06×（持平）** |
| 未命中，仅查找 | 9.38–9.60 µs/词 | 1.49 µs/词 | 慢 6.30×–6.44× |

**结论是精确定位的，不是「整体慢 6 倍」**：差距全在**未命中路径**（每个被拒的词要把每条
后缀规则、前缀规则、前缀×后缀叉积和双后缀族全试一遍）与**词典加载**；**直接查表已与
Hunspell 持平**。这两点就是明确、可验证、可排期的优化目标。

> 区间而非单值：重复运行同一脚本时，直接命中这一行会在 **0.89×–1.06×** 之间摆动
> （同一份代码两次跑出了相反的结论），所以这里报**实测区间**而不是挑一次好看的比值。
> 这也正是本项目把「重测」写进流程的原因。

### 6.5 产物体积

wasm **142.2 KiB** · wasm-gc **110.7 KiB** · js 458.1 KiB · native 743.3 KiB。
wasm 产物 142 KiB 且**无 C++ 运行时** —— 这是 wasm 宿主实际下载并运行的负载。

### 6.6 吃自己的狗粮

`bash examples/doccheck/run.sh` 用本库检查本仓库自己的文档与注释：

| 项 | 值 |
|---|---|
| 规模 | 34 个文件、**20,287 个词** |
| 首次运行（无 allowlist） | 标记 **616 处 / 118 个不同词** |
| 应用 109 条 allowlist 后 | **0** |
| **真实拼写错误数** | **0** —— 118 个全是通用英语词典在技术文本上的误报（如实记录） |

本仓库 CI 已经把这个门禁作为**阻塞步骤**（对真拼写错误变红、对网络抖动放行）。

---

## 七、诚信说明：刻意未实现的部分

最终验收看「项目完成度」，因此这里明确列出**未做**的部分，避免任何含糊。
**清单是封闭的：符合率里每一个未通过项都能在这里找到对应条目。**

- **ALL-CAPS 输入匹配混合大小写词条** —— Hunspell 能把 `OPENOFFICE.ORG` 匹配到
  `OpenOffice.org`、`IPOD` 到 `iPod`。本库只把全大写词折叠为小写与首字母大写两种拼写。
  `hunspell(5)` 手册只记录了 `KEEPCASE` / `CHECKSHARPS` 这些 **flag**，没有给出大小写算法
  本身，故不实现也不猜。（这是 6 个 `.good` 缺口的全部原因；连带使 `allcaps2` 的
  `iPodos` 被误接受）
- **匈牙利语 `LANG hu` 的 moving rule** —— 让 `COMPOUNDFORBIDFLAG` 词干在带连字符的复合词里
  重建自身（`forróvíz-tartály`）。`COMPOUNDWORDMAX` / `COMPOUNDSYLLABLE` 已实现，所以 `hu`
  只剩这一个词；手册只点名该规则，没有定义重建过程
- **`limit-multiple-compounding` 的三段复合词拼写检查** —— 该语料期望三段以上的复合词在
  「与某个词典词只差一个编辑」时被拒（`foobarbaz` vs `goobarbaz`）。没有指令要求它，
  手册也未描述，故不猜
- **`COMPOUNDROOT` / `SYLLABLENUM`** —— 已解析进 AST 但未施加；没有语料覆盖
- **ngram 相似度建议通道** —— `MAXNGRAMSUGS` / `MAXDIFF` / `ONLYMAXDIFF` 三个指令
  **已解析进 AST**，但不产生候选。理由：`hunspell(5)` 手册（已核对 1.7.0/1.7.2/1.7.3 英文版、
  语料自带的 `man/hunspell.5` 及其匈牙利语译本）只写了这是「基于公共 1/2/3/4 字符序列的
  相似度检索」，并给出 `MAXDIFF` 默认值 5、范围 0–10 与 `ONLYMAXDIFF` 的语义，
  **从未定义相似度评分函数**（各阶权重、归一化、阈值、何为「差」都没有）。
  该算法只存在于 LGPL-2.1 的 `suggestmgr.cxx`，本项目不能复制，因此不猜测评分函数。
  此外 37 个 `.sug` 套件中有 12 个显式写 `MAXNGRAMSUGS 0`（即**关闭**该通道），
  猜一个默认开启的评分器最可能的结果是让这 12 个**回归**
- **其他建议细节** —— `FORCEUCASE` 已解析并用于判定，但不驱动建议；编辑距离 2 只实现了
  有界的 O(n²) 子集；`PHONE` 把 `^^` 当作普通词首锚点；一个 `CHECKCOMPOUNDPATTERN` 的
  endchars 场景未覆盖。**这是 `.sug` 为 81.5% 而非更高的原因**
- **通用 Unicode 大写表** —— 大写转换是 ASCII 加显式 `İ`/`ı`/`ß` 规则
- **与 Hunspell C++ 库的 FFI 绑定** —— 本项目自行实现，不链接任何拼写器（设计选择）
- **编辑器插件与图形界面**

---

## 八、如何复现

```bash
export PATH="$HOME/.moon/bin:$PATH"

# 一条命令跑完全部闸门与测量（报告写入 .final-check/）
bash check-all.sh

# 或分别运行
moon check --deny-warn --target all   # 0 error, 0 warning
moon test  --target all               # 182 / 186，四后端
moon fmt --check && moon info         # 格式干净；.mbti diff 为空
bash conformance/run.sh               # 官方语料符合率
bash conformance/suggest.sh           # .sug 建议质量
bash conformance/differential.sh      # 与真实 hunspell 的 23.6 万词差分
bash bench/run.sh                     # 性能与产物体积（约 4 分钟）
bash examples/doccheck/run.sh         # 检查本仓库自身文档（退出码即门禁）
bash examples/ci-gate/run.sh          # 离线断言退出码契约
moon run examples/basic               # 可运行示例
```

`conformance/` 与 `bench/` 需要网络（语料/词典运行时拉取，**不随仓库分发**）；
`examples/ci-gate` 与全部闸门**不需要网络**。

---

## 九、验收前检查清单

- [x] `moon check --deny-warn --target all` 无错误、无警告
- [x] `moon build` 通过（wasm / wasm-gc / js / native 四后端 release 均成功）
- [x] `moon test --target all` 全部通过（182 / 182 / 182 / 186）
- [x] `moon fmt --check` 干净；`moon info` 的 `.mbti` diff 为空
- [x] CI 全步骤 success（14 步，含两步阻塞式门禁）
- [x] README 与本文的数字全部是**实测**的，且由 `check-all.sh` 可复现
- [x] `NOTICE` 的参考范围与许可证声明准确
- [x] `DEVLOG.md` 已补齐到最新
- [x] 申报书承诺的范围已逐条对照（[§五](#五与申报书的一致性对照)）
- [x] 仓库内无模板残留、无死链、无来源不明内容
