test(spec): 修掉 flow fixture 教的三种跑不通的形状 (#4924) - #5502
Merged
Conversation
…4924) `packages/spec/src/automation/flow.test.ts` demonstrated four flow node configs whose keys no executor reads. They stayed green because the fixtures assert `FlowSchema` / `FlowNodeSchema`, and `FlowNodeSchema.config` is deliberately an open `z.record(z.unknown())` (ADR-0018) — so the file was teaching material for shapes that cannot run, not a test that could go red. Corrected, each with an in-place comment saying why: - `get_record` / `update_record` / `delete_record`: `object` -> `objectName` (the ADR-0087 D2 `flow-node-crud-object-alias` spelling), `recordId` -> `filter: { id: … }` (CRUD executors locate rows through `filter` only), plus the execute-time-required `objectName` the update/delete nodes never had. The `delete_record` node had `recordId` as its ONLY key — a match-everything delete (#3810) wearing a key that reads like a constraint. - `decision`: the inert `config.condition` is gone. The key is the trigger gate on a `start` node and is read on no other node type (`flow-inert-node-condition`, #4414); branching moves to the out-edges — one guarded branch plus `isDefault: true` on the fallback. - the moved predicate is bare CEL (ADR-0032): `{…}` braces parse as a CEL map literal and are rejected by `registerFlow` (the #1491 trap). `FlowNodeSchema.config` is untouched — it is open by design (ADR-0018). Both fixtures now also parse their corrected node configs against the per-node-type contracts the executors parse at run time, so re-introducing any of these shapes fails the test instead of passing it.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckNo hand-written docs reference the 0 changed package(s). ✅ |
This was referenced Aug 5, 2026
Closed
os-zhuang
marked this pull request as ready for review
August 5, 2026 15:48
Contributor
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 31022222345 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Aug 5, 2026
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4924
背景
packages/spec/src/automation/flow.test.ts的示范 flow 里,四个节点写着 executor 一个都不读的 config 键。它们全绿,是因为 fixture 断言的是FlowSchema/FlowNodeSchema,而FlowNodeSchema.config按 ADR-0018 刻意是开放的z.record(z.unknown())(node.type对插件开放,插件 executor 自带configSchema)。所以这不是一个会红的测试,是一份会被照抄的教材。FlowNodeSchema.config没动 —— 按 issue 明示,它的开放是设计,不是遗漏。改了什么(四处,各带原地注释)
get_opportunity(get_record)object+recordIdobjectName+filter: { id: … }+outputVariable: 'opportunity'GetRecordConfigSchema两个旧键都不声明;object是 ADR-0087 D2flow-node-crud-object-alias在加载期改写的退役拼写,recordId从来没有 reader。补outputVariable是因为下游谓词引用的opportunity此前根本没被绑过check_amount(decision)config.conditionconfig.condition只有start节点(触发闸门)会读,其余节点类型上惰性 —— 正是flow-inert-node-condition(#4414)报的那件事。DecisionConfigSchema只声明conditionsauto_approve(update_record)recordIdobjectName+filter: { id: … }objectName是执行期必填,缺了 executor 直接refuseNode,所以这个节点原本也跑不起来delete_recordrecordId一个键objectName+filter: { id: '{item.id}' }出边(decision 修复的落点):
e3改成isDefault: true的兜底边(与condition互斥,同时写会被flow-default-edge-with-condition判 error),e4保留唯一的守卫分支,谓词改写成 bare CEL(opportunity.amount > 100000)——{…}模板花括号在 CEL 里是 map 字面量,registerFlow的表达式校验硬报错,就是 #1491 那个坑。让它变成一个「会红」的测试
只改 fixture 的话,下一个人照旧可以把
recordId写回来而测试依然全绿。所以两个 fixture 现在额外把修正后的节点 config 拿去过 executor 运行期真正 parse 的那几份契约(GetRecordConfigSchema/UpdateRecordConfigSchema/DeleteRecordConfigSchema),并断言 decision 无 config、出边恰好一条守卫 + 一条isDefault、谓词里不含{。验证
反向验证(方向是事先定好的:恢复旧形状应当变红,因为这些契约是
strictObject,旧键会作为 unknown key 被拒):flow.test.ts2 failed(approval flow 断在GetRecordConfigSchema.safeParse(...).success为 false;scheduled flow 断在DeleteRecordConfigSchema)config.condition放回去 → 1 failed:expected { Object (condition) } to be undefinedexpected [ { id: 'e3', …(4) }, …(1) ] to have a length of 1 but got 2三组 pin 各自独立生效,没有一个是靠别的失败遮住的。
关于 changeset
没有加。改动只落在一个
.test.ts文件里:没有 schema、导出、可授权键或运行时行为的变化,npm 包发的是dist,消费者拿不到这个文件,CHANGELOG.md里也无话可说。按 AGENTS.md 的「纯 bug fix 不需要 changeset」,这里连用户可见面都没碰到。范围外的发现,已单独立 issue
#5500(
finding标签,未指派):同一个文件里还有五类不同缺陷类的形状 ——{节点id.字段}这套引擎从不绑的输出引用方言、assign_output因为没有assignments包裹而实际创建了两个名叫variable/value的变量、loop_records是 legacy flat-graph loop(所以本 PR 里 delete 节点的{item.id}要等它改成 ADR-0031 结构化body才真的有值,原地注释已写明)、get_old_records的字符串filter(可跑形状需要拍板,没在这里猜)、以及另外三处 brace-CEL 出边条件和两处object别名。按 Prime Directive #10 记录,没有在本 PR 里顺手扩范围。Generated by Claude Code