与 #4988 同类。#4001 批 14 对 ui/ 六个文件逐个做门测量,11 个 strip 站点里 9 个是真门(已收紧)、2 个实测没有门 。这两个不收紧 —— 「一个被精确校验的死槽位是更有说服力的谎言」 (#4583 )—— 但它们需要的判定是 ADR-0049 enforce-or-remove,不是棘轮。
两个站点
schema
文件
NotificationActionSchema
packages/spec/src/ui/notification.zod.ts
EmbedConfigSchema
packages/spec/src/ui/sharing.zod.ts
注意 sharing.zod.ts 是同文件内劈开 的 —— 它的兄弟 SharingConfigSchema 是活门(FormViewSchema.sharing 承载,rest-server.ts 真的读 sharing.allowAnonymous / sharing.publicLink 来挂匿名表单路由,两个示例应用都在写),批 14 已收紧。这是账本第一次遇到一行两判,也是「per SCHEMA, not per file」这句话第一次真正生效。
三条独立测量(2026-08-03,均带阳性对照,同一次运行)
承载键 —— packages/spec/src 里除 ui/index.ts barrel 外无任何模块 import 这两个模块……
ui/notification.zod 的 importer 精确等于 ['ui/index.ts'];
ui/sharing.zod 的 importer 是 ['ui/index.ts', 'ui/view.zod.ts'],而 view.zod.ts 点名的是 SharingConfigSchema;全仓没有任何模块提到 EmbedConfigSchema 。
(匹配器按 specifier 解析 而非子串比对 —— 仓里有两个 sharing.zod,子串法会把 stack.zod.ts / security/index.ts 误记为 UI 那个的 importer。这一条是先证红发现的。)
图可达性 —— 从 24 个 metadata-type root 加 defineStack 的 ObjectStackSchema 做 BFS(build-schemas.ts 给 authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 删除检查用的同一套闭包),6860 个节点,两个都走不到。同一次运行里四个阳性对照 PageSchema / ActionSchema / DashboardWidgetSchema / WebhookSchema 全部 root-graph;注入一个合成承载键后两个都翻成 root-graph。对照通过,所以「不可达」是关于图的事实。
调用点 —— framework / objectui 里除各自单测外没有任何 .parse()。
一个值得单独记的细节:objectui 消费的是 shape ,不是 parse
NotificationActionSchema 并非无人问津 —— objectui 的 animation-notification-spec-parity.test.tsx 读 NotificationActionSchema.shape.variant,双向 pin 它自己手写的 NotificationActionButton 接口。但那是把 schema 当词汇表 用,和 posture 完全无关:收紧它不会让那条 pin 更强一分。
这恰好说明「有消费者」不等于「有授权门」,也是这两个站点该走 ADR-0049 而不是走棘轮的原因。
需要的判定
批 14 已在两处 schema 的 JSDoc + 测试 pin + 账本行三处留痕,pin 是会红的 :任何人给这两个形状接上承载键,那条断言立刻红并把人指回这里。
未指派。
与 #4988 同类。#4001 批 14 对
ui/六个文件逐个做门测量,11 个 strip 站点里 9 个是真门(已收紧)、2 个实测没有门。这两个不收紧 —— 「一个被精确校验的死槽位是更有说服力的谎言」(#4583)—— 但它们需要的判定是 ADR-0049 enforce-or-remove,不是棘轮。两个站点
NotificationActionSchemapackages/spec/src/ui/notification.zod.tsEmbedConfigSchemapackages/spec/src/ui/sharing.zod.ts注意
sharing.zod.ts是同文件内劈开的 —— 它的兄弟SharingConfigSchema是活门(FormViewSchema.sharing承载,rest-server.ts真的读sharing.allowAnonymous/sharing.publicLink来挂匿名表单路由,两个示例应用都在写),批 14 已收紧。这是账本第一次遇到一行两判,也是「per SCHEMA, not per file」这句话第一次真正生效。三条独立测量(2026-08-03,均带阳性对照,同一次运行)
packages/spec/src里除ui/index.tsbarrel 外无任何模块 import 这两个模块……ui/notification.zod的 importer 精确等于['ui/index.ts'];ui/sharing.zod的 importer 是['ui/index.ts', 'ui/view.zod.ts'],而view.zod.ts点名的是SharingConfigSchema;全仓没有任何模块提到EmbedConfigSchema。sharing.zod,子串法会把stack.zod.ts/security/index.ts误记为 UI 那个的 importer。这一条是先证红发现的。)defineStack的ObjectStackSchema做 BFS(build-schemas.ts给 authorable-surface 的 tombstone 门禁可被手编基线绕过 —— 删掉基线行就删掉了证据(#4638 / #4643 已两次这样过绿) #4650 删除检查用的同一套闭包),6860 个节点,两个都走不到。同一次运行里四个阳性对照PageSchema/ActionSchema/DashboardWidgetSchema/WebhookSchema全部root-graph;注入一个合成承载键后两个都翻成root-graph。对照通过,所以「不可达」是关于图的事实。.parse()。一个值得单独记的细节:objectui 消费的是 shape,不是 parse
NotificationActionSchema并非无人问津 —— objectui 的animation-notification-spec-parity.test.tsx读NotificationActionSchema.shape.variant,双向 pin 它自己手写的NotificationActionButton接口。但那是把 schema 当词汇表用,和 posture 完全无关:收紧它不会让那条 pin 更强一分。这恰好说明「有消费者」不等于「有授权门」,也是这两个站点该走 ADR-0049 而不是走棘轮的原因。
需要的判定
EmbedConfigSchema:iframe 嵌入从来没有承载键。是补一个(哪个 metadata type 该带embed?),还是按 enforce-or-remove 退役?NotificationActionSchema:spec 双源清账 C3:通知语汇 Notification(Schema)(./api ≠ ./ui)+ NotificationConfig(Schema)(./system ≠ ./ui)—— 4 条,单 PR #4610 已经因为零消费者删掉了它的两个 wrapper(NotificationSchema/NotificationConfigSchema),这个 action 形状是那次留下的孤儿。留作纯词汇表(那就该在文件里说清它不是可授权面),还是一并退役?批 14 已在两处 schema 的 JSDoc + 测试 pin + 账本行三处留痕,pin 是会红的:任何人给这两个形状接上承载键,那条断言立刻红并把人指回这里。
未指派。