Skip to Content

Chapitre 6.4 — Result & context

⏱️ TL;DR — Le noyau actorverbobject dit ce qui s’est passé. Deux champs optionnels le rendent exploitable. Le result porte la mesure : score (scaled de -1 à 1, plus raw/min/max), success (réussi ?), completion (terminé ?), duration (au format ISO 8601, ex. PT1H15M) et response (la réponse donnée). Le context porte le où ça se situe : registration (l’UUID de la tentative, ce qui relie tous les statements d’une même session), instructor, contextActivities (parent/grouping/category — la hiérarchie qui rattache un statement à un module, un parcours, un profil) et extensions (tes données maison, clés en IRI). Le result te donne des chiffres ; le context te donne du sens en reliant les statements entre eux.

🎯 Objectifs

  • Renseigner correctement un result : la bonne échelle de score, success vs completion, une duration ISO 8601 valide.
  • Ne pas confondre success (réussi) et completion (terminé) — la même distinction qu’en SCORM 2004 (Partie 5).
  • Utiliser registration pour regrouper les statements d’une même tentative.
  • Structurer contextActivities (parent, grouping, category) pour relier un statement à sa hiérarchie.
  • Ranger tes données spécifiques dans extensions sans polluer le noyau.

Le result : la mesure de l’expérience

result répond à « avec quel résultat ? ». Tous ses sous-champs sont optionnels ; on met ceux qui ont un sens.

"result": { "score": { "scaled": 0.92, // ratio de -1 à 1 (ici 92 %) — LE champ portable "raw": 46, // score brut "min": 0, // borne basse "max": 50 // borne haute }, "success": true, // a-t-il RÉUSSI ? (au-dessus du seuil) "completion": true, // a-t-il TERMINÉ ? (parcouru l'activité) "duration": "PT1H15M", // durée ISO 8601 : 1 h 15 min "response": "soudure conforme, angle 90°, pénétration correcte" // la réponse/production }

Le score : scaled, raw, min, max

Comme en SCORM 2004 (ce n’est pas un hasard, même famille ADL), scaled est un ratio de -1 à 1, pas un pourcentage entier :

  • 92 % s’écrit 0.92, jamais 92. Un 92 dans scaled est hors plage et invalide.
  • raw, min, max donnent le score brut et ses bornes. Un raw de 46 n’a de sens que si on sait qu’il est sur 50 (min: 0, max: 50).
  • scaled est le champ portable : il compare des activités de barèmes différents (46/50 et 18/20 valent tous deux ≈ 0,9). Privilégie-le pour l’agrégation ; ajoute raw/min/max pour la traçabilité fine.

⚠️ Piège — Mettre 92 dans scaled (au lieu de 0.92), ou envoyer un raw sans min/max. Le premier produit un score invalide (hors -1..1) ; le second produit un score ininterprétable (46 sur combien ?). Règle : scaled = ratio décimal ; raw = toujours accompagné de ses bornes.

success ≠ completion

C’est exactement la distinction complétion/réussite de SCORM 2004 (Partie 5), portée en xAPI :

ChampQuestionExemple « terminé mais raté »
completionA-t-il parcouru / achevé l’activité ?true
successA-t-il atteint le seuil de réussite ?false

Les deux sont indépendants. On peut avoir completion: true + success: false (a tout fait, mais échoué), ou completion: false + success: true (a réussi une partie sans finir le reste). Ne les fusionne jamais : ce sont deux informations distinctes que les rapports exploitent séparément.

💡 Réflexe — Choisis consciemment le verbe et les champs de result. « A réussi » se dit idéalement avec le verbe passed et success: true : verbe et result se confirment. De même completed va avec completion: true. Garde verbe et result cohérents — un statement passed avec success: false est un signal contradictoire qui trahit un bug.

duration : le format ISO 8601

duration suit le format durée ISO 8601 : préfixe P (période), T avant la partie horaire, puis heures/minutes/secondes.

Durée réelleÉcriture ISO 8601
10 minutesPT10M
1 h 15 minPT1H15M
1 h 30 min 45 sPT1H30M45S
90 secondesPT1M30S (ou PT90S)

Le T n’est pas optionnel devant les heures/minutes/secondes : PT10M = 10 minutes, alors que P10M (sans T) voudrait dire 10 mois. Cette lettre change tout.

⚠️ Piège — Oublier le T ou envoyer une durée en secondes brutes (4500). duration n’est pas un nombre : c’est une chaîne ISO 8601. 4500 est refusé ; PT1H15M (ou PT4500S) est correct. Et P10MPT10M : le premier, ce sont dix mois.

Le context : ce qui relie et situe

context répond à « dans quel cadre ? ». C’est lui qui transforme une collection de phrases isolées en un récit cohérent.

"context": { "registration": "3d6d3e0c-1f2b-4b8a-8c1a-9e2f7a6b5c4d", // UUID de LA tentative "instructor": { // le formateur qui encadre/atteste "objectType": "Agent", "name": "Karim Benali", "mbox": "mailto:karim.benali@formacampus.fr" }, "contextActivities": { "parent": [ { "id": "https://formacampus.fr/xapi/activities/module-soudure" } ], "grouping": [ { "id": "https://formacampus.fr/xapi/activities/cpjs-metallerie-2026" } ], "category": [ { "id": "https://formacampus.fr/xapi/profiles/atelier-presentiel" } ] }, "extensions": { "https://formacampus.fr/xapi/extensions/poste-soudure": "P12", "https://formacampus.fr/xapi/extensions/site": "Atelier Lyon-Est" } }

registration : l’UUID de la tentative

registration est un UUID qui identifie une inscription / une tentative à une activité. Son rôle : regrouper tous les statements produits pendant la même session d’apprentissage.

  • L’appli émet attempted, puis dix answered, puis completed et passed : si tous portent le même registration, le LRS (et ton tableau de bord) sait que c’est une tentative cohérente.
  • Une nouvelle tentative de la même activité par la même personne = un nouveau registration. On distingue ainsi « a repassé l’évaluation » de « premier passage ».

C’est le pendant xAPI de ce qu’on ne doit pas mettre dans l’id d’activité (chapitre 6.3) : le volatil (la session, la tentative) vit dans registration, pas dans l’id de l’activité.

contextActivities : parent, grouping, category

contextActivities rattache le statement à d’autres activités, selon trois relations :

RelationSensExemple FormaCampus
parentL’activité directement au-dessus dont fait partie l’objet.L’atelier appartient au module soudure.
groupingUn regroupement plus large, pas forcément direct.Le parcours métallerie 2026 englobant plusieurs modules.
categoryCe qui catégorise / caractérise le statement (souvent un profil xAPI).Le profil « atelier présentiel » qui cadre ce type de statement.

Ces relations sont ce qui permet de répondre à « montre-moi tout ce qu’a fait Léa dans le parcours métallerie » ou « agrège les résultats par module ». Sans elles, tu n’as que des phrases plates, sans hiérarchie.

💡 Réflexecategory est le champ où l’on déclare le profil xAPI que suit le statement (une convention de verbes et de structures pour un usage donné — évoqué en Partie 6). Quand tu adoptes un profil (cmi5, ou un profil maison documenté), tu le déclares en category : c’est ainsi qu’un outil sait « ce statement suit telles règles » et l’interprète correctement.

extensions : tes données, proprement rangées

extensions est l’échappatoire propre pour les données spécifiques à ton métier que le noyau ne prévoit pas : le numéro de poste de soudure, le site, la version de l’app, un identifiant de capteur… Les clés sont des IRI (comme les verbes), les valeurs sont libres (chaîne, nombre, objet JSON).

  • Avantage : tu enrichis sans polluer ni détourner les champs standard.
  • Règle : une clé = une IRI que tu contrôles (https://formacampus.fr/xapi/extensions/…), documentée. On peut mettre des extensions dans result et dans context selon que la donnée qualifie le résultat ou le cadre.

⚠️ Piège — Détourner un champ standard faute de connaître extensions. Mettre le numéro de poste dans result.response, ou le site dans le name de l’activité, corrompt des champs qui ont un sens précis et casse les rapports. Toute donnée maison va dans extensions, avec une clé IRI documentée. Jamais dans un champ standard « parce qu’il était libre ».

📚 La spec — Les sous-champs de result (score.scaled de -1 à 1, score.raw/min/max, success, completion, duration en ISO 8601, response) et de context (registration, instructor, contextActivities parent/grouping/category, extensions) sont définis par xAPI (ADL, adlnet.gov ; IEEE 9274.1.1 pour la 2.0). Les IRI d’extensions et de category (profils) sont des vocabulaires que tu déclares et documentes.

🧭 Sur FormaCampus — Le statement de l’atelier prend toute sa richesse. Léa réalise sa soudure : l’appli tablette émet un passed avec un result complet (scaled: 0.92, raw: 46/50, success: true, completion: true, duration: "PT1H15M", et en response la description du geste conforme). Le context fait le lien : registration regroupe cette tentative (si Léa repasse, ce sera un autre UUID) ; instructor nomme Karim qui atteste ; contextActivities.parent rattache l’atelier au module soudure, grouping au parcours métallerie 2026, category au profil « atelier présentiel » de FormaCampus ; et extensions note le poste P12 et le site Lyon-Est. Résultat : le tableau de bord de l’école peut afficher « progression de Léa dans le parcours métallerie », comparer les tentatives, filtrer par site — tout ça parce que le context a relié les phrases au lieu de les laisser flotter.

✏️ Exercices

Exercice 1 — Corrige le result. Un dev envoie ceci pour un score de 85 % obtenu en 20 minutes :

"result": { "score": { "scaled": 85 }, "duration": "20" }

Repère les deux erreurs et corrige.

✅ Solution

Deux erreurs : (1) scaled est un ratio de -1 à 1 → 85 % s’écrit 0.85, pas 85 (qui est hors plage, invalide) ; (2) duration est une chaîne ISO 8601, pas un nombre → 20 minutes = "PT20M", pas "20". Corrigé :

"result": { "score": { "scaled": 0.85, "raw": 85, "min": 0, "max": 100 }, "duration": "PT20M" }

On en profite pour ajouter raw/min/max : le score devient traçable et portable.

Exercice 2 — success vs completion. Un apprenant a parcouru entièrement l’évaluation mais a obtenu un score sous le seuil. Écris le result (score 0.55, seuil 0.7) et choisis le verbe cohérent.

✅ Solution

Il a terminé (completion: true) mais échoué (success: false). Verbe cohérent : failed.

"verb": { "id": "http://adlnet.gov/expapi/verbs/failed", "display": { "fr-FR": "a échoué" } }, "result": { "score": { "scaled": 0.55, "raw": 55, "min": 0, "max": 100 }, "completion": true, "success": false }

C’est le cas type « terminé mais raté » : les deux booléens sont indépendants, et le verbe (failed) confirme success: false. Les fusionner ferait perdre l’info « il est bien allé au bout ».

Exercice 3 — Relier une tentative. Léa fait une évaluation en trois écrans : elle répond à Q1, Q2, Q3 (trois statements answered), puis le module émet completed. Comment garantir que ces quatre statements sont vus comme une seule tentative, et comment distinguer une deuxième tentative plus tard ?

✅ Solution

On met le même context.registration (un UUID) sur les quatre statements : le LRS les regroupe alors comme une tentative cohérente. Pour une deuxième tentative (Léa repasse l’évaluation), on génère un nouveau registration : même acteur, même activité (même id), mais tentative distincte. C’est registration — et non l’id d’activité — qui porte le volatil de la session. Bonus : contextActivities.parent peut rattacher chaque answered à l’évaluation parente pour l’agrégation par activité.

🧠 Quiz de révision

1. Comment s’écrit un score de 78 % dans result.score ?

scaled: 0.78 (ratio de -1 à 1), idéalement accompagné de raw, min, max (ex. raw: 78, min: 0, max: 100). Jamais scaled: 78 : ce serait hors plage et invalide. scaled est un ratio décimal, pas un pourcentage entier.

2. Quelle différence entre success et completion ?

completion = a parcouru/achevé l’activité ; success = a atteint le seuil de réussite. Ils sont indépendants : on peut être completion: true + success: false (terminé mais raté). C’est la même distinction qu’en SCORM 2004. Il ne faut jamais les fusionner.

3. Écris « 1 heure 5 minutes » au format duration. Et pourquoi le T est-il crucial ?

PT1H5M. Le T sépare la partie date de la partie horaire : sans lui, P1H5M est invalide, et surtout P10M (sans T) signifie 10 mois alors que PT10M signifie 10 minutes. Le T est obligatoire devant heures/minutes/secondes.

4. À quoi sert context.registration ?

C’est l’UUID d’une tentative : il regroupe tous les statements produits pendant la même session d’apprentissage (un attempted, plusieurs answered, un completed…). Une nouvelle tentative = un nouveau registration. Le volatil de session vit ici, pas dans l’id d’activité.

5. Que mettre dans parent, grouping, category, et où rangerais-tu un numéro de poste de travail ?

parent = l’activité directement au-dessus (le module) ; grouping = un regroupement plus large (le parcours) ; category = ce qui catégorise le statement (souvent un profil xAPI). Un numéro de poste est une donnée maison → il va dans extensions, avec une clé IRI documentée, jamais dans un champ standard détourné.


Chapitre suivant : 6.5 — Le LRS — le magasin qui reçoit et sert tous ces statements : son API REST, l’immutabilité, le voiding, et pourquoi un LRS n’est pas un LMS.

Last updated on