You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(automation,spec): flow executors parse() their config; undeclared config keys reject at registration (#4277)
Half (a): the 12 contract-carrying builtins (CRUD quartet, screen, map,
notify, http, loop/parallel/try_catch) now parse node.config against their
Zod contracts before executing (builtin/parse-config.ts). A type or
missing-required violation refuses the node as a guard — not routable via
fault edges. Templates stay legal: string slots parse the raw config; http
parses post-interpolation, the shape its executor reads. A legacy
flat-graph loop (no config.body) stays exempt. LoopConfigSchema.collection
widened to string|array — the executor always accepted inline arrays
(map.collection already declared the union), so string-only under-declared.
Half (b): registerFlow now REJECTS config keys the node type's descriptor
configSchema does not declare (tightening the #4059 warning), naming the
path, the declared key set, a did-you-mean, and per-key tombstones
(the UNKNOWN_KEY_GUIDANCE pattern). assignment stays exempt wholesale (its
top-level keys are author variable names); schemaless types and keyValue
maps are unchanged.
Example metadata fixed at the producer (PD #12): two showcase notify nodes
missing the required recipients/title (both already failed at run time),
and app-todo's dead getAll/message/buttons keys plus bare-string select
options.
Closes#4277
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CW8ZP3zUuC7ovSxqnN5o77
* docs(automation): flows.mdx stops claiming node config is unchecked (#4277)
The docs-drift advisory on #4332 flagged flows.mdx, and it was right: the
node-property table and the strict-shells callout both described config as
an open record with no enforcement, which #4277 changed — undeclared keys
reject at registerFlow() and the contract-carrying builtins parse their
config at execute time.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CW8ZP3zUuC7ovSxqnN5o77
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: content/docs/automation/flows.mdx
+9-3Lines changed: 9 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -138,7 +138,7 @@ Each node performs a specific action in the flow.
138
138
|`id`|`string`| ✅ | Unique node identifier |
139
139
|`type`|`string`| ✅ | Node type — a built-in id from the table above **or** a plugin-registered one. Per ADR-0018 the spec does not gate this with a closed enum; it is checked against the live action registry at `registerFlow()`|
140
140
|`label`|`string`| ✅ | Display label |
141
-
|`config`|`object`| optional | Type-specific configuration (an open record — the registered executor's `configSchema` owns its shape) |
141
+
|`config`|`object`| optional | Type-specific configuration — the registered executor's `configSchema` owns its shape. Keys that schema does not declare are rejected at `registerFlow()`, and the built-in executors `parse()` the value against their Zod contract before running (#4277) |
142
142
|`connectorConfig`|`object`| optional |`{ connectorId, actionId, input }` for a `connector_action` node |
143
143
|`position`|`{ x, y }`| optional | Visual position on canvas |
0 commit comments