# moon-ipp 0.1.4 边界复核

本轮针对合法输入误拒绝、非法输入漏检、各阶段行为不一致及真实网络错误检查。历史其他项目的验收通知仅用于确定检查方法，未作为 moon-ipp 的拒绝结论。

## 已复现并修复

| 问题 | 修复与验证 |
| --- | --- |
| 合法联合类型多值被当作混合标签错误 | 通用编解码和 JSON 保留联合值；能力读取支持 keyword/name。任务编号、状态、目标等语义校验仍严格。 |
| 合法空 final Send-Document 被拒绝 | 允许 last-document=true 时无文档；false 时仍报错。请求构造、校验、编解码及客户端行为一致。 |
| 不完整 Unicode 造成 Wasm/native 中止或 JS 静默改写 | UTF-8 编码前检查代理对，统一返回 Invalid；正确 emoji 仍能无损往返。 |
| 将负有符号长度误当成较大正长度 | 在读取 payload 前拒绝高位长度；写入也拒绝不能表示的长度。 |
| octetString 与属性名称等边界不符合标准 | 检查 1023/1024 字节与名称语法；keyword 值保留版本号等已注册例外，不套用属性名称首字母规则。未知扩展值保留独立的 wire 长度上限。 |
| 重复 out-of-band 值被接受 | 整个属性只能有一个 out-of-band 值；对普通属性和集合成员同样执行。 |
| 构造值通过校验却无法编码 | 递归校验标量与集合内容，拒绝非法 keyword、非正 enum 等，避免校验与编码判断矛盾。 |

上面的问题先加入测试，原实现 8/8 失败，包含实际 Wasm 中止；修复后全部通过。依据：[RFC 8010 编码](https://www.rfc-editor.org/rfc/rfc8010.html#section-3.2)、[RFC 8011 联合属性](https://www.rfc-editor.org/rfc/rfc8011.html#section-5.1)、[空结束请求](https://www.rfc-editor.org/rfc/rfc8011.html#section-4.3.1.1)。没有依靠增加测试数量代替检查协议规定。

## 同时加固的错误路径

- Send-Document 提交文档及带有任务组的响应需要可用且相同的 job-id；缺失或不匹配时返回 SubmissionUncertain，不自动重发。空结束请求兼容 CUPS 不重复返回任务组的成功确认，仍核对请求编号。
- JS 传输改用显式取消、禁止重定向的 fetch；真实 Node.js HTTP 测试验证二进制请求、精确响应上限、307 不转发、403、错误媒体类型、截断与超时取消。
- JSON 在构造树时累计 wire 预算，防止先分配许多较大字节值才发现总量超限；嵌套集合的结构开销也计入。
- CLI 拒绝重复 JSON 键、超过 128 层的 JSON、无关参数和超限文件；文件在结束、错误路径都关闭。
- 属性名称查重改用 Map；大能力集合比较采用分桶匹配，保留多值重复次数及精确值语义。
- 请求编号最大值回绕后仍为正数，失败交换会释放客户端；本地无效参数不发送网络请求。

## 验证范围

独立 CUPS 在首轮后指出 keyword 的属性名称规则过严，会误拒绝合法的 `ipp-versions-supported` 版本值；已改为保留注册 keyword token（包括版本号和 raster 的大小写值），新增回归。

check、build、fmt 及 MSVC 兼容探针通过，公开 `.mbti` 无变化。有效实现统计见 evidence/source-count-0.1.4.json，排除测试、生成接口、脚本、依赖与 C 胶水。保留 5,000 个异常报文用例，新增 2,000 个固定种子合法报文检查 wire/JSON 往返和精确字节上限；测试集合深度 0、1、16、64。

最终[成功 CI 40179677640](https://github.com/liyun6666/moon-ipp/actions/runs/40179677640) 对应源码 `24d2652d25f2a7a3986e3c2f9ba79a11b9591405`。Windows/Linux 均通过 wasm-gc **69/69**、JS **93/93**、native **95/95**，以及检查、构建、格式和 Windows MSVC 兼容探针。有效实现 **4,806 行**。

Linux 独立 CUPS 完成全部既有打印、取消、分阶段提交、队列、ipptool、文档字节比较及大 JSON 往返；新增 `scripts/interop_boundaries.mbtx` 的先发送文档、再空结束流程也通过，任务完成且只保留一个字节未变化的文档。[既有场景摘要](evidence/cups-result-0.1.4.json)、[空结束摘要](evidence/cups-boundary-result-0.1.4.json)；原始命令及服务端日志在同一成功 CI 的 artifact。测试脚本在完成时取消后台 CUPS 并等待回收，不遗留后台进程。

第二轮 CUPS 已通过全部既有场景，并在空结束请求暴露兼容差异：服务端返回成功状态和匹配的请求编号，但不再重复任务属性组。客户端已只对这种不增加文档的确认放宽任务组存在要求；若返回了任务组，仍严格检查其任务编号与结构。

## 发布与独立安装

`moon publish` 对打包和解包后的工程检查成功，发布返回 HTTP 200；注册表确认 **0.1.4**、未撤回，时间为 2026-10-25 09:14:27 UTC（北京时间 17:14:27）。[Mooncakes](https://mooncakes.io/docs/liyun6666/moon-ipp)、[GitHub Release](https://github.com/liyun6666/moon-ipp/releases/tag/v0.1.4)。

独立消费工程实际下载 0.1.4，JS 严格检查和消费测试 1/1 通过，覆盖公开 codec/client API、联合值 wire/JSON 往返及空结束请求。下载包的全部 **45 个代码与构建支持文件**与上述源码提交一致，无本地路径依赖；见[发布核验](evidence/release-verification-0.1.4.json)。本轮后续文档提交不改变发布代码。

`client/moon.pkg` 仅关闭后端互斥导入产生的 unused_package 提示，其他诊断及 --deny-warn 保留。没有关闭运行时检查、UTF 校验或 C4005。响应正文有 byte 上限，HTTP 头部资源策略仍由网络后端负责；不将正文上限描述为整个 HTTP 协议的内存保证。

这些验证不等于对任意输入、任意设备和未来工具链版本的无缺陷证明。未实现功能仍按 README 边界说明；本轮没有修改其他项目或提交飞书表单。
