STET

agent_patch

runs/2026-02-21__03-36-16__gpt-5-1-codex-mini/flux-pr-1034/flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/agent-logs/agent.patch

15239 bytes

Back to adjudication
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/execution/graphql/normalization.go b/app/execution/graphql/normalization.go
index 62253b0..ff20a18 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/execution/graphql/normalization.go
+++ b/app/execution/graphql/normalization.go
@@ -33,16 +33,19 @@ func (r *Request) Normalize(schema *Schema, options ...astnormalization.Option)
 		}
 	}
 
+	options = append(options, astnormalization.WithCanonicalVariableNames())
+
+	var normalizer *astnormalization.OperationNormalizer
 	if r.OperationName != "" {
-		options = append(options, astnormalization.WithRemoveNotMatchingOperationDefinitions())
-		normalizer := astnormalization.NewWithOpts(options...)
+		normalizer = astnormalization.NewWithOpts(options...)
 		normalizer.NormalizeNamedOperation(&r.document, &schema.document, []byte(r.OperationName), &report)
 	} else {
 		// TODO: we should validate count of operations - to throw an error
 		// and do full normalization for the single anonymous operation
-		normalizer := astnormalization.NewWithOpts(options...)
+		normalizer = astnormalization.NewWithOpts(options...)
 		normalizer.NormalizeOperation(&r.document, &schema.document, &report)
 	}
+	r.variableNameMapping = normalizer.VariableNameMapping()
 
 	if report.HasErrors() {
 		return NormalizationResultFromReport(report)
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/execution/graphql/request.go b/app/execution/graphql/request.go
index 1e10748..594bbce 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/execution/graphql/request.go
+++ b/app/execution/graphql/request.go
@@ -42,7 +42,8 @@ type Request struct {
 	isNormalized bool
 	request      resolve.Request
 
-	validForSchema map[uint64]ValidationResult
+	validForSchema      map[uint64]ValidationResult
+	variableNameMapping map[string]string
 }
 
 func UnmarshalRequest(reader io.Reader, request *Request) error {
@@ -105,6 +106,17 @@ func (r *Request) IsNormalized() bool {
 	return r.isNormalized
 }
 
+func (r *Request) VariableNameMapping() map[string]string {
+	if len(r.variableNameMapping) == 0 {
+		return nil
+	}
+	mapping := make(map[string]string, len(r.variableNameMapping))
+	for canonical, original := range r.variableNameMapping {
+		mapping[canonical] = original
+	}
+	return mapping
+}
+
 func (r *Request) parseQueryOnce() (report operationreport.Report) {
 	if r.isParsed {
 		return report
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/astnormalization/astnormalization.go b/app/pkg/astnormalization/astnormalization.go
index 7cb6e18..288f753 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/astnormalization/astnormalization.go
+++ b/app/pkg/astnormalization/astnormalization.go
@@ -91,6 +91,7 @@ func NormalizeNamedOperation(operation, definition *ast.Document, operationName
 type OperationNormalizer struct {
 	operationWalkers     []*astvisitor.Walker
 	variablesExtraction  *variablesExtractionVisitor
+	variableMapper       *variableMapperVisitor
 	options              options
 	definitionNormalizer *DefinitionNormalizer
 }
@@ -130,6 +131,7 @@ type options struct {
 	extractVariables          bool
 	removeUnusedVariables     bool
 	normalizeDefinition       bool
+	canonicalizeVariables     bool
 }
 
 type Option func(options *options)
@@ -158,6 +160,12 @@ func WithNormalizeDefinition() Option {
 	}
 }
 
+func WithCanonicalVariableNames() Option {
+	return func(options *options) {
+		options.canonicalizeVariables = true
+	}
+}
+
 func (o *OperationNormalizer) setupOperationWalkers() {
 	o.operationWalkers = make([]*astvisitor.Walker, 0, 4)
 
@@ -194,6 +202,12 @@ func (o *OperationNormalizer) setupOperationWalkers() {
 
 		o.operationWalkers = append(o.operationWalkers, &variablesProcessing)
 	}
+
+	if o.options.canonicalizeVariables {
+		canonicalWalker := astvisitor.NewWalker(48)
+		o.variableMapper = canonicalizeVariables(&canonicalWalker)
+		o.operationWalkers = append(o.operationWalkers, &canonicalWalker)
+	}
 }
 
 func (o *OperationNormalizer) prepareDefinition(definition *ast.Document, report *operationreport.Report) {
@@ -231,6 +245,9 @@ func (o *OperationNormalizer) NormalizeNamedOperation(operation, definition *ast
 	if o.variablesExtraction != nil {
 		o.variablesExtraction.operationName = operationName
 	}
+	if o.variableMapper != nil {
+		o.variableMapper.operationName = operationName
+	}
 	for i := range o.operationWalkers {
 		o.operationWalkers[i].Walk(operation, definition, report)
 		if report.HasErrors() {
@@ -238,3 +255,10 @@ func (o *OperationNormalizer) NormalizeNamedOperation(operation, definition *ast
 		}
 	}
 }
+
+func (o *OperationNormalizer) VariableNameMapping() map[string]string {
+	if o.variableMapper == nil {
+		return nil
+	}
+	return o.variableMapper.Mapping()
+}
diff --git a/app/pkg/astnormalization/variable_mapper.go b/app/pkg/astnormalization/variable_mapper.go
new file mode 100644
index 0000000..c6e017c
--- /dev/null
+++ b/app/pkg/astnormalization/variable_mapper.go
@@ -0,0 +1,192 @@
+package astnormalization
+
+import (
+	"bytes"
+	"encoding/json"
+	"sort"
+	"strconv"
+
+	"github.com/wundergraph/graphql-go-tools/pkg/ast"
+	"github.com/wundergraph/graphql-go-tools/pkg/astvisitor"
+)
+
+func canonicalizeVariables(walker *astvisitor.Walker) *variableMapperVisitor {
+	visitor := &variableMapperVisitor{
+		Walker: walker,
+	}
+	walker.RegisterEnterDocumentVisitor(visitor)
+	walker.RegisterLeaveDocumentVisitor(visitor)
+	walker.RegisterOperationDefinitionVisitor(visitor)
+	walker.RegisterEnterArgumentVisitor(visitor)
+	return visitor
+}
+
+type variableMapperVisitor struct {
+	*astvisitor.Walker
+	operation           *ast.Document
+	definition          *ast.Document
+	operationName       []byte
+	skip                bool
+	seen                map[int]struct{}
+	canonicalCounter    int
+	canonicalOrder      []string
+	canonicalToOriginal map[string]string
+	mapping             map[string]string
+}
+
+func (v *variableMapperVisitor) EnterDocument(operation, definition *ast.Document) {
+	v.operation = operation
+	v.definition = definition
+	v.seen = map[int]struct{}{}
+	v.canonicalCounter = 0
+	v.canonicalOrder = v.canonicalOrder[:0]
+	v.canonicalToOriginal = map[string]string{}
+	v.mapping = nil
+	v.skip = false
+}
+
+func (v *variableMapperVisitor) LeaveDocument(operation, definition *ast.Document) {
+	if len(v.canonicalOrder) == 0 {
+		v.mapping = nil
+		return
+	}
+
+	v.rebuildVariablesJSON()
+
+	v.mapping = make(map[string]string, len(v.canonicalToOriginal))
+	for canonical, original := range v.canonicalToOriginal {
+		v.mapping[canonical] = original
+	}
+}
+
+func (v *variableMapperVisitor) EnterOperationDefinition(ref int) {
+	if len(v.operationName) == 0 {
+		v.skip = false
+		return
+	}
+	name := v.operation.OperationDefinitionNameBytes(ref)
+	v.skip = !bytes.Equal(name, v.operationName)
+}
+
+func (v *variableMapperVisitor) LeaveOperationDefinition(ref int) {
+	v.skip = false
+}
+
+func (v *variableMapperVisitor) EnterArgument(ref int) {
+	if v.skip {
+		return
+	}
+	v.traverseValue(v.operation.Arguments[ref].Value)
+}
+
+func (v *variableMapperVisitor) traverseValue(value ast.Value) {
+	switch value.Kind {
+	case ast.ValueKindVariable:
+		v.mapVariable(value.Ref)
+	case ast.ValueKindList:
+		for _, ref := range v.operation.ListValues[value.Ref].Refs {
+			listValue := v.operation.Value(ref)
+			v.traverseValue(listValue)
+		}
+	case ast.ValueKindObject:
+		for _, ref := range v.operation.ObjectValues[value.Ref].Refs {
+			v.traverseValue(v.operation.ObjectField(ref).Value)
+		}
+	}
+}
+
+func (v *variableMapperVisitor) mapVariable(ref int) {
+	if _, ok := v.seen[ref]; ok {
+		return
+	}
+	v.seen[ref] = struct{}{}
+
+	canonical := "v" + strconv.Itoa(v.canonicalCounter)
+	v.canonicalCounter++
+
+	original := v.operation.VariableValueNameString(ref)
+	v.operation.VariableValues[ref].Name = v.operation.Input.AppendInputBytes([]byte(canonical))
+
+	v.canonicalOrder = append(v.canonicalOrder, canonical)
+	v.canonicalToOriginal[canonical] = original
+}
+
+func (v *variableMapperVisitor) rebuildVariablesJSON() {
+	if len(v.operation.Input.Variables) == 0 {
+		return
+	}
+
+	var values map[string]json.RawMessage
+	if err := json.Unmarshal(v.operation.Input.Variables, &values); err != nil {
+		return
+	}
+
+	entries := make([]variableEntry, 0, len(values))
+
+	for _, canonical := range v.canonicalOrder {
+		original, ok := v.canonicalToOriginal[canonical]
+		if !ok {
+			continue
+		}
+		value, ok := values[original]
+		if !ok {
+			continue
+		}
+		entries = append(entries, variableEntry{
+			Name:  canonical,
+			Value: append([]byte{}, value...),
+		})
+		delete(values, original)
+	}
+
+	if len(values) > 0 {
+		remaining := make([]string, 0, len(values))
+		for key := range values {
+			remaining = append(remaining, key)
+		}
+		sort.Strings(remaining)
+		for _, key := range remaining {
+			entries = append(entries, variableEntry{
+				Name:  key,
+				Value: append([]byte{}, values[key]...),
+			})
+		}
+	}
+
+	if len(entries) == 0 {
+		return
+	}
+
+	v.operation.Input.Variables = encodeVariables(entries)
+}
+
+func (v *variableMapperVisitor) Mapping() map[string]string {
+	if len(v.mapping) == 0 {
+		return nil
+	}
+	mapping := make(map[string]string, len(v.mapping))
+	for canonical, original := range v.mapping {
+		mapping[canonical] = original
+	}
+	return mapping
+}
+
+type variableEntry struct {
+	Name  string
+	Value []byte
+}
+
+func encodeVariables(entries []variableEntry) []byte {
+	buf := bytes.Buffer{}
+	buf.WriteByte('{')
+	for i, entry := range entries {
+		if i > 0 {
+			buf.WriteByte(',')
+		}
+		buf.WriteString(strconv.Quote(entry.Name))
+		buf.WriteByte(':')
+		buf.Write(entry.Value)
+	}
+	buf.WriteByte('}')
+	return buf.Bytes()
+}
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/execution/handler.go b/app/pkg/execution/handler.go
index 5bcc331..838fb22 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/execution/handler.go
+++ b/app/pkg/execution/handler.go
@@ -71,7 +71,13 @@ func (h *Handler) Handle(requestData, extraVariables []byte) (executor *Executor
 		err = report
 		return
 	}
-	normalizer := astnormalization.NewNormalizer(true, true)
+	options := []astnormalization.Option{
+		astnormalization.WithExtractVariables(),
+		astnormalization.WithRemoveFragmentDefinitions(),
+		astnormalization.WithRemoveUnusedVariables(),
+		astnormalization.WithCanonicalVariableNames(),
+	}
+	normalizer := astnormalization.NewWithOpts(options...)
 	normalizer.NormalizeOperation(&operationDocument, h.base.Definition, &report)
 	if report.HasErrors() {
 		err = report
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/graphql/normalization.go b/app/pkg/graphql/normalization.go
index 55e8f89..0f2a60a 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/graphql/normalization.go
+++ b/app/pkg/graphql/normalization.go
@@ -24,17 +24,22 @@ func (r *Request) Normalize(schema *Schema) (result NormalizationResult, err err
 
 	r.document.Input.Variables = r.Variables
 
-	normalizer := astnormalization.NewWithOpts(
+	options := []astnormalization.Option{
 		astnormalization.WithExtractVariables(),
 		astnormalization.WithRemoveFragmentDefinitions(),
 		astnormalization.WithRemoveUnusedVariables(),
-	)
+		astnormalization.WithCanonicalVariableNames(),
+	}
 
+	var normalizer *astnormalization.OperationNormalizer
 	if r.OperationName != "" {
+		normalizer = astnormalization.NewWithOpts(options...)
 		normalizer.NormalizeNamedOperation(&r.document, &schema.document, []byte(r.OperationName), &report)
 	} else {
+		normalizer = astnormalization.NewWithOpts(options...)
 		normalizer.NormalizeOperation(&r.document, &schema.document, &report)
 	}
+	r.variableNameMapping = normalizer.VariableNameMapping()
 
 	if report.HasErrors() {
 		return normalizationResultFromReport(report)
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/graphql/normalization_test.go b/app/pkg/graphql/normalization_test.go
index 10db22e..14c8c08 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/graphql/normalization_test.go
+++ b/app/pkg/graphql/normalization_test.go
@@ -38,11 +38,11 @@ func TestRequest_Normalize(t *testing.T) {
 		assert.True(t, result.Successful)
 		assert.True(t, request.isNormalized)
 
-		normalizedOperation := `query Fragments($droidID: ID!){
+		normalizedOperation := `query Fragments($v0: ID!){
     hero {
         name
     }
-    droid(id: $droidID){
+    droid(id: $v0){
         name
     }
 }`
@@ -77,8 +77,8 @@ func TestRequest_Normalize(t *testing.T) {
 	t.Run("should successfully normalize single query with arguments", func(t *testing.T) {
 		request := requestForQuery(t, starwars.FileDroidWithArgQuery)
 
-		runNormalization(t, &request, `{"a":"R2D2"}`, `query($a: ID!){
-    droid(id: $a){
+		runNormalization(t, &request, `{"v0":"R2D2"}`, `query($v0: ID!){
+    droid(id: $v0){
         name
     }
 }`)
@@ -94,8 +94,8 @@ func TestRequest_Normalize(t *testing.T) {
 			Query: `query MySearch($s: String!, $other: String) {search(name: $s) {...on Human {name}}}`,
 		}
 
-		runNormalization(t, &request, `{"s":"Luke"}`, `query MySearch($s: String!){
-    search(name: $s){
+		runNormalization(t, &request, `{"v0":"Luke"}`, `query MySearch($v0: String!){
+    search(name: $v0){
         ... on Human {
             name
         }
@@ -138,7 +138,7 @@ func TestRequest_Normalize(t *testing.T) {
 				Query:         `query MySearch($s: String!, $s2: String, $s3: String) {search(name: $s) {...on Human {name}}}`,
 			},
 		} {
-			runNormalization(t, &v, `{"s":"Luke"}`, expectedVar)
+			runNormalization(t, &v, `{"v0":"Luke"}`, expectedVar)
 		}
 	})
 
diff --git a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/graphql/request.go b/app/pkg/graphql/request.go
index 2c47e20..8c2a55e 100644
--- a/tmp/agent-patch-flux-pr-1034.1-of-1.2026-03-05__17-48-26__gpt-5-1-codex-mini/app/pkg/graphql/request.go
+++ b/app/pkg/graphql/request.go
@@ -42,7 +42,8 @@ type Request struct {
 	isNormalized bool
 	request      resolve.Request
 
-	validForSchema map[uint64]ValidationResult
+	validForSchema      map[uint64]ValidationResult
+	variableNameMapping map[string]string
 }
 
 func UnmarshalRequest(reader io.Reader, request *Request) error {
@@ -97,6 +98,17 @@ func (r *Request) IsNormalized() bool {
 	return r.isNormalized
 }
 
+func (r *Request) VariableNameMapping() map[string]string {
+	if len(r.variableNameMapping) == 0 {
+		return nil
+	}
+	mapping := make(map[string]string, len(r.variableNameMapping))
+	for canonical, original := range r.variableNameMapping {
+		mapping[canonical] = original
+	}
+	return mapping
+}
+
 func (r *Request) parseQueryOnce() (report operationreport.Report) {
 	if r.isParsed {
 		return report