diff --git a/src/ClaudeDo.Worker/External/ExternalMcpService.cs b/src/ClaudeDo.Worker/External/ExternalMcpService.cs index 4055ebf7..00637b00 100644 --- a/src/ClaudeDo.Worker/External/ExternalMcpService.cs +++ b/src/ClaudeDo.Worker/External/ExternalMcpService.cs @@ -329,7 +329,7 @@ public sealed class ExternalMcpService // plus the recurring "mcp"/"task(s)"/"cleanup" nouns called out in the task write-up). private static readonly HashSet TitleStopWords = new(StringComparer.Ordinal) { - "der", "die", "das", "und", "von", "auf", "mit", "fur", "ein", "eine", + "der", "die", "das", "und", "von", "auf", "mit", "fuer", "ein", "eine", "ist", "sind", "oder", "nicht", "mcp", "task", "tasks", "cleanup", }; diff --git a/tests/ClaudeDo.Worker.Tests/External/ExternalMcpServiceTests.cs b/tests/ClaudeDo.Worker.Tests/External/ExternalMcpServiceTests.cs index 0fdfad3b..08c8d6ca 100644 --- a/tests/ClaudeDo.Worker.Tests/External/ExternalMcpServiceTests.cs +++ b/tests/ClaudeDo.Worker.Tests/External/ExternalMcpServiceTests.cs @@ -1829,6 +1829,24 @@ public sealed class ExternalMcpServiceTests : IDisposable Assert.Empty(result.PossibleDuplicates); } + [Fact] + public async Task AddTask_TitlesSharingOnlyOneWordPlusTheGermanStopwordFuer_AreNotReportedAsDuplicates() + { + // Regression for the "fur" (never-transliterated) stopword typo: NormalizeTitleWords + // transliterates "für" -> "fuer" before the stopword check, so a stopword list containing + // "fur" can never filter it. Before the fix these two titles shared "report" and "fuer" + // (2 words, 50% of the shorter title) and cleared the duplicate threshold undeservedly; + // with "fuer" correctly filtered as filler only "report" remains shared (1 word). + var listId = await SeedListAsync(); + await SeedTaskAsync(listId, "Neuer Report für Bestand", TaskStatus.Idle); + var sut = NewService(); + + var result = await sut.AddTask( + listId, "Anderer Report für Kunden", cancellationToken: CancellationToken.None); + + Assert.Empty(result.PossibleDuplicates); + } + [Fact] public async Task AddTask_MoreThanThreeMatches_CapsPossibleDuplicatesAtThree() {