Skip to content

3b — wire the flow executors to parse() their config, and tighten the undeclared-key warning into an error #4277

Description

@os-zhuang

承接 #4045最后一项,也是它唯一有意推迟的一项。#4045 本体(configSchema ↔ 执行器对账)已关闭;这条只装剩下的「让运行时真的执行契约」。

现状:契约齐了,但没有任何一处 parse

对账工作已经把材料备齐 —— 每个扁平内置节点都有一份从读执行器写出的 Zod:

文件 覆盖
automation/control-flow.zod.ts loop / parallel / try_catch
automation/io-node-config.zod.ts notify / http(#4210
automation/builtin-node-config.zod.ts CRUD 四件 / screen / map(#4228

但它们全是纯契约导出service-automation 里唯一的 .parse(wait-node.tsDate.parse()。所以今天仍然是 #4040 更正过的那句话所描述的状态 —— configSchema 不提供类型 / required / 未知键的运行时校验,FlowNodeSchema.configz.record(z.unknown()),作者写错的键静默通过。

#4059 已让 registerFlow 对未声明的键发警告(带路径、did-you-mean 与已声明键清单),但只是警告。

两半,可以分开做

(a) 执行器 parse 平台级的单一决定,不是逐节点的工作 —— 因为今天没有任何节点在 parse。有真实行为风险:今天能加载的 config 可能开始 parse 失败。

(b) 未知键 warn → error。 需要墓碑式的处方,照 object.zod.ts:1243UNKNOWN_KEY_GUIDANCE 模式立。

为什么必须等 #4059 的一个 release 数据

这不是拖延,是有依据的等。未知键有三类,这个缝今天分辨不了:

  1. 作者拼错(想拒绝)
  2. 执行器真的在读、但 schema 从未声明(拒绝会打断正在工作的 app)
  3. 死配置(无害)

而对账工作恰恰证明了第 2 类既真实又不少:光是 6 个扁平节点就查出 7 个(get_record.fieldsscreen.recordIdscreen.fields[].options/defaultValue/placeholdermap.indexVariable/input),外加 notify.sourcewait 的六个 loose 键、connector_action 的三元组、map.flow。这些现在都已声明或进了转换层,但它们说明的是:在收紧之前,得先知道存量 metadata 里未声明键的真实分布,而这正是 #4059 的警告在收集的东西。

直接 fail 等于拿存量 app 赌一个没测量过的分布。

落地时的约束(对账过程中攒下的,别重新踩)

  • keyValue 槽位z.record() 产出 additionalProperties: {} 而非契约要求的 true.meta({ additionalProperties: true }) 可覆盖。objectui 的 json-schema-to-fields.ts:456 判的是 !== undefined && !== false{} 照样渲染 keyValue —— 真正会红的是平台自己的 config-schemas.test.ts(严格 toBe(true)),它比它保护的消费者更严。
  • 区域型节点(loop/parallel/try_catch)不要合并成单一源test(automation): pin the control-flow trio's designer forms (#4045) #4064/test(automation): reconcile the control-flow designer forms against their Zod (#4045) #4078 已用实测否掉 —— 生成结果 9–17× 大、深 9 层、全内联无 $ref,要可用就得写投影裁掉九成,那时「单一真相源」是假的。它们走的是对账 ratchet,不是同源生成。
  • assignment 不可 parse:没有 assignments 包装时顶层 config 键就是作者自选的变量名,任何固定键集或 catchall 都无意义。它已入账为不可对账,收紧时必须整体豁免。
  • 契约未必在 configwaitwaitEventConfigconnector_actionconnectorConfig,都是 FlowNodeSchema 上声明的兄弟字段。任何建立在「configSchema ↔ 执行器读了什么」上的收紧都要把这种情况算进去,否则会把它们误报成读了没声明的键。

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions