# 设计与取舍

## 解决的问题

JSON 配置经过多人修改后，文本冲突不能直接解释业务字段的变化。MoonConfig 将变更表示成 JSON Pointer 路径和 JSON Patch 操作，并通过共同版本 base 判断双方是否真的修改了同一位置。

核心是 MoonBit 库，CLI 和浏览器共享同一个编译后的引擎。JavaScript 只负责读文件、显示、下载及本地服务。所有配置比较、路径解释、补丁执行和合并判断都在 MoonBit 中完成。

## 数据流

`JSON 文本 → MoonBit JSON 解析 → 验证 → diff / apply / merge → MoonBit JSON 序列化`

CLI 和演示将原始 JSON 文本作为 JSON 字符串字段传给引擎，再分别解析各文档；不把未验证的文档文本拼接进请求对象。JavaScript 的 JSON.parse 仅用于读取结果状态；实际输出由引擎序列化，避免大整数在 JavaScript Number 中四舍五入。

## 三方合并

比较每个位置的 base、ours、theirs，字段缺失使用 Option[Json] 表示，与 null 分开。

| 条件 | 结果 |
| --- | --- |
| ours 与 theirs 相同 | 采用共同结果 |
| ours 与 base 相同 | 采用 theirs |
| theirs 与 base 相同 | 采用 ours |
| 双方都是对象，base 是对象或缺失 | 按键递归 |
| 其他双方不同的变更 | 记录冲突，保留 base |

当 base 是标量、双方改成不同对象时，在当前位置报告类型替换冲突。双方新增不同字段的对象可合并。数组作为一个完整值：数组索引可能因插入而变化，目前不推测元素身份。

冲突预览不会选择某一方。`clean=false` 必须由调用方人工处理；原字段缺失时预览继续保持缺失。冲突候选包含 presence 标记。

## 显式解决与校验补丁

resolve 从 base/ours/theirs 重新计算冲突，再检查每个 Decision 的路径、唯一性、完整性和自定义值。Choice 为 Base/Ours/Theirs/Set(Json)/Delete，Set(null) 与 Delete 不同。禁止根删除。检查完整后统一应用决策，不对外暴露部分结果。

ResolvedMerge 的字段可供外部读取，不能在外部直接构造。Json 和 Array 自身仍为可变容器，调用方修改返回数据后需重新核对。

guarded_diff 在普通 diff 前加 Test("", base)。所有字段的语义变化都会拒绝回放，原对象键顺序和数字等值写法不会影响校验。这是一份带前置条件的标准补丁，不提供签名或字节认证。resolve 回放该补丁并用数值精确的 same 比较最终配置，然后返回结果。

补丁解析按每个 value 校验深度和节点，避免 base 校验加目标文档时被错误地按一个文档累计节点。操作数仍有独立上限，guarded_diff 会为前置 test 留出一个额度。

## 补丁与所有权

支持 RFC 6902 的六种操作；JSON Pointer 严格解码 ~0、~1，数组索引拒绝前导零、负数和溢出。move 使用删除后的索引，拒绝移动到自己的子节点。

apply 从输入副本开始，失败不会向调用方返回中间文档。输入、返回值和补丁值深拷贝隔离。根 remove 被明确拒绝：此 API 的返回类型必须是 JSON，无法表示“整个文档不存在”。

diff 对对象键按 Unicode 字符字典序输出，数组整体 replace。若生成超过 10000 个操作，改用一次根 replace，使生成的补丁仍可被 apply 使用。没有最短补丁保证。

## 数字

使用解析器保留的十进制文本归一化数值，移除多余零并整理指数。1、1.0、10e-1 相等；9007199254740992 与 9007199254740993 不相等。不依赖 Double 做精确比较。输入如果在调用前已经转成 Double，丢失的精度无法恢复。

## 资源限制

每份文档/操作值最多 128 层、100000 个 JSON 节点；10000 个补丁操作、10000 个决策、128 段路径；字符串入口最多 4000000 个 UTF-16 单位；十进制指数 ±1000000。每次补丁操作后验证中间结果，合并及解决完成后验证结果。网页最多交互处理 200 个冲突。

限制用于阻止显著过大的输入，不构成恶意输入下的严格 CPU/内存隔离。当前实现未提供流式解析；递归深度验证发生在 JSON 解析之后。

## 后续方向

显式冲突解决 UI 和跨模块消费示例已完成。后续优先完成远程交付、Mooncakes 发布与安装验证，再收集真实案例决定数组身份策略。YAML/TOML 和 schema 验证不计入当前能力。
