diff --git a/src/lib/analytics/sleep-night.ts b/src/lib/analytics/sleep-night.ts index d5b530aea..d3a2d58ea 100644 --- a/src/lib/analytics/sleep-night.ts +++ b/src/lib/analytics/sleep-night.ts @@ -309,10 +309,11 @@ const RECONSTRUCTED_TIMELINE_SOURCES: ReadonlySet = new Set([ /** * Separator between the source and device-type parts of a writer key. - * `` cannot appear in a `MeasurementSource` enum literal or a - * device-type tag, so the split-back is unambiguous. + * The unit-separator character (U+241F) cannot appear in a + * `MeasurementSource` enum literal or a device-type tag, so the + * split-back is unambiguous. */ -const WRITER_KEY_SEP = ""; +const WRITER_KEY_SEP = "\u241F"; /** * Writer-bucket key of a stage row: the source, refined by the device-type diff --git a/src/lib/insights/correlation-discovery.ts b/src/lib/insights/correlation-discovery.ts index 279944fd7..b7bd338b4 100644 --- a/src/lib/insights/correlation-discovery.ts +++ b/src/lib/insights/correlation-discovery.ts @@ -596,9 +596,17 @@ export function filterSeriesToWindow( })); } +/** + * Separator joining the two channel names into a stable pair key. The + * unit-separator character (U+241F) cannot appear in a correlation-channel + * name, so two distinct pairs never collide. The key is used only for Set + * membership (never split back), and lives for one discovery pass. + */ +const PAIR_KEY_SEP = "\u241F"; + /** Stable pair identity for double-count exclusion. */ function pairKey(behaviour: string, outcome: string): string { - return `${behaviour}${outcome}`; + return `${behaviour}${PAIR_KEY_SEP}${outcome}`; } export interface EmergingCorrelationResult {