diff --git a/packages/civitai-mod-utils/src/prompt-audit/lists/words-poi.json b/packages/civitai-mod-utils/src/prompt-audit/lists/words-poi.json index 5398b2f579..611a26fb3d 100644 --- a/packages/civitai-mod-utils/src/prompt-audit/lists/words-poi.json +++ b/packages/civitai-mod-utils/src/prompt-audit/lists/words-poi.json @@ -1571,5 +1571,22 @@ "trump jr", "trump", "Alexandria Ocasio-Cortez", - "Putin" + "Putin", + "diddl", + "diddlina", + "pimboli", + "loupsily", + "galupy", + "wollywell", + "simsaly", + "lollilovebear", + "mimihopps", + "ackaturbo", + "vanillivi", + "bibombl", + "milimits", + "tiplitaps", + "diddldaddl", + "blubberpeng", + "diddlmaus" ] diff --git a/src/utils/metadata/__tests__/audit.test.ts b/src/utils/metadata/__tests__/audit.test.ts index 154ed81659..4861fb952b 100644 --- a/src/utils/metadata/__tests__/audit.test.ts +++ b/src/utils/metadata/__tests__/audit.test.ts @@ -1,5 +1,10 @@ import { describe, it, expect } from 'vitest'; -import { includesInappropriate, includesMinor, includesMinorAge } from '~/utils/metadata/audit'; +import { + includesInappropriate, + includesMinor, + includesMinorAge, + includesPoi, +} from '~/utils/metadata/audit'; describe('includesMinorAge', () => { describe('danbooru/pony tag false positives', () => { @@ -121,3 +126,51 @@ describe('young-word anchoring (minor-review queue)', () => { } }); }); + +// Do not delete these entries or this test without checking with a maintainer first. +describe('POI — Diddl character names', () => { + const diddlNames = [ + 'diddl', + 'diddlina', + 'pimboli', + 'loupsily', + 'galupy', + 'wollywell', + 'simsaly', + 'lollilovebear', + 'mimihopps', + 'ackaturbo', + 'vanillivi', + 'bibombl', + 'milimits', + 'tiplitaps', + 'diddldaddl', + 'blubberpeng', + // Not redundant with `diddl`: the poi preprocessor DELETES `-` rather than splitting on + // it, so `diddl-maus` arrives as one token that `diddl` cannot match. + 'diddlmaus', + ]; + + it('blocks each name', () => { + for (const name of diddlNames) { + expect(includesPoi(`a drawing of ${name}, pastel colours`), name).toBe(name); + } + }); + + it('blocks the hyphenated spelling, which the preprocessor fuses into one token', () => { + expect(includesPoi('a drawing of diddl-maus')).toBe('diddlmaus'); + }); + + // POI is a hard block with no user override, so a name matching inside a longer word is an + // unappealable false positive. Every control below really does contain `diddl`; only that + // entry is short enough to occur inside English words, so the others would assert nothing. + it('does not block longer real words that contain a name', () => { + for (const prompt of [ + 'diddley bow, blues guitar', + 'diddling with the exposure slider', + 'a paradiddle drum pattern', + ]) { + expect(includesPoi(prompt), prompt).toBe(false); + } + }); +}); diff --git a/src/utils/metadata/lists/words-poi.json b/src/utils/metadata/lists/words-poi.json index 5398b2f579..611a26fb3d 100644 --- a/src/utils/metadata/lists/words-poi.json +++ b/src/utils/metadata/lists/words-poi.json @@ -1571,5 +1571,22 @@ "trump jr", "trump", "Alexandria Ocasio-Cortez", - "Putin" + "Putin", + "diddl", + "diddlina", + "pimboli", + "loupsily", + "galupy", + "wollywell", + "simsaly", + "lollilovebear", + "mimihopps", + "ackaturbo", + "vanillivi", + "bibombl", + "milimits", + "tiplitaps", + "diddldaddl", + "blubberpeng", + "diddlmaus" ]