Skip to documentation

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 calculateProbability formula 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/const numeric locals, arithmetic, comparisons, Boolean logic, ternaries, and bounded if/else statements.
  • 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, and ppesFromTimes. All deterministic ECMAScript 2022 Math constants and functions may be freely composed; Math.random remains prohibited.
  • A formula may assign p.probability, optional Boolean p.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, and eval/Function are 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&rsquo;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 &ldquo;Report Error&rdquo; 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

Operational Validation

  1. Validate at least one real student launch for this unit.
  2. Verify intended response/timing behavior in Data Output rows.
  3. If media is used, verify canonical media references resolve during runtime.