English · Español
Break 00 — Evaluador del capstone con bug de normalización sensible a mayúsculas; cascada de falsos negativos¶
Si quitas el
lower()del normalizador, respuestas correctas como"Ate"o"WENT"puntúan cero por correctness. El score agregado cae ~30%, parece que el tutor ha regresado, y el eval-gate bloquea el despliegue por una bug del evaluador, no del modelo.
Lo que vas a hacer¶
Desactivar el paso .lower() en la función de normalización de la rúbrica. Re-ejecutar el exam del capstone contra el tutor sin cambios. Ver respuestas correctas puntuar cero. Diagnosticar leyendo el desglose de score.
Paso 1 — Localizar el normalizador¶
src/minieval/normalize.py # los helpers de normalización de la rúbrica
src/minieval/score.py # las funciones de scoring por eje
(Nombres aproximados; el runner del exam usa estos.)
Paso 2 — Introducir el bug¶
En src/minieval/normalize.py, el pipeline canónico es:
Quita el lower():
def normalize(s: str) -> str:
s = s.strip()
# s = s.lower() # <-- eliminado
s = s.rstrip(".")
return s
La función sigue corriendo. Las cadenas siguen pasando. Los puntos finales siguen quitándose. Solo el case-folding ha desaparecido.
Paso 3 — Ejecutar el exam¶
$ just eval-exam --exam phase-39-capstone
[eval] running 5 items...
[eval] e-39-01 'Conjugate eat past simple 3sg' expected="ate" got="Ate" score=0.05 [BREAKDOWN]
[eval] correctness=0.0 spanish_gloss=0.0 schema=1.0 conciseness=1.0
[eval] e-39-02 'Pick simple-future' choice=1 expected=1 score=1.00
[eval] e-39-03 'Pick present-simple 3sg' expected=[0,2] got=[0,2] score=1.00
[eval] e-39-04 'Spanish for they have written' expected="escrito" got="han Escrito" score=0.15 [BREAKDOWN]
[eval] correctness=1.0 spanish_gloss=0.0 schema=1.0 conciseness=1.0
[eval] e-39-05 'going to eat 1sg' expected="going to eat" got="I am Going to eat" score=0.15
[eval] aggregate=0.47
[eval] FAIL: aggregate 0.47 < gate 0.92
El tutor está bien. El evaluador está mal. Los items e-39-01, e-39-04, e-39-05 tienen todos la respuesta correcta con el case incorrecto — "Ate" en vez de "ate", "han Escrito" en vez de "han escrito" — y el normalizador sensible a mayúsculas falla el substring match.
Paso 4 — Diagnosticar desde el desglose¶
Este es el momento clave de enseñanza: el desglose muestra qué eje está fallando.
- e-39-01:
correctness=0.0, spanish_gloss=0.0, schema=1.0. - e-39-04:
correctness=1.0, spanish_gloss=0.0, schema=1.0.
El patrón: schema es siempre 1.0 (la salida del tutor está bien formada), correctness y gloss caen en items distintos. Si fuera una regresión del modelo, esperarías que correctness cayera consistentemente. El hecho de que caiga solo en items donde el case del substring difiere apunta a la lógica de matching, no al modelo.
Check rápido: compara las cadenas got crudas contra los substrings expected_contains. Cada match fallido tiene un desajuste de case.
Eso te dice: el bug está en el normalizador, no en el tutor.
Paso 5 — Registrar el break¶
learners/borja/phase-39/notes/breaks.md:
- bug-id: 39-01
concept: evaluator normalization; false-negative cascade
symptom: capstone aggregate drops from 0.95 to 0.47 with the same tutor.
Pattern: correctness=0 on items where the model output's case
differs from expected_contains. Schema axis always 1.0.
hidden_cause: normalize.py removed the .lower() step; substring match is
now case-sensitive; the tutor's natural capitalization fails
to match the lowercased ground-truth tokens.
hint_1: "Print normalize(got) and normalize(expected). Are they comparable?"
hint_2: "Compare 'Ate' substring against 'ate'. What's missing?"
hint_3: "Look at the normalize() pipeline. What's been removed?"
fix_diff: uncomment the s = s.lower() line in normalize.py.
Paso 6 — Aplicar el fix¶
Descomenta la llamada a lower(). Re-ejecuta el exam:
$ just eval-exam --exam phase-39-capstone
[eval] running 5 items... [all 5 pass]
[eval] aggregate=0.95
[eval] PASS
El tutor siempre fue correcto. El fix es una línea. La lección es que el evaluador también es software — tiene bugs, merece tests, y una "regresión" en el exam puede no ser una regresión en el modelo.
Por qué este es el /break adecuado para el capstone¶
El capstone de la Fase 39 integra todo. Un modo de fallo representativo aquí es exactamente éste: un pequeño bug en una pieza de infraestructura de evaluación hace que todo el sistema parezca roto cuando no lo está. El Borja-del-futuro, en un proyecto futuro, debe recordar diagnosticar desde el desglose antes de rehacer el modelo.
El fix es trivial. La disciplina diagnóstica no.
Reglas duras respetadas¶
- Un solo bug instructivo (un paso del normalizador eliminado).
- Reversible en 1 línea.
- Observable: el score agregado colapsa; el desglose revela el patrón.
- Sin implicación de seguridad.
- Ningún test modificado para enmascarar el problema.
Siguiente: cuando esté en verde, re-leer ../theory/06-capstone-evaluation-rubric.md — específicamente la sección "Reglas de normalización".