Skip to content

zodShapeOf 的 unwrap 面比三个同族 walker 窄:缺 union 分支与 prefault(#5317 修完管道方向后剩下的两格) #6098

Description

@os-zhuang

发现于 #5317 实施途中(observation-class:两格今天都被 fail-closed 兜住,没有已知的错误产物)。

packages/spec/scripts/lib/zod-graph.tszodShapeOf#5317build-schemas.ts 抽出来的;它有三个同族 walker,做的是同一件事(把一个 Zod 节点解到对象 shape):

  • packages/spec/scripts/liveness/check-liveness.mtsunwrap / shapeOf
  • packages/spec/src/kernel/metadata-authoring-lint.tsunwrap / keyPosture
  • packages/spec/src/system/metadata-form-zod-reconciliation.test.tsunwrap / keysOf

#5317 已经把管道方向这一格对齐了(z.preprocess 走 OUT)。剩下两格仍然只有 zodShapeOf 缺:

事实 1 —— 没有 union 分支

zodShapeOf 只认 object,遇到 union 返回 null。三个同族 walker 都合并 union 成员的键(check-liveness 的 shapeOf 带着 #3095 的注释,说的正是「一个 metadata type 可能注册一组 shape 的 UNION 而不是单个对象」)。

后果,#5317 实测:view 是注册表里唯一的 z.preprocess ,其 OUT 是 z.union(#5074 的 console-decoration 剥离)。#5317 把方向修对之后,pipeAuthorableSide(view)transform 变成了 union —— 但 zodShapeOf(view) 依然是 null,因为没有 union 分支。所以「preprocess 根能被解出真实 shape」这句话对 view 今天仍然不成立,方向修对是必要但不充分。

packages/spec/scripts/zod-graph.test.ts 里有一条测试把这个状态诚实钉住了(documents that view's preprocess OUT is a union, so it still derives no shape),加 union 分支的人会先撞到它。

事实 2 —— wrapper 集合缺 prefault

zodShapeOfSHAPE_WRAPPER_TYPESoptional / nullable / default / catch / readonly / nonoptional。三个同族 walker 的对应列表都还有 prefault。一个 prefault 包着的对象在 zodShapeOf 下解不出 shape。

#5317 特意没有顺手加:它没被测量过,而 zodShapeOf 喂的是 derived-clone 桥,任何解出更多 shape 的改动都会新增桥项

为什么是 observation-class 而不是缺陷

两格的后果都落在 computeSurfaceReachabilityreachableVia,而那里解不出 shape 时 return 'root-graph'(fail closed —— 宁可多要一个 tombstone,不静默放宽)。所以当前表现是保守,不是错答;而且 reachableVia 只在 #4650 删除门禁发现「基线行被删」时才被调用,平时的 gen:schema 根本不走。今天没有用户能撞到。

修的时候注意(#5056)

这两格任何一格补上,都会让更多节点解出 shape,从而给 bridged 表新增 (propName → propSchemaInstance) 项 —— 这正是 #5056 提醒过的、会把死形状标成可达(nullderived-clone)的桥。所以不是加一行就完事:

两格建议放同一个 PR 一起量:它们改的是同一个函数的同一片 unwrap 面,分开做要把上面那套测量跑两遍。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions