Skip to content

Commit eb537ec

Browse files
committed
fix(storage): align remaining canonicalizers on code-unit key order
Review follow-up: the process-ownership stateJson envelope was canonicalized by three parties, and only one had moved to code-unit ordering, so the writer (processOwnershipStateCodec) and the worker-protocol validator could disagree with the storage validator once any key pair collates differently. Convert both remaining byte-form canonicalizers, plus the member-work-sync migration stringifier, so every canonical byte producer and validator sorts identically on any locale.
1 parent 0038913 commit eb537ec

3 files changed

Lines changed: 7 additions & 3 deletions

File tree

src/features/internal-storage/main/infrastructure/worker/internalStorageWorkerProtocol.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,8 +753,10 @@ function canonicalWorkerJson(value: unknown): string {
753753
}
754754
if (Array.isArray(value)) return `[${value.map(canonicalWorkerJson).join(',')}]`;
755755
const record = exactWorkerRecord(value, 'canonical-value');
756+
// Code-unit ordering: validates the same persisted stateJson bytes as the
757+
// process-ownership codec, so both must sort keys identically on any locale.
756758
return `{${Object.keys(record)
757-
.sort((left, right) => left.localeCompare(right))
759+
.sort((left, right) => (left < right ? -1 : left > right ? 1 : 0))
758760
.map((key) => `${JSON.stringify(key)}:${canonicalWorkerJson(record[key])}`)
759761
.join(',')}}`;
760762
}

src/features/member-work-sync/main/infrastructure/memberWorkSyncSqliteMappers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ function stableStringify(value: unknown): string {
239239
}
240240
const record = value as Record<string, unknown>;
241241
return `{${Object.keys(record)
242-
.sort((a, b) => a.localeCompare(b))
242+
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))
243243
.map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`)
244244
.join(',')}}`;
245245
}

src/features/team-runtime-control/main/adapters/output/process-supervision/processOwnershipStateCodec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,10 @@ function canonicalJson(value: unknown): string {
363363
}
364364
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;
365365
const record = plainRecord(value, 'canonical-value');
366+
// Code-unit ordering: these canonical bytes are persisted as stateJson and
367+
// byte-validated on read, so key order must not depend on locale/ICU.
366368
return `{${Object.keys(record)
367-
.sort((left, right) => left.localeCompare(right))
369+
.sort((left, right) => (left < right ? -1 : left > right ? 1 : 0))
368370
.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)
369371
.join(',')}}`;
370372
}

0 commit comments

Comments
 (0)