STET

agent_patch

runs/2026-02-28__13-38-10__gpt-5-1-codex-mini/flux-pr-1184/flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/agent-logs/agent.patch

13855 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
index 3484ce9..c90e48a 100644
--- a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter.go
@@ -168,6 +168,10 @@ func (r *fieldSelectionRewriter) unionFieldSelectionNeedsRewrite(selectionSetInf
 		return true
 	}
 
+	if selectionSetInfo.hasInlineFragmentsOnUnions {
+		return true
+	}
+
 	// when we do not have fragments on interfaces, but only on objects - we do not need to rewrite
 	if !selectionSetInfo.hasInlineFragmentsOnInterfaces {
 		return false
@@ -222,6 +226,10 @@ func (r *fieldSelectionRewriter) rewriteUnionSelection(fieldRef int, fieldInfo s
 		r.flattenFragmentOnInterface(inlineFragmentOnInterface.selectionSetInfo, inlineFragmentOnInterface.typeNamesImplementingInterface, unionTypeNames, &newSelectionRefs)
 	}
 
+	for _, inlineFragmentOnUnion := range fieldInfo.inlineFragmentsOnUnions {
+		r.flattenFragmentOnUnion(inlineFragmentOnUnion, unionTypeNames, unionTypeNames, &newSelectionRefs)
+	}
+
 	// filter existing fragments by type names exists in the current datasource
 	// TODO: do not need to iterate 2 times in filter and here
 	filteredObjectFragments, _ := r.filterFragmentsByTypeNames(fieldInfo.inlineFragmentsOnObjects, unionTypeNames)
@@ -304,6 +312,10 @@ func (r *fieldSelectionRewriter) processInterfaceSelection(fieldRef int, interfa
 }
 
 func (r *fieldSelectionRewriter) interfaceFieldSelectionNeedsRewrite(selectionSetInfo selectionSetInfo, interfaceTypeNames []string, entityNames []string) (needRewrite bool) {
+	if selectionSetInfo.hasInlineFragmentsOnUnions {
+		return true
+	}
+
 	// when we do not have fragments
 	if !selectionSetInfo.hasInlineFragmentsOnInterfaces && !selectionSetInfo.hasInlineFragmentsOnObjects {
 		// check that all types implementing the interface have a root node with the requested fields
@@ -440,6 +452,41 @@ func (r *fieldSelectionRewriter) flattenFragmentOnInterface(selectionSetInfo sel
 
 		r.flattenFragmentOnInterface(inlineFragmentInfo.selectionSetInfo, inlineFragmentInfo.typeNamesImplementingInterface, filteredImplementingTypes, selectionRefs)
 	}
+
+	for _, inlineFragmentInfo := range selectionSetInfo.inlineFragmentsOnUnions {
+		r.flattenFragmentOnUnion(inlineFragmentInfo, filteredImplementingTypes, allowedTypeNames, selectionRefs)
+	}
+}
+
+func (r *fieldSelectionRewriter) flattenFragmentOnUnion(inlineFragment inlineFragmentSelectionOnUnion, parentSelectionValidTypes []string, allowedTypeNames []string, selectionRefs *[]int) {
+	filteredUnionMemberTypes := r.allowedUnionMemberTypeNames(inlineFragment, parentSelectionValidTypes, allowedTypeNames)
+	if len(filteredUnionMemberTypes) == 0 {
+		return
+	}
+
+	if inlineFragment.selectionSetInfo.hasFields {
+		for _, typeName := range filteredUnionMemberTypes {
+			*selectionRefs = append(*selectionRefs, r.createFragmentSelection(typeName, inlineFragment.selectionSetInfo.fields))
+		}
+	}
+
+	for _, inlineFragmentInfo := range inlineFragment.selectionSetInfo.inlineFragmentsOnObjects {
+		if !slices.Contains(filteredUnionMemberTypes, inlineFragmentInfo.typeName) {
+			continue
+		}
+
+		fragmentSelectionRef := r.operation.CopySelection(inlineFragmentInfo.selectionRef)
+
+		*selectionRefs = append(*selectionRefs, fragmentSelectionRef)
+	}
+
+	for _, inlineFragmentInfo := range inlineFragment.selectionSetInfo.inlineFragmentsOnInterfaces {
+		r.flattenFragmentOnInterface(inlineFragmentInfo.selectionSetInfo, inlineFragmentInfo.typeNamesImplementingInterfaceInCurrentDS, filteredUnionMemberTypes, selectionRefs)
+	}
+
+	for _, inlineFragmentInfo := range inlineFragment.selectionSetInfo.inlineFragmentsOnUnions {
+		r.flattenFragmentOnUnion(inlineFragmentInfo, filteredUnionMemberTypes, filteredUnionMemberTypes, selectionRefs)
+	}
 }
 
 func (r *fieldSelectionRewriter) collectChangedRefs(fieldRef int, fieldRefsPaths map[int]string) (map[int][]int, error) {
diff --git a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go
index 17a53e1..b65955f 100644
--- a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter_helpers.go
@@ -45,7 +45,7 @@ func (r *fieldSelectionRewriter) entitiesImplementingInterface(typesImplementing
 		}
 	}
 
-	return entityNames
+	return out
 }
 
 func (r *fieldSelectionRewriter) entityNamesWithoutFragments(inlineFragments []inlineFragmentSelection, entityNames []string) []string {
@@ -168,7 +168,11 @@ func (r *fieldSelectionRewriter) interfaceFragmentsRequiresCleanup(inlineFragmen
 	return false
 }
 
-func (r *fieldSelectionRewriter) objectFragmentNeedCleanup(inlineFragment inlineFragmentSelection) bool {
+func (r *fieldSelectionRewriter) objectFragmentNeedCleanup(inlineFragment inlineFragmentSelection, parentSelectionValidTypes []string) bool {
+	if len(parentSelectionValidTypes) > 0 && !slices.Contains(parentSelectionValidTypes, inlineFragment.typeName) {
+		return true
+	}
+
 	if !r.hasTypeOnDataSource(inlineFragment.typeName) {
 		return true
 	}
@@ -179,6 +183,14 @@ func (r *fieldSelectionRewriter) objectFragmentNeedCleanup(inlineFragment inline
 		}
 	}
 
+	if inlineFragment.selectionSetInfo.hasInlineFragmentsOnUnions {
+		for _, fragmentOnUnion := range inlineFragment.selectionSetInfo.inlineFragmentsOnUnions {
+			if r.unionFragmentNeedCleanup(fragmentOnUnion, []string{inlineFragment.typeName}) {
+				return true
+			}
+		}
+	}
+
 	return false
 }
 
@@ -206,7 +218,7 @@ func (r *fieldSelectionRewriter) interfaceFragmentNeedCleanup(inlineFragment inl
 				return true
 			}
 
-			if r.objectFragmentNeedCleanup(fragmentOnObject) {
+			if r.objectFragmentNeedCleanup(fragmentOnObject, parentSelectionValidTypes) {
 				return true
 			}
 		}
@@ -222,6 +234,14 @@ func (r *fieldSelectionRewriter) interfaceFragmentNeedCleanup(inlineFragment inl
 		}
 	}
 
+	if inlineFragment.selectionSetInfo.hasInlineFragmentsOnUnions {
+		for _, fragmentOnUnion := range inlineFragment.selectionSetInfo.inlineFragmentsOnUnions {
+			if r.unionFragmentNeedCleanup(fragmentOnUnion, parentSelectionValidTypes) {
+				return true
+			}
+		}
+	}
+
 	if inlineFragment.selectionSetInfo.hasFields {
 		// NOTE: maybe we need to filter this typenames by parentSelectionValidTypes?
 		for _, typeName := range inlineFragment.typeNamesImplementingInterfaceInCurrentDS {
@@ -238,6 +258,85 @@ func (r *fieldSelectionRewriter) interfaceFragmentNeedCleanup(inlineFragment inl
 	return false
 }
 
+func (r *fieldSelectionRewriter) unionFragmentNeedCleanup(inlineFragment inlineFragmentSelectionOnUnion, parentSelectionValidTypes []string) bool {
+	if !r.hasTypeOnDataSource(inlineFragment.typeName) {
+		return true
+	}
+
+	filteredUnionMembers := r.allowedUnionMemberTypeNames(inlineFragment, parentSelectionValidTypes, nil)
+	if len(filteredUnionMembers) == 0 {
+		return false
+	}
+
+	if inlineFragment.selectionSetInfo.hasFields {
+		for _, typeName := range filteredUnionMembers {
+			if !r.typeHasAllFieldLocal(typeName, inlineFragment.selectionSetInfo.fields) {
+				return true
+			}
+
+			if r.hasRequiresConfigurationForField(typeName, inlineFragment.selectionSetInfo.fields) {
+				return true
+			}
+		}
+	}
+
+	if inlineFragment.selectionSetInfo.hasInlineFragmentsOnObjects {
+		for _, fragmentOnObject := range inlineFragment.selectionSetInfo.inlineFragmentsOnObjects {
+			if !slices.Contains(filteredUnionMembers, fragmentOnObject.typeName) {
+				return true
+			}
+
+			if r.objectFragmentNeedCleanup(fragmentOnObject, filteredUnionMembers) {
+				return true
+			}
+		}
+	}
+
+	if inlineFragment.selectionSetInfo.hasInlineFragmentsOnInterfaces {
+		for _, fragmentOnInterface := range inlineFragment.selectionSetInfo.inlineFragmentsOnInterfaces {
+			if r.interfaceFragmentNeedCleanup(fragmentOnInterface, filteredUnionMembers) {
+				return true
+			}
+		}
+	}
+
+	if inlineFragment.selectionSetInfo.hasInlineFragmentsOnUnions {
+		for _, fragmentOnUnion := range inlineFragment.selectionSetInfo.inlineFragmentsOnUnions {
+			if r.unionFragmentNeedCleanup(fragmentOnUnion, filteredUnionMembers) {
+				return true
+			}
+		}
+	}
+
+	return false
+}
+
+func (r *fieldSelectionRewriter) allowedUnionMemberTypeNames(inlineFragment inlineFragmentSelectionOnUnion, parentSelectionValidTypes []string, allowedTypeNames []string) []string {
+	unionMemberTypeNames := inlineFragment.unionMemberTypeNames
+	if len(inlineFragment.unionMemberTypeNamesInCurrentDS) > 0 {
+		unionMemberTypeNames = inlineFragment.unionMemberTypeNamesInCurrentDS
+	}
+
+	if len(unionMemberTypeNames) == 0 {
+		return nil
+	}
+
+	filtered := make([]string, 0, len(unionMemberTypeNames))
+	for _, typeName := range unionMemberTypeNames {
+		if len(parentSelectionValidTypes) > 0 && !slices.Contains(parentSelectionValidTypes, typeName) {
+			continue
+		}
+
+		if len(allowedTypeNames) > 0 && !slices.Contains(allowedTypeNames, typeName) {
+			continue
+		}
+
+		filtered = append(filtered, typeName)
+	}
+
+	return filtered
+}
+
 func (r *fieldSelectionRewriter) typeHasAllFieldLocal(typeName string, fields []fieldSelection) bool {
 	for _, field := range fields {
 		if field.fieldName == typeNameField {
diff --git a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
index 950ccb0..2085abf 100644
--- a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter_info.go
@@ -171,7 +171,7 @@ func (r *fieldSelectionRewriter) collectInlineFragmentInformation(
 				unionMemberTypeNamesFromCurrentDS, _ := r.upstreamDefinition.UnionTypeDefinitionMemberTypeNames(upstreamNode.Ref)
 				entityNames, _ := r.datasourceHasEntitiesWithName(unionMemberTypeNamesFromCurrentDS)
 
-				inlineFragmentSelectionOnUnion.unionMemberTypeNames = unionMemberTypeNamesFromCurrentDS
+				inlineFragmentSelectionOnUnion.unionMemberTypeNamesInCurrentDS = unionMemberTypeNamesFromCurrentDS
 				inlineFragmentSelectionOnUnion.unionMemberEntityNames = entityNames
 			}
 		}
diff --git a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go b/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go
index c58465a..418ac0c 100644
--- a/tmp/agent-patch-flux-pr-1184.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go
+++ b/app/v2/pkg/engine/plan/abstract_selection_rewriter_test.go
@@ -1265,6 +1265,162 @@ func TestInterfaceSelectionRewriter_RewriteOperation(t *testing.T) {
 				}`,
 			shouldRewrite: false,
 		},
+		{
+			name: "nested union fragment inside interface field gets flattened",
+			definition: `
+				interface Node {
+					name: String!
+				}
+
+				type User implements Node {
+					name: String!
+				}
+
+				type Admin implements Node {
+					name: String!
+				}
+
+				union Account = User | Admin
+
+				type Query {
+					iface: Node!
+				}
+			`,
+			upstreamDefinition: `
+				interface Node {
+					name: String!
+				}
+
+				type User implements Node {
+					name: String!
+				}
+
+				type Admin implements Node {
+					name: String!
+				}
+
+				union Account = User | Admin
+
+				type Query {
+					iface: Node!
+				}
+			`,
+			dsConfiguration: dsb().
+				RootNode("Query", "iface").
+				RootNode("User", "name").
+				RootNode("Admin", "name").
+				KeysMetadata(FederationFieldConfigurations{
+					{
+						TypeName:     "User",
+						SelectionSet: "name",
+					},
+					{
+						TypeName:     "Admin",
+						SelectionSet: "name",
+					},
+				}).
+				DS(),
+			operation: `
+				query {
+					iface {
+						... on Node {
+							... on Account {
+								name
+							}
+						}
+					}
+				}
+			`,
+			expectedOperation: `
+				query {
+					iface {
+						... on User {
+							name
+						}
+						... on Admin {
+							name
+						}
+					}
+				}
+			`,
+			shouldRewrite: true,
+		},
+		{
+			name:      "nested union fragment inside union field gets flattened",
+			fieldName: "accounts",
+			definition: `
+				type User {
+					name: String!
+				}
+
+				type Admin {
+					name: String!
+				}
+
+				union Account = User | Admin
+
+				type Query {
+					accounts: [Account!]!
+				}
+			`,
+			upstreamDefinition: `
+				type User {
+					name: String!
+				}
+
+				type Admin {
+					name: String!
+				}
+
+				union Account = User | Admin
+
+				type Query {
+					accounts: [Account!]!
+				}
+			`,
+			dsConfiguration: dsb().
+				RootNode("Query", "accounts").
+				RootNode("User", "name").
+				RootNode("Admin", "name").
+				KeysMetadata(FederationFieldConfigurations{
+					{
+						TypeName:     "User",
+						SelectionSet: "name",
+					},
+					{
+						TypeName:     "Admin",
+						SelectionSet: "name",
+					},
+				}).
+				DS(),
+			operation: `
+				query {
+					accounts {
+						... on Account {
+							... on User {
+								name
+							}
+							... on Admin {
+								name
+							}
+						}
+					}
+				}
+			`,
+			expectedOperation: `
+				query {
+					accounts {
+						... on User {
+							name
+						}
+						... on Admin {
+							name
+						}
+					}
+				}
+			`,
+			shouldRewrite: true,
+		},
 		{
 			name: "field is a type",
 			definition: `