Skip to content

Docs / How it works / Exercise sessions

How a session is built.

Ignia turns a goal into a structured course: a plan, a map of concepts, lessons, and exercises. That course is taught in scheduled sessions, and a session is a set of exercises on a handful of concepts, sized to the time you said you could give it.

This page is about how that set gets chosen. It is the question most people actually mean when they ask whether an AI learning app is any good, because it is where the pedagogy either happens or does not.

The short answer: the exercises are not a model's improvisation. A deterministic algorithm decides how many exercises, on which concepts, at which cognitive level and in which order, before any AI is called. The AI then writes the content for slots it cannot add to, remove from, reorder or escape.

Below: the mechanism, real output from the engine, and the places where it is not finished. For exact variable names, constants and data structures, see the session engine reference.

A word on vocabulary.

Three words carry most of this page.

  • Concept

    The smallest thing your course tracks: one idea, skill or fact, with its own cognitive level and its own retention state. A course has dozens.

  • Session

    One sitting. Some lesson content if there is new material, then a set of exercises. Its length is the one you chose, between fifteen and sixty minutes.

  • Slot

    One exercise-shaped hole in the plan: which concept, which cognitive tier, which types are allowed. The planner creates slots; the AI fills them.

Why the AI does not choose.

Ask a language model for "ten exercises on this topic" and you get a predictable failure: mostly multiple-choice, mostly recognition, all at the same level, drifting easier over time because easier questions are easier to write. Those are pedagogical decisions, and they are too consequential to leave to a text generator with no memory of what you have already been asked.

So the decisions are split. A pure function (same inputs, same output, no randomness beyond a fixed per-session seed) computes the exercise plan. The AI receives that plan and authors the content. If it returns an exercise of the wrong type, the response is rejected and regenerated with the exact error. The constraints are enforced, not requested.

The engine decides

Session length. How many exercises per concept. The cognitive level of each one. Which types are permissible. The scaffolding ladder. Where a misconception check or a transfer probe is inserted.

The AI writes

The question itself, the answer, the distractors, the worked context, and one bounded choice: which type to use among the ones the engine allows for that slot, so a language concept gets a word-order task and a history concept does not.

What the engine knows about you.

Before it computes anything, the engine assembles a snapshot of every concept in the session. Nothing here is an AI judgement. It is all measured from your answers.

  • Cognitive level

    What the concept requires of you: remember, understand, apply, analyze, evaluate or create. Set when the course is planned; you can override it.

  • Mastery band

    New, weak, developing or strong, derived from a durability model rather than from your last score.

  • Retention forecast

    The probability you would recall it right now, and whether that has decayed past its review target.

  • Recent lapses

    How many times you have missed it since your last success. This is the strongest single signal that a concept needs a different treatment.

  • Registered misconception

    Whether the grader has recorded a specific wrong idea on this concept, and the wording it recorded. Its own page: what happens to a wrong idea.

  • Transfer status

    Whether you have ever succeeded on a genuinely novel application of it, as opposed to a variation of something you trained on.

Those six signals are combined into a single struggle score per concept, weighted toward recent lapses. A concept you keep missing pulls more exercises, easier variants within its legal range, and more scaffolding. A concept you hold comfortably gets fewer and harder ones.

One note on how that weighting is kept alive. Weighting only has room to act while a session has more exercises than concepts to spend them on — and until recently it did not: one number sized both, so the session flattened to one exercise per concept as soon as a learner knew more concepts than their session length could hold, and the weighting had nothing left to distribute. A session now sizes the two separately: it aims at roughly two exercises per concept and touches correspondingly fewer concepts. A thirty-minute course session that used to spread seven exercises across seven concepts now puts them on about four. The weighting, the load reduction and the support ladder all keep something to act on however far into a course you are.

The six stages.

Every session is built the same way.

  1. 1

    Session budget. Your chosen session length sets a target count, roughly ten exercises for a thirty-minute practice session, scaled linearly and clamped between half and double. If you are struggling across the board, the session is shortened by twenty percent rather than being allowed to become a slog.

  2. 2

    Share it out. The budget is split across the session's concepts by need: struggle, plus an extra weight if the concept is due for review and its forecast recall has dropped. Every concept in the session is guaranteed at least one exercise, even when that means going slightly over budget.

  3. 3

    Choose the cognitive mix. Each cognitive level has a base distribution across six tiers: recall, recognition, cued recall, procedural, analysis, production. An apply concept sits mostly in procedural work; a create concept sits almost entirely in production. Your chosen course depth tilts that distribution up or down.

  4. 4

    Round to whole exercises. Stage 3 produced percentages, but you cannot serve part of an exercise. Take a real case: an apply concept with three exercises and a mix of 70% procedural, 16% analysis, 14% production. That is 2.10, 0.48 and 0.42 exercises. Round each one down and one exercise is left unassigned; round each to the nearest and you get 2, 0, 0, so both minority tiers vanish and the session becomes purely procedural. Instead the leftover goes to whichever tier came closest to earning another whole exercise, here analysis at 0.48. Final answer: 2 procedural, 1 analysis. The rule is called largest-remainder apportionment, the same one used to turn vote shares into parliamentary seats.

  5. 5

    Pick the permissible types. Each tier contains several exercise types. The engine filters out anything below the concept's cognitive floor, enforces the multiple-choice cap, and hands the AI the surviving set. A single-type set means the type is forced.

  6. 6

    Scaffolding and inserts. A support ladder is assigned per slot, and extra exercises may be appended, at most two of each: a misconception check for a concept you hold a recorded wrong idea about, and a transfer probe for a concept you are strong on but have never demonstrated in a new context.

The transfer probe.

This one shows up in the tables below and deserves its own explanation, because it is the least obvious thing the engine does.

Getting good at the exercises you have been given is not the same as understanding the concept. Practise enough variations of one problem shape and you get fast at that shape, which feels exactly like mastery from the inside and collapses the moment the problem is posed differently. This is the most common way a learner is fooled about their own level, and an app that only ever tests you on the material it trained you on will confirm the illusion rather than catch it.

So before the app is willing to call a concept mastered, it wants one success on a structurally new application: a task in a context you have not met on that concept, not a re-skin of a trained item with the numbers changed. That is the transfer probe.

  • When it fires. On a concept you are already strong on, that has never passed a probe, and whose target level is apply or above. Not on new or weak concepts, where transfer is not yet the question, and not on concepts you only need to recall or explain, where a "new context" would not mean anything.
  • What it looks like. One extra open-answer exercise appended to the session, with the AI instructed to pose a genuinely new application rather than a surface paraphrase.
  • How often. Every session on that concept until you pass it once, then never again. It cannot nag you forever, and it cannot be quietly skipped either.
  • What it is not. It is not graded against you and it lowers nothing. It is a piece of evidence the mastery model wants before it accelerates you.

Two honest caveats. The probe is currently additive, so it lengthens the session rather than replacing an exercise, and it is not capped; both are listed under limits below. And the gate that would actually withhold "mastered" until a probe passes is built but deliberately switched off, pending a check that the questions the AI writes are genuinely novel.

The glossary your course builds.

Every lesson, at the moment its content is written, also lists the terms that lesson introduces: the named concepts, with a short self-contained definition and, where a usage sentence helps, an example. Those terms go into a glossary that belongs to the course.

The glossary is durable, which the exercises are not. Exercises are rebuilt from scratch every session. The glossary is only ever added to: a later lesson contributes its own terms, and nothing is thrown away. A term, once banked, stays for the life of the course.

It is not only there to read. Some of your exercises are written from it, on your device, with no AI call at all. Two types today: flashcards, and matching sets drawn from the terms of one concept. The generator is deterministic and seeded, so the same session state reproduces the same items, and the window it draws from rotates between sessions: a term met as a matching pair this week comes back as a flashcard next.

Because that generation is code rather than a model, the usual failure mode is gone by construction. A flashcard's answer cannot appear on its own front or in its hint, and a matching set's right-hand column is exactly the definitions of the same terms it lists on the left, so there is no external distractor to leak anything. If a session's slots are all covered by the glossary, that session reaches you without a single AI call.

There is one more thing it does, and it needed almost no machinery. A list of terms beside their definitions is already something people test themselves on — you cover the right-hand column with your hand and work down the left. A page that prints the answer next to every prompt takes that away. So the glossary can now hide its definitions: the terms stay as prompts, and each card gives its own meaning back when you ask for it.

One card at a time, and that part is deliberate. A single button that unhid everything would end the exercise at the first term you wanted to check, and the page would be a list to read again. Revealing per term keeps the sequence that does the work: try, then reveal, then judge for yourself. Nothing about it is recorded — no score, no count, no streak — because it is your own check, not ours, and reading mode stays the default so someone who came to look a word up still finds it.

Three limits worth stating. The glossary is read-only today: you can hide what it banked and test yourself against it, but you cannot change it — no correcting a definition you think is wrong, no marking a term as one you already knew. A glossary entry carries one relation, a term and its meaning, so it can only feed the lower rungs of the ladder. Everything that asks you to apply, analyse or produce is authored against the plan, not drawn from the glossary.

And the third follows from the second, which is why we would rather say it than let you infer the opposite. A session's slots are allocated by the level of the concept being worked, and a concept pitched at apply or above is allocated no recall or recognition slot at all. So on a course built entirely of demanding concepts, the glossary is written and never handed back to you in an exercise — its terms are still there to read on the glossary page, but nothing draws on them. We think that is wrong, for a reason worth being plain about: the vocabulary of a demanding concept is not decoration, it is a part you have to have ready before you can use the concept at all. It is on the list to fix, and this page will say so when it is.

Worked examples.

Everything in these tables is real output from the engine, produced by running the planner on constructed learner states. They are not illustrations written by hand.

All the examples use one running course, a short introduction to statistics, so you can compare them against each other. Five concepts, each carrying the level its objective demands:

ConceptTarget levelWhat it asks of you
mean-vs-medianrememberKnow what each one is.
when-to-use-medianunderstandExplain why a skewed distribution changes the answer.
compute-std-devapplyCarry out the calculation on data you have not seen.
spot-misleading-chartanalyzeTake a chart apart and find what it distorts.
critique-a-studyevaluateJudge whether a study supports the claim it makes.

The target level is set when the course is planned and you can change it. It is the single input with the most influence on what a session looks like, which is where these examples start.

What the target level changes

One concept, one learner, a budget of five exercises. Same mastery, same history, same everything. Only the level the concept aims at changes.

Target levelThe five exercises the engine produces
rememberflashcard flashcard mcq word_order word_order
understandmcq word_order word_order word_order code_bug_spot
applycode_trace code_trace code_trace code_trace code_bug_spot
analyzecode_bug_spot code_bug_spot code_bug_spot code_bug_spot writing
evaluatewriting writing writing writing writing
createwriting writing writing writing writing

This is the whole design in one table. A remember concept gets recall and recognition work. Push the same concept to apply and recall disappears entirely, because answering a flashcard would no longer be evidence of the thing being claimed. At evaluate the session is written work only: there is no way to demonstrate judgement by picking from a list. The level does not make a session harder in some vague sense. It changes what counts as evidence.

Two things this table exposes, both real, and both listed under limits below. evaluate and create produce identical plans. And the apply and analyze rows are full of code exercises on a statistics concept. That second one is not a stray preference: on any analyze-level concept, in any subject, code_bug_spot is the engine's default in four or five slots out of six, because it sits in the analysis tier for every course rather than only for courses about code. The AI is expected to pick something else from the offered set, and the prompt tells it to, but the engine should not be proposing these here at all. We are showing you the tables the planner actually produced rather than fixtures chosen to look better.

A first session on new material

The first four concepts, all brand new. Thirty-minute course session, course depth "deep practical", target seven exercises.

#ConceptLevel · stateType usedTypes the AI could choose fromSupport
1mean-vs-medianremember · newword_orderword_order short_answer fill_blankfaded
2when-to-use-medianunderstand · newshort_answershort_answer fill_blank word_orderfaded
3when-to-use-medianunderstand · neworderingordering categorize short_answersolo
4compute-std-devapply · newsolve_equationsolve_equation fill_blank numeric_answer code_tracefaded
5compute-std-devapply · newcode_tracecode_trace fill_blank solve_equation numeric_answersolo
6spot-misleading-chartanalyze · newshort_answershort_answer ordering categorizefaded
7spot-misleading-chartanalyze · newwritingwriting code_bug_spot short_answersolo

Read the Support column down the page. Each concept opens faded — the first exercise on something you have never seen hands you part of the work — and then the support is taken away on the next one. That withdrawal is the point of the ladder; being handed part of the work every time would leave you with nothing to show that you can do it unaided. Notice too that the four concepts sit at different tiers within the same session, each at the level its own objective demands.

One concept here never gets its unaided turn: seven exercises across four concepts cannot be split evenly, and mean-vs-median draws the single slot. That is a known limit of the split, not a judgement about the concept, and it is listed under limits below.

A mixed session

Later in the course. One concept you are weak on, one coming along, one you hold well. Thirty-minute practice session, target ten.

#ConceptLevel · stateType usedTypes the AI could choose fromSupport
1compute-std-devapply · weakcode_tracecode_trace fill_blank solve_equation numeric_answerfaded
2compute-std-devapply · weaknumeric_answernumeric_answer fill_blank solve_equation code_tracesolo
3compute-std-devapply · weakfill_blankfill_blank numeric_answer solve_equation code_tracesolo
4compute-std-devapply · weakorderingordering categorize code_bug_spotsolo
5compute-std-devapply · weakcode_bug_spotcode_bug_spot short_answersolo
6when-to-use-medianunderstand · developingmcqmcq matchingfaded
7when-to-use-medianunderstand · developingword_orderword_order short_answer fill_blanksolo
8when-to-use-medianunderstand · developingcode_bug_spotcode_bug_spot ordering categorizesolo
9critique-a-studyevaluate · strongwritingwriting forcedsolo
10critique-a-studyevaluate · strongwritingwriting code_bug_spot short_answersolo
11critique-a-studyevaluate · strongshort_answer transfer probeshort_answer forcedsolo

The weak concept takes half the session, and only its first exercise is scaffolded. The strong one gets two exercises, both written work, because its level is evaluate and nothing below writing would count. Since it has never passed a transfer check, an eleventh exercise is appended asking it to be applied to a study it has not seen. Note the session ran to eleven against a budget of ten: the probe is additive, capped at two per session.

The same state as an exam

Identical concepts, identical learner, but a graded exam instead of practice. Target eight.

#ConceptLevel · stateType usedTypes the AI could choose fromSupport
1compute-std-devapply · weakcode_tracecode_trace fill_blank solve_equation numeric_answersolo
2compute-std-devapply · weaknumeric_answernumeric_answer fill_blank solve_equation code_tracesolo
3compute-std-devapply · weakorderingordering categorize code_bug_spotsolo
4when-to-use-medianunderstand · developingmcqmcq matchingsolo
5when-to-use-medianunderstand · developingword_orderword_order short_answer fill_blanksolo
6when-to-use-medianunderstand · developingcode_bug_spotcode_bug_spot ordering categorizesolo
7critique-a-studyevaluate · strongwritingwriting forcedsolo
8critique-a-studyevaluate · strongwritingwriting code_bug_spot short_answersolo

Compare it line by line with the mixed session above. Every slot is solo: no scaffolding on any concept, including the weak one. The transfer probe is gone, and so would a misconception check be. And the counts have flattened to three, three and two instead of five, three and two, because an exam weights concepts uniformly rather than by how much you need them.

That last point is the one that matters. A graded assessment must not be quietly softened by what the app knows you are weak on, so your performance history is withheld from the generator entirely for exams, along with your stated learning preferences. An exam measures you; it does not help you.

A review session on the same state sits between the two. It keeps the adaptation and the scaffolding but tilts the mix half a notch down, toward retrieving what you know rather than stretching past it. On this state the only visible change is the weak concept's fourth exercise, which moves from analysis back to procedural work.

A struggling learner

Three concepts, all with repeated recent failures. Target was ten.

#ConceptLevel · stateType usedTypes the AI could choose fromSupport
1compute-std-devapply · weaknumeric_answernumeric_answer fill_blank solve_equation code_tracefaded
2compute-std-devapply · weaknumeric_answernumeric_answer fill_blank solve_equation code_tracefaded
3compute-std-devapply · weakcategorizecategorize ordering code_bug_spotfaded
4spot-misleading-chartanalyze · weakcategorizecategorize ordering code_bug_spotfaded
5spot-misleading-chartanalyze · weakcategorizecategorize ordering code_bug_spotfaded
6spot-misleading-chartanalyze · weakshort_answershort_answer code_bug_spot writingfaded
7when-to-use-medianunderstand · weakmatchingmatching mcqfaded
8when-to-use-medianunderstand · weakword_orderword_order short_answer fill_blankfaded

Eight instead of ten, and every single slot scaffolded. The engine also switched its within-tier preference to the lowest-load type available, which is why numeric_answer and categorize lead here where code_trace led in the earlier tables. Nothing drops below each concept's cognitive floor: the struggling apply concept still gets apply-level work, in its gentlest form, with support, and less of it. Struggling is not treated as a reason to demote you to multiple choice.

Where the inserts appear

One concept you hold a recorded wrong idea about, one strong concept never verified in a new context. Target six.

#ConceptLevel · stateType usedTypes the AI could choose fromSupport
1when-to-use-medianunderstand · weakmatchingmatching mcqfaded
2when-to-use-medianunderstand · weakfill_blankfill_blank short_answer word_ordersolo
3when-to-use-medianunderstand · weakfill_blankfill_blank short_answer word_ordersolo
4when-to-use-medianunderstand · weakcategorizecategorize ordering code_bug_spotsolo
5when-to-use-medianunderstand · weaktrue_false misconception checktrue_false forcedsolo
6compute-std-devapply · strongcode_tracecode_trace fill_blank solve_equation numeric_answersolo
7compute-std-devapply · strongcode_tracecode_trace fill_blank solve_equation numeric_answersolo
8compute-std-devapply · strongshort_answer transfer probeshort_answer forcedsolo

Both inserts have a forced type and sit outside the normal quota, which is why eight exercises came out of a budget of six. True-or-false is never used as a regular exercise type in Ignia, because it is too easy to guess. It appears only here, where the false statement is written to encode the specific wrong idea you have shown, so answering correctly means rejecting your own error rather than recognising a fact.

What is guaranteed.

These hold by construction, not by asking the model nicely. They are enforced in the planner and re-checked when the AI's output comes back.

  • Never below the concept's level. An exercise type that would measure a lower competence than the concept claims is filtered out of the permissible set, so no AI choice can reach it.
  • Multiple choice capped at thirty percent. Enforced on the offered set, not just on the engine's own picks: once the cap is spent, multiple choice is removed from every remaining slot.
  • At least three different types in any session with three or more exercises.
  • A written exercise for every evaluate or create concept. Forced, with no alternative offered, because you cannot demonstrate "create" by picking from a list.
  • True-or-false only as a misconception check. Never a quota type.
  • Exams are mastery-blind. No adaptation, no scaffolding, no inserts, uniform counts.
  • Reproducible. Same state and same session seed produce the same plan, so it can be re-derived and audited after the fact.

Honest limits.

Parts of this mechanism are built but not fully connected. They are set out here because a guarantee you cannot check is not a guarantee.

  • On most exercise types, the "why" is still optional. Five of the fourteen types are graded by a language model and always come back with an explanation and a next step. Five of the nine graded by exact comparison now have somewhere to put a one-sentence explanation, and it is required on the misconception check — but on the other four there is nowhere to put one, and where the field exists a model may still leave it empty. The app no longer papers over that: a miss with no explanation now shows no explanation, rather than restating the answer already marked on your screen. Requiring it more widely is queued.
  • When the exercises do not divide evenly, one concept misses its unaided turn. A session aims at about two exercises per concept, but the two budgets are computed separately and need not divide: a thirty-minute course session writes seven exercises across four concepts, so three concepts get two and one gets a single exercise. A concept with one exercise only ever reaches the scaffolded rung — the support is never withdrawn on it, which is the same gap as the item above, now confined to one concept per uneven session. Which concept draws the short straw is a property of the split rather than a judgement about the concept. The fix is to settle how many exercises a concept should aim for, and it wants real usage data rather than a guess.
  • Course depth does nothing on the highest concepts. For "evaluate" and "create" concepts, all four depth settings produce an identical plan. The cognitive floor already pins them to production tier, so there is nothing left for depth to tilt. Depth needs to reach a different lever there.
  • One exercise type is over-specialised and leaks everywhere. code_bug_spot asks you to find the fault in a piece of code. It belongs in the analysis tier of a programming course and nowhere else, but it currently sits in that tier for every course, so on an analyze-level concept it is the engine's default in four or five slots out of six regardless of subject. The competence it tests, finding and fixing a flaw, is genuinely valuable and general; the exercise is the code-specific version of it. The fix is to make the general version the default and keep the code one for code courses.

Each of these is described with its exact location in the session engine reference.

Related.

The exercise types page covers what each of the fourteen types tests and how it is graded. The session engine reference gives the exact functions, constants and data structures. The course modification map places session generation in the wider system.