摘要
- RFC 9661 把脚本内容上传、语法与能力验证、
SieveScript对象写入以及单一活动脚本切换分成不同动作。 SieveScript/set成功并返回isActive=true,证明的是对象状态变化,而不是所有最终投递 worker 已装载该 blob,也不是某封邮件已经得到预期处置。- 可辩护的回执必须连接 blob 哈希、验证时的能力集、条件状态、激活响应、跨接口读回、worker 版本、测试邮件轨迹与最终结果。
变更窗口结束时,一切都是绿色。新脚本已经上传,通过验证,被创建并借助 onSuccessActivateScript 设为活动状态;响应同时报告旧脚本已停用。几分钟后,测试邮件却进入旧规则指定的文件夹。
这不必然意味着 API 报错了。更可能的解释是:控制面已经完成了它承诺的事务,而执行面仍处于另一代状态。
RFC 9661 为通过 JMAP 管理 Sieve 脚本定义数据模型。一个 SieveScript 包含服务器设置的 id、账户内唯一名称、指向原始脚本的 blobId,以及服务器设置的 isActive。每个账户最多只有一个活动脚本。规范让“存了什么、声明谁活动”变得清晰,却没有规定邮件平台内部如何把该状态同步到所有最终投递进程。
“已激活”之前有三份不同的回执
上传只证明服务器接收了一组字节。SieveScript/validate 在不存储脚本对象的前提下检查内容是否有效,以及 require 中的扩展是否受支持。它既不是保存回执,也不是激活回执。RFC 5228 还明确区分编译期错误和运行期错误:语法正确的脚本仍可能在处理真实邮件时因资源、动作组合或瞬时故障而失败。
对象写入遵循 RFC 8620 的通用 JMAP /set 规则。ifInState 可以阻止客户端把修改应用到已经变化的集合上,避免并发覆盖。这是对象层的乐观并发控制。状态串是不透明同步标识,并非脚本字节的密码学证明,也没有替某个 worker 对其内存状态签名。
激活本身又多一层原子性:只有创建、修改、删除全部成功,onSuccessActivateScript 才切换活动脚本。服务器还必须在响应中报告被激活和被停用的对象。这一设计消除了 JMAP 事务内部的半成品,却不能消除事务边界之外的复制延迟、编译缓存、失效队列积压或分批发布。
两个管理接口一致,执行面仍可能分裂
RFC 9661 旨在让 JMAP 与 ManageSieve 看到同一组脚本。因此,切换后从两个接口读回活动名称和内容,是必要检查。若两边不同,存储或投影已经失配。
即使两边相同,也只能说明它们可能读到了同一个权威存储。某些投递进程可能定时刷新,某些依赖消息队列,某些从副本读取,还有一些把编译后的规则长期放在内存里。分批更新期间,新旧 worker 完全可能同时存在。
真正需要保存的不是“Sieve 已开启”这个布尔值,而是一组可关联事实:账户、脚本 id、blob 哈希、活动状态代次、投递 worker 身份、邮件测试标识、执行决定。没有这个连接,控制面和邮件面各自真实的日志仍可能描述不同对象。
邮件结果必须独立观察
Sieve 在最终投递时执行。keep、fileinto、redirect 与 discard 对应不同结果。邮件出现在目标文件夹,是比激活响应更接近结果的证据,但仍需确认测试账户、收件人、worker 和规则版本。邮件没有出现尤其不能直接证明 discard:上游拒绝、延迟、垃圾邮件处理、路由错误或存储故障都可能造成相同表象。
稳健的测试应从真实入口注入带唯一标识的邮件,保留接收记录,捕获最终投递 worker 与脚本代次,并观察实际文件夹、重定向或丢弃决定。隐私要求较高时,可使用加盐测试标识和受限结果码完成连接,无需留存正文。
VacationResponse 展示了“谁有权改”
RFC 8621 定义 VacationResponse。当服务器用 Sieve 脚本实现自动回复时,RFC 9661 允许通过 JMAP Sieve 读取和激活它,却禁止用 SieveScript/set 修改或删除其内容;内容所有权属于 VacationResponse/set。
这条规则把“能看见、能启停”与“有权改写”分开,避免两个合法接口同时成为作者。运维记录也应保存脚本来源:人工编辑、VacationResponse 生成、备份恢复、ManageSieve 或自动化。对象正确而来源不明,仍可能绕过授权流程。
RFC 9404 提供 blob 管理方法,RFC 9425 提供配额可见性,IANA JMAP 注册表 固定公共能力、数据类型和错误码。它们都改善了边界条件,却不会观察某封邮件到底执行了哪条规则。
从结果反向拼接证据
先确定测试邮件的预期动作,再记录实际处理该邮件的 worker 与脚本代次;把代次解析到活动脚本 id 和精确 blob 哈希;随后保留激活响应、切换前后状态、ifInState 前提、验证结果和当时的能力快照;最后从 JMAP 与 ManageSieve 读回同一内容。
负向测试同样重要:激活不存在的 id 时,现有活动脚本不应变化;删除活动脚本应返回 sieveIsActive;语法有效但会触发受控运行错误的脚本,应产生可分类结果;VacationResponse 所有的脚本应拒绝从错误接口写入;配额压力和 worker 重启也应被演练。
Heng Lu 的最小初始规范给出合适边界:共同规范保持最小、可实现、可审计,本地架构则用证据承担责任。现实层阻止“活动”这个标签借用“已执行”的权威;运行代码优先把最终判断放回真正改变邮件命运的位置。
RFC 9661 让活动对象可管理。领导层必须继续追问:究竟是哪一代代码处理了哪一封邮件。
来源
- RFC 9661 — HTML
- RFC 9661 — 规范文本
- RFC 9661 — XML 源文件
- RFC Editor — RFC 9661 信息页
- RFC 9661 勘误查询
- IETF Datatracker — RFC 9661 历史
- RFC 8620 — JMAP 核心
- RFC 5228 — Sieve
- RFC 5804 — ManageSieve
- RFC 8621 — JMAP Mail
- RFC 9404 — JMAP Blob 管理
- RFC 9425 — JMAP 配额
- IANA — JMAP 注册表
- Heng Lu — Running-Code Primacy
- Heng Lu — Minimum Initial Specification
- Heng Lu — Reality Layers
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance

