fix(scorm): mark Welcome page unmarkForCompletion so LMS completion reports#5
Merged
Conversation
…eports The 0.0.3 release reported 0% completion to an LMS even though the learner finished every quiz. Root cause, traced through the HAR of a real attempt plus Xerte's xttracking_scorm1.2.js + xenith.js: with navigation="Menu with Page Controls", Xerte inserts a built-in Table-of-Contents page as x_pages[0] AFTER toCompletePages is built from currActPage over the 43 content nodes. So every content page's page_nr (used by exitInteraction to mark completedPages[i]) is currActPage + 1 -- a systematic off-by-one: - toCompletePages[0] == 0 could only be matched by page_nr == 0 (the menu), which is never exited (menu pages are excluded from x_endPageTracking), so completedPages[0] (the first content page, "Welcome") stayed false forever. - getSuccessStatus() returns 'incomplete' whenever any completedPages[i] is false, so finishTracking() set cmi.core.lesson_status='incomplete' (a no-op against Moodle's pre-set 'incomplete'), and the LMS never left the incomplete state. cmi.core.score.raw WAS being sent (75, then 100) but never mattered to the displayed completion. Changes to source/data.xml + source/preview.xml (identical): - unmarkForCompletion="true" on the Welcome page (linkID="PG1781882348053"). This makes markedPages skip currActPage == 0, so toCompletePages becomes [1,2,...,42], aligning with the content pages' page_nr values. completedPages[0] (Welcome) is now marked true when the learner leaves it. Validated end-to-end through a running XOT (docker-container branch) instance on host port 8088: - Pushed source/data.xml + source/preview.xml into the container; both carry unmarkForCompletion="true" on the Welcome page and are byte-identical to the repo source. - play.php?template_id=1 returns 200; HTML5 editor opens. - SCORM export is valid SCORM 1.2 (one SCO, 13 MB) and the exported template.xml carries unmarkForCompletion="true", trackingMode="full", trackingWeight 1x7 + 21, trackingPassed="80%", 45 questions, 8 quizzes, 0 empty options -- all unchanged from 0.0.3 except the fix. - Drove the exported package against a SCORM 1.2 mock API: a completed run sends cmi.core.lesson_status="passed" (score.raw=100), a failing run sends lesson_status="failed" (score.raw=62.5), and an incomplete run sends lesson_status="incomplete" + cmi.core.exit="suspend". Before the fix the completed run reported "incomplete". Trade-off: the Final quiz (page_nr == 43) is still outside toCompletePages (no index 43), so its completion is not tracked in completedPages -- but its score is still tracked via its interactions and trackingWeight="21", so the LMS grade and pass/fail are correct. The Welcome page is no longer "required" for completion, which is acceptable for an intro page. A proper fix would be in the Xerte engine (xenith.js: build toCompletePages from page_nr after the menu is inserted), but that would not survive XOT rebuilds; this content-level workaround is used because the release workflow builds from the XOT engine. Do not remove unmarkForCompletion="true" from the Welcome page without a replacement fix -- re-introducing the off-by-one will silently break LMS completion reporting again. Guidance updates: - docs/PROJECT_CONTEXT.md: added "SCORM completion bug fix" section documenting the root cause, fix, and trade-off; noted the Welcome page carries unmarkForCompletion="true" in the current-state list. - docs/COURSE_VERIFICATION.md: added "LMS completion fix (post-0.0.3)" section with the HAR evidence, root cause, fix, and validation results. Generated with pi 0.80.3 and GLM 5.2
📖 Course content previewDownload the
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The 0.0.3 release reported 0% completion to an LMS even
though the learner finished every quiz. Root cause, traced through the
HAR of a real attempt plus Xerte's xttracking_scorm1.2.js + xenith.js:
with navigation="Menu with Page Controls", Xerte inserts a built-in
Table-of-Contents page as x_pages[0] AFTER toCompletePages is built
from currActPage over the 43 content nodes. So every content page's
page_nr (used by exitInteraction to mark completedPages[i]) is
currActPage + 1 -- a systematic off-by-one:
menu), which is never exited (menu pages are excluded from
x_endPageTracking), so completedPages[0] (the first content page,
"Welcome") stayed false forever.
is false, so finishTracking() set cmi.core.lesson_status='incomplete'
(a no-op against Moodle's pre-set 'incomplete'), and the LMS never
left the incomplete state. cmi.core.score.raw WAS being sent (75, then
100) but never mattered to the displayed completion.
Changes to source/data.xml + source/preview.xml (identical):
(linkID="PG1781882348053"). This makes markedPages skip currActPage
== 0, so toCompletePages becomes [1,2,...,42], aligning with the
content pages' page_nr values. completedPages[0] (Welcome) is now
marked true when the learner leaves it.
Validated end-to-end through a running XOT (docker-container branch)
instance on host port 8088:
carry unmarkForCompletion="true" on the Welcome page and are
byte-identical to the repo source.
template.xml carries unmarkForCompletion="true", trackingMode="full",
trackingWeight 1x7 + 21, trackingPassed="80%", 45 questions, 8
quizzes, 0 empty options -- all unchanged from 0.0.3 except the fix.
run sends cmi.core.lesson_status="passed" (score.raw=100), a failing
run sends lesson_status="failed" (score.raw=62.5), and an incomplete
run sends lesson_status="incomplete" + cmi.core.exit="suspend".
Before the fix the completed run reported "incomplete".
Trade-off: the Final quiz (page_nr == 43) is still outside
toCompletePages (no index 43), so its completion is not tracked in
completedPages -- but its score is still tracked via its interactions
and trackingWeight="21", so the LMS grade and pass/fail are correct.
The Welcome page is no longer "required" for completion, which is
acceptable for an intro page. A proper fix would be in the Xerte engine
(xenith.js: build toCompletePages from page_nr after the menu is
inserted), but that would not survive XOT rebuilds; this content-level
workaround is used because the release workflow builds from the XOT
engine. Do not remove unmarkForCompletion="true" from the Welcome page
without a replacement fix -- re-introducing the off-by-one will silently
break LMS completion reporting again.
Guidance updates:
documenting the root cause, fix, and trade-off; noted the Welcome
page carries unmarkForCompletion="true" in the current-state list.
section with the HAR evidence, root cause, fix, and validation
results.
Generated with pi 0.80.3 and GLM 5.2