fix(wizard): no silenciar preguntas con qué o por qué - #274
Conversation
JS word boundaries are ASCII-only, so accented qué/por qué never matched the informational-turn allowlist and the Wizard replaced the model answer with a false empty-turn receipt. Fold diacritics before the classifier. Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
PR Review — Loreframe StudioRisk: low Automated review from Findings
Changed files
CONTRIBUTING checklist
Posted by the repo PR review workflow. Re-runs on each push to the PR. |
Code healthQuality score: 56.4/100Higher is better. The score is a trend dashboard; the independent ratchet below remains the CI gate.
Change vs PR base: +0.0 points.
Markdown, JSON catalogs and tests are out of this table. Only Most complex functions
Trend vs baseline
Warnings
Ratchet passed. |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_a84b4643-9df9-48dc-a19c-9710891c1864) |
|
Superseded by #279, which applies this fix together with the other Cursor Wizard/Studio corrections on |
Resumen ejecutivo
Qué cambia
El Wizard vuelve a mostrar la respuesta del modelo cuando alguien pregunta «¿Qué son las colecciones?» o «¿Por qué falló?». Antes sustituía esa respuesta por «No se ha ejecutado ninguna acción».
Para qué sirve
Tras el PR #270, las preguntas informativas en español con qué / por qué (las más habituales) no se reconocían. El chat mentía al usuario y ocultaba la explicación.
Impacto para el usuario
Las preguntas con qué y por qué conservan la respuesta. Un turno mixto («¿Qué son…? Crea …») sigue fallando cerrado si no hubo acción real.
Riesgo
Estado
Summary
allowsExplanation()inwizardTurnReport.tsused JS\\bafterqu[eé]. In JavaScript,\\bis ASCII-only, soéis not a word character and«Qué son…?»/«Por qué…?»never matched.formatWizardTurnReplythen treated a valid informational turn as empty and replaced the model reply withnoActionReceipt.AgentAssistantPanelpasses the userquestionintoformatWizardTurnReply, so this is the live Wizard path. EnglishWhatand SpanishCómo/Dónde/Cuálstill worked (they end on ASCII letters). UnaccentedQue/Por quealso worked, which hid the bug from the existing tests.Trigger: user asks
¿Qué son las colecciones?or¿Por qué falló la generación?with no actions. Model returns an explanation. UI shows «No se ha ejecutado ninguna acción en este turno».Fix: fold diacritics with the same NFD +
\\u0300-\\u036fstrip already used inagentActions/ story helpers, then apply the existing regexes.Mixed turns with a delimiter (
Qué son las colecciones? Crea una llamada Nightwatch.) still fail closed.Overview
PR #270 added a conservative presentation policy so model prose cannot certify action-bearing turns. The allowlist for informational questions missed accented
québecause of ASCII\\b. This change only fixes that classifier input; it does not widen the mixed-turn guard or change execution.Detailed changes
Backend
No backend changes.
UI and Wizard
ui/src/features/agent/wizardTurnReport.ts: normalize accents beforeallowsExplanation.ui/tests/wizardTurnReport.test.ts: lockQué/Por quéinformational replies and a mixedQué …? Crea …fail-closed case.Data, provenance and compatibility
No persistence, workspace, or schema changes.
Files and ownership
wizardTurnReport.ts— presentation classifier only.wizardTurnReport.test.ts— regression coverage.agentActions.tshow-to / cancel classifiers (already tracked in fix(wizard): no encolar generación ante preguntas how-to #272 and fix(wizard): no cancelar ni generar ante frases educativas con para #273).Validation
cd ui && npx tsx --tsconfig tsconfig.app.json --import ./tests/setupI18n.ts --test tests/wizardTurnReport.test.ts— 16/16 passformatWizardTurnReplycases:Qué/¿Qué/Por quékeep the model reply; mixedCreastill emitsnoActionReceiptgit diff --checkpython scripts/verify_clean_repo.py— N/A (UI-only)python -m compileall— N/Acd ui && npm run i18n:check— N/A (no catalog changes)cd ui && npm run lint -- --max-warnings=0— not rerun in this passcd ui && npm run build— not rerun in this passCode quality
main: pending CICI and review
Coste de la tarea
Notes and limitations
Does not change how-to / resume / cancel classifiers (open PRs #272, #273). Does not treat undelimited mixed English (
What are collections create Nightwatch) as action-bearing; that remains the existing delimiter policy.Follow-up work
None required for this classifier. Existing open fixes: #263 (CAS sibling drop), #269 (DramaBox duration 0→1s), #272 (how-to vs resume), #273 (
paravs parar).Checklist
Note
Low Risk
UI-only presentation classifier change with regression tests; no auth, execution, or persistence impact.
Overview
Fixes a Wizard presentation bug where accented Spanish questions (
Qué,por qué) were misclassified as non-informational turns, soformatWizardTurnReplyreplaced the model’s explanation with the “no action executed” receipt.allowsExplanationnow folds diacritics (NFD + strip combining marks) before the existing regexes, because JavaScript\bis ASCII-only and broke word boundaries afteré. Mixed turns (e.g.Qué son…? Crea…) still fail closed via the unchanged imperative guard.Tests lock informational
Qué/¿Qué/Por quéreplies and one mixed Spanish qué + crea case.Reviewed by Cursor Bugbot for commit 2813671. Configure here.