现象
packages/lint 里所有走 flow 节点的规则都只遍历顶层 flow.nodes。一旦作者把同一个节点挪进 try_catch / loop / parallel 的嵌套 region,检查就整体失效。
同一组「坏节点」放在顶层 vs 放进 try_catch.config.try.nodes,实测(对着已构建的 @objectstack/lint dist):
| 规则 |
严重级 |
顶层 |
嵌套 |
flow-node-write-unknown-field(#4369/#4374) |
error |
1 |
0 |
flow-update-readonly-field(#3425) |
error |
1 |
0 |
approval-approver-type-unknown 等(#3583) |
error/warning |
1 |
0 |
flow-template-unknown-field filter 位置(#3810) |
error |
1 |
1,但降级为 warning |
最后一行是最隐蔽的一种失败。validateFlowTemplatePaths 因为对整个 config 做递归 string-leaf 扫描,碰巧还能看见嵌套节点里的 token,但 collectNodeLeaves 只在节点 config 的顶层拆分 filter 键,嵌套后 filter 位置信息丢失:
FLAT error flow "f" node "get_record" flows[0].nodes[1]
NESTED warning flow "f" node "try_catch" flows[0].nodes[1]
即 #3810 那条「条件被抹掉会放宽查询,运行时直接拒绝执行该节点」的 gating 判断,变成一行黄色 advisory,而且定位到外层 try_catch 而不是真正出问题的 get_record。这正是那条规则的严重级分档所要防止的事。
根因
FlowRegionSchema(packages/spec/src/automation/control-flow.zod.ts:79)持有完整的 nodes: z.array(FlowNodeSchema).min(1),一共四个嵌套槽位:
| 节点类型 |
槽位 |
try_catch |
config.try、config.catch |
loop |
config.body |
parallel |
config.branches[](ParallelBranchSchema) |
而每条规则都是同一行:
const nodes = Array.isArray(flow.nodes) ? (flow.nodes as AnyRec[]) : [];
出现在 validate-flow-node-writes.ts:184、validate-readonly-flow-writes.ts:137、validate-flow-template-paths.ts:248/266/290、validate-approval-approvers.ts:154、validate-expressions.ts:132。没有一条递归进 region。
(validate-flow-trigger-readiness.ts:72 找的是 start 节点,按定义只在顶层,不受影响。validate-expressions.ts 在结构上属于同一类,但我的探针在顶层也没触发它,未确认。)
影响面不是假设
app-showcase 现在就有一个 update_record 落在 catch region 里(examples/app-showcase/src/automation/flows/index.ts:967-978,写 sync_status / sync_error)。那个节点字段是对的,所以不是线上 bug —— 但它从未被检查过,而 os validate 通过给了它「已检查」的假象。「在 catch 分支里用 update_record 记录失败」恰恰是这个 region 最典型的用法。
建议
不要三处各写一遍遍历 —— 那正是会漂移的形状(#3583 建套件、#4330 收拢 system-fields 都是在收拾这个)。
- 在
packages/lint 出一个共享的 flow 节点游走器,产出 { node, path, container };
path 必须能表达嵌套位置(flows[0].nodes[1].config.catch.nodes[0].config.fields.stagee),否则 finding 定位不到真正的节点 —— 上面 NESTED 那行报在 flows[0].nodes[1] 就是这个问题;
- 上述规则改用它;
validateFlowTemplatePaths 还需要让 filter 位置判定跟着嵌套走,否则 gating 降级问题不会因为「能看见」而自动修好;
- 一条测试钉住四个槽位都被走到 —— 参照
validate-flow-node-writes.test.ts 里对着 spec schema 行为式推导的 partition 测试,让新增的嵌套槽位无法静默漏掉。
版本
@objectstack/*@17.0.0-rc.0,main @ 38182ffb8。发现自 #4369 / #4374(flow write-set gate)的收尾核查。
现象
packages/lint里所有走 flow 节点的规则都只遍历顶层flow.nodes。一旦作者把同一个节点挪进try_catch/loop/parallel的嵌套 region,检查就整体失效。同一组「坏节点」放在顶层 vs 放进
try_catch.config.try.nodes,实测(对着已构建的@objectstack/lintdist):flow-node-write-unknown-field(#4369/#4374)flow-update-readonly-field(#3425)approval-approver-type-unknown等(#3583)flow-template-unknown-fieldfilter 位置(#3810)最后一行是最隐蔽的一种失败。
validateFlowTemplatePaths因为对整个config做递归 string-leaf 扫描,碰巧还能看见嵌套节点里的 token,但collectNodeLeaves只在节点 config 的顶层拆分filter键,嵌套后 filter 位置信息丢失:即 #3810 那条「条件被抹掉会放宽查询,运行时直接拒绝执行该节点」的 gating 判断,变成一行黄色 advisory,而且定位到外层
try_catch而不是真正出问题的get_record。这正是那条规则的严重级分档所要防止的事。根因
FlowRegionSchema(packages/spec/src/automation/control-flow.zod.ts:79)持有完整的nodes: z.array(FlowNodeSchema).min(1),一共四个嵌套槽位:try_catchconfig.try、config.catchloopconfig.bodyparallelconfig.branches[](ParallelBranchSchema)而每条规则都是同一行:
出现在
validate-flow-node-writes.ts:184、validate-readonly-flow-writes.ts:137、validate-flow-template-paths.ts:248/266/290、validate-approval-approvers.ts:154、validate-expressions.ts:132。没有一条递归进 region。(
validate-flow-trigger-readiness.ts:72找的是start节点,按定义只在顶层,不受影响。validate-expressions.ts在结构上属于同一类,但我的探针在顶层也没触发它,未确认。)影响面不是假设
app-showcase 现在就有一个
update_record落在catchregion 里(examples/app-showcase/src/automation/flows/index.ts:967-978,写sync_status/sync_error)。那个节点字段是对的,所以不是线上 bug —— 但它从未被检查过,而os validate通过给了它「已检查」的假象。「在catch分支里用update_record记录失败」恰恰是这个 region 最典型的用法。建议
不要三处各写一遍遍历 —— 那正是会漂移的形状(#3583 建套件、#4330 收拢 system-fields 都是在收拾这个)。
packages/lint出一个共享的 flow 节点游走器,产出{ node, path, container };path必须能表达嵌套位置(flows[0].nodes[1].config.catch.nodes[0].config.fields.stagee),否则 finding 定位不到真正的节点 —— 上面 NESTED 那行报在flows[0].nodes[1]就是这个问题;validateFlowTemplatePaths还需要让filter位置判定跟着嵌套走,否则 gating 降级问题不会因为「能看见」而自动修好;validate-flow-node-writes.test.ts里对着 spec schema 行为式推导的 partition 测试,让新增的嵌套槽位无法静默漏掉。版本
@objectstack/*@17.0.0-rc.0,main@38182ffb8。发现自 #4369 / #4374(flow write-set gate)的收尾核查。