Skip to content

spec: hour/minute/day-shaped deadline keys in incident-response, training, change-management and ESignature schemas have zero readers and no EXPERIMENTAL tag (ADR-0049 shape) #14477

Description

@os-zhuang

Found while measuring #13801 (duration-shaped declarations in packages/spec). Not addressed there — #13801 is scoped to the wall-clock/business-hours misread on live declarations; this card is the enforce-or-remove question on declarations nothing reads.

What was measured

Four packages/spec schema files declare hour/minute/day-shaped deadline and SLA keys that no package outside packages/spec reads (git grep over packages/** excluding packages/spec, tests and changelogs: zero hits for every key below), and none of the four carries the ADR-0049 [EXPERIMENTAL — not enforced] tag (grep -c EXPERIMENTAL = 0 in each file):

schema file keys (all bare numbers, unit in .describe() prose only)
packages/spec/src/system/incident-response.zod.ts IncidentResponsePhase.targetHours (:97), IncidentNotificationRule.withinMinutes (:142), regulatory deadline hours (:154), auto-escalation minutes (:177), IncidentResponsePolicy.triageDeadlineHours (:346), retentionDays (:363)
packages/spec/src/system/training.zod.ts TrainingCourse.durationMinutes (:89), validityDays (:104), recertification interval days (:185), grace-period days (:197), reminder lead days (:209)
packages/spec/src/system/change-management.zod.ts durationMinutes (:97), estimatedMinutes (:150, :285)
packages/spec/src/data/document.zod.ts ESignatureConfig.expirationDays (:218), reminderDays (:224)

All of them are on the published authorable surface (packages/spec/authorable-surface/system.json:508-521, :1308-1314; data.json for ESignatureConfig) and in the exported API surface (packages/spec/api-surface/system.json), so an author can write triageDeadlineHours: 4 today and nothing on the platform will ever act on it — the same declared-but-inert shape ADR-0049 names, here on SLA-shaped numbers rather than security bits. The schemas are exported from packages/spec/src/system/index.ts:68 but mounted by no stack key (stack.zod.ts does not reference them) and registered as no metadata type.

Why it is filed rather than fixed in #13801

#13801's ruling is about making the clock semantics of live duration declarations un-misreadable. An inert declaration has no clock to misread — its disposition is enforce-or-remove (ADR-0049 / the spec-property-retirement playbook), which is a separate decision per schema family (ISO-27001 compliance shapes vs the e-signature config). The 2026-06 liveness ledgers under docs/audits/ have no mention of incident-response, training or change-management, so this family appears to have missed the audit.

Suggested disposition (for triage, not decided here)

Per family: tag [EXPERIMENTAL — not enforced] in the describe text if a consumer is roadmapped, or retire via ADR-0087 conversion if none is. Either way the JSON-schema/reference-docs output (content/docs/references/**, generated from .describe()) stops advertising a deadline the platform does not keep.

Refs #13801.


Triage — graded

Spot-checked at origin/main 4a37870: grep -c EXPERIMENTAL is 0 in all four files, and the sampled keys (triageDeadlineHours, expirationDays, validityDays) have zero readers anywhere in packages/** outside packages/spec. The measurement holds.

The card is right that this is enforce-or-remove and right that it is a per-family question. Graded as a decision: retiring keys that sit on the published authorable surface is an ADR-0087 conversion each, and "is a consumer roadmapped" is product knowledge the seat does not have. Whoever executes after the ruling should run the spec-property-retirement playbook rather than improvising the route.

<!-- os-decision-facets -->

  • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 平台今天在公开的可编写面上摆着一批期限键:事故triage 几小时、证书多少天过期、电子签名多少天失效。作者可以写,写完平台永远不会照做。这不是「还没实现」,而是一份平台没打算守的承诺印在了参考文档里(那些文档正是从这些 describe 生成的)。ADR-0049 的 enforce-or-remove 就是为这个形状立的。长远终态:公开面上的每一个键,要么被执行,要么被标注为未执行,要么不存在 —— 三者之外没有第四种。①指向收窄:没有路线图的整族退役。
  • ② 实际业务拉动 —— 零。四个文件、十五个键,全仓没有一个读取方,也没有客户在报。⇒ 按分歧推荐序,零拉动 ⇒ 荐④不扩散,而④在这里正好也指向退役。
  • ③ 防 AI 犯错 —— 出错时谁看到什么:一个 AI 作者读参考文档,看到 triageDeadlineHours,合理地认为写上 4 平台就会在 4 小时后升级事故。它不会。没有报错、没有告警、没有任何反馈 —— 只有一条永远不会触发的 SLA,而这恰恰是合规场景里最不能静默失败的东西(ISO-27001 形状的键尤其如此)。[EXPERIMENTAL — not enforced] 标注是最低限度的响亮;退役是彻底的响亮。
  • ④ 创业阶段不扩散 —— 每一个已声明的键都是永久义务:向后兼容、迁移路径、文档、以及「将来真要实现时得按这个形状实现」的约束。十五个没有消费者的键,是十五条白背的义务。remove 优于 declare-and-maintain,这一条在本卡上是字面意义的。

推荐:A —— 按族分别处置,默认退役。incident-response / training / change-management 三族(合规形状、无消费者、连 2026-06 的 liveness 台账都没收录),走 ADR-0087 转换退役,执行时按 spec-property-retirement playbook 走,⛔ 不要自创路线。对 ESignatureConfig(document.zod.ts)单独判:它与已在跑的文档子系统同族,最可能是四族里唯一有路线图的,若确有,给它 [EXPERIMENTAL — not enforced] 标注而不是退役。①④同向,②零拉动不构成保留理由。
回退:B —— 四族全部只加 [EXPERIMENTAL — not enforced] 标注,不退役。 若维护者判定这批合规形状是有意留下的路线图占位(ISO-27001 是可预期的商业需求),那就把「未执行」这件事说清楚,并把它们补进 liveness 台账,以免下一轮审计再次漏掉。代价:十五条永久义务原地保留。
置信缺口(本分析看不见什么): 看不见路线图 —— 这四族到底有没有计划中的消费者,是唯一能把 A 翻成 B 的变量,而它不在代码里。另外本席只抽验了三个键的读取方(triageDeadlineHours / expirationDays / validityDays),不是全部十五个;执行前应把卡面那张表整表重跑一遍,因为「零读取方」是整个推荐的地基。

Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions