← Índice
Secciones (7) ▾

Laboratorio I+D+I — Vocabulario del catálogo: redundancia y telemetría M2M

Independiente de notebook-infraestructura-transporte.md (esa pregunta es cómo viaja el mensaje; esta es qué contenido tiene sentido que exista en el catálogo humano de códigos, antes incluso de elegir transporte). Notebook vivo, igual que los otros: se amplía con fecha según avancen los experimentos.


La pregunta que dispara este notebook (2026-09-11)

Surgió al hablar de una posible V2 con "nueva filosofía de chat": si dentro de las 10.000 frases posibles del cartucho actual (código 4D: Categoría-Subcategoría-Acción-Matiz) hay muchas que con códigos distintos producen la misma frase, no tiene sentido mantener un catálogo de 10.000 — mejor reducir el vocabulario que ve el humano y usar la capacidad sobrante para que el propio dispositivo rellene automáticamente ("telemetría M2M") los matices que hoy elige la persona a mano.

Dos preguntas concretas a resolver antes de decidir nada:

  1. ¿Cuánta redundancia real hay hoy en el catálogo?
  2. De los matices que hoy elige el humano, ¿cuáles podría rellenar el propio dispositivo sin preguntarle, y cuáles no deberían automatizarse nunca?

Medición 1: cuánta redundancia real hay hoy (2026-09-11)

Método: se replicó la lógica real de composeSmartSentence (src/services/translator.ts:905), alimentada con los datos reales de src/config/schemas.ts y src/config/cartridgeContent.ts, para generar las 10.000 frases posibles del código 4D completo (10 categorías × 10 subcategorías × 10 acciones × 10 matices) y comparar los textos resultantes letra por letra. Script de un solo uso, no forma parte del código de producción.

Resultado global:

Métrica Valor
Códigos 4D posibles 10.000
Frases finales realmente distintas 3.700 (37%)
Códigos que repiten el texto exacto de otro código 6.300 (63%)
Media de frases distintas por tema (Categoría+Subcategoría), de 100 combinaciones Acción×Matiz posibles 37

No hay colisiones entre temas distintos (100 temas × 37 = 3.700 exacto) — toda la redundancia está dentro de la combinación Acción×Matiz de un mismo tema, no entre temas.

Desglose por acción (tema de referencia: Categoría "Evacuación/Incendio" → Subcategoría "Incendio/Evacuación General"; el patrón se repite igual en los 100 temas):

Acción Distintas / 10 matices Agrupación de matices que dan el mismo texto
Solicitar Informe 1 {0,1,2,3,4,5,6,7,8,9} — el matiz no cambia nada nunca
Estado Despejado / OK 3 {0,2,4,6,7,8,9} · {1,3} · {5}
Retener / Esperar 4 {0,2,6,7,8,9} · {1,3} · {4} · {5}
Cancelar Alerta 4 {0,2,4,6,7,8} · {1,3} · {5} · {9}
Trasladar / Reubicar 4 {0,2,6,7,8,9} · {1,3} · {4} · {5}
Confirmar Recibido 4 {0,2,4,6,7,8,9} · {1} · {3} · {5}
Denegar / Sin Recursos 4 {0,2,6,7,8,9} · {1,3} · {4} · {5}
Avisar Incidencia 4 {0,2,4,6,8,9} · {1,3} · {5} · {7}
Pedir Auxilio / SOS 4 {0,2,4,6,7,8,9} · {1} · {3} · {5}
Activar Protocolo 5 {0,2,6,7,8,9} · {1} · {3} · {4} · {5}

Causa raíz: cartridgeContent.ts solo define 1-2 variantes de texto con matiz propio por acción (el resto de matices cae en una plantilla "catch-all" genérica) — está marcado explícitamente en el código como "contenido beta para la demo de inversores", no como límite estructural. Parte de la "distinción" que sí existe es solo puntuación (¡...! para matices 1/3, ¿...? para el 5), no contenido realmente distinto.

Implicación para el tamaño del catálogo: el contenido que ya existe hoy diferencia 3.700 mensajes, no 1.000. Recortar a un número redondo como 1.000 no sería solo "quitar el desperdicio" — también fusionaría o perdería variedad que ya funciona. Si el objetivo es eliminar solo la redundancia, el número que refleja lo que hay hoy ronda 3.700-4.000, no 1.000. Si 1.000 es una meta deliberada de simplicidad (aceptando perder variedad), decidir a mano qué mensajes sobreviven en vez de dejar que un recorte numérico lo decida.


Medición 2: qué matices podría rellenar la máquina sola (2026-09-11)

De los 10 matices del cartucho actual (schemas.tsnuances), se dividen en dos grupos según si reflejan un hecho que el propio dispositivo ya puede conocer, o un juicio que debe seguir siendo decisión humana:

Grupo A — el dispositivo ya tiene el dato, candidato a auto-rellenar:

Grupo B — juicio humano, no debe automatizarse:

Conclusión de esta pasada: la idea de "telemetría interna entre dispositivos rellena matices" es acertada solo para el Grupo A. Ahí, además, resuelve dos problemas a la vez: quita fricción al humano (no tiene que acordarse de marcarlo) y reduce exactamente la parte del catálogo que hoy es más redundante. El Grupo B debe seguir siendo elección explícita del humano aunque eso conserve algo de la redundancia actual — ahí la redundancia es el precio de dejar la decisión donde debe estar.


Medición 3: UX — ¿el operario tiene que ver o memorizar el código? (2026-09-11)

La pregunta: ningún operario va a aprenderse un código de 4 dígitos con su significado, por guiado que esté el proceso. ¿Cómo evitarlo?

Lo que ya existe hoy y va en la buena dirección: el flujo real de entrada (no la demo de inversores) ya es por reconocimiento, no por recuerdo — el operario escribe o dicta en lenguaje natural (src/components/Chat/ChatInput.tsx) y translator.encodeNaturalText() traduce a código por detrás. Comprobado además que esa traducción ya es determinista: mismo texto → siempre el mismo código (empates resueltos siempre a favor del primer candidato por orden fijo, matiz por defecto siempre "Estándar" cuando el texto no da señal — translator.ts:623-660). No hace falta arreglar nada ahí.

Lo que sí contradice el objetivo: hoy el código SÍ se enseña siempre, de forma prominente, en cada burbuja de mensaje (badge #{rawCode} en MessageBubble.tsx:58-63), y también aparece en el propio cuadro de texto tras traducir (el código sustituye la frase escrita). Es decir: aunque la entrada ya es "por reconocimiento", la confirmación visual actual sigue enseñando el número.

Propuesta de diseño (solo para una V2, ver más abajo por qué no para V1 tal cual):

Por qué esto NO debería aplicarse a la V1 (demo de inversores) solo para tapar el problema de duplicados: ocultar el código no arregla el fallo de la Medición 1 (63% de códigos duplicados por contenido sin escribir) — solo lo hace menos visible. Si alguien lo descubre después de todos modos (probando el teclado numérico, o en una auditoría técnica), parece que se ocultó a propósito en vez de solucionarse, lo cual es peor para la confianza que dejarlo visible con el hueco de contenido aún sin cerrar. Además, para V1 mostrar el código puede ser una decisión de producto válida por sí misma (parte del argumento de venta: "esto es un protocolo real de 4 dígitos, no magia").

Si de verdad preocupa que el fallo de duplicados se note en una demo con inversores, el arreglo correcto es cerrar el contenido que falta (Medición 1) — probablemente solo para el puñado de códigos que aparecen en el guion real de la demo (quickChips de mockData.ts + timeline de SurgicalDemo.tsx), no las 10.000 combinaciones. Eso sí arregla el fallo de verdad, y sirve para V1 y V2 a la vez — ocultar la interfaz solo serviría para V2, y ahí el problema de fondo (Medición 1) seguiría sin resolverse igualmente y habría que abordarlo aparte.


Medición 4: respuestas sugeridas al hilo del mensaje recibido (2026-09-11)

La pregunta: ¿podría el sistema recomendar opciones de respuesta a partir del mensaje que se acaba de recibir?

Decisión de diseño clave: tabla de reglas estática y determinista (CRITICAL_REPLY_SUGGESTIONS en cartridgeContent.ts), no un modelo estadístico/entrenado tipo Smart Reply de Gmail — mantiene la sugerencia auditable línea por línea y no rompe la premisa de NumChat de funcionar sin red ni servidor. La respuesta sugerida siempre conserva el mismo tema (Categoría/Subcategoría) que el mensaje recibido, solo cambia la Acción, y el Matiz siempre se deja en "Estándar" — el sistema no adivina la urgencia por el operario.

Tabla de primera versión (a revisar con feedback real de un vertical de emergencias, ver notebook-mvp-validacion-institucional.md):

Acción recibida Respuestas sugeridas
Estado Despejado/OK Confirmar Recibido, Solicitar Informe
Activar Protocolo Confirmar Recibido, Retener/Esperar, Avisar Incidencia
Retener/Esperar Confirmar Recibido, Solicitar Informe
Cancelar Alerta Confirmar Recibido
Trasladar/Reubicar Confirmar Recibido, Solicitar Informe
Confirmar Recibido Estado Despejado/OK, Solicitar Informe
Denegar/Sin Recursos Solicitar Informe, Pedir Auxilio/SOS
Solicitar Informe Estado Despejado/OK, Avisar Incidencia, Pedir Auxilio/SOS
Avisar Incidencia Confirmar Recibido, Activar Protocolo, Pedir Auxilio/SOS
Pedir Auxilio/SOS Confirmar Recibido, Activar Protocolo, Denegar/Sin Recursos

El problema de UX que casi se cuela: el plan inicial era una fila nueva "💬 Responder:" además de "⭐ Favoritos" y "🔥 Frecuentes" — es decir, tres filas de chips apiladas. Se corrigió a tiempo: eso contradice directamente la Medición 3 (menos carga cognitiva, no más). Solución adoptada: una sola fila fusionada, con un icono por chip que indica el origen (💬 respuesta contextual, ⭐ favorito, 🔥 frecuente), en orden de prioridad fijo y sin duplicar un código que encaje en más de una categoría. La fila ya tenía scroll horizontal de fábrica, así que no hizo falta limitar el total por espacio — solo se mantiene un tope en Frecuentes (ahora 10, antes 6) para que "frecuente" siga significando algo, no por sitio en pantalla.

Implementado (2026-09-11):

Verificado: npm test sigue en 42/42 + 8/8. Script de prueba directo sobre translator.getReplySuggestions() confirma que, por ejemplo, recibir #9111 (Activar Protocolo, Simulacro) sugiere #9150 (Confirmar Recibido), #9120 (Retener/Esperar) y #9180 (Avisar Incidencia) — mismo tema, Matiz 0, tal como se diseñó. Comprobado también en el navegador que la fila fusionada de Favoritos+Frecuentes ya renderiza correctamente con un icono por chip (la parte 💬 contextual usa el mismo mecanismo, verificado a nivel de lógica; no se forzó una recepción real de dos dispositivos en esta sesión de pruebas).


Próximos pasos / preguntas abiertas

Cómo se generó este análisis

Script de un solo uso (Node + tsx) que importa directamente schemas.ts y cartridgeContent.ts del código real de la app y reproduce la lógica de composeSmartSentence para generar y comparar las 10.000 frases posibles. No se guardó como parte del repositorio — si se quiere repetir la medición, reconstruir el script es trivial a partir de los dos ficheros de datos citados arriba.