From 4bb86fa01482d15c1cc9645636500a74d8111b74 Mon Sep 17 00:00:00 2001 From: Eli Mallon Date: Thu, 30 Apr 2026 12:32:11 -0700 Subject: [PATCH] Pet-type pick: require whole-message match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a footgun spotted on stream: felinus typed "did you turn me into a duck" and the pet-type picker happily turned them into a duck because the regex matched the bare word "duck" anywhere in the message. Goose.art flagged it ("i thought it was hardcoded only for people with goose in their handle, so i'm a bit confused") — explanation is the casual- mention rule. Now the message must be just `cat`, `!cat`, `dog`, `!dog` etc. (with optional surrounding whitespace) to swap pet type. `random` follows the same whole-message rule for clearing the override. Casual sentences containing animal words no longer rewrite the chatter's avatar — closer to what goose.art's mental model already assumed. Co-Authored-By: Claude Opus 4.7 (1M context) --- pets.html | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pets.html b/pets.html index c2b1e23..8bf5a18 100644 --- a/pets.html +++ b/pets.html @@ -1784,9 +1784,10 @@ async function handleChatMessage(authorDid, record) { // Temporarily replace the handle pill with the redacted chat message pet.showMessage(record.text || ''); - // Pet-type pick: 'cat', 'dog', 'bunny', etc. swap the chatter's pet in place. - // 'random' clears the override and falls back to the hash-derived default. - // Use word boundaries so casual mentions (`my cat`, `dancing dog`) still match. + // Pet-type pick: must be the *whole* message (optionally with a leading !). + // Casual mentions ("did you turn me into a duck") used to trigger this and + // accidentally morph the speaker — that was a footgun, hence the strict match. + // 'random' (also whole-message-only) clears the override. const TYPE_WORDS = { cat: 'cat', kitty: 'cat', kitten: 'cat', katze: 'cat', kat: 'cat', dog: 'dog', doggo: 'dog', puppy: 'dog', hund: 'dog', hond: 'dog', @@ -1795,13 +1796,15 @@ async function handleChatMessage(authorDid, record) { hamster: 'hamster', goose: 'goose', gans: 'goose', }; + const typeMatch = text.match(/^\s*!?([a-zäöü]+)\s*$/i); let chosenType = null; - for (const [word, type] of Object.entries(TYPE_WORDS)) { - if (new RegExp(`\\b${word}\\b`, 'i').test(text)) { chosenType = type; break; } - } - if (/\brandom\b/i.test(text) && !chosenType) { - petTypeOverrides.delete(authorDid); - chosenType = '__rebuild__'; + if (typeMatch) { + const w = typeMatch[1].toLowerCase(); + if (TYPE_WORDS[w]) chosenType = TYPE_WORDS[w]; + else if (w === 'random') { + petTypeOverrides.delete(authorDid); + chosenType = '__rebuild__'; + } } if (chosenType) { if (chosenType !== '__rebuild__') petTypeOverrides.set(authorDid, chosenType); -- 2.51.2