From 3c99485f3c838b5de0a97c9919fc7b7ff24b366c Mon Sep 17 00:00:00 2001 From: Libby Date: Wed, 11 Nov 2026 13:45:12 +0000 Subject: [PATCH 1/2] cultcache-ts: tests pin the single-put judge's alias and key-pair order (kills the code-point and NFD mutants) Co-Authored-By: Claude Sonnet 5.5 --- .../cultcache-ts/test/unique-index.test.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/cultcache-ts/test/unique-index.test.ts b/packages/cultcache-ts/test/unique-index.test.ts index 955c439a..252f4f45 100644 --- a/packages/cultcache-ts/test/unique-index.test.ts +++ b/packages/cultcache-ts/test/unique-index.test.ts @@ -550,3 +550,25 @@ test("registerIndex of a second unique alias judges it, naming the two smallest assert.equal(cache.getKeyByIndex(document, "a", "1"), "z", "the alias already installed is intact"); assert.equal(cache.getKeyByIndex(document, "b", "s"), undefined); }); + +// ---- the single-put judge's two orders, which no pair-order vector row reaches from TS (a vector row's second record +// arrives in a batch that TS cannot perform): aliases by UTF-16 code unit, then the key pair by UTF-16 code unit ---- + +test("a put colliding on two aliases names the one least by UTF-16 code unit, not by code point", async () => { + // U+10400 is the surrogate pair D801 DC00, so it sorts before U+FF21 by code unit and after it by code point. + const document = pair({ indexes: { "A": "a", "\u{10400}": "b" } }); + const cache = memory(document); + await cache.put(document, "h1", { a: "s1", b: "t1" }); + await cache.put(document, "h2", { a: "s2", b: "t2" }); + await assert.rejects(cache.put(document, "p", { a: "s1", b: "t2" }), { message: refusal("h2", "p", "tests.pair", "\u{10400}") }); + assert.equal(cache.get(document, "p"), undefined); +}); + +test("a put names its key pair by UTF-16 code unit, not by normalised form", async () => { + // "e" U+0302 is the NFD form of U+00EA: equal when normalised, and less by code unit. + const document = item("item"); + const cache = memory(document); + await cache.put(document, "ê", { sku: "v" }); + await assert.rejects(cache.put(document, "ê", { sku: "v" }), { message: refusal("ê", "ê", "tests.item", "sku") }); + assert.equal(cache.get(document, "ê"), undefined); +}); -- 2.47.3 From 5e7cb663dad451f7dcc7fddd627420088f499a11 Mon Sep 17 00:00:00 2001 From: Libby Date: Wed, 11 Nov 2026 13:56:31 +0000 Subject: [PATCH 2/2] cultcache-ts: a put's alias order is pinned against normalised sorts too Co-Authored-By: Claude Sonnet 5.5 --- packages/cultcache-ts/test/unique-index.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/cultcache-ts/test/unique-index.test.ts b/packages/cultcache-ts/test/unique-index.test.ts index 252f4f45..d36c2cf2 100644 --- a/packages/cultcache-ts/test/unique-index.test.ts +++ b/packages/cultcache-ts/test/unique-index.test.ts @@ -572,3 +572,12 @@ test("a put names its key pair by UTF-16 code unit, not by normalised form", asy await assert.rejects(cache.put(document, "ê", { sku: "v" }), { message: refusal("ê", "ê", "tests.item", "sku") }); assert.equal(cache.get(document, "ê"), undefined); }); + +test("a put colliding on two aliases orders them by UTF-16 code unit, not by normalised form", async () => { + // U+00EA normalises to e U+0302, which is less than e U+0303 when normalised and greater by code unit. + const document = pair({ indexes: { "ê": "a", "ẽ": "b" } }); + const cache = memory(document); + await cache.put(document, "h1", { a: "s1", b: "t1" }); + await cache.put(document, "h2", { a: "s2", b: "t2" }); + await assert.rejects(cache.put(document, "p", { a: "s1", b: "t2" }), { message: refusal("h2", "p", "tests.pair", "ẽ") }); +}); -- 2.47.3