STET

agent_patch

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

8833 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1232.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go
index 9fb8c1c..115cf62 100644
--- a/tmp/agent-patch-flux-pr-1232.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go
+++ b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches.go
@@ -14,9 +14,18 @@ func (d *deduplicateSingleFetches) ProcessFetchTree(root *resolve.FetchTreeNode)
 	if d.disable {
 		return
 	}
+	if root == nil || len(root.ChildNodes) <= 1 {
+		return
+	}
+	replacements := make(map[int]int)
 	for i := range root.ChildNodes {
 		for j := i + 1; j < len(root.ChildNodes); j++ {
 			if root.ChildNodes[i].Item.Equals(root.ChildNodes[j].Item) {
+				keptID := root.ChildNodes[i].Item.Fetch.Dependencies().FetchID
+				removedID := root.ChildNodes[j].Item.Fetch.Dependencies().FetchID
+				if keptID != removedID {
+					replacements[removedID] = keptID
+				}
 				root.ChildNodes[i].Item.FetchPath = d.mergeFetchPath(root.ChildNodes[i].Item.FetchPath, root.ChildNodes[j].Item.FetchPath)
 
 				root.ChildNodes = append(root.ChildNodes[:j], root.ChildNodes[j+1:]...)
@@ -24,6 +33,7 @@ func (d *deduplicateSingleFetches) ProcessFetchTree(root *resolve.FetchTreeNode)
 			}
 		}
 	}
+	d.updateDependencies(root.ChildNodes, replacements)
 }
 
 func (d *deduplicateSingleFetches) mergeFetchPath(left, right []resolve.FetchItemPathElement) []resolve.FetchItemPathElement {
@@ -34,6 +44,57 @@ func (d *deduplicateSingleFetches) mergeFetchPath(left, right []resolve.FetchIte
 	return left
 }
 
+func (d *deduplicateSingleFetches) updateDependencies(nodes []*resolve.FetchTreeNode, replacements map[int]int) {
+	if len(replacements) == 0 {
+		return
+	}
+	for _, node := range nodes {
+		if node == nil || node.Item == nil {
+			continue
+		}
+		switch fetch := node.Item.Fetch.(type) {
+		case *resolve.SingleFetch:
+			d.updateSingleFetchDependencies(fetch, replacements)
+		}
+	}
+}
+
+func (d *deduplicateSingleFetches) updateSingleFetchDependencies(fetch *resolve.SingleFetch, replacements map[int]int) {
+	fetch.FetchDependencies.DependsOnFetchIDs = d.replaceFetchIDs(fetch.FetchDependencies.DependsOnFetchIDs, replacements)
+	for i := range fetch.FetchConfiguration.CoordinateDependencies {
+		for j := range fetch.FetchConfiguration.CoordinateDependencies[i].DependsOn {
+			fetch.FetchConfiguration.CoordinateDependencies[i].DependsOn[j].FetchID = d.resolveFetchID(fetch.FetchConfiguration.CoordinateDependencies[i].DependsOn[j].FetchID, replacements)
+		}
+	}
+}
+
+func (d *deduplicateSingleFetches) replaceFetchIDs(ids []int, replacements map[int]int) []int {
+	if len(ids) == 0 {
+		return ids
+	}
+	out := make([]int, 0, len(ids))
+	seen := make(map[int]struct{}, len(ids))
+	for _, id := range ids {
+		mapped := d.resolveFetchID(id, replacements)
+		if _, ok := seen[mapped]; ok {
+			continue
+		}
+		seen[mapped] = struct{}{}
+		out = append(out, mapped)
+	}
+	return out
+}
+
+func (d *deduplicateSingleFetches) resolveFetchID(id int, replacements map[int]int) int {
+	for {
+		mapped, ok := replacements[id]
+		if !ok || mapped == id {
+			return id
+		}
+		id = mapped
+	}
+}
+
 func (d *deduplicateSingleFetches) mergeTypeNames(left []string, right []string) []string {
 	if len(left) == 0 || len(right) == 0 {
 		return nil // if either side is empty, fetch is unscoped
diff --git a/tmp/agent-patch-flux-pr-1232.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go
index 88cf2be..77ff7f5 100644
--- a/tmp/agent-patch-flux-pr-1232.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go
+++ b/app/v2/pkg/engine/postprocess/deduplicate_single_fetches_test.go
@@ -115,4 +115,108 @@ func TestDeduplicateSingleFetches_ProcessFetchTree(t *testing.T) {
 
 		assert.Equal(t, output, input)
 	})
+
+	t.Run("update dependencies after merging duplicates", func(t *testing.T) {
+		keep := &resolve.FetchTreeNode{
+			Kind: resolve.FetchTreeNodeKindSingle,
+			Item: &resolve.FetchItem{
+				FetchPath: []resolve.FetchItemPathElement{{Kind: resolve.FetchItemPathElementKindObject, Path: []string{"a"}}},
+				Fetch: &resolve.SingleFetch{
+					FetchDependencies:  resolve.FetchDependencies{FetchID: 0},
+					FetchConfiguration: resolve.FetchConfiguration{Input: "a"},
+				},
+			},
+		}
+
+		duplicate := &resolve.FetchTreeNode{
+			Kind: resolve.FetchTreeNodeKindSingle,
+			Item: &resolve.FetchItem{
+				FetchPath: []resolve.FetchItemPathElement{{Kind: resolve.FetchItemPathElementKindObject, Path: []string{"a"}}},
+				Fetch: &resolve.SingleFetch{
+					FetchDependencies:  resolve.FetchDependencies{FetchID: 1},
+					FetchConfiguration: resolve.FetchConfiguration{Input: "a"},
+				},
+			},
+		}
+
+		dependent := &resolve.FetchTreeNode{
+			Kind: resolve.FetchTreeNodeKindSingle,
+			Item: &resolve.FetchItem{
+				FetchPath: []resolve.FetchItemPathElement{{Kind: resolve.FetchItemPathElementKindObject, Path: []string{"b"}}},
+				Fetch: &resolve.SingleFetch{
+					FetchDependencies: resolve.FetchDependencies{FetchID: 2, DependsOnFetchIDs: []int{1}},
+					FetchConfiguration: resolve.FetchConfiguration{
+						Input: "b",
+						CoordinateDependencies: []resolve.FetchDependency{
+							{
+								Coordinate: resolve.GraphCoordinate{TypeName: "T", FieldName: "f"},
+								DependsOn:  []resolve.FetchDependencyOrigin{{FetchID: 1}},
+							},
+						},
+					},
+				},
+			},
+		}
+
+		root := &resolve.FetchTreeNode{
+			ChildNodes: []*resolve.FetchTreeNode{keep, duplicate, dependent},
+		}
+
+		dedup := &deduplicateSingleFetches{}
+		dedup.ProcessFetchTree(root)
+
+		assert.Len(t, root.ChildNodes, 2)
+		remaining := root.ChildNodes[1].Item.Fetch.(*resolve.SingleFetch)
+		assert.Equal(t, []int{0}, remaining.FetchDependencies.DependsOnFetchIDs)
+		assert.Equal(t, 0, remaining.FetchConfiguration.CoordinateDependencies[0].DependsOn[0].FetchID)
+	})
+
+	t.Run("ignores coordinate dependencies when deduping", func(t *testing.T) {
+		a := &resolve.FetchTreeNode{
+			Kind: resolve.FetchTreeNodeKindSingle,
+			Item: &resolve.FetchItem{
+				FetchPath: []resolve.FetchItemPathElement{{Kind: resolve.FetchItemPathElementKindObject, Path: []string{"a"}}},
+				Fetch: &resolve.SingleFetch{
+					FetchDependencies: resolve.FetchDependencies{FetchID: 0},
+					FetchConfiguration: resolve.FetchConfiguration{
+						Input: "a",
+						CoordinateDependencies: []resolve.FetchDependency{
+							{
+								Coordinate: resolve.GraphCoordinate{TypeName: "T"},
+								DependsOn:  []resolve.FetchDependencyOrigin{{FetchID: 1}},
+							},
+						},
+					},
+				},
+			},
+		}
+
+		b := &resolve.FetchTreeNode{
+			Kind: resolve.FetchTreeNodeKindSingle,
+			Item: &resolve.FetchItem{
+				FetchPath: []resolve.FetchItemPathElement{{Kind: resolve.FetchItemPathElementKindObject, Path: []string{"a"}}},
+				Fetch: &resolve.SingleFetch{
+					FetchDependencies: resolve.FetchDependencies{FetchID: 1},
+					FetchConfiguration: resolve.FetchConfiguration{
+						Input: "a",
+						CoordinateDependencies: []resolve.FetchDependency{
+							{
+								Coordinate: resolve.GraphCoordinate{TypeName: "T"},
+								DependsOn:  []resolve.FetchDependencyOrigin{{FetchID: 2}},
+							},
+						},
+					},
+				},
+			},
+		}
+
+		root := &resolve.FetchTreeNode{
+			ChildNodes: []*resolve.FetchTreeNode{a, b},
+		}
+
+		dedup := &deduplicateSingleFetches{}
+		dedup.ProcessFetchTree(root)
+
+		assert.Len(t, root.ChildNodes, 1)
+	})
 }
diff --git a/tmp/agent-patch-flux-pr-1232.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetch.go b/app/v2/pkg/engine/resolve/fetch.go
index 9979256..7446adf 100644
--- a/tmp/agent-patch-flux-pr-1232.1-of-1.2026-02-28__13-38-10__gpt-5-1-codex-mini/app/v2/pkg/engine/resolve/fetch.go
+++ b/app/v2/pkg/engine/resolve/fetch.go
@@ -319,23 +319,6 @@ func (fc *FetchConfiguration) Equals(other *FetchConfiguration) bool {
 	if fc.SetTemplateOutputToNullOnVariableNull != other.SetTemplateOutputToNullOnVariableNull {
 		return false
 	}
-	if !slices.EqualFunc(fc.CoordinateDependencies, other.CoordinateDependencies, func(a, b FetchDependency) bool {
-		if a.Coordinate != b.Coordinate {
-			return false
-		}
-		if a.IsUserRequested != b.IsUserRequested {
-			return false
-		}
-		return slices.EqualFunc(a.DependsOn, b.DependsOn, func(x, y FetchDependencyOrigin) bool {
-			return x.FetchID == y.FetchID &&
-				x.Subgraph == y.Subgraph &&
-				x.Coordinate == y.Coordinate &&
-				x.IsKey == y.IsKey &&
-				x.IsRequires == y.IsRequires
-		})
-	}) {
-		return false
-	}
 	return true
 }