fix(merge): fuse near matches only across sources

Near matching exists to reconcile two sources describing one event under
different titles. Within one source it has no such job: the page has already
told us these are two rows, the parser has already dropped repeats of the same
id, and fusing them overrules a distinction the publisher made on purpose.

The loose 0.80 threshold that makes the rule useful across sources makes it
actively wrong within one. Umamusume's banner list runs "3 Star Guaranteed 1.5
Anniversary Scout (Character)" and "(Support)" concurrently — titles differing
by a single parenthetical, starting the same day — and fusing them dropped a
live banner off the calendar with nothing anywhere reporting it. A silent drop
is the failure this codebase ranks as the dangerous one.

Same-id fusion is untouched, so nothing duplicates.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Lucas Winther
2026-08-19 03:52:57 +02:00
co-authored by Claude Opus 5
parent 04c69fd3df
commit 6b00d9a9c0
4 changed files with 81 additions and 4 deletions
+12
View File
@@ -124,6 +124,18 @@ function isSameEvent(
): boolean {
if (a.id === b.id) return true;
// Near-match fusion reconciles two *sources* describing one event under
// different titles. Within one source it has no such job to do: the page has
// already told us these are two rows, the parser has already dropped repeats
// of the same id, and fusing them here overrules a distinction the publisher
// made on purpose. Game8's Umamusume page is the case that surfaced it — its
// `3 Star Guaranteed 1.5 Anniversary Scout (Character)` and `(Support)` are
// two concurrent banners whose titles differ by one parenthetical, which
// scores far above any workable threshold and starts on the same day. Fusing
// them dropped a real banner off the calendar with nothing reporting it,
// which is the silent drop this codebase treats as the dangerous failure.
if (a.sourceId === b.sourceId) return false;
// Overlap alone misses a source that appends a qualifier: "Bedazzling
// Dawnstar" vs "Bedazzling Dawnstar Sign-In" scores 0.67, well under any
// safe threshold, yet is plainly one event.