[PR #1034] [MERGED] fix(domain): order canonical paths by code point, not UTF-16 unit #2598

Closed
opened 2026-10-17 21:08:02 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1034
Author: @TahsinArafat
Created: 10/7/2026
Status: ✅ Merged
Merged: 10/8/2026
Merged by: @N0zoM1z0

Base: main ← Head: fix/canonical-ordering-code-points


📝 Commits (2)

  • 616609f fix(domain): order canonical paths by code point, not UTF-16 unit
  • 9dd42ee Merge remote-tracking branch 'origin/main' into review/1034-unicode-ordering

📊 Changes

2 files changed (+57 additions, -5 deletions)

View changed files

➕ src/domain/canonicalOrdering.test.ts (+47 -0)
📝 src/domain/canonicalOrdering.ts (+10 -5)

📄 Description

Summary

compareCodePoints documented a Unicode code-point comparison but used </>,
which compares UTF-16 code units. This delegates it to the existing
compareUnicodeCodePoints so the two canonical comparators in the domain agree,
and adds the missing regression coverage.

Problem and expected behavior

src/domain/canonicalOrdering.ts states it "Compares strings by Unicode code
point (</>)". For astral code points (above U+FFFF) the two orderings
diverge, because the lead surrogate 0xD800-0xDBFF is numerically below the BMP
tail U+E000-U+FFFF:

import { compareCodePoints, uniqueSorted } from "./src/domain/canonicalOrdering.ts";

compareCodePoints("\uFFFD", "\u{1F600}");
// observed: 1   (\uFFFD sorts after the emoji)
// expected: < 0 (U+FFFD = 65533 < U+1F600)

uniqueSorted(["\u{1F600}", "\uFFFD"]);
// observed: ["\u{1F600}", "\uFFFD"]
// expected: ["\uFFFD", "\u{1F600}"]

src/domain/unicodeCodePointOrder.ts already implements the documented
contract with codePointAt, so the domain was shipping two "canonical"
comparators that disagreed on astral input.

Change and scope

  • compareCodePoints now delegates to compareUnicodeCodePoints; the JSDoc
    records why code-point and code-unit ordering differ for astral input.
  • New src/domain/canonicalOrdering.test.ts covers astral versus BMP-tail
    ordering, equality, prefix ordering, and uniqueSorted deduplication. No
    test previously covered astral ordering for this comparator.
  • The change is confined to src/domain/canonicalOrdering.ts; no contract,
    schema, catalog, or generated artifact changes.

Every call site uses only the sign of the result (Array.prototype.sort and two
< 0 checks), so the returned magnitude is not a relied-upon contract. The
trigger requires sibling values where one begins with an astral code point and
the other with a BMP code point in U+E000-U+FFFF, so no existing fixture
changed.

Verification

  • npm run test:fast — 2760 passed, 7 skipped (was 2754 passed before; +6 new).
  • npm run check:fast — typecheck and lint pass.
  • oxfmt --check on the two changed files passes; pre-commit ran oxfmt and
    oxlint on the staged files.

I did not run the real-Hopper or real-provider lanes; this change is pure domain
ordering with no provider behavior.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1034 **Author:** [@TahsinArafat](https://github.com/TahsinArafat) **Created:** 10/7/2026 **Status:** ✅ Merged **Merged:** 10/8/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `fix/canonical-ordering-code-points` --- ### 📝 Commits (2) - [`616609f`](https://github.com/morluto/rea/commit/616609fce6fbea0d531a36cb350ba85cc97b4933) fix(domain): order canonical paths by code point, not UTF-16 unit - [`9dd42ee`](https://github.com/morluto/rea/commit/9dd42ee63a2875f1e70862cc362572e4a569c97f) Merge remote-tracking branch 'origin/main' into review/1034-unicode-ordering ### 📊 Changes **2 files changed** (+57 additions, -5 deletions) <details> <summary>View changed files</summary> ➕ `src/domain/canonicalOrdering.test.ts` (+47 -0) 📝 `src/domain/canonicalOrdering.ts` (+10 -5) </details> ### 📄 Description ## Summary `compareCodePoints` documented a Unicode code-point comparison but used `<`/`>`, which compares UTF-16 code units. This delegates it to the existing `compareUnicodeCodePoints` so the two canonical comparators in the domain agree, and adds the missing regression coverage. ## Problem and expected behavior `src/domain/canonicalOrdering.ts` states it "Compares strings by Unicode code point (`<`/`>`)". For astral code points (above U+FFFF) the two orderings diverge, because the lead surrogate `0xD800-0xDBFF` is numerically below the BMP tail `U+E000-U+FFFF`: ```js import { compareCodePoints, uniqueSorted } from "./src/domain/canonicalOrdering.ts"; compareCodePoints("\uFFFD", "\u{1F600}"); // observed: 1 (\uFFFD sorts after the emoji) // expected: < 0 (U+FFFD = 65533 < U+1F600) uniqueSorted(["\u{1F600}", "\uFFFD"]); // observed: ["\u{1F600}", "\uFFFD"] // expected: ["\uFFFD", "\u{1F600}"] ``` `src/domain/unicodeCodePointOrder.ts` already implements the documented contract with `codePointAt`, so the domain was shipping two "canonical" comparators that disagreed on astral input. ## Change and scope - `compareCodePoints` now delegates to `compareUnicodeCodePoints`; the JSDoc records why code-point and code-unit ordering differ for astral input. - New `src/domain/canonicalOrdering.test.ts` covers astral versus BMP-tail ordering, equality, prefix ordering, and `uniqueSorted` deduplication. No test previously covered astral ordering for this comparator. - The change is confined to `src/domain/canonicalOrdering.ts`; no contract, schema, catalog, or generated artifact changes. Every call site uses only the sign of the result (`Array.prototype.sort` and two `< 0` checks), so the returned magnitude is not a relied-upon contract. The trigger requires sibling values where one begins with an astral code point and the other with a BMP code point in `U+E000-U+FFFF`, so no existing fixture changed. ## Verification - `npm run test:fast` — 2760 passed, 7 skipped (was 2754 passed before; +6 new). - `npm run check:fast` — typecheck and lint pass. - `oxfmt --check` on the two changed files passes; pre-commit ran oxfmt and oxlint on the staged files. I did not run the real-Hopper or real-provider lanes; this change is pure domain ordering with no provider behavior. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:08:02 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2598
No description provided.