From a0e0349feeaabaae05837c6330caa27a5d6887f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:16:03 +0000 Subject: [PATCH 1/3] Initial plan From ac963a2fe7cde2423f9aca52fd3b68f5273162be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:24:11 +0000 Subject: [PATCH 2/3] Fix import ordering: preserve topological order instead of alphabetical sorting Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ci-coach.lock.yml | 2 +- pkg/workflow/compiler_yaml.go | 8 +++----- pkg/workflow/compiler_yaml_test.go | 24 ++++++++++++++---------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci-coach.lock.yml b/.github/workflows/ci-coach.lock.yml index d75a6339c2..ba414c0c68 100644 --- a/.github/workflows/ci-coach.lock.yml +++ b/.github/workflows/ci-coach.lock.yml @@ -25,9 +25,9 @@ # # Resolved workflow manifest: # Imports: -# - shared/ci-data-analysis.md # - shared/ci-optimization-strategies.md # - shared/jqschema.md +# - shared/ci-data-analysis.md # - shared/mood.md # - shared/reporting.md # diff --git a/pkg/workflow/compiler_yaml.go b/pkg/workflow/compiler_yaml.go index 75fd733835..62bcf8afd0 100644 --- a/pkg/workflow/compiler_yaml.go +++ b/pkg/workflow/compiler_yaml.go @@ -83,11 +83,9 @@ func (c *Compiler) generateWorkflowHeader(yaml *strings.Builder, data *WorkflowD if len(data.ImportedFiles) > 0 { yaml.WriteString("# Imports:\n") - // Sort imports for deterministic output - sortedImports := make([]string, len(data.ImportedFiles)) - copy(sortedImports, data.ImportedFiles) - sort.Strings(sortedImports) - for _, file := range sortedImports { + // ImportedFiles is already sorted in topological order by the parser + // (dependencies before dependents). Preserve this ordering. + for _, file := range data.ImportedFiles { cleanFile := stringutil.StripANSIEscapeCodes(file) // Normalize to Unix paths (forward slashes) for cross-platform compatibility cleanFile = filepath.ToSlash(cleanFile) diff --git a/pkg/workflow/compiler_yaml_test.go b/pkg/workflow/compiler_yaml_test.go index 3aaab1161e..cc42bee8e8 100644 --- a/pkg/workflow/compiler_yaml_test.go +++ b/pkg/workflow/compiler_yaml_test.go @@ -1238,9 +1238,11 @@ This is a test workflow.` } } -// TestManifestHeaderOrderingDeterministic tests that imported and included files -// are always rendered in sorted order, regardless of input ordering. -// This ensures deterministic lock file output and prevents noisy diffs. +// TestManifestHeaderOrderingDeterministic tests that included files are sorted +// alphabetically while imported files preserve their topological ordering. +// ImportedFiles must maintain topological order (dependencies before dependents) +// as determined by the parser. IncludedFiles can be sorted alphabetically for +// deterministic output since they don't have dependency relationships. func TestManifestHeaderOrderingDeterministic(t *testing.T) { tmpDir := testutil.TempDir(t, "manifest-ordering-test") @@ -1291,18 +1293,20 @@ Test content.` }, } - // Expected sorted order for each test case + // Expected order for each test case: + // - ImportedFiles: Preserve input order (already topologically sorted by parser) + // - IncludedFiles: Alphabetically sorted for determinism expectedImports := map[string][]string{ - "reverse_alphabetical_imports": {"a-file.md", "m-file.md", "z-file.md"}, + "reverse_alphabetical_imports": {"z-file.md", "m-file.md", "a-file.md"}, // Preserve topological order "reverse_alphabetical_includes": {}, - "mixed_order_both": {"a-import.md", "b-import.md", "c-import.md"}, - "nested_paths": {"common/a.md", "lib/m.md", "shared/z.md"}, + "mixed_order_both": {"b-import.md", "a-import.md", "c-import.md"}, // Preserve topological order + "nested_paths": {"shared/z.md", "common/a.md", "lib/m.md"}, // Preserve topological order } expectedIncludes := map[string][]string{ "reverse_alphabetical_imports": {}, - "reverse_alphabetical_includes": {"a-include.md", "m-include.md", "z-include.md"}, - "mixed_order_both": {"x-include.md", "y-include.md", "z-include.md"}, - "nested_paths": {"helpers/k.md", "tools/y.md", "utils/b.md"}, + "reverse_alphabetical_includes": {"a-include.md", "m-include.md", "z-include.md"}, // Alphabetically sorted + "mixed_order_both": {"x-include.md", "y-include.md", "z-include.md"}, // Alphabetically sorted + "nested_paths": {"helpers/k.md", "tools/y.md", "utils/b.md"}, // Alphabetically sorted } for _, tt := range tests { From 50deaaa9286d896ea254363d10f607c210877fbf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:25:43 +0000 Subject: [PATCH 3/3] Final validation: all tests passing Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/compiler_yaml_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/workflow/compiler_yaml_test.go b/pkg/workflow/compiler_yaml_test.go index cc42bee8e8..6803469fe3 100644 --- a/pkg/workflow/compiler_yaml_test.go +++ b/pkg/workflow/compiler_yaml_test.go @@ -1300,13 +1300,13 @@ Test content.` "reverse_alphabetical_imports": {"z-file.md", "m-file.md", "a-file.md"}, // Preserve topological order "reverse_alphabetical_includes": {}, "mixed_order_both": {"b-import.md", "a-import.md", "c-import.md"}, // Preserve topological order - "nested_paths": {"shared/z.md", "common/a.md", "lib/m.md"}, // Preserve topological order + "nested_paths": {"shared/z.md", "common/a.md", "lib/m.md"}, // Preserve topological order } expectedIncludes := map[string][]string{ "reverse_alphabetical_imports": {}, "reverse_alphabetical_includes": {"a-include.md", "m-include.md", "z-include.md"}, // Alphabetically sorted "mixed_order_both": {"x-include.md", "y-include.md", "z-include.md"}, // Alphabetically sorted - "nested_paths": {"helpers/k.md", "tools/y.md", "utils/b.md"}, // Alphabetically sorted + "nested_paths": {"helpers/k.md", "tools/y.md", "utils/b.md"}, // Alphabetically sorted } for _, tt := range tests {