Aller au contenu

Z1 — Transitions Mastery

États · Régressions · Spaced repetition · next_due_at

La machine à états Mastery est le cœur de la valeur produit. Une régression silencieuse ou un calcul incorrect de next_due_at casse la répétition espacée sans que l'élève s'en aperçoive.

Note : les règles Z1-AC01 à Z1-AC10 s'appliquent uniformément quel que soit le type de session (diagnostic, daily, mock_exam), sauf consolidation_optional (cf. Z4-AC13 — pas de régression). Le type de session n'affecte pas la logique de transition de maîtrise en dehors de cette exception.

Convention timestamps : Toute tentative met à jour last_review_at = now. Si la réponse est correcte (score ≥ 0.7), last_success_at = now est également mis à jour. Ces mises à jour s'appliquent indépendamment de la transition d'état. Les mentions explicites de last_review_at dans les AC individuels sont des rappels — la règle s'applique systématiquement.

Z1-AC01 — Progression UNKNOWN → FRAGILE

Lot 0 P1
GIVEN Un item en état UNKNOWN.
WHEN L'élève répond correctement une fois à une question liée à cet item (score ≥ 0.7, sans aide).
THEN L'état passe à FRAGILE. consecutive_successes = 1. next_due_at = now + 1 jour.

Z1-AC02 — Progression FRAGILE → OK

Lot 0 P1
GIVEN Un item en état FRAGILE avec consecutive_successes ≥ 1.
WHEN L'élève répond correctement une fois à une question liée à cet item (score ≥ 0.7, sans aide).
THEN L'état passe à OK. consecutive_successes = 2. next_due_at = now + 3 jours (ajusté par Z1-AC08 si contrôle posé).

NOTE : La progression FRAGILE→OK n'exige pas un espacement de 24h. L'espacement de 24h est requis uniquement pour OK→SOLID.

NOTE : « Répond correctement » signifie un score ≥ seuil de réussite du pack. Pour les questions NUMERIC avec unit_required = true, l'unité fait partie intégrante de la réponse : une valeur juste sans unité est un échec (cf. Z1-AC10). Pour les RUBRIC, le seuil est ≥ seuil_pack (cf. Z1-AC10). Cette définition de « réponse correcte » s'applique uniformément à tous les AC Z1.

Z1-AC03 — Progression OK → SOLID (espacement requis)

Lot 0 P1
GIVEN Un item en état OK avec consecutive_successes ≥ 2 et last_success_at ≥ 24h avant la tentative actuelle.
WHEN L'élève répond correctement à une question liée à cet item (score ≥ 0.7, sans aide).
THEN L'état passe à SOLID. consecutive_successes += 1. next_due_at = now + 7 jours (ajusté par Z1-AC08 si contrôle posé).

Z1-AC04 — Blocage OK → SOLID sans espacement

Lot 0 P1
GIVEN Un item en état OK avec last_success_at < 24h.
WHEN L'élève répond correctement à une question liée à cet item dans la même session.
THEN L'état reste OK. consecutive_successes n'est PAS incrémenté. next_due_at n'est PAS modifié. Aucun feedback trompeur n'est affiché. Un message explicatif positif est affiché : « Bonne réponse ! Reviens demain pour verrouiller ce point — ton cerveau a besoin d'une nuit pour bien mémoriser. » Le message apparaît une seule fois par session (pas de spam si plusieurs items OK sont dans ce cas).

Z1-AC05 — Régression SOLID → OK sur échec unique

Lot 0 P1
GIVEN Un item en état SOLID avec consecutive_successes ≥ 3.
WHEN L'élève répond incorrectement une fois à une question liée à cet item.
THEN L'état passe à OK (pas FRAGILE). consecutive_successes = 0. next_due_at = now + 2 jours (ajusté par Z1-AC08 si contrôle posé). Le feedback affiché utilise un framing growth mindset : « Ce point a besoin d'un petit refresh — on le revoit bientôt ! » (jamais « tu as perdu ta maîtrise » ni « régression »).

NOTE : La régression SOLID saute FRAGILE. Tomber directement en FRAGILE serait punitif et démotivant pour un élève ayant prouvé une maîtrise solide. Le framing « refresh » (pas « régression ») est fondé sur la recherche de Dweck sur le growth mindset : les élèves qui perçoivent l'échec comme temporaire et spécifique persistent plus longtemps que ceux qui le perçoivent comme permanent et global.

Z1-AC06 — Régression OK → FRAGILE sur échec

Lot 0 P1
GIVEN Un item en état OK.
WHEN L'élève répond incorrectement à une question liée à cet item.
THEN L'état passe à FRAGILE. consecutive_successes = 0. next_due_at = now + 1 jour. Le feedback affiché : « Pas encore acquis — on reprend demain, tu vas y arriver ! » (framing growth mindset, jamais « échec » ni « tu as régressé »).

Z1-AC07 — Régression FRAGILE sur échec (pas de descente sous FRAGILE)

Lot 0 P1
GIVEN Un item en état FRAGILE.
WHEN L'élève répond incorrectement à une question liée à cet item.
THEN L'état reste FRAGILE. consecutive_successes = 0. next_due_at = now + 1 jour. Pas de retour à UNKNOWN.

Z1-AC07b — Récupération FRAGILE après régression (cs=0, réponse correcte)

Lot 0 P1
GIVEN Un item en état FRAGILE avec consecutive_successes = 0 (suite à régression Z1-AC06/AC07 ou demi-succès Z1-AC24).
WHEN L'élève répond correctement à une question liée à cet item (score ≥ 0.7, sans aide).
THEN consecutive_successes = 1. L'état reste FRAGILE. next_due_at = now + 1 jour (ajusté par Z1-AC08 si contrôle posé). Au prochain succès, Z1-AC02 s'applique (FRAGILE→OK avec cs≥1).

NOTE : Sans cet AC, un item FRAGILE avec cs=0 (après échec) ne matchait aucune règle sur réponse correcte : Z1-AC01 exige UNKNOWN, Z1-AC02 exigeait cs=1. L'élève réussissait et rien ne se passait — dead end. Cet AC comble la lacune en créant le chemin FRAGILE(cs=0) → FRAGILE(cs=1) → OK(cs=2).

Z1-AC07c — Récupération OK après régression (cs<2, réponse correcte)

Lot 0 P1
GIVEN Un item en état OK avec consecutive_successes < 2 (suite à régression Z1-AC05 ou demi-succès Z1-AC24).
WHEN L'élève répond correctement à une question liée à cet item (score ≥ 0.7, sans aide, last_success_at ≥ 24h ou cs < 2).
THEN consecutive_successes += 1. L'état reste OK. next_due_at = now + 3 jours (ajusté par Z1-AC08 si contrôle posé). Le chemin de récupération est : OK(cs=0) → OK(cs=1) → OK(cs=2) → SOLID (si last_success_at ≥ 24h, Z1-AC03).

NOTE : Après une régression SOLID→OK (Z1-AC05), cs est remis à 0. Sans cet AC, l'item OK avec cs=0 ne matchait aucune règle sur réponse correcte : Z1-AC03 exige cs≥2. L'élève était dans un dead end. Le chemin de récupération est maintenant OK(cs=0) → OK(cs=1) → OK(cs=2) → SOLID — 3 succès espacés, conforme à l'intention SRS.

Z1-AC08 — Resserrement proportionnel si contrôle posé

Lot 0 P2
GIVEN Un item dont next_due_at vient d'être calculé par les règles Z1-AC01 à Z1-AC07. Au moins un Exam actif (non expiré) référence le chapitre de cet item via chapter_ids[]. Le temps restant T = min(exam.exam_date) − now (en jours), calculé sur l'exam le plus proche parmi tous les Exams liés au chapitre.
WHEN next_due_at est recalculé (après réponse ou lors de la composition de session).
THEN L'intervalle standard est remplacé par un intervalle proportionnel au temps restant :
État Intervalle standard Intervalle si contrôle dans T jours
UNKNOWN J+1 J+1 (incompressible)
FRAGILE J+1 J+1 (incompressible)
OK J+3 J + max(1, ⌊T/3⌋)
SOLID J+7 J + max(2, ⌊T/2⌋)
Régression SOLID→OK J+2 J + max(1, ⌊T/4⌋)

Cap absolu : next_due_at ≤ exam_date − 1 jour (sur l'exam le plus proche). L'item reste visible dans les sessions pré-contrôle même s'il est SOLID. Interaction avec les indisponibilités (Z6-AC46) : si le report pour indisponibilité pousserait next_due_at au-delà du cap exam, l'item est inclus dans la session du dernier soir disponible avant le cap, même si la session est légèrement allongée. Si l'Exam a notion_ids[] (Z7-AC19), seuls les items appartenant aux Notions sélectionnées sont soumis au resserrement.

NOTE : Les contrôles sont typiquement annoncés à +7 jours. Exemples avec T=7 : OK → J+2, SOLID → J+3, régression → J+1. Avec T=3 : OK → J+1, SOLID → J+2, régression → J+1. Sans aucun Exam lié, les intervalles standard s'appliquent (cf. Z1-AC01 à Z1-AC07).

Multi-exam : Si un chapitre est lié à plusieurs Exams (ex : interro chapitre 3 le 15/03 + contrôle séquence chapitres 1-3 le 20/03), c'est l'exam_date le plus proche qui pilote T. Le resserrement est donc maximal — l'élève est préparé pour l'échéance imminente.

Edge case T ≤ 0 : Si tous les exam_date liés au chapitre sont passés (T ≤ 0 pour chaque), le resserrement ne s'applique plus — les intervalles standard reprennent. Les Exams expirés sont ignorés (équivalent à « pas de contrôle posé »). Le système ne doit jamais produire un next_due_at dans le passé.

Z1-AC09 — Indépendance des Mastery states entre items

Lot 0 P1
GIVEN Deux items A et B dans le même chapitre, A en SOLID, B en UNKNOWN.
WHEN L'élève échoue sur B.
THEN Le Mastery state de A n'est pas modifié. Les states sont isolés par (user_id, item_id).

Z1-AC10 — Scoring par type de question (RUBRIC, NUMERIC, KEYWORDS)

Lot 0 P2
GIVEN Un item lié à une question de type RUBRIC, NUMERIC, ou KEYWORDS.
WHEN L'élève fournit une réponse.
THEN Les règles de scoring suivantes s'appliquent selon le type de question : — RUBRIC : Score ≥ seuil_pack (défaut 3/4) = réussite. En dessous = pas de progression, le feedback affiche les critères manquants. — NUMERIC avec unit_required = true : La valeur correcte (dans la tolérance ± 2 %) sans unité = échec. consecutive_successes est remis à 0. Le feedback indique « unité manquante ». La même logique vaut pour tous les états de mastery (régression selon Z1-AC05 / Z1-AC06 pour OK et SOLID). — KEYWORDS : Score ≥ N-1 = réussite (tolérance d'un mot-clé manquant). consecutive_successes est incrémenté et la progression mastery s'applique normalement. En dessous de N-1 = échec. Le feedback indique les mots-clés manquants à titre informatif.

NOTE : Le seuil RUBRIC est paramétrable par pack (défaut MVP : 3/4 critères). La règle NUMERIC formalise le PRD « Faux négatif si unité absente même si valeur correcte » — elle s'applique à tous les états, pas seulement FRAGILE. Le seuil KEYWORDS ≥ N-1 (PRD §17.3 « Score partiel si N-1 ») compense les variations de formulation naturelles en français.

Z1-AC11 — Échec sur item UNKNOWN (pas de descente sous UNKNOWN)

Lot 0 P1
GIVEN Un item en état UNKNOWN avec consecutive_successes = 0.
WHEN L'élève répond incorrectement à une question liée à cet item.
THEN L'état reste UNKNOWN. consecutive_successes = 0. next_due_at = now + 1 jour. Aucune régression n'est possible en dessous de UNKNOWN.

Z1-AC12 — Maintien SOLID sur réussite successive

Lot 0 P1
GIVEN Un item en état SOLID avec consecutive_successes ≥ 3 et last_review_at ≥ 24h.
WHEN L'élève répond correctement à une question liée à cet item.
THEN L'état reste SOLID. consecutive_successes += 1. next_due_at = now + 7 jours (ajusté par Z1-AC08 si contrôle posé). last_review_at est mis à jour. La question utilisée pour cet item devrait être un gabarit d'élaboration si disponible dans le pack (cf. Z4-AC14, difficulté 3) : « Explique pourquoi… », « Quel est le lien entre X et Y ? », « Donne un exemple concret de… ». Si aucun gabarit d'élaboration n'est disponible, les gabarits standards de difficulté 3 (RUBRIC, KEYWORDS exigeant) sont utilisés.

NOTE : Un item SOLID qui continue d'être réussi reste SOLID avec un intervalle constant de J+7. L'incrémentation de consecutive_successes au-delà de 3 permet de distinguer un item « fraîchement SOLID » d'un item « profondément ancré ». La recherche sur l'interrogation élaborative (Dunlosky et al. 2013, utilité modérée) montre que les questions « pourquoi » approfondissent les schémas et favorisent le transfert — mais uniquement quand l'élève a des connaissances préalables suffisantes. Un item SOLID est le candidat idéal : l'élève maîtrise le fait, il est prêt à comprendre le mécanisme. Sans élaboration, la consolidation SOLID dégénère en répétition mécanique (flashcard → réponse automatique → aucun approfondissement).

Z1-AC13 — Plafond maîtrise OK pour items restreints aux templates simples

Lot 0 P2
GIVEN Un item avec validation_required = true qui ne reçoit que des gabarits simples (GEN.KNOW.DEF_SHORT, GEN.KNOW.FLASH_MCQ — cf. Z3-AC01). L'item est en état OK avec consecutive_successes = 2.
WHEN L'élève répond correctement à une question liée à cet item (gabarit simple).
THEN L'état reste OK (plafonné). L'item ne peut PAS passer SOLID tant que validation_required = true. consecutive_successes est incrémenté normalement mais la transition OK → SOLID est bloquée. Le dashboard affiche un badge « maîtrise partielle — vérification requise » sur cet item.

NOTE : C'est le AC le plus critique pour l'intégrité de la maîtrise. Sans ce plafond, un item potentiellement hallucé (fidelity_score null ou < 0.5) peut atteindre SOLID via des QCM triviaux. Le parent voit alors une maîtrise à 80%+ qui ne reflète pas la réalité. Ce AC empêche structurellement la pollution du signal mastery par des items non vérifiés. La résolution de la ValidationTask (Z3-AC02/03) lève automatiquement le plafond.

Z1-AC14 — Micro-célébration sur transitions de maîtrise positives

Lot 0
GIVEN Un item vient de transiter vers un nouvel état positif (UNKNOWN → FRAGILE, FRAGILE → OK, OK → SOLID).
WHEN La transition est enregistrée en base (Mastery state update).
THEN L'interface affiche un feedback visuel de célébration adapté à la transition : — UNKNOWN → FRAGILE : message « Bien joué, tu commences à maîtriser [term] ! » (encouragement léger). — FRAGILE → OK : message « [term] est de mieux en mieux — continue comme ça ! » + animation subtile. — OK → SOLID : message « [term] est acquis — bravo ! 🎯 » + animation marquée + compteur d'items SOLID du chapitre incrémenté visiblement. Le feedback est affiché en fin de question (après le feedback de correction), pendant 2 secondes, et ne bloque pas la navigation vers la question suivante.

NOTE : L'absence de célébration est le premier facteur de désengagement identifié chez les 11-15 ans. Le service valorise la qualité (« tu maîtrises ce concept ») plutôt que la quantité (pas de streak). Les animations sont légères et non-bloquantes — le but est un micro-shot de dopamine, pas une interruption. Ce AC complète Z6-AC15 (pas de streak) : on ne célèbre pas la régularité mais la progression réelle.

Z1-AC15 — Débrief de fin de session

Lot 0
GIVEN L'élève termine une session (toutes les questions répondues ou TTL expiré avec ≥ 1 question répondue).
WHEN La session passe en status = COMPLETED.
THEN Un écran de débrief est affiché avec : — Score global de la session (X/Y correctes). — Liste des items ayant progressé positivement (transitions vers un état supérieur) avec le nouveau badge. — 1 item prioritaire à revoir (le plus fragile encore, avec next_due_at le plus proche). — Message de fermeture contextuel : si session evening_first → « Super première prise de contact ! ». Si session pre_class → « Tu es prêt(e) pour demain ! ». Si session daily → « Bonne révision, à demain ! ». Si session paper_report (Z7-AC26) → variant simplifié : pas de score X/Y (l'auto-évaluation n'est pas un quiz noté). À la place : « Tu as reporté [X] réussites et [Y] points à revoir sur ta fiche [Chapitre]. [N] points seront vérifiés ce soir en session. » + liste des items ayant progressé (UNKNOWN→FRAGILE, FRAGILE→OK) + message « Bon travail en étude ! On consolide ce soir. » Le débrief paper_report ne mentionne PAS le plafond OK→SOLID (information technique inutile pour l'élève). — Bouton unique « Terminer » (pas de partage, pas de gamification complexe). Le débrief est optionnel : l'élève peut fermer l'app sans le lire (pas de blocage).

NOTE : Le débrief est le moment le plus important pour la rétention. Un élève qui ne sait pas s'il a progressé ne reviendra pas. Ce écran doit être rapide (< 3 secondes de chargement), positif (mettre en avant les progrès, pas les échecs) et actionnable (montrer le prochain objectif). L'absence de débrief est le 2ème facteur de churn identifié après l'absence de célébration.

Z1-AC16 — Score contrôle blanc : caveat qualité si items non validés

Lot 0
GIVEN L'élève complète un contrôle blanc (mock_exam). Sur 20 questions, 6 portent sur des items avec validation_required = true (restreints aux templates simples, cf. Z3-AC01).
WHEN Le score du contrôle blanc est calculé et affiché (à l'élève et dans le résumé parent).
THEN Le score global est affiché normalement (ex. 14/20). Un sous-texte est ajouté : « Score basé sur [14] questions complètes et [6] questions simplifiées (contenu en cours de vérification) ». Le résumé envoyé au parent inclut la même mention. Le score est accompagné d'un indicateur de confiance : score_confidence = (questions_full_templates / total_questions) — ici 0.70. Si score_confidence < 0.5, un avertissement explicite est ajouté : « Plus de la moitié des questions étaient simplifiées — ce score est peu représentatif. Encouragez [Prénom] à vérifier les zones incertaines. »

NOTE : Sans ce caveat, le parent voit « 14/20 » et pense que l'enfant est prêt. Mais 6 questions étaient des QCM simples au lieu d'exercices de calcul ou rédaction — le score est structurellement gonflé. Ce AC rend l'inflation visible et actionnable. Le score_confidence est également exploité par le digest (Z6-AC35).

Z1-AC17 — Script 3 minutes : exclusion des items sous investigation

Lot 0
GIVEN Le parent consulte le « script 3 minutes » pour un chapitre. 3 items sont les plus fragiles : Item A (FRAGILE, validation_required = false), Item B (FRAGILE, validation_required = true, source = 'fidelity_check'), Item C (UNKNOWN, anomaly_flag = 'high_failure_rate').
WHEN Le système compose les 2–3 questions orales du script.
THEN Item B et Item C sont exclus du script (items sous investigation). Seul Item A est inclus. Si moins de 2 items sont éligibles après exclusion, le script est complété avec des items OK récemment révisés (consolidation orale). Le script n'inclut jamais un item avec validation_required = true, anomaly_flag != null, ou is_demo = true (Z8-AC01). Si le seul chapitre est le chapitre démo, le script affiche : « Pas encore de contenu pour le script — encouragez [Prénom] à capturer son premier cours ! » Un message est affiché si des items ont été exclus : « [N] point(s) sont en cours de vérification et ne sont pas inclus dans le script. »

NOTE : Le script 3 minutes est le moment où le parent teste activement l'enfant à l'oral. Si le parent pose une question basée sur un item hallucé ou défectueux, et que l'enfant répond correctement selon le cours réel (pas l'item erroné), le parent conclut que l'app est défaillante. C'est un des moments de rupture de confiance les plus forts.

Z1-AC18 — Modification de la date d'exam → recalcul des intervalles compressés

Lot 0
GIVEN Un exam « Contrôle HG » est fixé au 20 mars. 12 items du chapitre sont en états variés (3 SOLID, 5 OK, 4 FRAGILE). Les next_due_at ont été compressés selon Z1-AC08 (cap = exam_date − 1 jour). L'élève modifie la date d'exam au 27 mars (+7 jours).
WHEN La mise à jour de l'exam est sauvegardée.
THEN Tous les next_due_at des items liés à cet exam sont recalculés avec la nouvelle exam_date. Les intervalles reprennent les valeurs standard (1j/3j/7j) si le nouveau T le permet, sinon la compression est recalculée proportionnellement au nouveau T. Le recalcul ne touche pas les items dont le next_due_at est déjà passé (ils restent dus immédiatement). Si la date est avancée (ex: 20 mars → 15 mars), les intervalles se compriment davantage et un avertissement s'affiche : « Tu as peu de temps — les sessions seront plus fréquentes pour ce chapitre. » Si la date est repoussée, un message positif : « Plus de temps pour bien réviser ! » Le digest parent suivant mentionne le changement de date.

NOTE : Un contrôle reporté par le prof est un cas fréquent au collège. Si l'élève met à jour la date mais que les intervalles restent compressés sur l'ancienne date, il révisera inutilement de manière intensive pendant 7 jours de plus. Inversement, si le contrôle est avancé et que les intervalles ne se compriment pas, l'élève arrive sous-préparé. Le recalcul automatique maintient la cohérence du plan de révision.

Z1-AC19 — Descente de difficulté après échecs répétés sur un item

Lot 0
GIVEN Un item FRAGILE ou UNKNOWN a été présenté à l'élève 3 fois consécutives dans les 5 derniers jours, et l'élève a échoué les 3 fois. Les questions utilisaient des gabarits de difficulté ≥ 2 (ex: GEN.KNOW.ASSOC_TERM_DEF, GEN.DOC.INTERPRET_WITH_CONCEPT).
WHEN Le moteur de composition sélectionne cet item pour la session suivante.
THEN Le gabarit choisi est rétrogradé au niveau de difficulté 1 pour cet item (ex: GEN.KNOW.FLASH_MCQ ou GEN.KNOW.DEF_SHORT). Un indice est ajouté au feedback de la question : référence au passage pertinent de la carte de leçon (« Relis la section [titre_section] de ta leçon »). Si l'élève réussit avec le gabarit simplifié, la question suivante pour cet item remonte à difficulté 2. Si l'élève échoue même au gabarit simplifié (5ème échec consécutif), un message d'encouragement s'affiche : « Ce point est difficile — on va le revoir autrement. Regarde ta leçon et on réessaie demain. » L'item est reporté à J+2 au lieu de J+1 (pause pédagogique). La détection d'anomalie Z3-AC16/AC21 continue de fonctionner en parallèle.

NOTE : Un élève qui échoue 3 fois de suite sur le même item à la même difficulté entre dans un cycle de frustration : il voit la même question, ne comprend pas, échoue encore, se sent nul. La descente de difficulté brise ce cycle en offrant un exercice plus accessible (MCQ vs question ouverte). Le renvoi vers la carte de leçon transforme un moment d'échec en moment d'apprentissage. La pause J+2 après 5 échecs évite l'acharnement contre-productif — le cerveau a besoin de temps pour consolider.

Z1-AC20 — Détection et rattrapage des items UNKNOWN jamais révisés (starvation)

Lot 0
GIVEN Un chapitre a 20 items. 12 sont en état FRAGILE (tous dus quotidiennement). 8 sont en état UNKNOWN avec next_due_at dépassé depuis 7+ jours. La politique 70/20/10 sélectionne systématiquement les 12 items FRAGILE dans le bucket 70% (dues) car ils sont plus prioritaires. Les items UNKNOWN n'ont jamais été présentés en session depuis leur création.
WHEN Le moteur de composition crée une session daily.
THEN Un mécanisme anti-starvation garantit que chaque session inclut au minimum 1 item UNKNOWN s'il existe des items UNKNOWN non présentés depuis 7+ jours. Cet item est injecté dans le bucket 10% « découverte », même si le bucket 70% est plein. Si plusieurs items UNKNOWN sont en starvation, le plus ancien (plus grand écart next_due_at - now) est sélectionné en priorité. Un job hebdomadaire détecte les items UNKNOWN avec 0 tentatives depuis > 14 jours et crée une alerte admin ITEM_STARVATION (priorité MEDIUM). Le dashboard élève affiche un indicateur discret : « [N] points pas encore abordés » si des items UNKNOWN existent depuis > 7 jours sans tentative.

NOTE : Un chapitre dense (30+ items) avec beaucoup de FRAGILE peut créer une file d'attente infinie pour les items UNKNOWN. Le 70/20/10 est optimal en régime stable mais pathologique en cas de dette : les items FRAGILE monopolisent le bucket et les UNKNOWN ne sont jamais vus. L'élève pense réviser tout le chapitre mais a des trous systématiques. Pire : le mock exam peut tester ces items jamais vus, et l'élève découvre un pan entier du cours le jour du contrôle blanc.

Z1-AC21 — Bouton « Voir ma leçon » contextuel pendant une question

Lot 0
GIVEN L'élève est en session (daily, evening_first, mock_exam…). Une question est affichée sur l'item « masse volumique ρ = m/V ». L'item appartient à la Notion « Masse volumique (ρ) » du chapitre « Densité et masse volumique ». L'élève hésite et ne se souvient plus de la formule.
WHEN L'élève tape sur le bouton « 📖 Voir ma leçon » (visible en permanence sous la zone de réponse, discret mais accessible).
THEN Un panneau coulissant (bottom sheet / drawer) s'ouvre et affiche uniquement la section pertinente de la carte de leçon : les blocs OCR correspondant à la Notion de l'item en cours (pas toute la leçon — juste la section liée). Le titre du panneau est « Ta leçon — [nom de la Notion] ». Si l'item a un linked_doc_id (document lié), le document est aussi affiché. Le panneau est scrollable si la section est longue. La question reste visible en arrière-plan (effet de transparence ou split-screen sur tablette). L'élève peut fermer le panneau et revenir à la question pour répondre. Impact maîtrise : la réponse est marquée hint_used = true. Si la réponse est correcte avec hint, elle compte comme un demi-succès : elle ne casse pas la série de consecutive_successes mais ne l'incrémente pas non plus (neutre). L'item ne peut pas passer de OK → SOLID sur une réponse avec hint (il faut une réussite « propre » pour SOLID). L'item peut passer de UNKNOWN → FRAGILE ou FRAGILE → OK avec hint (l'élève a quand même fait l'effort de chercher et répondre). Un indicateur discret « 📖 » apparaît sur la question dans le débrief de session pour les questions où le hint a été utilisé.

NOTE : Ce bouton est conçu pour l'élève « orienté résultat » qui ne veut pas relire sa leçon de manière proactive mais a besoin d'un coup de pouce quand il est bloqué. La clé est la contextualisation : on ne montre pas toute la leçon (ennuyeux, trop long) mais uniquement la Notion pertinente (2-4 blocs OCR, ~30 secondes de lecture). C'est l'équivalent numérique de « demander au prof de répéter » — pas de la triche, mais un étayage (scaffolding). Le demi-succès est le bon compromis : on ne pénalise pas l'effort (l'élève a cherché, lu, compris, puis répondu) mais on ne le récompense pas autant qu'une réponse de mémoire (le passage SOLID exige la récupération sans aide, c'est le standard de la maîtrise réelle). Pré-requis : l'entité Notion (Z7-AC17) et le champ Item.notion_id doivent exister pour que le panneau affiche la bonne section. Si notion_id est absent (migration, chapitre ancien), le panneau affiche la carte de leçon complète du chapitre en fallback. Voir Z1-AC24 pour la matrice complète de transition maîtrise avec hint_used.

Z1-AC22 — Bouton « Je ne comprends pas la question » : reformulation et clarification

Lot 0
GIVEN L'élève est en session. La question affichée est : « Explique pourquoi un objet plus dense que l'eau coule » (gabarit GEN.KNOW.DEF_SHORT, item « densité et flottaison »). L'élève ne comprend pas ce qu'on lui demande : est-ce la définition de la densité ? La formule ? Le lien avec la flottaison ?
WHEN L'élève tape sur le bouton « ❓ Je ne comprends pas la question » (visible à côté du bouton « Voir ma leçon »).
THEN Le système affiche une reformulation en 2 parties (générée par template, pas LLM live) : (1) Ce qu'on te demande (intention de la question en langage simple) : « On te demande d'expliquer le lien entre la densité d'un objet et le fait qu'il coule dans l'eau. » (2) Un indice de démarrage (sans donner la réponse) : « Pense à comparer la densité de l'objet avec celle de l'eau (ρ_eau = 1 g/cm³). » La reformulation est pré-générée lors de l'instanciation de la question (étape 3 du moteur d'exploitation, PRD §7.2) : chaque question instanciée contient un champ clarification { intent: string, starter_hint: string } généré par le LLM au moment de la composition (coût marginal ~50 tokens par question). Si le champ clarification est absent (question ancienne, migration), un fallback textuel s'affiche : « Cette question porte sur : [item.term]. Essaie de répondre avec ce que tu sais, même partiellement ! » Impact maîtrise : l'utilisation de la clarification est marquée clarification_used = true. Même impact que hint_used (Z1-AC21) : demi-succès, pas de passage OK→SOLID. L'élève peut cumuler clarification + hint leçon sur la même question (les deux marqueurs sont indépendants). Le débrief affiche « ❓ » pour les questions où la clarification a été utilisée.

NOTE : « Je ne comprends pas la question » est un signal d'UX fondamental qu'aucune app de révision ne gère correctement. Quand un élève ne comprend pas l'intention d'une question, il a trois options : (1) répondre au hasard → feedback non informatif, frustration, (2) passer → pas d'apprentissage, (3) demander à un parent → interruption. Le bouton ❓ offre une 4ème option : comprendre ce qu'on attend de lui, puis essayer. La reformulation en deux parties (intention + indice de démarrage) est inspirée des pratiques des bons profs : avant de donner la réponse, ils reformulent la question et donnent un « coup de pouce ». Le coût LLM est marginal car la clarification est pré-générée à la composition, pas en temps réel.

Z1-AC23 — Réponse partielle encouragée : « Je ne sais pas tout mais je tente »

Lot 0
GIVEN L'élève est face à une question SHORT_ANSWER ou KEYWORDS. Il a une vague idée mais n'est pas sûr de lui. Il n'a pas envie de voir la leçon (trop long) ni de passer la question (frustrant).
WHEN L'élève soumet une réponse partielle (pour KEYWORDS : 1 mot-clé sur 3 attendus ; pour SHORT_ANSWER : réponse incomplète mais contenant ≥ 1 élément correct).
THEN La correction reconnaît explicitement l'effort partiel : (1) Score partiel : pour KEYWORDS, chaque mot-clé correct vaut des points (ex: 1/3 = « Tu as trouvé 1 mot-clé sur 3 — c'est un début ! »). Pour SHORT_ANSWER, si ≥ 1 concept-clé est présent dans la réponse, le score est ≥ 0.3 (pas 0). (2) Feedback différencié : « Tu as trouvé [élément correct]. Il manquait [éléments manquants]. » au lieu d'un simple « Faux ». (3) Impact maîtrise : un score partiel (≥ 0.3 et < 0.7) est traité comme un « demi-échec » : l'item ne régresse pas (pas de OK→FRAGILE) mais ne progresse pas non plus (le consecutive_successes est remis à 0 sans pénalité supplémentaire). Un score ≥ 0.7 est traité comme une réussite. Un score < 0.3 est traité comme un échec. (4) Le feedback affiche toujours la réponse complète pour que l'élève voie ce qu'il manquait, même en cas de réponse partielle. Le message de feedback partiel utilise un ton encourageant : « Bien, tu y es presque ! » (score 0.5-0.7), « C'est un bon début ! » (score 0.3-0.5).

NOTE : L'élève orienté résultat a besoin de voir que son effort est reconnu, même incomplet. Un système binaire « correct/incorrect » est frustrant car il met au même niveau « je n'avais aucune idée » et « j'avais 2 mots-clés sur 3 ». Le score partiel valorise la connaissance partielle et évite le découragement. C'est aussi pédagogiquement juste : en vrai contrôle, un élève qui donne 2 mots-clés sur 3 n'a pas 0 — il a une note intermédiaire. Le seuil 0.3 pour « demi-échec » (pas de régression) est un filet de sécurité : l'élève qui tente une réponse partielle ne doit pas être puni plus sévèrement que celui qui passe la question.

Z1-AC24 — Matrice de transition maîtrise avec hint, clarification et score partiel

Lot 0
GIVEN L'élève répond à une question sur un item. Il a potentiellement utilisé le hint leçon (hint_used), la clarification (clarification_used), ou les deux. Ou bien le résultat provient d'un report papier (Attempt.source = 'paper_report', cf. Z7-AC26). Le score obtenu est dans l'une des 3 tranches : échec (< 0.3), partiel (0.3–0.7), réussite (≥ 0.7). Pour un report papier, ✓ = réussite (score 1.0) et ✗ = échec (score 0.0).
WHEN Le moteur de maîtrise calcule la transition d'état pour cet item.
THEN Exception session consolidation_optional (Z4-AC13) : les règles d'échec (A, score < 0.3) et de demi-échec (A/C, score 0.3–0.7) ne s'appliquent PAS dans une session consolidation_optional. Seuls les succès et demi-succès sont enregistrés. Les échecs et scores partiels sont enregistrés comme Attempt (audit) mais ne déclenchent ni régression ni reset de consecutive_successes. La matrice ci-dessous s'applique à tous les autres types de session. La matrice de transition est la suivante : (A) Sans aide, session interactive (hint=false, clarification=false, source='interactive') : score < 0.3 = échec (régression Z1-AC05/06/07, consecutive_successes = 0). Score 0.3–0.7 = demi-échec (consecutive_successes = 0, pas de régression). Score ≥ 0.7 = réussite (consecutive_successes += 1, progression Z1-AC01/02/03). (B) Avec aide (hint=true et/ou clarification=true, source='interactive') : score < 0.3 = échec standard (même que A). Score 0.3–0.7 = demi-échec standard (même que A). Score ≥ 0.7 = demi-succès : consecutive_successes inchangé (ni incrémenté, ni remis à 0). Pas de régression. L'item ne peut PAS passer OK→SOLID sur un demi-succès (exige réussite sans aide). L'item PEUT passer UNKNOWN→FRAGILE ou FRAGILE→OK sur un demi-succès (l'effort de chercher dans la leçon et de répondre correctement vaut progression). Mastery.last_success_at est mis à jour sur un demi-succès (car la réponse est correcte, même aidée). (B') Report papier (source='paper_report') : un report ✓ est traité exactement comme un demi-succès (B, score ≥ 0.7 avec aide) : UNKNOWN→FRAGILE et FRAGILE→OK autorisés, OK→SOLID bloqué (plafond papier, cf. Z7-AC26). consecutive_successes inchangé. Mastery.last_success_at mis à jour. Un report ✗ est traité comme un échec standard (A, score < 0.3) : régression normale Z1-AC05/06/07, consecutive_successes = 0. Le canal papier étant non vérifiable, il ne peut jamais produire une réussite « propre » (A, score ≥ 0.7 sans aide) — seule une session interactive vérifiée par le système le peut. (C) Cumul aide + partiel : si hint=true ET score 0.3–0.7, le résultat est un demi-échec (le score partiel domine). Le champ Attempt.hint_used et Attempt.clarification_used sont indépendants — l'utilisation des deux sur la même question n'aggrave pas le résultat vs un seul. (D) Espacement 24h (clarification Z1-AC03/AC04) : le passage OK→SOLID exige last_success_at datant de ≥ 24h avant la tentative actuelle. Une réponse correcte dans la même session qu'un passage FRAGILE→OK ne peut PAS déclencher OK→SOLID : le last_success_at vient d'être positionné à l'instant, l'écart est 0h < 24h. Cette règle est de toute façon redondante pour le papier (OK→SOLID bloqué par B').

NOTE : Cette matrice consolide les règles dispersées dans Z1-AC01 à Z1-AC23 et Z7-AC26 en un tableau de décision unique. Le point (B') est le pendant papier du point (B) : même mécanique de demi-succès, même blocage OK→SOLID. La justification est identique — un canal non vérifiable (report papier) mérite le même traitement qu'une réponse aidée (hint/clarification). Le développeur n'a qu'une seule matrice à implémenter : if (source == 'paper_report' || hint_used || clarification_used) → demi-succès. La clarification de la règle « même session » (point D) résout l'ambiguïté entre Z1-AC02 (permet FRAGILE→OK en même session) et Z1-AC04 (bloque OK→SOLID si < 24h) : les deux sont vrais simultanément, car le mécanisme de blocage est last_success_at, pas le numéro de session.

Z1-AC25 — Jugement de confiance (JOL) pour entraîner la métacognition

Lot 0
GIVEN L'élève vient de répondre à une question sur un item en état FRAGILE ou OK (pas UNKNOWN — trop tôt pour l'auto-évaluation, ni SOLID — peu d'enjeu).
WHEN La réponse est soumise et avant que le feedback de correction ne s'affiche.
THEN Un prompt rapide s'affiche : « Étais-tu sûr(e) de ta réponse ? » avec 3 options visuelles (feu tricolore) : 🔴 « Pas sûr(e) » / 🟡 « Moyen » / 🟢 « Sûr(e) ». Le prompt est optionnel : un timer de 3 secondes s'écoule, après quoi le feedback de correction s'affiche automatiquement (l'élève peut aussi taper une option pour accélérer). La réponse de confiance est loggée dans Attempt.confidence_level (1/2/3 ou null si ignoré). Le résultat de confiance n'impacte PAS le mastery, le scoring ni les transitions d'état — c'est un signal purement pédagogique. Dans le débrief de session (Z1-AC15), une stat métacognitive est affichée si ≥ 3 réponses de confiance ont été collectées : « Tu étais sûr(e) sur [N] réponses fausses — attention aux pièges ! » (si confiance 🟢 + réponse incorrecte ≥ 2) ou « Bonne auto-évaluation — tu sais ce que tu sais ! » (si la corrélation confiance/résultat est bonne). Le prompt JOL n'est affiché que pour 1 question sur 3 (échantillonnage pour éviter la lassitude). Il n'apparaît jamais sur les questions avec hint_used = true ou clarification_used = true (l'aide biaise le jugement).

NOTE : Les 11-15 ans sont systématiquement surconfiants dans leurs Judgments of Learning (Van Loon et al. 2017). Cette surconfiance cause un arrêt prématuré de l'étude — l'élève pense savoir alors qu'il ne sait pas. Une méta-analyse de 56 études montre que l'entraînement métacognitif améliore la calibration avec un effet g=-0.565. Le feu tricolore est adapté à l'âge (faible charge cognitive, ~1 seconde de réflexion). L'échantillonnage 1/3 évite que le prompt ne devienne un frein à la fluidité de la session. La stat dans le débrief transforme un signal individuel en prise de conscience : « je croyais savoir mais je ne savais pas » est le moment d'apprentissage métacognitif le plus puissant.

Z1-AC26 — Framing growth mindset systématique dans tous les messages

Lot 0
GIVEN L'interface affiche un message à l'élève suite à un événement de mastery (progression, régression, stagnation, débrief).
WHEN Le message est composé (templates de messages, débrief Z1-AC15, célébrations Z1-AC14, régressions Z1-AC05/AC06).
THEN Tous les messages respectent les principes de framing growth mindset : (1) Vocabulaire interdit : « échec », « raté », « perdu », « régressé », « mauvais ». (2) Vocabulaire obligatoire : « pas encore » (au lieu de « pas »), « refresh » (au lieu de « régression »), « en cours » (au lieu de « non acquis »). (3) Ratio positif/négatif ≥ 3:1 dans le débrief de session : si 4 régressions et 2 progressions, le débrief met en avant les progressions d'abord et résume les régressions en une ligne neutre (« 4 points à revoir demain »). (4) Effort-based praise : « Tu as travaillé sur 12 points ce soir — c'est ce qui compte ! » plutôt que « Tu as eu 8/12 ». (5) Normalisation de la difficulté : après un score < 50%, un message contextuel s'affiche : « C'est normal que ce soit difficile au début — chaque tentative renforce ta mémoire, même quand tu te trompes. » Les templates de messages sont versionnés et auditables (pas de LLM live pour le framing — les variantes sont pré-écrites et assignées par rotation).

NOTE : La recherche de Dweck montre que le framing « not yet » vs « failed » change significativement la persistance chez les adolescents. Steuer & Narciss (2025, BJEP) montrent que l'apprentissage productif à partir des erreurs nécessite un scaffolding émotionnel — il ne se produit pas spontanément. Le ratio 3:1 positif/négatif est fondé sur les travaux de Losada & Heaphy (seuil de flourishing). L'effort-based praise (« tu as travaillé dur ») surpasse l'ability-based praise (« tu es intelligent ») car il attribue le succès à un facteur contrôlable. Le versionnage des templates garantit que le framing ne dépend pas d'un prompt LLM variable.