CFA lessons on Oncourse
What a lesson looks like section by section, what each section is for, the candidate evidence behind it, and how the pipeline makes sure every lesson actually has it.
19 Sep 2026 · 36 v3 lessons live on staging (app and web) · generator on API branch feat/cfa-lesson-v3, renderer merged to app dev (PR #1910) · 2027 curriculum · screenshots are real Oncourse staging captures
The idea
Candidates told us, across roughly 250 forum threads, that they do not want more content. They want compression without information loss: one LOS per unit, 10 to 20 minutes, one worked example, immediate practice with a reason for every wrong option, calculator steps, and a summary layer they can revise from. Every praised provider tags by LOS; none of our 50 earlier drafts did. That research is the spec.
- Unit of teaching: our existing subject → topic → chapter hierarchy. In the 2027 seed each chapter maps to exactly one LOS, so a chapter lesson teaches one LOS in about 1,000 words.
- Topic lesson: an overview, not a second long read. Why the module matters, the learning outcomes with links to each chapter, how the exam tests the module, mixed practice, snapshot.
- Level register: L1 vocabulary and intuition with three-option MCQs; L2 case and model choice with an item set; L3 mandate and command words with a constructed response carrying a minimum answer and a teaching answer.
- Truth layer: numbers are compiled in code from fixtures; sources are a hash-sealed pack of official outlines and provider samples; the model never gets to invent a figure.
Full research: product research · presentation features (33 sources) · subject teaching guidelines · contract: api/docs/cfa/v3-contract.md
Chapter lesson anatomy
Shown on a Level I Fixed Income chapter, Bond price from yield-to-maturity between coupon dates. Every chapter lesson follows the same order; headings are fixed so the app can collapse and the reviewer can check them.

1LOS heading and "On the exam"
- What we do The heading is the LOS text verbatim, sentence case. Directly under it, one line: On the exam: what question shape to expect, what is usually given, what is usually asked.
- Why Candidates rank LOS mapping across explanation, formula, example and question as a top wish, and left the CFA Institute's own platform when it dropped LOS labels. The most common reason for picking Schweser or Mark Meldrum over the curriculum is that they say what matters for the exam. Our earlier drafts: 0 of 50 referenced an LOS, 4 of 30 framed the exam.
- Borrowed from Schweser module openers and LOS numbering; Mark Meldrum's "weight and typical question form" habit.
- Guard
los_heading_mismatchis a major static finding; Jev checksexam_framing_presentper unit.

2Teaching in the level's register
- What we do Plain-language explanation of the mechanism, then the formula with every variable named, its intuition, and the direction of change. Level I reads like a tutor building vocabulary; Level II argues model choice from a case; Level III speaks in mandates and client language.
- Why "Explained formula system: variables, intuition, direction of change" is a recurring ask. Thin notes are punished hardest at L2 and L3 ("states conclusions without scaffolding", "omits the one-line nuance that gets tested"), so we did not cut depth to hit a word count; we moved derivations behind a Go deeper heading instead.
- Borrowed from IFT's variable glossaries and intuition-first explanations; the curriculum's precise wording for Ethics and edge cases.
- Guard Word budget per unit from the LOS count (over 15% is major); markdown lint for unbalanced math, heading jumps, wide tables; renderer profile pinned so what passes on the server renders in the app.

3Worked example, fixture-bound
- What we do One example per unit with named inputs, the calculation walked step by step, and the interpretation of the result. The planner declares the inputs and expressions; code computes the values; the writer may only use those values.
- Why Curriculum blue-box examples are the most-praised teaching device at every level. But every provider we studied has been caught with arithmetic errors, so the model is not trusted with numbers.
- Borrowed from CFAI blue-box examples; UWorld's "show the calculation, then interpret it" pattern.
- Guard Fixture compile before writing; the teaching reviewer must quote numeric claims verbatim and an arithmetic checker recomputes them.

4Changed condition
- What we do Take the worked example and change one thing: yield up, coupon down, a different day count. State what moves, which way, and why.
- Why Exam questions rarely repeat the example; they perturb it. Candidates describe "direction of change" as the part of a formula they most need and least get. It is also the cheapest attempt-first mechanic we can ship without a reveal widget.
- Borrowed from Mark Meldrum's "now what if" habit; Schweser's comparison tables.
- Guard Required heading; Jev
template_order_followed.

5Common error
- What we do A named trap per unit: the wrong rate, the wrong sign, the wrong base. What the wrong answer looks like, why it is tempting, how to spot it.
- Why UWorld is praised precisely because it explains why each wrong option is wrong; MM narrates traps. 25 of 30 earlier drafts had some near-miss text, but not as a findable section a learner can revise from.
- Borrowed from UWorld rationales; MM trap narration.
- Guard Jev
trap_callout_present; reviewer rubric item.

6Calculator
- What we do For any calculation the exam expects on a BA II Plus (TVM, bonds, NPV/IRR, statistics), a Keys / Display table bound to the same fixture as the worked example. Emitted as a machine-checkable block, rendered as a compact table.
- Why "BA II Plus keystrokes beside each applicable example" is a standing request; IFT and Schweser do it, we did it in 0 of 30 drafts. Calculator fluency is a frequent reason candidates cite for running out of time.
- Borrowed from IFT and Schweser keystroke boxes.
- Guard
cfa-calculatorschema; the final display must match the compiled fixture value; invalid blocks are dropped, not published.

7Diagrams and figures
- What we do Mermaid diagrams for flows, decisions and relationships, with the chart types allowed per subject family (flowcharts everywhere; timelines, quadrant and pie charts only where they carry meaning). Timelines and payoff figures are drawn deterministically from fixture data as SVG.
- Why Explicit demand for visuals is thinner than for practice and formulas, and it is for visuals that do calculation work: cash-flow timelines, payoff diagrams, fee waterfalls. Decorative art was the main thing to remove.
- Borrowed from The curriculum's timelines; MM's whiteboard payoff diagrams.
- Guard Mermaid parsed on the server with the exact version the app renders (11.12.1), type allowlist, size cap (8 nodes, 4-word labels). This closed the "valid on server, broken in app" class of bugs.

8Check yourself
- What we do Practice generated with the lesson as structured JSON and rendered as an interactive widget. Eight formats: MCQ, yes/no, fill-in, ordered response, cloze dropdown, matrix grid, item set (L2 vignette with 4 to 6 questions), constructed response (L3). Level I MCQs have three options, like the exam.
- Why Exam-format practice inside the lesson and a rationale for every wrong option are the top two content wishes. Every Schweser module ends with a quiz; the curriculum has end-of-reading sets; ours had at most a short untyped self-check.
- Borrowed from Schweser module quizzes; UWorld every-option rationales; the CFA question-type specification (Learn Well / question handoff).
- Guard
cfa-practice/1schema on both sides; numeric keys must match the fixture; Jev item QA asks whether there is a single defensible key and whether the item tests the stated LOS, and regenerates weak items once. One bad item degrades to a card; it never takes the lesson down.

8bFeedback
- What we do On check: the verdict, the rationale for the option the learner picked, the full explanation. Answer keys live in the JSON, never in the prose, so they cannot leak into the reading.
- Why "Explain every option" is the single feature candidates most credit UWorld for and most miss elsewhere.
- Guard Grading rules are written once in the contract and implemented identically in API tests and app tests.

9Revision snapshot
- What we do A one-screen recap: the formula, the direction of change, the trap, the exam angle. Capped at 150 words and one table so it stays a snapshot.
- Why Every praised provider separates first teaching from fast revision (SchweserNotes vs QuickSheet, IFT notes vs high-yield sheet). Candidates want a two-layer summary; the cap makes this layer usable as a cumulative topic sheet later.
- Borrowed from Schweser QuickSheet; IFT high-yield.
- Guard Required heading; Jev
revision_snapshot_present; word and table cap is a static finding.
Topic lesson anatomy
Shown on a Level I Derivatives module, Derivative Instrument and Derivative Market Features. A topic lesson is the map of the module, budgeted at 1,500 to 2,500 words; the teaching lives in the chapters.

T1Why this module matters
- What we do Two or three paragraphs: what the module is for, its exam weight, which later modules depend on it.
- Why Candidates want prerequisite and "used again in" context and a reason to care before 1,000 words of teaching. It replaces the old 4,500-word topic read that duplicated the chapters.

T2Learning outcomes
- What we do The module's LOS list, each in the official wording, with 2 to 4 sentences of orientation and a link to the chapter that teaches it. Chapters not yet written show a pending marker instead of a dead link.
- Why This is the LOS map candidates use to plan and track; it also gives the app a natural place for LOS-level progress later.
- Guard LOS text from the 2027 outline; link resolution against usable chapter rows; unresolved links are a lint finding.

T3How the exam tests this module
- What we do The module-level version of "On the exam": typical item shapes, the calculations that recur, the distinctions the exam likes to test.
- Why The "say what matters for the exam" gap, at the level where candidates decide how much time to spend.

T4Check yourself and snapshot
- What we do Practice that samples the whole module in the level's exam format, then a revision snapshot for the module.
- Why L2 candidates want a vignette right after the standalone examples; L3 candidates want command-word drills. The module is the right grain for both.
Level III: two answer keys
Shown on Code of Ethics and Standards of Professional Conduct. This is the clearest "best resource" verdict in the research: Bill Campbell's long teaching answer beside the short scoring answer.


- What we do Every L3 constructed response carries the command word, the point allocation, a minimum answer a grader would accept, and a longer teaching answer. Numeric and choice fields are auto-graded; free-text fields are self-assessed against the two answers.
- Why L3 candidates fail on writing too much or too little for the marks available. Seeing the minimum beside the full answer is the habit they say fixed it.
- Guard Minimum answer required and capped at 40 words; teaching answer required; Jev checks the item against the LOS.
Subject playbooks: exam-specific guidelines per domain
A bond lesson and an Ethics lesson should not be written the same way. We researched how each CFA topic area is actually tested and taught, wrote a playbook per subject family, and encoded it as configuration the planner and validators read. Sources: the CFA Institute list of 17 LOS command words, the 2027 topic outlines and curriculum update, provider practice (Kaplan, Mark Meldrum, IFT, UWorld, Salt), the cognitive-load and retrieval-practice literature, and candidate threads. Full document: subject teaching guidelines.
Rules that apply everywhere
- Depth comes from the LOS verb. A define LOS gets a short unit; evaluate or recommend and justify must end in a conclusion grounded in case facts. Discuss is reserved for Level III.
- Level progression. Level I learns and describes; Level II analyses vignette evidence and selects models; Level III integrates, recommends and justifies under constraints.
- No decorative visuals. A visual must externalise a relationship, sequence, cash-flow pattern, decision boundary or reconciliation. Quantitative geometry (payoffs, curves, distributions, frontiers, attribution bridges) is drawn from data, never sketched.
- Mermaid for conceptual structure only: flowcharts, timelines, mind maps, quadrant charts, block diagrams. Each subject has an allowlist.
- Alternate demonstration and retrieval. Fully worked example, then a faded one, then independent retrieval. Formative formats (fill-in, matrix, ordering, cloze) are scaffolds; the exit item is always exam-authentic for the level.
- Every distractor names its misconception: the sign error, convention error or ignored case fact that produced it.
What each subject family gets
| Family | Reasoning the exam wants | Register rule (what the writer must always label) | Visual that earns its place | Tables | Classic traps we call out | Practice shapes |
|---|---|---|---|---|---|---|
| Ethics (I–III) | Rule application under ambiguous facts; prevention | Exact Standard name; required vs recommended vs permitted vs prohibited; disclosure vs consent; violation vs mere risk | Decision flowchart: actor → duty → fact → exception → conclusion; optional Standards mind map | High: rule / trigger / required action / trap | Picking the most restrictive answer; treating disclosure as a cure; importing personal morality; answering for the wrong actor | 3-option MCQ with fact-pattern distractors, matrix, yes/no + reason, L3 short constructed response |
| Quantitative Methods (I–II) | Procedural calculation; model selection | Units, frequency, compounding, population vs sample, hypotheses, tail, calculator mode | Data-drawn distribution or scatter; probability tree; method-selection flow | Medium-high: method / assumptions / inputs / output | Annual vs periodic inputs; variance vs SD; percent vs decimal; wrong tail; statistical vs economic significance | Numeric fill-in, MCQ, ordered steps, L2 item set with data exhibit |
| Economics (I–II) | Model selection; causal chains | Ceteris paribus; nominal vs real; short vs long run; FX quote written price/base with direction | Data-drawn curve chart; transmission flowchart shock → variables → asset effect | Medium: shock / first-round / second-round / ambiguity | Reversed FX quote; movement along vs shift of a curve; treating short-run results as long-run | MCQ, item set, ordered transmission chain, matrix |
| Financial Statement Analysis (I–II) | Accounting-rule application; reconciliation; analyst adjustment | Every example labelled IFRS, US GAAP or "same under both"; reported vs adjusted; period vs point-in-time | Statement exhibit with affected rows; before → adjustment → after bridge | Very high: IFRS / US GAAP / implication; transaction / IS / BS / CF | Cash flow vs earnings; average vs ending balance; pre- vs after-tax; double-counting an adjustment | Statement-heavy item set, MCQ, numeric fill-in, matrix of statement effects |
| Corporate Finance (I–II) | Incremental decision analysis; governance judgment | Project vs firm; operating vs financing; pre/post-tax; sunk vs opportunity cost; whose objective | Cash-flow timeline; governance decision flow | Medium-high: cash flow / time / sign / tax | Including sunk cost; forgetting working-capital reversal; firm WACC for a different-risk project; value vs EPS accretion | MCQ, item set, numeric fill-in, governance matrix |
| Equities (I–II) | Forecast construction; valuation-model selection | Enterprise vs equity value; per-share vs aggregate; trailing vs forward; normalised; scenario assumptions | Forecast driver chart; valuation bridge or sensitivity; positioning quadrant | High: model / inputs / fit / limitation; scenario matrix | Mixing EV and equity; inconsistent numerator/denominator; double-counting growth; point estimate as certainty | MCQ, company item set, numeric fill-in, model-selection matrix, cloze |
| Fixed Income (I–II) | Cash-flow valuation; curve and spread interpretation | Clean vs dirty; settlement date; yield convention; compounding; spread and duration definitions | Cash-flow timeline; price–yield or curve chart; data-drawn rate tree | Medium-high: security / cash-flow rule / risk / measure | Clean vs dirty; annual vs semiannual; YTM as realised return; spread vs rate duration; ignoring optionality | MCQ, item set, numeric fill-in, ordered valuation steps, security-to-risk matrix |
| Derivatives and Risk (I–III) | Replication; no-arbitrage; strategy selection | Long/short, payer/receiver, underlying, notional, maturity, premium timing, settlement, FX convention | Payoff/profit diagram from data; contract timeline; hedge-selection flow | High: strategy / objective / payoff / max gain-loss / risk | Value vs payoff vs profit; long/short reversal; forgetting premium or carry; futures price vs contract value | MCQ, item set, numeric fill-in, matrix, L3 constructed response |
| Alternative Investments (I–II) | Structure comparison; return calculation; fee and liquidity judgment | Gross/net; levered/unlevered; committed/called/invested; appraisal vs market; TWR vs MWR | Fee or carry waterfall from data; lifecycle timeline; quadrant | Very high: structure / liquidity / valuation / fees / risks | Commitment vs invested; IRR vs multiple; fee base; stale appraisals; illiquidity mistaken for diversification | MCQ, item set, matrix, numeric fill-in |
| Portfolio Construction (I–III) | Model selection; constrained judgment | Objective vs constraint; risk tolerance vs capacity; benchmark; risk budget; client type | Frontier / CAL / risk-contribution plot; IPS flow | High: investor / objective / constraint / implication | Willingness vs ability; arithmetic answer that is not implementable; diversification by label; ignoring liquidity and tax | MCQ, item set, matrix, L3 constructed response |
| Asset Allocation (III) | Forecast integration; recommendation under constraints | Strategic vs tactical; asset-only vs liability-relative vs goals-based; nominal vs real; model output vs decision | Frontier, surplus-risk or scenario plot; decision flow | High: approach / objective / constraint / failure mode | Nominal liabilities with real returns; unstable optimised weights; recommending without citing client facts | Item set, constructed response, matrix, scenario ordering |
| Performance Measurement (III) | Reconciliation; attribution; manager evaluation | Portfolio vs benchmark; contribution vs attribution; arithmetic vs geometric; gross vs net | Attribution bridge; drawdown chart | Very high: allocation / selection / interaction; metric / use / flaw | Sign errors; effects that do not reconcile; alpha vs excess return; one strong period read as skill | Item set, numeric fill-in, matrix, constructed response |
| Portfolio Management pathway (III) | Strategy construction; implementation | Mandate language: benchmark, active risk, tracking error, alpha source, capacity, turnover, execution benchmark | Risk/return or tracking-error chart; process flow; trade-cost bridge | High: strategy / alpha source / risk / implementation | Strategy inconsistent with mandate; Active Share vs tracking error; execution benchmark chosen after the trade | Item set, constructed response, matrix, ordered response |
| Private Markets pathway (III) | Deal-process judgment; underwriting; fund economics | GP/LP; entry/exit; pre/post-money; EV vs equity; seniority; gross/net; committed/invested | Fee/carry waterfall; deal timeline; capital stack | Very high: instrument / control / cash flow / downside | EV/equity confusion; dilution; IRR timing; public-market liquidity assumptions; ignoring downside priority | Item set, constructed response, numeric fill-in, matrix |
| Private Wealth pathway (III) | Client-centred judgment under tax, legal, behavioural and liquidity constraints | Goals, jurisdiction, after-tax wealth, human capital, concentrated position, family governance | Goals timeline; decision tree; balance-sheet waterfall | High: goal / horizon / priority / instrument / tax effect | Pre-tax wealth; double-counting human capital; illiquid solution for a near-term goal; missing family dynamics | Item set, constructed response, matrix, timeline ordering |
How the playbook reaches the lesson
- Encoded, not prompted from memory. The 15 families live in
subject-config.json: reasoning type, register lines, visual kinds with their Mermaid type and per-lesson count range, table density and shapes, worked-example counts, allowed practice formats, Mermaid allowlist, per-level deltas and a template family. A subject is matched by its staging subject name and level. - Planner. Receives the family block with the LOS and plans the unit's visuals, examples and practice from it, so a Fixed Income unit gets a timeline and a keystroke table while an Ethics unit gets a decision flowchart and three micro-cases.
- Writer. Gets the register lines verbatim as instructions; Jev then asks per unit whether each register rule was followed (
register_followed_1..3in the structural pass). - Validators. A practice format outside the family's allowed list, a Mermaid type outside its allowlist, or a visual kind the family does not configure is a finding, and the offending block is dropped rather than published.
- Practice cycle per unit. Retrieval check after the first concept, worked example after the procedure, a faded example, two to four formative interactions, then one exam-authentic exit item for the level. Every distractor names the misconception behind it.
How it is produced
Two model families and a gate after every model stage. GPT-5.6 Luna plans, writes and reviews teaching; Jev (TypeSafe AI) answers cheap yes/no structural questions per unit and per item. Every gate has one bounded repair with the exact error, and every failure is checkpointed and resumable.
- Per-subject configuration drives the planner: allowed practice formats, chart types, register lines, calculator use, derived from the subject teaching guidelines.
- Evidence per lesson: plan, fixtures, practice, calculators, static findings, Jev scores, review, arithmetic, raw model outputs and hashes. Prompt changes are benchmarked against the same lesson ids, not eyeballed.
- Audit viewer (
pnpm cfa:viewer): renders every lesson as the app does, shows Jev questions on hover, records accept / changes / reject per lesson and exports CSV. - App renderer:
cfa-practiceandcfa-calculatorblocks as widgets; Mermaid pinned to the server's version; answer keys never render as text; a bad item degrades to a card.
Versus medical lessons
| Medical (NEET-PG, USMLE…) | CFA v3 | |
|---|---|---|
| Unit | One long page per topic or chapter (6 to 8 A4 pages). | One LOS per chapter lesson, about 1,000 words; topic lesson is an overview. |
| Organising principle | Bloom's taxonomy, six sections from Remember to Synthesize, clinical vignettes, high-yield summary. | The exam's outline: LOS text as heading, LOS verb sets the goal, fixed section order. |
| Exam framing | Implicit. | Mandatory per unit and per module; trap callouts; changed condition. |
| Numbers | From the model. | Compiled from fixtures in code; reviewer claims recomputed. |
| Practice | Pulled from the question bank afterwards. | Generated with the lesson in eight formats, graded in the app. |
| Sources | Model knowledge. | Hash-sealed source pack with per-LOS coverage requirements. |
| Generation | One call (Claude Sonnet 4.5), media in parallel, shape validator. | Ten stages, two model families, gates with bounded repair, evidence bundle. |
| Diagrams | Mermaid rendered to images on the server; retrieved clinical images. | Mermaid validated at the app's pinned version and rendered live; deterministic SVG from data. |
Providers: what we took, what we avoided
| Provider | Praised for | Complained about | Oncourse response |
|---|---|---|---|
| Schweser | LOS-numbered modules, module quizzes, QuickSheet | Too thin at L2 and L3; omits the tested nuance | Took the module structure, quiz and snapshot; kept full teaching depth with a Go deeper section |
| Mark Meldrum | Explains why, states exam weight, narrates traps | Hours of video; watched at 2x | Took exam framing and trap callouts into text; no video needed |
| IFT | Variable glossaries, intuition first, calculator boxes | Full course too long | Took the formula system and keystroke tables |
| UWorld | Rationale for every option, visual logic | All depth before it is needed | Took every-option rationales in practice; depth stays behind Go deeper |
| CFAI curriculum | Blue-box examples, precise wording, end-of-reading questions | Length; platform lost LOS labels and annotation | Took fixture-bound examples and official LOS wording; kept LOS labels everywhere |
| Bill Campbell / L3 tutors | Minimum answer beside teaching answer | Niche, expensive | Took the two-answer-key pattern for every L3 prompt |
External resources inform the mechanics; all lesson wording, numbers and questions are original and fixture-bound.
Numbers from the 60-lesson benchmark
What the team should decide
- Length. Chapter lessons now sit near 1,000 words. Is that the right stopping point, or should Go deeper be visible by default for L2 and L3?
- Practice count. 3 to 5 items per chapter unit and one module set per topic. Enough for retrieval, or should each chapter carry a mini item set at L2?
- Revision layer first? The snapshot is at the end. Should the app offer it as the collapsed default with "expand to full teaching"?
- Calculator scope. BA II Plus only. Add an HP 12C toggle now or after learner data?
- Reviewer strictness. The tutor reviewer requests changes on most drafts. Publish on automated gates plus spot audit, or hold for a tutor pass?
- Free-text grading. Constructed-response prose is self-assessed today. Is that acceptable for launch, or do we want a model grader behind it?
Links: L1 chapter (bond pricing) · L1 chapter (business structures) · L2 chapter (commodities) · L1 topic (derivatives) · L3 topic (ethics) · staging login required.