从 #4001 批 13 拆出(发现,不是缺陷修复)。批 13 的任务是把 ui/ 六个交互/呈现配置文件从 .strip 收紧。其中五个在「收紧前先验证可授权性」这一步上实测为负,所以没有收紧 —— 本 issue 记录测量结果与它引出的那个真正的问题。
测量结果
| 文件 |
z.object 站点 |
是否可从授权路径到达 |
packages/spec/src/ui/touch.zod.ts |
7 |
否 |
packages/spec/src/ui/animation.zod.ts |
4 |
否 |
packages/spec/src/ui/dnd.zod.ts |
4 |
否 |
packages/spec/src/ui/keyboard.zod.ts |
4 |
否 |
packages/spec/src/ui/offline.zod.ts |
3 |
否 |
| 合计 |
22 |
|
同批的第六个文件 ui/responsive.zod.ts(4 站点)测量为可达(page.components[].responsive / .responsiveStyles),已在 #4001 批 13 收紧,不在本 issue 范围内。
三条独立证据(2026-08-03,origin/main fe83042)
1. 静态 —— 没有承载键。 packages/spec/src 里除了 ui/index.ts 这个 barrel 之外,没有任何模块 import 这五个文件。协议里不存在 component.touch、page.dnd、app.motion 这类槽位,也就是说作者在任何一份元数据里都写不出通向这些形状的键。
2. 图可达性 —— BFS 全不命中。 用 build-schemas.ts 给 #4650 删除检查所用的同一套闭包(24 个 metadata-type root,来自 listMetadataTypeSchemaTypes(),外加 defineStack 的 ObjectStackSchema)对本次构建的内存 Zod 图做 BFS,6849 个节点,这 22 个 schema 一个都没走到。同一次运行里三个阳性对照全部命中 root-graph:
PageSchema(metadata-type root)
WebhookSchema(批 11 判定「可授权」所依据的 defineStack({ webhooks }) 那条门)
StateMachineSchema(批 10 判定「可授权」所依据的 agent.lifecycle 那条门)
对照通过,说明「不可达」是关于图的事实,而不是仪器坏了 —— 这正是 #4852 重测留下的教训:先证明尺子是准的。
3. 调用点 —— 没有 parse。 objectstack / objectui / 三个示例应用里,除各文件自己的单测外,不存在对这些 schema 的 .parse() / .safeParse()。objectui 只 re-export 推断出的类型,并且明确写了不 re-export 校验器(@object-ui/types,#2561 的注释)。
由此引出的问题
这不是「要不要 strict」的问题。strict 是 parse 的属性,而这里根本没有 parse —— 收紧它们不会拦住任何东西,只会花掉一次 v17 的破坏性变更让文件「看起来完成了」,并留下本仓账本自己警告过的那件东西:「一个被精确校验的死槽位是更有说服力的谎言」(docs/audits/2026-07-unknown-key-strictness-ledger.md,#4583 DatasourceCapabilities 那一行)。
真正要决的是 ADR-0049 enforce-or-remove:
为什么这条不能拖着不判
content/docs/references/ui/{touch,dnd,keyboard,animation,offline}.mdx 是已生成并已发布的,读起来就是一张授权表(| **dragItem** | … | optional | Configuration for draggable item |)。authorable-surface.json 里也躺着这五个文件的 58 个键,而那份文件的自述是「every AUTHORABLE key in the spec — what a metadata author may write, which for this platform IS the third-party API」。
也就是说,对 AI 作者而言,当前状态的失效模式不是「DndConfigSchema 里的静默剥离」,而是文档在宣传一套没有承载键的词汇:AI 照着 dnd.mdx 往页面组件上写一个 dnd: 块,会被 PageComponentSchema.strict()(ADR-0089 D3a)直接拒绝,因为任何组件上都没有 dnd 这个键。这正是 Prime Directive #10 那句「never advertise or demo a capability the runtime doesn't actually deliver」。
相关
按 AGENTS.md Prime Directive #10 归档,未指派。
从 #4001 批 13 拆出(发现,不是缺陷修复)。批 13 的任务是把
ui/六个交互/呈现配置文件从.strip收紧。其中五个在「收紧前先验证可授权性」这一步上实测为负,所以没有收紧 —— 本 issue 记录测量结果与它引出的那个真正的问题。测量结果
packages/spec/src/ui/touch.zod.tspackages/spec/src/ui/animation.zod.tspackages/spec/src/ui/dnd.zod.tspackages/spec/src/ui/keyboard.zod.tspackages/spec/src/ui/offline.zod.ts同批的第六个文件
ui/responsive.zod.ts(4 站点)测量为可达(page.components[].responsive/.responsiveStyles),已在 #4001 批 13 收紧,不在本 issue 范围内。三条独立证据(2026-08-03,
origin/mainfe83042)1. 静态 —— 没有承载键。
packages/spec/src里除了ui/index.ts这个 barrel 之外,没有任何模块 import 这五个文件。协议里不存在component.touch、page.dnd、app.motion这类槽位,也就是说作者在任何一份元数据里都写不出通向这些形状的键。2. 图可达性 —— BFS 全不命中。 用
build-schemas.ts给 #4650 删除检查所用的同一套闭包(24 个 metadata-type root,来自listMetadataTypeSchemaTypes(),外加defineStack的ObjectStackSchema)对本次构建的内存 Zod 图做 BFS,6849 个节点,这 22 个 schema 一个都没走到。同一次运行里三个阳性对照全部命中root-graph:PageSchema(metadata-type root)WebhookSchema(批 11 判定「可授权」所依据的defineStack({ webhooks })那条门)StateMachineSchema(批 10 判定「可授权」所依据的agent.lifecycle那条门)对照通过,说明「不可达」是关于图的事实,而不是仪器坏了 —— 这正是 #4852 重测留下的教训:先证明尺子是准的。
3. 调用点 —— 没有 parse。
objectstack/objectui/ 三个示例应用里,除各文件自己的单测外,不存在对这些 schema 的.parse()/.safeParse()。objectui 只 re-export 推断出的类型,并且明确写了不 re-export 校验器(@object-ui/types,#2561 的注释)。由此引出的问题
这不是「要不要 strict」的问题。strict 是 parse 的属性,而这里根本没有 parse —— 收紧它们不会拦住任何东西,只会花掉一次 v17 的破坏性变更让文件「看起来完成了」,并留下本仓账本自己警告过的那件东西:「一个被精确校验的死槽位是更有说服力的谎言」(
docs/audits/2026-07-unknown-key-strictness-ledger.md,#4583DatasourceCapabilities那一行)。真正要决的是 ADR-0049 enforce-or-remove:
Notification/NotificationConfig、spec 双源清账 C13+C15(一单):DataSyncConfig + ConflictResolution(automation 死删 / integration 改名 / ui 保名)—— 4 条 #4738 删除automation/sync.zod.ts同类。代价:@objectstack/spec/ui的公开导出面收缩,需要墓碑 + 变更集迁移说明;并且要和 objectui 协调 ——@object-ui/core的DndProtocol/KeyboardProtocol与@object-ui/mobile的useSpecGesture/useTouchTarget都按这些类型写成(注意:这些 helper 本身在两个仓里也都没有调用方,只是导出的库 API),另有跨仓 parity 测试。ui/component.zod.ts的 SDUI 组件定义,或page.components[])加上touch/dnd/keyboard/animation/offline槽位,并让渲染器真的读。这是把 objectui 那几个 helper 从「导出但没人调」变成活的接线 —— 但那是一个真正的特性,不是清账。authorable-surface.json。为什么这条不能拖着不判
content/docs/references/ui/{touch,dnd,keyboard,animation,offline}.mdx是已生成并已发布的,读起来就是一张授权表(| **dragItem** | … | optional | Configuration for draggable item |)。authorable-surface.json里也躺着这五个文件的 58 个键,而那份文件的自述是「every AUTHORABLE key in the spec — what a metadata author may write, which for this platform IS the third-party API」。也就是说,对 AI 作者而言,当前状态的失效模式不是「
DndConfigSchema里的静默剥离」,而是文档在宣传一套没有承载键的词汇:AI 照着dnd.mdx往页面组件上写一个dnd:块,会被PageComponentSchema.strict()(ADR-0089 D3a)直接拒绝,因为任何组件上都没有dnd这个键。这正是 Prime Directive #10 那句「never advertise or demo a capability the runtime doesn't actually deliver」。相关
Notification/NotificationConfig零 importer 删除的先例)、spec 双源清账 C13+C15(一单):DataSyncConfig + ConflictResolution(automation 死删 / integration 改名 / ui 保名)—— 4 条 #4738(automation/sync.zod.ts整文件删除的先例)、POST /data/sharing/rules绕过SharingRuleSchema:criteria缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896(view.responsive/view.performance的 inert 清退)、spec:DashboardWidgetSchema.responsive按断点建模 —— objectui#3173 维护者已裁决;目标 17.0.0 正式版,带回退条款 #4876(dashboard.widgets[].responsive清退,同日)按 AGENTS.md Prime Directive #10 归档,未指派。