What is a Learning Session?
# Learning Sessions (Learning Units)
Last Updated: 2026-09-04 | For: Teachers & Content Creators | Level: Advanced
What is a Learning Session?
A learning session is a unit where MoFaCTS uses AI-style adaptive scheduling, implemented through configurable cognitive memory models and probability calculations, to select which question to show the student next. Unlike assessment sessions (which have a fixed sequence), learning sessions continuously adapt based on:
- Student's correct and incorrect answers
- Time since last seeing each question
- Overall performance trends
- Spacing and retention intervals
This supports the testing effect by giving learners repeated retrieval practice and concentrating practice on items that the model predicts need more work.
A learning unit may also include unitinstructions; these display before adaptive practice. For a screen with only instructions and no practice items, omit learningsession and use an instruction-only unit instead.
When to Use Learning Sessions
Use learning sessions for:
- Practice and review activities
- Long-term retention training
- Adaptive flashcard-style learning
- Mastery-based learning
Don't use learning sessions for:
- Standardized tests (use assessment sessions instead)
- Fixed-order tutorials
- Pre/post tests requiring consistent ordering
Learning Session Configuration
Prerequisites: understand Stimulus Files, Trial Types Reference, and Learning Algorithms Reference before customizing adaptive behavior.
Resume and Persistence Behavior
Learning sessions now resume from committed history rather than a persisted per-card cache.
- After each completed trial, the canonical saved record is the history row for that trial.
- On resume, MoFaCTS reconstructs learning state from history and recomputes probabilities fresh.
- The next card shown after resume may differ from the card that was on screen before reload if forgetting or other time-sensitive model inputs have changed.
- If a card was displayed but not answered before reload, there is no new committed history for that card, so the unit restarts from its deterministic unit-start state and current history.
Learning sessions are configured in a unit using the learningsession tag:
| Fields | Default | Explanation |
|---|---|---|
| clusterlist | not specified | This is a consecutive list of x-y pairs indicating the sequential chunks of clusters. All stimuli in each cluster are always used in learning sessions. For example, 0-6 12-17 would indicate the first 7 items, followed by items 13 to item 18. The example 12-17 0-6 is invalid, since it is nonsequential. |
| unitMode | unspecified | This is the selection algorithm that specifies a method to select the next item to display for the learning session. Thresholdceiling and distance are current options described below. |
| calculateProbability | not specified | A JavaScript-like mathematical body executed by MoFaCTS's bounded interpreter. It must set p.probability to a finite value from 0 through 1 and end with return p. It may compose approved numeric/history inputs, Math primitives, and pFunc helpers, but it cannot use arbitrary JavaScript. Invalid formulas fail validation and are never executed as JavaScript. |
displayMinSeconds |
0 | Set this in deliverySettings; minimum time before the learner may continue from a timed learning unit. |
displayMaxSeconds |
0 | Set this in deliverySettings; maximum time before a timed learning unit advances automatically. |
Learning-session deliverySettings are documented in Content Creation Reference Tables.
Progressive Course Practice
Course Assignments can combine compatible lessons into an ordered progressive lesson. Every member must contain exactly two units: Unit 1 is an instruction unit and Unit 2 is a named learning session. The Unit 2 clusterlist must select valid canonical stimulus clusters, and maxTrials and practiceseconds must be zero or omitted so practice can continue indefinitely.
When a student chooses progressive practice through a particular member, MoFaCTS combines that member with all earlier members. It uses the selected member's Unit 1 instructions and Unit 2 learning model/settings, merges clusters with the same normalized clusterKC, and keeps distinct stimuli separate using the pair stimuliSetId + stimulusKC.
Every saved trial retains its original member TDF, stimulus-set, item, cluster, and Unit 2 identity. As a result, trials completed in the combined runtime reappear when that original lesson is later opened individually. There is no progressive completion state; teachers may change membership or ordering without rewriting or deleting prior learner history.
learningsession is for units that should generate adaptive practice trials. If the intended unit is only a transition, explanation, consent, or completion screen, use an instruction-only unit with instruction fields and no learningsession object.
For first-introduction behavior, deliverySettings.studyFirst can be set to a probability from 0 to 1 to control how often newly introduced items begin with a study trial instead of a normal drill trial. 0 means never, 1 means always, and values such as 0.1, 0.5, or 0.9 give that proportion of first introductions a study trial.
- A
calculateProbabilityformula receives a data-only snapshot. Raw stimulus/response objects, browser/server globals, DOM, Meteor, network APIs, and credentials are never exposed. - Formulas may use numeric literals, comments, parentheses, semicolons,
let/constnumeric locals, arithmetic, comparisons, Boolean logic, ternaries, and boundedif/elsestatements. - Approved array inputs support numeric indexing,
.length, and.slice(). Every helper exposed by the MoFaCTS probability runtime is supported:testFunction,mul,logitdec,recency,quaddiffcor,quaddiffincor,linediffcor,linediffincor,arrSum,errlist,componentSpacing,spacingLagged,ppew,ppet,ppetw,slideppetw,ppes, andppesFromTimes. All deterministic ECMAScript 2022Mathconstants and functions may be freely composed;Math.randomremains prohibited. - A formula may assign
p.probability, optional Booleanp.available, and author-named numeric/Boolean/short literal-string diagnostics. Model inputs are read-only. - Loops, functions, callbacks, recursion, objects/classes,
new, imports, async work, computed-property escapes, prototypes/constructors, randomness, andeval/Functionare rejected with a field-path and line/column error.
| Description | Variable | Assignment | Explanation |
|---|---|---|---|
| Current Indices | p.clusterIndex | cardIndex | The current index of the cluster. |
| p.stimIndex | stimIndex | The current index of the stimulus. | |
| Top-level metrics | p.userTotalResponses | cardProbabilities. numQuestionsAnswered | The total number of questions answered by the user. |
| p.userCorrectResponses | cardProbabilities.numCorrectAnswers | The total number of correct answers given by the user. | |
| Card/cluster metrics | p.questionSuccessCount | card.priorCorrect | The count of successful questions. |
| p.questionFailureCount | card.priorIncorrect | The count of failed questions. | |
| p.questionTotalTests | p.questionSuccessCount + p.questionFailureCount | The total number of question tests. | |
| p.questionStudyTrialCount | card.priorStudy | The count of study trials for the question. | |
| p.questionSecsSinceLastShown | elapsed (card.lastSeen) | Seconds since the question was last shown. | |
| p.questionSecsSinceFirstShown | elapsed (card.firstSeen) | Seconds since the question was first shown. | |
| p.questionSecsPracticingOthers | secs (card.otherPracticeTime) | Seconds spent practicing other questions. | |
| Stimulus/cluster-version metrics | p.stimSecsSinceLastShown | elapsed (stim.lastSeen) | Seconds since the stimulus was last shown. |
| p.stimSecsSinceFirstShown | elapsed (stim.firstSeen) | Seconds since the stimulus was first shown. | |
| p.stimSecsPracticingOthers | secs (stim.otherPracticeTime) | Seconds spent practicing other stimuli. | |
| p.stimSuccessCount | stim.priorCorrect | The count of successful stimuli. | |
| p.stimFailureCount | stim.priorIncorrect | The count of failed stimuli. | |
| p.stimStudyTrialCount | stim.priorStudy | The count of study trials for the stimulus. | |
| p.responseSuccessCount | p.resp.priorCorrect | The count of successful responses. | |
| p.responseFailureCount | p.resp.priorIncorrect | The count of failed responses. | |
| p.responseOutcomeHistory | JSON.parse(JSON.stringify (p.resp.outcomeStack)) | The outcome history of the response, deep-copied. | |
| p.responseSecsSinceLastShown | elapsed (p.resp.lastSeen) | Seconds since the response was last shown. | |
| p.responseStudyTrialCount | p.resp.priorStudy | The count of study trials for the response. | |
| Cluster metrics | p.clusterPreviousCalculatedProbabilities | JSON.parse(JSON.stringify(card.previousCalculatedProbabilities)) | Previously calculated probabilities for this cluster. |
| Cluster metrics | p.clusterOutcomeHistory | JSON.parse(JSON.stringify(card.outcomeStack)) | Outcome history for this cluster. |
| Cluster metrics | p.stimParameters | stimCluster.stims[stimIndex].params.split(',').map((x) => _.floatval(x)) | Parsed numeric params for the current stim. |
| Cluster metrics | p.stimOutcomeHistory | JSON.parse(JSON.stringify(stim.outcomeStack)) | Outcome history for the current stim version. |
| Cluster metrics | p.overallOutcomeHistory | Session-derived from committed history | Outcome history available to the probability model at runtime. |
| Cluster metrics | p.overallStudyHistory | Session-derived from committed history | Practice order array with 1 for studies and 0 for drills. |
Set p.available = false to make the current stimulus unavailable to the selection algorithm.
Starter calculateProbability model
For authors who want a practical starting point, this model is a reasonable default for many standard practice lessons:
p.y = -0.77 + .665 * pFunc.logitdec( p.overallOutcomeHistory.slice( Math.max(p.overallOutcomeHistory.length-60, 0), p.overallOutcomeHistory.length), .966)+ .51* (p.stimSuccessCount) + 11.1 * pFunc.recency(p.stimSecsSinceLastShown, .443) ; p.probability = 1.0 / (1.0 + Math.exp(-p.y)); return p
This form was adapted from a multiday high school practice experiment supported by NSF and is included here as a useful authoring baseline rather than a universal best model.
Example of Learning session unit:
{
"unitinstructions": "<p>Welcome to MoFaCTS! </p>\n <p>How it Works: fill-in-the-blank to complete each sentence from your textbook. MoFaCTS helps you practice - you are not graded on your performance, and it expects you to get answers wrong. MoFaCTS automatically moves on to the next flashcard so you can keep practicing at a good pace, and come back to difficult ones later.</p>\n <p>Progress: The Progress page shows how much practice you have done and how well you have learned the material to help you decide if you should keep practicing.</p>\n <p>Audio Settings: You can silently read and type your answers, or the system can read the questions out loud and detect your spoken answers.</p>\n <p>Practice Tips</p>\n <ul>\n <li>Read your textbook before using MoFaCTS</li>\n </ul>\n <ul>\n <li>Use the Refutation and Dialogue Feedback if you need help learning why you got an answer wrong</li>\n <li>This is not a test! It’s ok to get answers wrong. The system will help you practice those items.</li>\n <li>If you have any technical problems, use the “Report Error” button to automatically alert the programmers about your issue.</li>\n </ul>",
"unitname": "Learning unit",
"learningsession": {
"clusterlist": "0-77",
"unitMode": "distance",
"calculateProbability": "p.y = -0.77 + .665 * pFunc.logitdec(p.overallOutcomeHistory.slice(Math.max(p.overallOutcomeHistory.length - 60, 0), p.overallOutcomeHistory.length), .966) + .51 * p.stimSuccessCount + 11.1 * pFunc.recency(p.stimSecsSinceLastShown, .443); p.probability = 1 / (1 + Math.exp(-p.y)); return p"
},
"deliverySettings": {
"allowPhoneticMatching": "true",
"studyFirst": "0.5",
"drill": "30000",
"purestudy": "16000",
"skipstudy": "false",
"reviewstudy": "6000",
"correctprompt": "750",
"fontsize": "24"
}
}
unitModes
'distance' using function selectCardAndHintClosestToOptimalProbability
Pick the item closest to optimal probability, where distance is measured in logit units (which solves problems with probability having a cieling).
'thresholdcieling' using function selectCardAndHintBelowOptimalProbability
Pick the item closest to the optimal probability, but below
See Also
- Learning Algorithms Reference - Probability model and unitMode details
- Content Creation Reference Tables - Delivery settings
- Assessment Sessions - Fixed-order tests and quizzes
- Trial Types Reference - Understanding d, t, s, m, n, i, f trial types
- Troubleshooting - Canonical issue triage
Operational Validation
- Validate at least one real student launch for this unit.
- Verify intended response/timing behavior in Data Output rows.
- If media is used, verify canonical media references resolve during runtime.