摘要

  • JSCalendar 2.0 草案第 21 版增加了一项很小却关键的条件:Task 没有显式总 progress 时,至少要有一名参与者提交进度,默认值才可能是 completed。
  • 沉默不是失败,也不是正在进行;但它同样不是完成证据。系统应同时保存报告人数、收到的值、规则版本,以及最终状态是显式声明还是推导结果。

想象一个项目表格:任务列出了参与者,但进度栏全部为空。没有人说已经完成,也没有人报告失败或正在处理。仪表盘却亮起绿色,因为在一个没有任何值的集合中,“所有进度值都是 completed”没有遇到反例。

这正是 JSCalendar 2.0: A JSON Representation of Calendar Data 第 21 版中一个短句所处理的边界。文件在 2026 年 10 月 2 日进入 IETF Datatracker。修订对象不是任务内容,而是 Task 未显式填写总 progress 时,系统如何从参与者记录中得出默认状态。

第 20 版延续 RFC 8984 已经公布的表述:如果所有参与者的 progress 值都是 completed,Task 默认完成。第 21 版加入存在性条件:至少一名参与者必须实际拥有 progress 属性,并且所有拥有该属性的参与者都报告 completed。

这不是文字洁癖。在形式逻辑和一些程序表达中,对空集合说“所有元素都满足条件”可以得到真。如果规范只写“所有进度都已完成”,实现者、查询语言或规则引擎便可能把零条进度当作没有反对票。冻结的资料没有证明任何真实产品这样运行过,因此本文不会制造事故叙事。但新版本确实在共享语义层消除了这种可能性。

新规则也不等于“每一名列出的参与者都必须报告”。参与者的 progress 是可选字段。一个 Task 可以列出十人,只有两人提交进度;只要这两名报告者都写 completed,而且 Task 没有显式总进度,默认结果仍可为 completed。另外八人的沉默不会自动阻塞。第 21 版禁止的是在报告数为零时推导完成。

因此,分母必须进入决策回执。“两名报告者中的两名完成”和“十名参与者中只有两名报告且均完成”可以产生同一个 JSCalendar 默认值,却不是同一个管理事实。前者说明谓词是否成立,后者说明证据覆盖率。只显示一个绿色聚合值,会把领导层最需要追问的差异删掉。

默认规则有明确次序。首先,至少存在一个参与者进度值,且所有已提供的参与者进度都是 completed,才推导完成。如果这一步不成立,只要有一条 failed,默认就是失败。如果没有失败但至少有一条 in-process,默认就是正在进行。其余情形——包括没有任何人报告——落到 needs-action。

次序决定混合情形。completed 与 failed 并存不是多数表决,而是 failed;completed 与 in-process 并存得到 in-process。缺失值不会被虚构成失败、进行中或完成。它继续保持缺失,规则只评估实际存在的参与者进度值。

这套聚合仅在 Task 级 progress 缺省时运行。如果有权写入的生产者明确填了总进度,参与者推导不会覆盖它。于是同一个 completed 可能有两种来源:一项直接声明,或者一套默认规则的输出。审计若只保存最后一个词,就无法复演是谁作出了什么判断。

参与者进度本身也有前提。第 21 版只允许它出现在 Task 内部的 Participant 上;设置时必须有 calendarAddress,并且该参与者的 participationStatus 必须是 accepted。基础值为 in-process、completed 与 failed,另可按草案规则使用 IANA 注册值或厂商扩展值。Task 总进度虽然允许 cancelled,参与者进度的基础词表却不包含 cancelled。

percentComplete 也不能偷偷替代它。草案把百分比定义为另一个可选的 0 到 100 整数,可按各自条件用于 Task 或 Participant。它能提供更细视图,却没有被定义为分类状态的平均数。除非本地政策另有明确且可审计的转换,系统不应把 100 自动写成 completed,也不应把缺失百分比当成零。

旧标准说明了这种分离为何重要。RFC 5545 把 VTODO 的 STATUS、完成时间和参加者的参与状态作为不同表面;RFC 5546 也区分组织者控制的对象状态与调度交换中的参加者 PARTSTAT。JSON 表达更便利,并不会让个人贡献和任务整体状态变成同一个事实。

传输又是另一层。JMAP Calendars 可以携带并同步日历数据,CalDAV 调度有自己的身份、投递和权限规则。API 保存成功、调度消息被接收,或某个名称出现在当前 IANA 注册表,都不能证明特定产品已经执行第 21 版的聚合。Datatracker 当前把该文件列为 CALENDAR EXTENSIONS 工作组、IETF stream、拟议 Proposed Standard、处于 AD Evaluation;它还不是 RFC。

更不能把日历状态当作现实结果回执。参与者可以标记贡献完成而文件并未到达;机器可以同步一个 Task,而外部作业已经失败;显式总状态也可能错误。第 21 版的改进,是不再从零报告制造完成。它没有证明每条报告都真实,更没有证明现实义务已经履行。

Lu Heng 的 Minimum Initial Specification 给出了适当尺度:共同层只需要一条足够确定的规则,阻止“没有观察”变成“已经完成”。Running-Code Primacy 继续追问实际运行的是哪一版语义、哪条查询、哪个默认与覆盖路径。Reality Layers 则防止一个有效的调度状态获得它从未观察过的履约权威。

真正可用的控制是一份聚合回执:保存 Task UID 和 version、显式总进度(若有)、参与者总数、报告人数、被接受的进度值、扩展值、谓词次序、推导结果、执行该规则的软件版本以及触发的下游动作。回执必须写清 derived 还是 asserted,而不是只重复最终状态。

一条很短的存在性条件承担了严肃的制度工作:所谓一致证据,至少要先有一项证据。沉默可能意味着还需追问,但不能被方便的默认值升级为成功。

来源