Skip to content

English · Español

Teoría 00 — Por qué un portal

🇪🇸 El currículo pre-escrito (A12) es un libro de texto: completo, ordenado, navegable. Pero un libro no aprende contigo. El portal cierra ese hueco: identifica al estudiante, registra qué leyó y qué falló, y le devuelve sus fallos en el momento espaciado correcto. Es la pieza que convierte el currículo en tutoría.

La pregunta que este archivo responde

Si LYNX_CORTEX_ADDENDUM.md §A12 ya pre-escribe 40 fases de teoría + enunciados de lab + planes, ¿qué añade un portal web que no añada un directorio de Markdown?

La respuesta honesta es: nada, para el primer learner. Borja puede estudiar el repo con mkdocs serve y un editor de texto. El portal se gana su existencia solo cuando (a) más de una persona estudia el currículo, (b) la misma persona estudia a lo largo de muchas sesiones y necesita que el sistema recuerde su estado, y © el fallo es una señal sobre la que queremos actuar automáticamente — re-presentar respuestas erróneas en el momento correcto, no solo registrarlas.

Este archivo establece esas tres afirmaciones como la única justificación de la existencia del portal, y deja que toda decisión de diseño aguas abajo fluya desde ellas. Si una característica no sirve a (a), (b) o ©, está fuera de alcance.

El contrato entre el currículo y el learner

El currículo pre-escrito ofrece un contrato:

"En cualquier fase NN, la teoría que necesitas para entender el lab está commiteada; el lab plantea el problema con precisión; la solución se retiene hasta que hayas commiteado un intento."

El contrato no tiene estado respecto al learner. El repo no sabe quién lo está leyendo. No sabe qué lab ha intentado. No sabe qué preguntas de examen falló hace tres semanas.

Para un único learner trabajando en una sola sesión larga, esto está bien — el learner es el estado. Para:

  • Un segundo learner que se incorpora seis meses después: el currículo está intacto, pero su progreso es invisible para los demás.
  • El mismo learner que vuelve tras una pausa de 10 días: nada en el repo le dice dónde estaba, qué fue difícil o qué le queda pendiente.
  • Un profesor que quiere ver cómo van tres estudiantes: no hay vista.

El portal es la capa de mantenimiento de estado sobre el currículo sin estado. El currículo se queda como está — archivos markdown en docs/, módulos fuente en src/. El portal lo renderiza, atribuye las interacciones de cada estudiante con él, y cierra el bucle sobre los fallos.

Una consecuencia clave: el portal nunca debe ser dueño del contenido del currículo. Si el archivo de teoría de una fase vive en la base de datos, la base de datos se convierte en una segunda fuente de verdad y tenemos un problema de migración en cada commit. La teoría y los enunciados de lab se quedan en docs/; el portal los lee en tiempo de petición y los renderiza a través de Jinja2. La DB es dueña solo del estado del learner: estudiantes, sesiones, notas, intentos de quiz, intentos de examen, tarjetas de revisión, eventos. Nada más.

Por qué pre-escribir no basta

A12 pre-escribe los materiales. No pre-escribe el bucle de mentoría. El bucle de mentoría tiene tres propiedades que ningún documento estático puede tener:

  1. Identidad. Dos personas pueden leer el mismo archivo de teoría; el portal sabe quién lo leyó y cuándo, por lo que podemos responder "¿pasó Ana la Fase 17?" sin preguntar a Ana.
  2. Memoria del fallo. Cuando un estudiante responde incorrectamente una pregunta de examen, el portal lo registra de tal forma que pueda re-presentarse más tarde. El currículo estático puede mostrarte la respuesta correcta una vez; no puede volver a ti, tres días después, luego nueve, luego veinte, hasta que la respuesta incorrecta se convierta en la correcta. Esto es repetición espaciada (spaced repetition) (teoría 01 §SR), y es lo único más importante que añade el portal.
  3. Visibilidad del proceso. Una nota que dice "esto me confundió el día 4" es invisible salvo que el sistema la almacene donde el profesor (o el yo futuro) pueda leerla. El portal hace que "estar atascado" sea direccionable.

Sin estas tres propiedades, pre-escribir el currículo es una emisión unidireccional. Con ellas, el currículo se convierte en correspondencia — llamada y respuesta a lo largo de días y semanas.

La decisión de "sin contraseña por defecto"

La mayoría de portales se entregan con una contraseña de admin por defecto (admin/admin, o una impresa en el script de instalación). A nivel industrial, este es el vector más común de compromisos en despliegues de dev / staging — incluso en repos que enseñan seguridad (la ironía no los salva). security/THREATS.md de la Fase 37 marca explícitamente esta clase de mala configuración.

La postura de la Fase 41 es más afilada:

Nunca se genera, se establece por defecto, se transmite ni se almacena "temporalmente" una contraseña. La única forma en que la contraseña de un estudiante entra en el sistema es cuando el estudiante la escribe en el primer login.

Mecánicamente: el admin emite un token de invitación de un solo uso — una cadena corta URL-safe firmada con itsdangerous, que incluye el id del estudiante, una marca de tiempo de emisión y un nonce single-use. El estudiante abre el enlace, ve un formulario con dos campos de contraseña, elige la suya, envía. El portal:

  1. Verifica la firma del token, la marca de tiempo (dentro del TTL, por defecto 24 horas) y que el nonce no se haya usado.
  2. Hashea la contraseña elegida con Argon2id + el pepper del servidor.
  3. Almacena el hash; invalida el token.
  4. Emite una cookie de sesión (session cookie). El estudiante está dentro.

El admin nunca ve la contraseña. El repo nunca almacena una contraseña por defecto. El enlace de invitación es el único artefacto en el modelo de amenazas con la propiedad "se canjea por credenciales", y tiene la propiedad de TTL y de un solo uso.

Esta decisión ergonómica cae limpiamente del trabajo de modelo de amenazas de la Fase 37 y es el único mecanismo que el portal soporta para añadir un estudiante. El Lab 01 recorre el flujo.

El eje multi-estudiante

Hay tres roles en el portal:

  • Estudiante (learner). Rol por defecto. Solo puede ver su propio estado. Puede leer el currículo (abierto para todos). Puede enviar notas, quizzes, exámenes. Puede ver su propio mazo de revisión.
  • Profesor. Subcaso de admin (en v1 los dos se fusionan; el BLUEPRINT los separa para una futura división). Puede ver el progreso, las notas y el historial de exámenes de todos los estudiantes. No puede suplantar a un estudiante. Las lecturas se auditan (teoría 01 §auditoría (audit)).
  • Admin. Crea estudiantes. Emite enlaces de invitación. Rota el pepper del servidor. No puede leer respuestas individuales de quiz — eso es una preocupación del profesor, no de la infraestructura.

Por qué importa esta separación: combinar "crea cuentas" con "lee notas" produce un rol-dios, que es malo tanto por mínimo privilegio (security/THREATS.md) como por la dinámica social de una cohorte pequeña. En v1 el mismo humano (Borja, y más tarde cualquiera que ejecute el repo) lleva ambos sombreros — pero el sistema registra cada acción contra el rol ejercido, así que la traza de auditoría es honesta.

Concretamente: cada lectura de admin o profesor de las notas de un estudiante escribe una fila en event_log etiquetada admin_read_notes con el id del estudiante, el id del admin y una marca de tiempo. El estudiante puede ver quién leyó sus notas y cuándo, vía su propio dashboard. Esto no es defensa frente a vigilancia — es visibilidad mutua: si yo puedo ver tus notas, tú puedes ver que las he mirado.

El bucle de mentoría, en concreto

Para cada pregunta de examen:

  • El portal almacena la pregunta, la respuesta canónica, la rúbrica (string match / multiple choice / numérico ± tolerancia).
  • Cuando un estudiante responde, el portal puntúa.
  • Si es incorrecta: la pregunta entra en el mazo de revisión del estudiante con un calendario SM-2. La primera re-presentación es al día siguiente; las re-presentaciones posteriores se estiran por el multiplicador del factor de facilidad; los fallos resetean el intervalo.
  • Si es correcta tras haber sido incorrecta: el intervalo de la pregunta se extiende y permanece en el mazo (sigue siendo re-presentable; al currículo le importa más la retención que la puntuación en el primer intento).
  • Si es correcta tras suficientes re-presentaciones correctas consecutivas (por defecto: 3 con intervalos ≥ 21 días): la pregunta se retira.

El núcleo matemático (regla de actualización SM-2 + fórmula del factor de facilidad) está en PHASE_41_PLAN.md §2 y se desarrolla en el lab 04. El punto pedagógico está en este archivo: el portal existe para hacer del bucle, no de la puntuación, el entregable. Una respuesta incorrecta es el comienzo, no el final, del aprendizaje.

Para qué sirve el registro de proceso

La tabla event_log es la forma consultable de la capa intermedia del log de tres capas de §A4 (journal diario), promovida a una fila por evento. Permite:

  • "¿Este estudiante abrió de verdad el archivo de teoría de la fase 13 antes de intentar el lab?" (auditoría de cumplimiento del currículo.)
  • "¿Cuánto tarda entre abrir el lab y enviar el examen?" (estimación de tiempo en tarea.)
  • "¿Qué fase abandonan más a menudo los estudiantes?" (señal de calidad del currículo.)
  • "¿Cuál es el gap entre una pregunta de examen fallada y su primera re-presentación correcta?" (señal de velocidad de aprendizaje.)

No sirve para:

  • Reemplazar el journal. El journal es prosa reflexiva; el event log son eventos estructurados. Se mantienen ambos.
  • Vigilar sesiones individuales. La granularidad es por-acción, no por-pulsación.

El Lab 03 construye las queries del event-log y el dashboard de admin.

El hilo en español

A2 (política bilingüe) y A13 (alcance del tutor de gramática) demandan ambas presencia del español. El portal honra ambas:

  • A13 (materia): cada pregunta de examen presentada a un estudiante está en inglés con una traducción al español pareada en el enunciado de la pregunta, exactamente como las almacena el corpus. El bucle de mentor es bilingüe por construcción.
  • A2 (inglés canónico con resúmenes en español): las plantillas muestran contenido canónico en inglés; un partial opcional "🇪🇸 Resumen" renderiza los resúmenes en español inline que los archivos de teoría ya contienen. Conmutable por estudiante en sus preferencias.

El portal no traduce dinámicamente. Expone las traducciones que el currículo ya commiteó.

Qué NO cubre este archivo

  • La arquitectura (FastAPI, SQLite, Jinja2, HTMX, Argon2id) está en theory/01-architecture.md.
  • La matemática de SM-2 está en PHASE_41_PLAN.md §2 y el lab 04.
  • El replay de seguridad de las amenazas de la Fase 37 está en el lab 05.
  • Por qué HTMX en vez de React está en theory/01-architecture.md (un párrafo defendiendo la elección contra §10 de la spec).
  • Envío de email, SSO, pagos están fuera de alcance según PHASE_41_PLAN.md §8 — y serían tres enmiendas separadas si alguna vez aterrizaran.

Una meta-lección

El portal es la pieza de infraestructura más pequeña que hace al currículo genuinamente multi-tenant y mentorización-capable. No es deliberadamente impresionante. No tiene framework de JavaScript, ni worker pool, ni cola de mensajes, ni manifiesto de Kubernetes, ni stack de métricas-y-trazas, ni historia multi-cloud. El tutor de gramática (Fase 39) tiene todo eso; el portal no tiene nada, porque el portal es entrega, no inferencia.

Un modo de fallo común en herramientas educativas es sobre-construir la capa de entrega hasta que eclipse al currículo. La presión de diseño de la Fase 41 va en sentido contrario: cualquier característica que no sirva a la identidad, la memoria del fallo o la visibilidad del proceso queda rechazada. El portal es pequeño a propósito.

Siguiente: 01-architecture.md — el recorrido C4, el stack FastAPI + Jinja2 + HTMX, el flujo de petición canónico "enviar respuesta de examen" con los middlewares de la Fase 37 aplicados.