From e117fb0ad2335fb79587f866a146861090c48033 Mon Sep 17 00:00:00 2001
From: Paul Dittamo <37558497+pvditt@users.noreply.github.com>
Date: Mon, 2 Dec 2024 07:53:29 -0800
Subject: [PATCH] add sub_node_interface field to array node (#6018)

* add is_original_sub_node_interface field to array node

Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>

* update idl

Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>

* make arraynode compilation backwards compatible

Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>

* use boolvalue for is_original_sub_node_interface

Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>

---------

Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
---
 flyteidl/clients/go/assets/admin.swagger.json |  4 +
 .../gen/pb-es/flyteidl/core/workflow_pb.ts    | 10 +-
 .../gen/pb-go/flyteidl/core/workflow.pb.go    | 97 +++++++++++--------
 .../flyteidl/service/admin.swagger.json       |  4 +
 flyteidl/gen/pb-js/flyteidl.d.ts              |  6 ++
 flyteidl/gen/pb-js/flyteidl.js                | 19 ++++
 .../pb_python/flyteidl/core/workflow_pb2.py   | 48 ++++-----
 .../pb_python/flyteidl/core/workflow_pb2.pyi  |  6 +-
 flyteidl/gen/pb_rust/flyteidl.core.rs         |  3 +
 flyteidl/protos/flyteidl/core/workflow.proto  |  3 +
 10 files changed, 133 insertions(+), 67 deletions(-)

diff --git a/flyteidl/clients/go/assets/admin.swagger.json b/flyteidl/clients/go/assets/admin.swagger.json
index f8a50f0f15..01ae020a09 100644
--- a/flyteidl/clients/go/assets/admin.swagger.json
+++ b/flyteidl/clients/go/assets/admin.swagger.json
@@ -6564,6 +6564,10 @@
         "execution_mode": {
           "$ref": "#/definitions/coreArrayNodeExecutionMode",
           "description": "execution_mode determines the execution path for ArrayNode."
+        },
+        "is_original_sub_node_interface": {
+          "type": "boolean",
+          "title": "Indicates whether the sub node's original interface was altered"
         }
       },
       "description": "ArrayNode is a Flyte node type that simplifies the execution of a sub-node over a list of input\nvalues. An ArrayNode can be executed with configurable parallelism (separate from the parent\nworkflow) and can be configured to succeed when a certain number of sub-nodes succeed."
diff --git a/flyteidl/gen/pb-es/flyteidl/core/workflow_pb.ts b/flyteidl/gen/pb-es/flyteidl/core/workflow_pb.ts
index 20c235c187..7dce890e0d 100644
--- a/flyteidl/gen/pb-es/flyteidl/core/workflow_pb.ts
+++ b/flyteidl/gen/pb-es/flyteidl/core/workflow_pb.ts
@@ -4,7 +4,7 @@
 // @ts-nocheck
 
 import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf";
-import { Duration, Message, proto3 } from "@bufbuild/protobuf";
+import { BoolValue, Duration, Message, proto3 } from "@bufbuild/protobuf";
 import { BooleanExpression } from "./condition_pb.js";
 import { Error, LiteralType } from "./types_pb.js";
 import { Identifier } from "./identifier_pb.js";
@@ -554,6 +554,13 @@ export class ArrayNode extends Message<ArrayNode> {
    */
   executionMode = ArrayNode_ExecutionMode.MINIMAL_STATE;
 
+  /**
+   * Indicates whether the sub node's original interface was altered
+   *
+   * @generated from field: google.protobuf.BoolValue is_original_sub_node_interface = 6;
+   */
+  isOriginalSubNodeInterface?: boolean;
+
   constructor(data?: PartialMessage<ArrayNode>) {
     super();
     proto3.util.initPartial(data, this);
@@ -567,6 +574,7 @@ export class ArrayNode extends Message<ArrayNode> {
     { no: 3, name: "min_successes", kind: "scalar", T: 13 /* ScalarType.UINT32 */, oneof: "success_criteria" },
     { no: 4, name: "min_success_ratio", kind: "scalar", T: 2 /* ScalarType.FLOAT */, oneof: "success_criteria" },
     { no: 5, name: "execution_mode", kind: "enum", T: proto3.getEnumType(ArrayNode_ExecutionMode) },
+    { no: 6, name: "is_original_sub_node_interface", kind: "message", T: BoolValue },
   ]);
 
   static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): ArrayNode {
diff --git a/flyteidl/gen/pb-go/flyteidl/core/workflow.pb.go b/flyteidl/gen/pb-go/flyteidl/core/workflow.pb.go
index 14ac613ea6..d484bd7ae9 100644
--- a/flyteidl/gen/pb-go/flyteidl/core/workflow.pb.go
+++ b/flyteidl/gen/pb-go/flyteidl/core/workflow.pb.go
@@ -10,7 +10,7 @@ import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	durationpb "google.golang.org/protobuf/types/known/durationpb"
-	_ "google.golang.org/protobuf/types/known/wrapperspb"
+	wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
 	reflect "reflect"
 	sync "sync"
 )
@@ -785,6 +785,8 @@ type ArrayNode struct {
 	SuccessCriteria isArrayNode_SuccessCriteria `protobuf_oneof:"success_criteria"`
 	// execution_mode determines the execution path for ArrayNode.
 	ExecutionMode ArrayNode_ExecutionMode `protobuf:"varint,5,opt,name=execution_mode,json=executionMode,proto3,enum=flyteidl.core.ArrayNode_ExecutionMode" json:"execution_mode,omitempty"`
+	// Indicates whether the sub node's original interface was altered
+	IsOriginalSubNodeInterface *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=is_original_sub_node_interface,json=isOriginalSubNodeInterface,proto3" json:"is_original_sub_node_interface,omitempty"`
 }
 
 func (x *ArrayNode) Reset() {
@@ -868,6 +870,13 @@ func (x *ArrayNode) GetExecutionMode() ArrayNode_ExecutionMode {
 	return ArrayNode_MINIMAL_STATE
 }
 
+func (x *ArrayNode) GetIsOriginalSubNodeInterface() *wrapperspb.BoolValue {
+	if x != nil {
+		return x.IsOriginalSubNodeInterface
+	}
+	return nil
+}
+
 type isArrayNode_ParallelismOption interface {
 	isArrayNode_ParallelismOption()
 }
@@ -1801,7 +1810,7 @@ var file_flyteidl_core_workflow_proto_rawDesc = []byte{
 	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x66, 0x6c, 0x79, 0x74, 0x65, 0x69, 0x64,
 	0x6c, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x43, 0x6f, 0x6e, 0x64,
 	0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x05, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x42, 0x0b,
-	0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xda, 0x02, 0x0a, 0x09,
+	0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xba, 0x03, 0x0a, 0x09,
 	0x41, 0x72, 0x72, 0x61, 0x79, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x6e, 0x6f, 0x64,
 	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x66, 0x6c, 0x79, 0x74, 0x65, 0x69,
 	0x64, 0x6c, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f,
@@ -1817,7 +1826,13 @@ var file_flyteidl_core_workflow_proto_rawDesc = []byte{
 	0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x66, 0x6c, 0x79, 0x74, 0x65, 0x69, 0x64, 0x6c, 0x2e, 0x63,
 	0x6f, 0x72, 0x65, 0x2e, 0x41, 0x72, 0x72, 0x61, 0x79, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x45, 0x78,
 	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0d, 0x65, 0x78, 0x65,
-	0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x32, 0x0a, 0x0d, 0x45, 0x78,
+	0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x5e, 0x0a, 0x1e, 0x69, 0x73,
+	0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x6e, 0x6f,
+	0x64, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x1a,
+	0x69, 0x73, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x53, 0x75, 0x62, 0x4e, 0x6f, 0x64,
+	0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x22, 0x32, 0x0a, 0x0d, 0x45, 0x78,
 	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x4d,
 	0x49, 0x4e, 0x49, 0x4d, 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0e,
 	0x0a, 0x0a, 0x46, 0x55, 0x4c, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x10, 0x01, 0x42, 0x14,
@@ -2020,13 +2035,14 @@ var file_flyteidl_core_workflow_proto_goTypes = []interface{}{
 	(*Identifier)(nil),                    // 23: flyteidl.core.Identifier
 	(*LiteralType)(nil),                   // 24: flyteidl.core.LiteralType
 	(*durationpb.Duration)(nil),           // 25: google.protobuf.Duration
-	(*RetryStrategy)(nil),                 // 26: flyteidl.core.RetryStrategy
-	(*Binding)(nil),                       // 27: flyteidl.core.Binding
-	(*QualityOfService)(nil),              // 28: flyteidl.core.QualityOfService
-	(*TypedInterface)(nil),                // 29: flyteidl.core.TypedInterface
-	(*Resources)(nil),                     // 30: flyteidl.core.Resources
-	(*ExtendedResources)(nil),             // 31: flyteidl.core.ExtendedResources
-	(*LiteralMap)(nil),                    // 32: flyteidl.core.LiteralMap
+	(*wrapperspb.BoolValue)(nil),          // 26: google.protobuf.BoolValue
+	(*RetryStrategy)(nil),                 // 27: flyteidl.core.RetryStrategy
+	(*Binding)(nil),                       // 28: flyteidl.core.Binding
+	(*QualityOfService)(nil),              // 29: flyteidl.core.QualityOfService
+	(*TypedInterface)(nil),                // 30: flyteidl.core.TypedInterface
+	(*Resources)(nil),                     // 31: flyteidl.core.Resources
+	(*ExtendedResources)(nil),             // 32: flyteidl.core.ExtendedResources
+	(*LiteralMap)(nil),                    // 33: flyteidl.core.LiteralMap
 }
 var file_flyteidl_core_workflow_proto_depIdxs = []int32{
 	21, // 0: flyteidl.core.IfBlock.condition:type_name -> flyteidl.core.BooleanExpression
@@ -2047,36 +2063,37 @@ var file_flyteidl_core_workflow_proto_depIdxs = []int32{
 	9,  // 15: flyteidl.core.GateNode.sleep:type_name -> flyteidl.core.SleepCondition
 	14, // 16: flyteidl.core.ArrayNode.node:type_name -> flyteidl.core.Node
 	0,  // 17: flyteidl.core.ArrayNode.execution_mode:type_name -> flyteidl.core.ArrayNode.ExecutionMode
-	25, // 18: flyteidl.core.NodeMetadata.timeout:type_name -> google.protobuf.Duration
-	26, // 19: flyteidl.core.NodeMetadata.retries:type_name -> flyteidl.core.RetryStrategy
-	12, // 20: flyteidl.core.Node.metadata:type_name -> flyteidl.core.NodeMetadata
-	27, // 21: flyteidl.core.Node.inputs:type_name -> flyteidl.core.Binding
-	13, // 22: flyteidl.core.Node.output_aliases:type_name -> flyteidl.core.Alias
-	5,  // 23: flyteidl.core.Node.task_node:type_name -> flyteidl.core.TaskNode
-	6,  // 24: flyteidl.core.Node.workflow_node:type_name -> flyteidl.core.WorkflowNode
-	4,  // 25: flyteidl.core.Node.branch_node:type_name -> flyteidl.core.BranchNode
-	10, // 26: flyteidl.core.Node.gate_node:type_name -> flyteidl.core.GateNode
-	11, // 27: flyteidl.core.Node.array_node:type_name -> flyteidl.core.ArrayNode
-	28, // 28: flyteidl.core.WorkflowMetadata.quality_of_service:type_name -> flyteidl.core.QualityOfService
-	1,  // 29: flyteidl.core.WorkflowMetadata.on_failure:type_name -> flyteidl.core.WorkflowMetadata.OnFailurePolicy
-	20, // 30: flyteidl.core.WorkflowMetadata.tags:type_name -> flyteidl.core.WorkflowMetadata.TagsEntry
-	23, // 31: flyteidl.core.WorkflowTemplate.id:type_name -> flyteidl.core.Identifier
-	15, // 32: flyteidl.core.WorkflowTemplate.metadata:type_name -> flyteidl.core.WorkflowMetadata
-	29, // 33: flyteidl.core.WorkflowTemplate.interface:type_name -> flyteidl.core.TypedInterface
-	14, // 34: flyteidl.core.WorkflowTemplate.nodes:type_name -> flyteidl.core.Node
-	27, // 35: flyteidl.core.WorkflowTemplate.outputs:type_name -> flyteidl.core.Binding
-	14, // 36: flyteidl.core.WorkflowTemplate.failure_node:type_name -> flyteidl.core.Node
-	16, // 37: flyteidl.core.WorkflowTemplate.metadata_defaults:type_name -> flyteidl.core.WorkflowMetadataDefaults
-	30, // 38: flyteidl.core.TaskNodeOverrides.resources:type_name -> flyteidl.core.Resources
-	31, // 39: flyteidl.core.TaskNodeOverrides.extended_resources:type_name -> flyteidl.core.ExtendedResources
-	23, // 40: flyteidl.core.LaunchPlanTemplate.id:type_name -> flyteidl.core.Identifier
-	29, // 41: flyteidl.core.LaunchPlanTemplate.interface:type_name -> flyteidl.core.TypedInterface
-	32, // 42: flyteidl.core.LaunchPlanTemplate.fixed_inputs:type_name -> flyteidl.core.LiteralMap
-	43, // [43:43] is the sub-list for method output_type
-	43, // [43:43] is the sub-list for method input_type
-	43, // [43:43] is the sub-list for extension type_name
-	43, // [43:43] is the sub-list for extension extendee
-	0,  // [0:43] is the sub-list for field type_name
+	26, // 18: flyteidl.core.ArrayNode.is_original_sub_node_interface:type_name -> google.protobuf.BoolValue
+	25, // 19: flyteidl.core.NodeMetadata.timeout:type_name -> google.protobuf.Duration
+	27, // 20: flyteidl.core.NodeMetadata.retries:type_name -> flyteidl.core.RetryStrategy
+	12, // 21: flyteidl.core.Node.metadata:type_name -> flyteidl.core.NodeMetadata
+	28, // 22: flyteidl.core.Node.inputs:type_name -> flyteidl.core.Binding
+	13, // 23: flyteidl.core.Node.output_aliases:type_name -> flyteidl.core.Alias
+	5,  // 24: flyteidl.core.Node.task_node:type_name -> flyteidl.core.TaskNode
+	6,  // 25: flyteidl.core.Node.workflow_node:type_name -> flyteidl.core.WorkflowNode
+	4,  // 26: flyteidl.core.Node.branch_node:type_name -> flyteidl.core.BranchNode
+	10, // 27: flyteidl.core.Node.gate_node:type_name -> flyteidl.core.GateNode
+	11, // 28: flyteidl.core.Node.array_node:type_name -> flyteidl.core.ArrayNode
+	29, // 29: flyteidl.core.WorkflowMetadata.quality_of_service:type_name -> flyteidl.core.QualityOfService
+	1,  // 30: flyteidl.core.WorkflowMetadata.on_failure:type_name -> flyteidl.core.WorkflowMetadata.OnFailurePolicy
+	20, // 31: flyteidl.core.WorkflowMetadata.tags:type_name -> flyteidl.core.WorkflowMetadata.TagsEntry
+	23, // 32: flyteidl.core.WorkflowTemplate.id:type_name -> flyteidl.core.Identifier
+	15, // 33: flyteidl.core.WorkflowTemplate.metadata:type_name -> flyteidl.core.WorkflowMetadata
+	30, // 34: flyteidl.core.WorkflowTemplate.interface:type_name -> flyteidl.core.TypedInterface
+	14, // 35: flyteidl.core.WorkflowTemplate.nodes:type_name -> flyteidl.core.Node
+	28, // 36: flyteidl.core.WorkflowTemplate.outputs:type_name -> flyteidl.core.Binding
+	14, // 37: flyteidl.core.WorkflowTemplate.failure_node:type_name -> flyteidl.core.Node
+	16, // 38: flyteidl.core.WorkflowTemplate.metadata_defaults:type_name -> flyteidl.core.WorkflowMetadataDefaults
+	31, // 39: flyteidl.core.TaskNodeOverrides.resources:type_name -> flyteidl.core.Resources
+	32, // 40: flyteidl.core.TaskNodeOverrides.extended_resources:type_name -> flyteidl.core.ExtendedResources
+	23, // 41: flyteidl.core.LaunchPlanTemplate.id:type_name -> flyteidl.core.Identifier
+	30, // 42: flyteidl.core.LaunchPlanTemplate.interface:type_name -> flyteidl.core.TypedInterface
+	33, // 43: flyteidl.core.LaunchPlanTemplate.fixed_inputs:type_name -> flyteidl.core.LiteralMap
+	44, // [44:44] is the sub-list for method output_type
+	44, // [44:44] is the sub-list for method input_type
+	44, // [44:44] is the sub-list for extension type_name
+	44, // [44:44] is the sub-list for extension extendee
+	0,  // [0:44] is the sub-list for field type_name
 }
 
 func init() { file_flyteidl_core_workflow_proto_init() }
diff --git a/flyteidl/gen/pb-go/gateway/flyteidl/service/admin.swagger.json b/flyteidl/gen/pb-go/gateway/flyteidl/service/admin.swagger.json
index f8a50f0f15..01ae020a09 100644
--- a/flyteidl/gen/pb-go/gateway/flyteidl/service/admin.swagger.json
+++ b/flyteidl/gen/pb-go/gateway/flyteidl/service/admin.swagger.json
@@ -6564,6 +6564,10 @@
         "execution_mode": {
           "$ref": "#/definitions/coreArrayNodeExecutionMode",
           "description": "execution_mode determines the execution path for ArrayNode."
+        },
+        "is_original_sub_node_interface": {
+          "type": "boolean",
+          "title": "Indicates whether the sub node's original interface was altered"
         }
       },
       "description": "ArrayNode is a Flyte node type that simplifies the execution of a sub-node over a list of input\nvalues. An ArrayNode can be executed with configurable parallelism (separate from the parent\nworkflow) and can be configured to succeed when a certain number of sub-nodes succeed."
diff --git a/flyteidl/gen/pb-js/flyteidl.d.ts b/flyteidl/gen/pb-js/flyteidl.d.ts
index 0aa9a63142..594d93f657 100644
--- a/flyteidl/gen/pb-js/flyteidl.d.ts
+++ b/flyteidl/gen/pb-js/flyteidl.d.ts
@@ -4586,6 +4586,9 @@ export namespace flyteidl {
 
             /** ArrayNode executionMode */
             executionMode?: (flyteidl.core.ArrayNode.ExecutionMode|null);
+
+            /** ArrayNode isOriginalSubNodeInterface */
+            isOriginalSubNodeInterface?: (google.protobuf.IBoolValue|null);
         }
 
         /** Represents an ArrayNode. */
@@ -4612,6 +4615,9 @@ export namespace flyteidl {
             /** ArrayNode executionMode. */
             public executionMode: flyteidl.core.ArrayNode.ExecutionMode;
 
+            /** ArrayNode isOriginalSubNodeInterface. */
+            public isOriginalSubNodeInterface?: (google.protobuf.IBoolValue|null);
+
             /** ArrayNode parallelismOption. */
             public parallelismOption?: "parallelism";
 
diff --git a/flyteidl/gen/pb-js/flyteidl.js b/flyteidl/gen/pb-js/flyteidl.js
index 51fce69ae8..e0d05981e9 100644
--- a/flyteidl/gen/pb-js/flyteidl.js
+++ b/flyteidl/gen/pb-js/flyteidl.js
@@ -10982,6 +10982,7 @@
                  * @property {number|null} [minSuccesses] ArrayNode minSuccesses
                  * @property {number|null} [minSuccessRatio] ArrayNode minSuccessRatio
                  * @property {flyteidl.core.ArrayNode.ExecutionMode|null} [executionMode] ArrayNode executionMode
+                 * @property {google.protobuf.IBoolValue|null} [isOriginalSubNodeInterface] ArrayNode isOriginalSubNodeInterface
                  */
     
                 /**
@@ -11039,6 +11040,14 @@
                  */
                 ArrayNode.prototype.executionMode = 0;
     
+                /**
+                 * ArrayNode isOriginalSubNodeInterface.
+                 * @member {google.protobuf.IBoolValue|null|undefined} isOriginalSubNodeInterface
+                 * @memberof flyteidl.core.ArrayNode
+                 * @instance
+                 */
+                ArrayNode.prototype.isOriginalSubNodeInterface = null;
+    
                 // OneOf field names bound to virtual getters and setters
                 var $oneOfFields;
     
@@ -11098,6 +11107,8 @@
                         writer.uint32(/* id 4, wireType 5 =*/37).float(message.minSuccessRatio);
                     if (message.executionMode != null && message.hasOwnProperty("executionMode"))
                         writer.uint32(/* id 5, wireType 0 =*/40).int32(message.executionMode);
+                    if (message.isOriginalSubNodeInterface != null && message.hasOwnProperty("isOriginalSubNodeInterface"))
+                        $root.google.protobuf.BoolValue.encode(message.isOriginalSubNodeInterface, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
                     return writer;
                 };
     
@@ -11134,6 +11145,9 @@
                         case 5:
                             message.executionMode = reader.int32();
                             break;
+                        case 6:
+                            message.isOriginalSubNodeInterface = $root.google.protobuf.BoolValue.decode(reader, reader.uint32());
+                            break;
                         default:
                             reader.skipType(tag & 7);
                             break;
@@ -11184,6 +11198,11 @@
                         case 1:
                             break;
                         }
+                    if (message.isOriginalSubNodeInterface != null && message.hasOwnProperty("isOriginalSubNodeInterface")) {
+                        var error = $root.google.protobuf.BoolValue.verify(message.isOriginalSubNodeInterface);
+                        if (error)
+                            return "isOriginalSubNodeInterface." + error;
+                    }
                     return null;
                 };
     
diff --git a/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.py b/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.py
index 0c62aca3ad..9f5b5f0881 100644
--- a/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.py
+++ b/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.py
@@ -23,7 +23,7 @@
 from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2
 
 
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lyteidl/core/workflow.proto\x12\rflyteidl.core\x1a\x1d\x66lyteidl/core/condition.proto\x1a\x1d\x66lyteidl/core/execution.proto\x1a\x1e\x66lyteidl/core/identifier.proto\x1a\x1d\x66lyteidl/core/interface.proto\x1a\x1c\x66lyteidl/core/literals.proto\x1a\x19\x66lyteidl/core/tasks.proto\x1a\x19\x66lyteidl/core/types.proto\x1a\x1c\x66lyteidl/core/security.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1egoogle/protobuf/wrappers.proto\"{\n\x07IfBlock\x12>\n\tcondition\x18\x01 \x01(\x0b\x32 .flyteidl.core.BooleanExpressionR\tcondition\x12\x30\n\tthen_node\x18\x02 \x01(\x0b\x32\x13.flyteidl.core.NodeR\x08thenNode\"\xd4\x01\n\x0bIfElseBlock\x12*\n\x04\x63\x61se\x18\x01 \x01(\x0b\x32\x16.flyteidl.core.IfBlockR\x04\x63\x61se\x12,\n\x05other\x18\x02 \x03(\x0b\x32\x16.flyteidl.core.IfBlockR\x05other\x12\x32\n\telse_node\x18\x03 \x01(\x0b\x32\x13.flyteidl.core.NodeH\x00R\x08\x65lseNode\x12,\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x14.flyteidl.core.ErrorH\x00R\x05\x65rrorB\t\n\x07\x64\x65\x66\x61ult\"A\n\nBranchNode\x12\x33\n\x07if_else\x18\x01 \x01(\x0b\x32\x1a.flyteidl.core.IfElseBlockR\x06ifElse\"\x97\x01\n\x08TaskNode\x12>\n\x0creference_id\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierH\x00R\x0breferenceId\x12>\n\toverrides\x18\x02 \x01(\x0b\x32 .flyteidl.core.TaskNodeOverridesR\toverridesB\x0b\n\treference\"\xa6\x01\n\x0cWorkflowNode\x12\x42\n\x0elaunchplan_ref\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierH\x00R\rlaunchplanRef\x12\x45\n\x10sub_workflow_ref\x18\x02 \x01(\x0b\x32\x19.flyteidl.core.IdentifierH\x00R\x0esubWorkflowRefB\x0b\n\treference\"/\n\x10\x41pproveCondition\x12\x1b\n\tsignal_id\x18\x01 \x01(\tR\x08signalId\"\x90\x01\n\x0fSignalCondition\x12\x1b\n\tsignal_id\x18\x01 \x01(\tR\x08signalId\x12.\n\x04type\x18\x02 \x01(\x0b\x32\x1a.flyteidl.core.LiteralTypeR\x04type\x12\x30\n\x14output_variable_name\x18\x03 \x01(\tR\x12outputVariableName\"G\n\x0eSleepCondition\x12\x35\n\x08\x64uration\x18\x01 \x01(\x0b\x32\x19.google.protobuf.DurationR\x08\x64uration\"\xc5\x01\n\x08GateNode\x12;\n\x07\x61pprove\x18\x01 \x01(\x0b\x32\x1f.flyteidl.core.ApproveConditionH\x00R\x07\x61pprove\x12\x38\n\x06signal\x18\x02 \x01(\x0b\x32\x1e.flyteidl.core.SignalConditionH\x00R\x06signal\x12\x35\n\x05sleep\x18\x03 \x01(\x0b\x32\x1d.flyteidl.core.SleepConditionH\x00R\x05sleepB\x0b\n\tcondition\"\xda\x02\n\tArrayNode\x12\'\n\x04node\x18\x01 \x01(\x0b\x32\x13.flyteidl.core.NodeR\x04node\x12\"\n\x0bparallelism\x18\x02 \x01(\rH\x00R\x0bparallelism\x12%\n\rmin_successes\x18\x03 \x01(\rH\x01R\x0cminSuccesses\x12,\n\x11min_success_ratio\x18\x04 \x01(\x02H\x01R\x0fminSuccessRatio\x12M\n\x0e\x65xecution_mode\x18\x05 \x01(\x0e\x32&.flyteidl.core.ArrayNode.ExecutionModeR\rexecutionMode\"2\n\rExecutionMode\x12\x11\n\rMINIMAL_STATE\x10\x00\x12\x0e\n\nFULL_STATE\x10\x01\x42\x14\n\x12parallelism_optionB\x12\n\x10success_criteria\"\x8c\x03\n\x0cNodeMetadata\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x33\n\x07timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.DurationR\x07timeout\x12\x36\n\x07retries\x18\x05 \x01(\x0b\x32\x1c.flyteidl.core.RetryStrategyR\x07retries\x12&\n\rinterruptible\x18\x06 \x01(\x08H\x00R\rinterruptible\x12\x1e\n\tcacheable\x18\x07 \x01(\x08H\x01R\tcacheable\x12%\n\rcache_version\x18\x08 \x01(\tH\x02R\x0c\x63\x61\x63heVersion\x12/\n\x12\x63\x61\x63he_serializable\x18\t \x01(\x08H\x03R\x11\x63\x61\x63heSerializableB\x15\n\x13interruptible_valueB\x11\n\x0f\x63\x61\x63heable_valueB\x15\n\x13\x63\x61\x63he_version_valueB\x1a\n\x18\x63\x61\x63he_serializable_value\"/\n\x05\x41lias\x12\x10\n\x03var\x18\x01 \x01(\tR\x03var\x12\x14\n\x05\x61lias\x18\x02 \x01(\tR\x05\x61lias\"\x9f\x04\n\x04Node\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x37\n\x08metadata\x18\x02 \x01(\x0b\x32\x1b.flyteidl.core.NodeMetadataR\x08metadata\x12.\n\x06inputs\x18\x03 \x03(\x0b\x32\x16.flyteidl.core.BindingR\x06inputs\x12*\n\x11upstream_node_ids\x18\x04 \x03(\tR\x0fupstreamNodeIds\x12;\n\x0eoutput_aliases\x18\x05 \x03(\x0b\x32\x14.flyteidl.core.AliasR\routputAliases\x12\x36\n\ttask_node\x18\x06 \x01(\x0b\x32\x17.flyteidl.core.TaskNodeH\x00R\x08taskNode\x12\x42\n\rworkflow_node\x18\x07 \x01(\x0b\x32\x1b.flyteidl.core.WorkflowNodeH\x00R\x0cworkflowNode\x12<\n\x0b\x62ranch_node\x18\x08 \x01(\x0b\x32\x19.flyteidl.core.BranchNodeH\x00R\nbranchNode\x12\x36\n\tgate_node\x18\t \x01(\x0b\x32\x17.flyteidl.core.GateNodeH\x00R\x08gateNode\x12\x39\n\narray_node\x18\n \x01(\x0b\x32\x18.flyteidl.core.ArrayNodeH\x00R\tarrayNodeB\x08\n\x06target\"\xfc\x02\n\x10WorkflowMetadata\x12M\n\x12quality_of_service\x18\x01 \x01(\x0b\x32\x1f.flyteidl.core.QualityOfServiceR\x10qualityOfService\x12N\n\non_failure\x18\x02 \x01(\x0e\x32/.flyteidl.core.WorkflowMetadata.OnFailurePolicyR\tonFailure\x12=\n\x04tags\x18\x03 \x03(\x0b\x32).flyteidl.core.WorkflowMetadata.TagsEntryR\x04tags\x1a\x37\n\tTagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"Q\n\x0fOnFailurePolicy\x12\x14\n\x10\x46\x41IL_IMMEDIATELY\x10\x00\x12(\n$FAIL_AFTER_EXECUTABLE_NODES_COMPLETE\x10\x01\"@\n\x18WorkflowMetadataDefaults\x12$\n\rinterruptible\x18\x01 \x01(\x08R\rinterruptible\"\xa2\x03\n\x10WorkflowTemplate\x12)\n\x02id\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierR\x02id\x12;\n\x08metadata\x18\x02 \x01(\x0b\x32\x1f.flyteidl.core.WorkflowMetadataR\x08metadata\x12;\n\tinterface\x18\x03 \x01(\x0b\x32\x1d.flyteidl.core.TypedInterfaceR\tinterface\x12)\n\x05nodes\x18\x04 \x03(\x0b\x32\x13.flyteidl.core.NodeR\x05nodes\x12\x30\n\x07outputs\x18\x05 \x03(\x0b\x32\x16.flyteidl.core.BindingR\x07outputs\x12\x36\n\x0c\x66\x61ilure_node\x18\x06 \x01(\x0b\x32\x13.flyteidl.core.NodeR\x0b\x66\x61ilureNode\x12T\n\x11metadata_defaults\x18\x07 \x01(\x0b\x32\'.flyteidl.core.WorkflowMetadataDefaultsR\x10metadataDefaults\"\xc5\x01\n\x11TaskNodeOverrides\x12\x36\n\tresources\x18\x01 \x01(\x0b\x32\x18.flyteidl.core.ResourcesR\tresources\x12O\n\x12\x65xtended_resources\x18\x02 \x01(\x0b\x32 .flyteidl.core.ExtendedResourcesR\x11\x65xtendedResources\x12\'\n\x0f\x63ontainer_image\x18\x03 \x01(\tR\x0e\x63ontainerImage\"\xba\x01\n\x12LaunchPlanTemplate\x12)\n\x02id\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierR\x02id\x12;\n\tinterface\x18\x02 \x01(\x0b\x32\x1d.flyteidl.core.TypedInterfaceR\tinterface\x12<\n\x0c\x66ixed_inputs\x18\x03 \x01(\x0b\x32\x19.flyteidl.core.LiteralMapR\x0b\x66ixedInputsB\xb3\x01\n\x11\x63om.flyteidl.coreB\rWorkflowProtoP\x01Z:github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core\xa2\x02\x03\x46\x43X\xaa\x02\rFlyteidl.Core\xca\x02\rFlyteidl\\Core\xe2\x02\x19\x46lyteidl\\Core\\GPBMetadata\xea\x02\x0e\x46lyteidl::Coreb\x06proto3')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lyteidl/core/workflow.proto\x12\rflyteidl.core\x1a\x1d\x66lyteidl/core/condition.proto\x1a\x1d\x66lyteidl/core/execution.proto\x1a\x1e\x66lyteidl/core/identifier.proto\x1a\x1d\x66lyteidl/core/interface.proto\x1a\x1c\x66lyteidl/core/literals.proto\x1a\x19\x66lyteidl/core/tasks.proto\x1a\x19\x66lyteidl/core/types.proto\x1a\x1c\x66lyteidl/core/security.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1egoogle/protobuf/wrappers.proto\"{\n\x07IfBlock\x12>\n\tcondition\x18\x01 \x01(\x0b\x32 .flyteidl.core.BooleanExpressionR\tcondition\x12\x30\n\tthen_node\x18\x02 \x01(\x0b\x32\x13.flyteidl.core.NodeR\x08thenNode\"\xd4\x01\n\x0bIfElseBlock\x12*\n\x04\x63\x61se\x18\x01 \x01(\x0b\x32\x16.flyteidl.core.IfBlockR\x04\x63\x61se\x12,\n\x05other\x18\x02 \x03(\x0b\x32\x16.flyteidl.core.IfBlockR\x05other\x12\x32\n\telse_node\x18\x03 \x01(\x0b\x32\x13.flyteidl.core.NodeH\x00R\x08\x65lseNode\x12,\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x14.flyteidl.core.ErrorH\x00R\x05\x65rrorB\t\n\x07\x64\x65\x66\x61ult\"A\n\nBranchNode\x12\x33\n\x07if_else\x18\x01 \x01(\x0b\x32\x1a.flyteidl.core.IfElseBlockR\x06ifElse\"\x97\x01\n\x08TaskNode\x12>\n\x0creference_id\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierH\x00R\x0breferenceId\x12>\n\toverrides\x18\x02 \x01(\x0b\x32 .flyteidl.core.TaskNodeOverridesR\toverridesB\x0b\n\treference\"\xa6\x01\n\x0cWorkflowNode\x12\x42\n\x0elaunchplan_ref\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierH\x00R\rlaunchplanRef\x12\x45\n\x10sub_workflow_ref\x18\x02 \x01(\x0b\x32\x19.flyteidl.core.IdentifierH\x00R\x0esubWorkflowRefB\x0b\n\treference\"/\n\x10\x41pproveCondition\x12\x1b\n\tsignal_id\x18\x01 \x01(\tR\x08signalId\"\x90\x01\n\x0fSignalCondition\x12\x1b\n\tsignal_id\x18\x01 \x01(\tR\x08signalId\x12.\n\x04type\x18\x02 \x01(\x0b\x32\x1a.flyteidl.core.LiteralTypeR\x04type\x12\x30\n\x14output_variable_name\x18\x03 \x01(\tR\x12outputVariableName\"G\n\x0eSleepCondition\x12\x35\n\x08\x64uration\x18\x01 \x01(\x0b\x32\x19.google.protobuf.DurationR\x08\x64uration\"\xc5\x01\n\x08GateNode\x12;\n\x07\x61pprove\x18\x01 \x01(\x0b\x32\x1f.flyteidl.core.ApproveConditionH\x00R\x07\x61pprove\x12\x38\n\x06signal\x18\x02 \x01(\x0b\x32\x1e.flyteidl.core.SignalConditionH\x00R\x06signal\x12\x35\n\x05sleep\x18\x03 \x01(\x0b\x32\x1d.flyteidl.core.SleepConditionH\x00R\x05sleepB\x0b\n\tcondition\"\xba\x03\n\tArrayNode\x12\'\n\x04node\x18\x01 \x01(\x0b\x32\x13.flyteidl.core.NodeR\x04node\x12\"\n\x0bparallelism\x18\x02 \x01(\rH\x00R\x0bparallelism\x12%\n\rmin_successes\x18\x03 \x01(\rH\x01R\x0cminSuccesses\x12,\n\x11min_success_ratio\x18\x04 \x01(\x02H\x01R\x0fminSuccessRatio\x12M\n\x0e\x65xecution_mode\x18\x05 \x01(\x0e\x32&.flyteidl.core.ArrayNode.ExecutionModeR\rexecutionMode\x12^\n\x1eis_original_sub_node_interface\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValueR\x1aisOriginalSubNodeInterface\"2\n\rExecutionMode\x12\x11\n\rMINIMAL_STATE\x10\x00\x12\x0e\n\nFULL_STATE\x10\x01\x42\x14\n\x12parallelism_optionB\x12\n\x10success_criteria\"\x8c\x03\n\x0cNodeMetadata\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x33\n\x07timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.DurationR\x07timeout\x12\x36\n\x07retries\x18\x05 \x01(\x0b\x32\x1c.flyteidl.core.RetryStrategyR\x07retries\x12&\n\rinterruptible\x18\x06 \x01(\x08H\x00R\rinterruptible\x12\x1e\n\tcacheable\x18\x07 \x01(\x08H\x01R\tcacheable\x12%\n\rcache_version\x18\x08 \x01(\tH\x02R\x0c\x63\x61\x63heVersion\x12/\n\x12\x63\x61\x63he_serializable\x18\t \x01(\x08H\x03R\x11\x63\x61\x63heSerializableB\x15\n\x13interruptible_valueB\x11\n\x0f\x63\x61\x63heable_valueB\x15\n\x13\x63\x61\x63he_version_valueB\x1a\n\x18\x63\x61\x63he_serializable_value\"/\n\x05\x41lias\x12\x10\n\x03var\x18\x01 \x01(\tR\x03var\x12\x14\n\x05\x61lias\x18\x02 \x01(\tR\x05\x61lias\"\x9f\x04\n\x04Node\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x37\n\x08metadata\x18\x02 \x01(\x0b\x32\x1b.flyteidl.core.NodeMetadataR\x08metadata\x12.\n\x06inputs\x18\x03 \x03(\x0b\x32\x16.flyteidl.core.BindingR\x06inputs\x12*\n\x11upstream_node_ids\x18\x04 \x03(\tR\x0fupstreamNodeIds\x12;\n\x0eoutput_aliases\x18\x05 \x03(\x0b\x32\x14.flyteidl.core.AliasR\routputAliases\x12\x36\n\ttask_node\x18\x06 \x01(\x0b\x32\x17.flyteidl.core.TaskNodeH\x00R\x08taskNode\x12\x42\n\rworkflow_node\x18\x07 \x01(\x0b\x32\x1b.flyteidl.core.WorkflowNodeH\x00R\x0cworkflowNode\x12<\n\x0b\x62ranch_node\x18\x08 \x01(\x0b\x32\x19.flyteidl.core.BranchNodeH\x00R\nbranchNode\x12\x36\n\tgate_node\x18\t \x01(\x0b\x32\x17.flyteidl.core.GateNodeH\x00R\x08gateNode\x12\x39\n\narray_node\x18\n \x01(\x0b\x32\x18.flyteidl.core.ArrayNodeH\x00R\tarrayNodeB\x08\n\x06target\"\xfc\x02\n\x10WorkflowMetadata\x12M\n\x12quality_of_service\x18\x01 \x01(\x0b\x32\x1f.flyteidl.core.QualityOfServiceR\x10qualityOfService\x12N\n\non_failure\x18\x02 \x01(\x0e\x32/.flyteidl.core.WorkflowMetadata.OnFailurePolicyR\tonFailure\x12=\n\x04tags\x18\x03 \x03(\x0b\x32).flyteidl.core.WorkflowMetadata.TagsEntryR\x04tags\x1a\x37\n\tTagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"Q\n\x0fOnFailurePolicy\x12\x14\n\x10\x46\x41IL_IMMEDIATELY\x10\x00\x12(\n$FAIL_AFTER_EXECUTABLE_NODES_COMPLETE\x10\x01\"@\n\x18WorkflowMetadataDefaults\x12$\n\rinterruptible\x18\x01 \x01(\x08R\rinterruptible\"\xa2\x03\n\x10WorkflowTemplate\x12)\n\x02id\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierR\x02id\x12;\n\x08metadata\x18\x02 \x01(\x0b\x32\x1f.flyteidl.core.WorkflowMetadataR\x08metadata\x12;\n\tinterface\x18\x03 \x01(\x0b\x32\x1d.flyteidl.core.TypedInterfaceR\tinterface\x12)\n\x05nodes\x18\x04 \x03(\x0b\x32\x13.flyteidl.core.NodeR\x05nodes\x12\x30\n\x07outputs\x18\x05 \x03(\x0b\x32\x16.flyteidl.core.BindingR\x07outputs\x12\x36\n\x0c\x66\x61ilure_node\x18\x06 \x01(\x0b\x32\x13.flyteidl.core.NodeR\x0b\x66\x61ilureNode\x12T\n\x11metadata_defaults\x18\x07 \x01(\x0b\x32\'.flyteidl.core.WorkflowMetadataDefaultsR\x10metadataDefaults\"\xc5\x01\n\x11TaskNodeOverrides\x12\x36\n\tresources\x18\x01 \x01(\x0b\x32\x18.flyteidl.core.ResourcesR\tresources\x12O\n\x12\x65xtended_resources\x18\x02 \x01(\x0b\x32 .flyteidl.core.ExtendedResourcesR\x11\x65xtendedResources\x12\'\n\x0f\x63ontainer_image\x18\x03 \x01(\tR\x0e\x63ontainerImage\"\xba\x01\n\x12LaunchPlanTemplate\x12)\n\x02id\x18\x01 \x01(\x0b\x32\x19.flyteidl.core.IdentifierR\x02id\x12;\n\tinterface\x18\x02 \x01(\x0b\x32\x1d.flyteidl.core.TypedInterfaceR\tinterface\x12<\n\x0c\x66ixed_inputs\x18\x03 \x01(\x0b\x32\x19.flyteidl.core.LiteralMapR\x0b\x66ixedInputsB\xb3\x01\n\x11\x63om.flyteidl.coreB\rWorkflowProtoP\x01Z:github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core\xa2\x02\x03\x46\x43X\xaa\x02\rFlyteidl.Core\xca\x02\rFlyteidl\\Core\xe2\x02\x19\x46lyteidl\\Core\\GPBMetadata\xea\x02\x0e\x46lyteidl::Coreb\x06proto3')
 
 _globals = globals()
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -53,27 +53,27 @@
   _globals['_GATENODE']._serialized_start=1350
   _globals['_GATENODE']._serialized_end=1547
   _globals['_ARRAYNODE']._serialized_start=1550
-  _globals['_ARRAYNODE']._serialized_end=1896
-  _globals['_ARRAYNODE_EXECUTIONMODE']._serialized_start=1804
-  _globals['_ARRAYNODE_EXECUTIONMODE']._serialized_end=1854
-  _globals['_NODEMETADATA']._serialized_start=1899
-  _globals['_NODEMETADATA']._serialized_end=2295
-  _globals['_ALIAS']._serialized_start=2297
-  _globals['_ALIAS']._serialized_end=2344
-  _globals['_NODE']._serialized_start=2347
-  _globals['_NODE']._serialized_end=2890
-  _globals['_WORKFLOWMETADATA']._serialized_start=2893
-  _globals['_WORKFLOWMETADATA']._serialized_end=3273
-  _globals['_WORKFLOWMETADATA_TAGSENTRY']._serialized_start=3135
-  _globals['_WORKFLOWMETADATA_TAGSENTRY']._serialized_end=3190
-  _globals['_WORKFLOWMETADATA_ONFAILUREPOLICY']._serialized_start=3192
-  _globals['_WORKFLOWMETADATA_ONFAILUREPOLICY']._serialized_end=3273
-  _globals['_WORKFLOWMETADATADEFAULTS']._serialized_start=3275
-  _globals['_WORKFLOWMETADATADEFAULTS']._serialized_end=3339
-  _globals['_WORKFLOWTEMPLATE']._serialized_start=3342
-  _globals['_WORKFLOWTEMPLATE']._serialized_end=3760
-  _globals['_TASKNODEOVERRIDES']._serialized_start=3763
-  _globals['_TASKNODEOVERRIDES']._serialized_end=3960
-  _globals['_LAUNCHPLANTEMPLATE']._serialized_start=3963
-  _globals['_LAUNCHPLANTEMPLATE']._serialized_end=4149
+  _globals['_ARRAYNODE']._serialized_end=1992
+  _globals['_ARRAYNODE_EXECUTIONMODE']._serialized_start=1900
+  _globals['_ARRAYNODE_EXECUTIONMODE']._serialized_end=1950
+  _globals['_NODEMETADATA']._serialized_start=1995
+  _globals['_NODEMETADATA']._serialized_end=2391
+  _globals['_ALIAS']._serialized_start=2393
+  _globals['_ALIAS']._serialized_end=2440
+  _globals['_NODE']._serialized_start=2443
+  _globals['_NODE']._serialized_end=2986
+  _globals['_WORKFLOWMETADATA']._serialized_start=2989
+  _globals['_WORKFLOWMETADATA']._serialized_end=3369
+  _globals['_WORKFLOWMETADATA_TAGSENTRY']._serialized_start=3231
+  _globals['_WORKFLOWMETADATA_TAGSENTRY']._serialized_end=3286
+  _globals['_WORKFLOWMETADATA_ONFAILUREPOLICY']._serialized_start=3288
+  _globals['_WORKFLOWMETADATA_ONFAILUREPOLICY']._serialized_end=3369
+  _globals['_WORKFLOWMETADATADEFAULTS']._serialized_start=3371
+  _globals['_WORKFLOWMETADATADEFAULTS']._serialized_end=3435
+  _globals['_WORKFLOWTEMPLATE']._serialized_start=3438
+  _globals['_WORKFLOWTEMPLATE']._serialized_end=3856
+  _globals['_TASKNODEOVERRIDES']._serialized_start=3859
+  _globals['_TASKNODEOVERRIDES']._serialized_end=4056
+  _globals['_LAUNCHPLANTEMPLATE']._serialized_start=4059
+  _globals['_LAUNCHPLANTEMPLATE']._serialized_end=4245
 # @@protoc_insertion_point(module_scope)
diff --git a/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.pyi b/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.pyi
index 664581b0f4..6099ea6d6e 100644
--- a/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.pyi
+++ b/flyteidl/gen/pb_python/flyteidl/core/workflow_pb2.pyi
@@ -91,7 +91,7 @@ class GateNode(_message.Message):
     def __init__(self, approve: _Optional[_Union[ApproveCondition, _Mapping]] = ..., signal: _Optional[_Union[SignalCondition, _Mapping]] = ..., sleep: _Optional[_Union[SleepCondition, _Mapping]] = ...) -> None: ...
 
 class ArrayNode(_message.Message):
-    __slots__ = ["node", "parallelism", "min_successes", "min_success_ratio", "execution_mode"]
+    __slots__ = ["node", "parallelism", "min_successes", "min_success_ratio", "execution_mode", "is_original_sub_node_interface"]
     class ExecutionMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
         __slots__ = []
         MINIMAL_STATE: _ClassVar[ArrayNode.ExecutionMode]
@@ -103,12 +103,14 @@ class ArrayNode(_message.Message):
     MIN_SUCCESSES_FIELD_NUMBER: _ClassVar[int]
     MIN_SUCCESS_RATIO_FIELD_NUMBER: _ClassVar[int]
     EXECUTION_MODE_FIELD_NUMBER: _ClassVar[int]
+    IS_ORIGINAL_SUB_NODE_INTERFACE_FIELD_NUMBER: _ClassVar[int]
     node: Node
     parallelism: int
     min_successes: int
     min_success_ratio: float
     execution_mode: ArrayNode.ExecutionMode
-    def __init__(self, node: _Optional[_Union[Node, _Mapping]] = ..., parallelism: _Optional[int] = ..., min_successes: _Optional[int] = ..., min_success_ratio: _Optional[float] = ..., execution_mode: _Optional[_Union[ArrayNode.ExecutionMode, str]] = ...) -> None: ...
+    is_original_sub_node_interface: _wrappers_pb2.BoolValue
+    def __init__(self, node: _Optional[_Union[Node, _Mapping]] = ..., parallelism: _Optional[int] = ..., min_successes: _Optional[int] = ..., min_success_ratio: _Optional[float] = ..., execution_mode: _Optional[_Union[ArrayNode.ExecutionMode, str]] = ..., is_original_sub_node_interface: _Optional[_Union[_wrappers_pb2.BoolValue, _Mapping]] = ...) -> None: ...
 
 class NodeMetadata(_message.Message):
     __slots__ = ["name", "timeout", "retries", "interruptible", "cacheable", "cache_version", "cache_serializable"]
diff --git a/flyteidl/gen/pb_rust/flyteidl.core.rs b/flyteidl/gen/pb_rust/flyteidl.core.rs
index 39a7e18f52..0cfc6a19ae 100644
--- a/flyteidl/gen/pb_rust/flyteidl.core.rs
+++ b/flyteidl/gen/pb_rust/flyteidl.core.rs
@@ -2435,6 +2435,9 @@ pub struct ArrayNode {
     /// execution_mode determines the execution path for ArrayNode.
     #[prost(enumeration="array_node::ExecutionMode", tag="5")]
     pub execution_mode: i32,
+    /// Indicates whether the sub node's original interface was altered
+    #[prost(message, optional, tag="6")]
+    pub is_original_sub_node_interface: ::core::option::Option<bool>,
     #[prost(oneof="array_node::ParallelismOption", tags="2")]
     pub parallelism_option: ::core::option::Option<array_node::ParallelismOption>,
     #[prost(oneof="array_node::SuccessCriteria", tags="3, 4")]
diff --git a/flyteidl/protos/flyteidl/core/workflow.proto b/flyteidl/protos/flyteidl/core/workflow.proto
index 3df4b2422f..cf75850ece 100644
--- a/flyteidl/protos/flyteidl/core/workflow.proto
+++ b/flyteidl/protos/flyteidl/core/workflow.proto
@@ -147,6 +147,9 @@ message ArrayNode {
 
     // execution_mode determines the execution path for ArrayNode.
     ExecutionMode execution_mode = 5;
+
+    // Indicates whether the sub node's original interface was altered
+    google.protobuf.BoolValue is_original_sub_node_interface = 6;
 }
 
 // Defines extra information about the Node.