From 03d15cef468084c92fb04a2b231becb1d9af5a31 Mon Sep 17 00:00:00 2001 From: XperiAndri Date: Sat, 10 Oct 2026 15:25:39 +0200 Subject: [PATCH 1/2] docs: add the pipeline harmony rule to the agent instructions A pipeline reads best when its steps come from one module. The rule asks for that wherever the module has the function, the conversion at the end included: Seq.sort |> Seq.toArray instead of Seq.sort |> Array.ofSeq. It follows the existing rule that keeps a chain in the Seq module and materializes at the end, and comes from the review of #44. Co-Authored-By: Claude Opus 5.5 --- .github/copilot-instructions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 49bc09a8..c4559ec4 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -76,6 +76,7 @@ Agents discover servers from #file:'.mcp.json'; these are only hints on when to * When casting sequence items use `Seq.cast` instead of `Seq.map (fun item -> item :> TargetType)`. * When concatenating two sequences or lists, prefer `seq { yield! xs; yield! ys }` (or `[ yield! xs; yield! ys ]` for lists) over the `@` operator or `Seq.append`. * When pipe operators are used on a materializable collection multiple times in a row, prefer `Seq` module for the chain and materialize at the end. +* Keep a pipeline in harmony: when consecutive steps can come from one module, take them from that module, the conversion at the end included – `xs |> Seq.filter isValid |> Seq.sort |> Seq.toArray`, not `… |> Seq.sort |> Array.ofSeq`, and `items |> List.map _.Id |> List.toArray`, not `… |> Array.ofList`. Change the module only where the steps that follow need the other collection. ### Functions, Lambdas and Strings From a23f4eb90c32f307e582180c9f17ac6a8bba3857 Mon Sep 17 00:00:00 2001 From: XperiAndri Date: Sat, 10 Oct 2026 15:25:42 +0200 Subject: [PATCH 2/2] test: keep the id pipelines of the iteration tests in one module The two assertions on the iterated ids mapped a list with List.map and converted it with Array.ofList. They end with List.toArray now, as the pipeline harmony rule asks; these were the only pipelines in src and tests that changed the module for the conversion. Co-Authored-By: Claude Opus 5.5 --- tests/Cosmos.Tests/IterationExtensionsTests.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Cosmos.Tests/IterationExtensionsTests.fs b/tests/Cosmos.Tests/IterationExtensionsTests.fs index 352cd7d2..eac66657 100644 --- a/tests/Cosmos.Tests/IterationExtensionsTests.fs +++ b/tests/Cosmos.Tests/IterationExtensionsTests.fs @@ -33,7 +33,7 @@ type IterationExtensionsIntegrationTests () = Assert.HasCount (2, iteratedItems, "FeedIterator.AsAsyncEnumerable should return exactly the seeded items.") CollectionAssert.AreEquivalent ( expectedIds, - iteratedItems |> List.map _.id |> Array.ofList, + iteratedItems |> List.map _.id |> List.toArray, "FeedIterator.AsAsyncEnumerable should iterate seeded items without duplicates or omissions." ) } @@ -59,7 +59,7 @@ type IterationExtensionsIntegrationTests () = Assert.HasCount (2, iteratedItems, "IQueryable.AsAsyncEnumerable should return exactly the seeded items.") CollectionAssert.AreEquivalent ( expectedIds, - iteratedItems |> List.map _.id |> Array.ofList, + iteratedItems |> List.map _.id |> List.toArray, "IQueryable.AsAsyncEnumerable should iterate seeded items without duplicates or omissions." ) }