From 302bcef22571dbb5f4eb784a3180d2b68bae3178 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Thu, 23 Apr 2026 12:20:43 +0700 Subject: [PATCH] fix(doantu): reset round when target fell out of phow2sim vocab Pre-phow2sim games (Workers AI era) left targets in KV that phow2sim doesn't know. The API returned in_vocab_a:false, similarity:null, which our handler misread as a guess-OOV and blamed the player's word. Now we detect target-OOV explicitly, wipe the stale round, and prompt the user to start fresh. --- src/modules/doantu/handlers.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/modules/doantu/handlers.js b/src/modules/doantu/handlers.js index 21233a2..92bac6a 100644 --- a/src/modules/doantu/handlers.js +++ b/src/modules/doantu/handlers.js @@ -94,7 +94,19 @@ async function submitGuess(ctx, { db, client }, subject, game, arg) { logFail("similarity", err); return ctx.reply(UPSTREAM_FAIL); } - if (!res?.in_vocab_b || res.similarity == null) { + // Target OOV means the round was seeded before phow2sim owned the vocab + // (pre-refactor Worker, or an old rank-40k+ pick). Reset the round instead + // of letting the player type forever against a ghost target. + if (!res?.in_vocab_a) { + logFail("target_oov", new UpstreamError(`target ${game.target} not in phow2sim vocab`)); + await clearGame(db, subject); + return ctx.reply( + "⚠️ This round's target is no longer valid (upstream vocabulary changed). " + + "Send /doantu again to start a fresh round.", + { parse_mode: "HTML" }, + ); + } + if (!res.in_vocab_b || res.similarity == null) { return ctx.reply(`🤔 ${escapeHtml(guess)} isn't in the vocabulary.`, { parse_mode: "HTML", });