-
Notifications
You must be signed in to change notification settings - Fork 1
ISet<string> list values expand in hash order while pair-sets are canonicalized #61
Copy link
Copy link
Open
Labels
bugSomething isn't workingSomething isn't workingdifficulty:mediumtriage difficulty ratingtriage difficulty ratingdocumentationImprovements or additions to documentationImprovements or additions to documentationeffort:striage effort ratingtriage effort ratingmoscow:shouldtriage moscow ratingtriage moscow ratingpriority:mediumtriage priority ratingtriage priority ratingreadiness:needs-decisiontriage readiness ratingtriage readiness ratingrisk:mediumtriage risk ratingtriage risk ratingtype:bugtriage type ratingtriage type rating
Description
Activity
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingdifficulty:mediumtriage difficulty ratingtriage difficulty ratingdocumentationImprovements or additions to documentationImprovements or additions to documentationeffort:striage effort ratingtriage effort ratingmoscow:shouldtriage moscow ratingtriage moscow ratingpriority:mediumtriage priority ratingtriage priority ratingreadiness:needs-decisiontriage readiness ratingtriage readiness ratingrisk:mediumtriage risk ratingtriage risk ratingtype:bugtriage type ratingtriage type rating
Found during a repeat repo-wide read-only correctness sweep (2026-08-23).
Severity: info. Current behavior may well be the right choice; the issue is that it is undocumented and inconsistent with the sibling case.
Problem
The expander canonicalizes
ISet<KeyValuePair<...>>for determinism, but leavesIEnumerable<string>— includingHashSet<string>— in enumeration order (src/Chatter.Rest.UriTemplates/UriTemplateExpander.cs:53-69).So
{?tags*}withtags = new HashSet<string>{"b","a"}expands in hash order, which can differ across processes. That is exactly the nondeterminism the associative-array ordering contract was built to eliminate (src/Chatter.Rest.UriTemplates/UriTemplateExpander.cs:229-318, and the ordering section ofdocs/usage.md), and it matters for the same reasons: cache keys and signed URLs.The ordering contract in
docs/usage.mddiscusses pairs only. String-set list values are not addressed anywhere.Existing coverage
None for
ISet<string>list values.Options
ISet<string>so the two shapes behave alike. This is a runtime-behavior change, so a minor bump — cheap now at 0.x, more expensive after 1.0.Worth deciding now rather than after 1.0.