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
fix(cli): gate the two routing shapes that can never work, flag the inert condition (#4414) (#4493)
Two follow-ups to #4440, both about metadata that reads like a guard and is
not one.
`flow-branch-label-unmatched` and `flow-default-edge-with-condition` now FAIL
the build. The bar is restated at the top of the file, because the old one —
"a guaranteed runtime failure" — no longer described the set: it is now **no
reading of the author's metadata does what it says, deterministically, on
every run**. A branch label no out-edge carries cannot route; an edge that is
both `isDefault` and conditional always lets the condition win, so the marker
routes nothing. Neither FAILS; both are wrong every time and silently.
The other two stay advisory, and the policy now says why. A decision with one
guarded and one unconditional out-edge is usually a guard that does not guard,
but it is also a legal "maybe notify, always continue" fan-out, and two
default edges can genuinely mean "when nothing matched, do both". The bar is
provability, not severity of consequence — failing a customer's build on a
shape we cannot prove wrong is the worse trade. No wiring change: the rule is
already `tier: 'gating'` across all three commands (#4409).
`flow-inert-node-condition` is new. `config.condition` is the trigger gate on
a `start` node and is read by no other node type — the engine parse-validates
it everywhere and then ignores it, so on a `decision`, where the name makes it
read as the branch predicate, it is a guard that gates nothing. Two of the
three bundled apps had one: app-todo's `check_recurring` and app-showcase's
`needs_exec`, each a third copy of a predicate its out-edges were already
enforcing. The showcase even carried a comment saying the node condition "is
not evaluated by the engine" and kept it anyway — the residue this rule exists
to stop accumulating. Both are now plain exclusive gateways.
Advisory: the surrounding edges usually still route correctly, so it is dead
weight rather than a provable misroute. The node-type list is a closed set of
builtins whose executors were actually read, not "everything but `start`" —
ADR-0018 keeps `node.type` open and a plugin executor may legitimately declare
and read its own `config.condition`.
Claude-Session: https://claude.ai/code/session_01Q8as8yR67v41xEdomiTba9
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments