@@ -1648,6 +1648,65 @@ describe('EdgeManager', () => {
16481648 // sentinel_end should be ready because all paths to it are deactivated
16491649 expect ( ready2 ) . toContain ( sentinelEndId )
16501650 } )
1651+
1652+ it ( 'should NOT execute intermediate nodes in long cascade chains (2+ hops)' , ( ) => {
1653+ // Regression test: When condition hits dead-end with 2+ intermediate nodes,
1654+ // only sentinel_end should be ready, NOT the intermediate nodes.
1655+ //
1656+ // Structure: sentinel_start → condition → funcA → funcB → sentinel_end
1657+ // When condition hits dead-end, funcA and funcB should NOT execute.
1658+
1659+ const sentinelStartId = 'sentinel-start'
1660+ const sentinelEndId = 'sentinel-end'
1661+ const conditionId = 'condition'
1662+ const funcAId = 'funcA'
1663+ const funcBId = 'funcB'
1664+
1665+ const sentinelStartNode = createMockNode ( sentinelStartId , [ { target : conditionId } ] )
1666+ const conditionNode = createMockNode (
1667+ conditionId ,
1668+ [ { target : funcAId , sourceHandle : 'condition-if' } ] ,
1669+ [ sentinelStartId ]
1670+ )
1671+ const funcANode = createMockNode ( funcAId , [ { target : funcBId } ] , [ conditionId ] )
1672+ const funcBNode = createMockNode ( funcBId , [ { target : sentinelEndId } ] , [ funcAId ] )
1673+ const sentinelEndNode = createMockNode (
1674+ sentinelEndId ,
1675+ [
1676+ { target : sentinelStartId , sourceHandle : 'loop_continue' } ,
1677+ { target : 'after-loop' , sourceHandle : 'loop_exit' } ,
1678+ ] ,
1679+ [ funcBId ]
1680+ )
1681+ const afterLoopNode = createMockNode ( 'after-loop' , [ ] , [ sentinelEndId ] )
1682+
1683+ const nodes = new Map < string , DAGNode > ( [
1684+ [ sentinelStartId , sentinelStartNode ] ,
1685+ [ conditionId , conditionNode ] ,
1686+ [ funcAId , funcANode ] ,
1687+ [ funcBId , funcBNode ] ,
1688+ [ sentinelEndId , sentinelEndNode ] ,
1689+ [ 'after-loop' , afterLoopNode ] ,
1690+ ] )
1691+
1692+ const dag = createMockDAG ( nodes )
1693+ const edgeManager = new EdgeManager ( dag )
1694+
1695+ // Simulate execution up to condition
1696+ conditionNode . incomingEdges . clear ( )
1697+
1698+ // Condition hits dead-end (else branch with no edge)
1699+ const ready = edgeManager . processOutgoingEdges ( conditionNode , {
1700+ selectedOption : null ,
1701+ } )
1702+
1703+ // Only sentinel_end should be ready
1704+ expect ( ready ) . toContain ( sentinelEndId )
1705+
1706+ // Intermediate nodes should NOT be in readyNodes
1707+ expect ( ready ) . not . toContain ( funcAId )
1708+ expect ( ready ) . not . toContain ( funcBId )
1709+ } )
16511710 } )
16521711
16531712 describe ( 'Condition inside parallel - parallel control edges should not be cascade-deactivated' , ( ) => {
0 commit comments