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 面,分开做要把上面那套测量跑两遍。

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions