fix(spec,service-automation): reconcile notify/http/connector declared config with what the executors read (#4045) - #4210
Merged
Conversation
…d config with what the executors read (#4045) The notify/http/connector step of the declared-vs-read worklist: - notify/http gain executor-derived Zod contracts (NotifyConfigSchema, HttpConfigSchema) written from the executors, not the form literals, plus a bidirectional form <-> Zod key-set ledger test. Both reconcile clean, with no deliberately-shallow entries. - connector_action's configSchema is retired: the executor reads only the declared FlowNodeSchema.connectorConfig sibling, but the published schema declared the trio as config keys - and the schema-driven Studio form roots every field at config.<key>, replacing the hand-written connectorConfig form, so online authoring produced nodes that refused to dispatch. Schemaless drops the designer back onto the correct form. - flow-node-connector-config-lift (ADR-0087 D2, protocol 17) heals stored flows carrying the mis-taught config.{connectorId,actionId, input} shape, with a completeness guard so a step-time refusal never becomes a load failure. - connectorConfig.input is optional, matching the executor (input ?? {}) and the designer's keyValue editor, which omits an empty map. - check:variant-docs (new in #4177) is classified in the check:generated ledger (NO_GENERATOR) - unclassified, it failed every gate run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UDhMtxPLLoFaGtdpNA7xTU
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…-2z3fab # Conflicts: # packages/spec/scripts/check-generated.ts
os-zhuang
marked this pull request as ready for review
July 30, 2026 16:14
os-zhuang
added a commit
that referenced
this pull request
Jul 30, 2026
…config with what the executors read (#4045) (#4228) Completes the declared-vs-read reconciliation across the flat builtins, after notify/http/connector in #4210. Six executor-derived Zod contracts land in automation/builtin-node-config.zod.ts (get/create/update/delete_record, screen + its field item, map), each written by READING the executor rather than transcribing the descriptor literal — so the new bidirectional ledger test is evidence, not a tautology. Contract exports only; nothing parses with them yet (step 3b, gated on the #4059 warning data). Writing them against the executors surfaced seven live capabilities that no form offered, online or offline — authorable only by hand-written metadata: get_record.fields (the projection passed into find/findOne), screen.recordId (the record `mode: 'edit'` opens — the form declared the mode but not its target), screen.fields[].options/defaultValue/placeholder (all three forwarded into the ScreenSpec the client renders, so a select field's choices could not be authored in Studio at all — the same nested repeater position as #3528), and map.indexVariable/map.input. All are declared on their descriptors now. map's undeclared `flow` alias went the other route: the executor carried `cfg.flowName ?? cfg.flow` for a spelling no schema ever described — the notify.source shape (PD #12). The bare fallback is deleted and flow-node-map-flow-alias (protocol 17, retires at 18) renames it at load, including the registerFlow rehydration seam. assignment is pinned as deliberately un-reconcilable with its reason on record: with no `assignments` wrapper its top-level config keys ARE the author's variable names, so no fixed key set describes it and a catchall Zod would reconcile vacuously. The ledger pins what CAN be pinned — the form offers exactly the canonical assignments map, and that map stays open. Every builtin publishing a configSchema is now reconciled against its executor; those publishing none each have a recorded reason. Claude-Session: https://claude.ai/code/session_01UDhMtxPLLoFaGtdpNA7xTU Co-authored-by: Claude <noreply@anthropic.com>
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.
#4045 本体 —— 按 issue 结论「先只做 notify / http / connector 这 3 个完全封闭的」落地对账。
wait的判断已由 #4161 单独完成。notify / http:执行器派生的 Zod + 双向键集对账
automation/io-node-config.zod.ts:NotifyConfigSchema(11 键)、HttpConfigSchema(7 键),从读执行器写出,不是照configSchema抄的——两侧独立成文,对账才不是同义反复(issue 里那条纪律)。与 control-flow 三 Zod 一样是纯契约导出,运行时零变化;接parse属于 3b,等 feat(automation,formula): warn on undeclared flow-node config keys (#4045) #4059 的分布数据。io-node-form-zod-ledger.test.ts(test(automation): reconcile the control-flow designer forms against their Zod (#4045) #4078 的扁平版):表单 ↔ Zod 双向键集比对。两个节点全部对上,无需任何 shallow 账本条目——issue 预判的「3 个干净样本可能一个问题都没有」在这两个上成立。connector_action:对账抓到的真实漂移(本 PR 的主要发现)
执行器完全不读
config——契约是声明的兄弟块FlowNodeSchema.connectorConfig。但描述符发布着一份把connectorId/actionId/input声明成 config 键的configSchema,而这不是无害的文档错位:FlowNodeInspector走serverFields ?? fieldsForNodeType(...)——发布了 schema 就用 schema 生成表单,且json-schema-to-fields把每个字段都根在['config', key]。connectorConfig表单(连带 connector/action 选择器一起丢失),把三元组写进执行器永远不读的位置——在线创作的 connector 节点必然以 "connectorConfig.connectorId and .actionId are required" 拒绝执行。Console: screen-flow Submit never calls the resume endpoint — every screen flow is un-completable from the UI #3528 的失效形态,活的。处置(三件一体):
configSchema,加入wait/decision/script/subflow的 deliberately-schemaless 类(config-schemas.test.ts 钉住不许回来)。objectui 零改动自动回落到正确的手写表单。flow-node-connector-config-lift(ADR-0087 D2,protocol 17,18 退役):把被误教的config.{connectorId,actionId,input}抬进声明块,含registerFlow再水化缝。带完备性守卫:抬升凑不齐必填的connectorId+actionId对就整节点不动——绝不把「注册成功、步骤拒绝」变成「加载失败」。connectorConfig.input改为 optional:执行器本来就input ?? {},设计器的 keyValue 编辑器空映射时整个省略——spec 里的 required 是 declared ≠ read,且把「无输入的 action」变成过registerFlow解析失败。顺手修(一行,会挡住所有人)
check:generated的账本自检在 main 上就红:#4177 新增的check:variant-docs没有分类。已按其性质入NO_GENERATOR(审计手写文档,无生成器可跑)。验证
check:generated:8 个生成物全绿(spec-changes / upgrade-guide / api-surface / docs 已按--fix精确再生)clientValidation对connector_action本就是 forward-compat 开放点,无需跨仓库改动🤖 Generated with Claude Code
https://claude.ai/code/session_01UDhMtxPLLoFaGtdpNA7xTU
Generated by Claude Code