# Ten reps — lesson

Gym heading: Capstone. Written before the code (Sep 7 2026). This module has **no teach screen** — that is the module. The text below is the build note and the record of what the module does; it is not shown to you before the reps, because being told what to look for is exactly what is being taken away.

Persistent header: none. Nothing at the top of a rep says which module the chart came from.

## What it is

Ten reps drawn at random from every finished module in the gym, with the instruction stripped. No teach screen, no rule panel, no persistent header, no module name. Just the chart and the question the module asks about it.

Every other module tells you what to look at before it shows you anything. That is right for learning a read and wrong for using one. At the trade there is no heading above the chart telling you this one is about acceptance. You get a chart. You decide whether anything on it is worth a decision, and which read answers it, and then you answer.

## What it doesn't say

A good score here does not mean the reads are good. It means you can pick the right read without being told which one it is. A bad score with good module scores means the reads are fine and the selection isn't — which is its own diagnosis, and the reason the summary breaks the score out per module.

## The rep

One chart, the source module's own chart, drawn by the source module's own code. The question is that module's own question, with that module's own answer options and its own soft clock. Confidence first, then the answer. What is removed: the teach screen, the "What's the rule?" link and the panel behind it, the persistent header, and the source module's rep counter. What stays: everything you would have to read off the chart anyway, including M.

Ten reps, ten different modules — each session samples ten of the twenty-one without replacement, so no module comes up twice in a session and, over many sessions, every module comes up equally often.

## The reveal

The source module's own reveal, unchanged: its chart with the threshold drawn, its Correct / Incorrect banner, its answer and takeaway line, its arithmetic in M, its feedback lines. Above it, the one thing this module adds: **the name of the module the rep came from**, with a link to it. That is the point of the reveal here — you find out which read it was after you have committed to one.

## Scoring

Identical to every other module, because it is the other modules' scoring: the source module grades its own rep with its own answer key and its own `CONF_P` (low 0.40, medium 0.65, high 0.90). This module reads the graded rep back and keeps the same session row, the same Brier, the same calibration table, the same history under the summary.

Confidence is never defaulted. A rep does not advance without a confidence click; with `CONFIDENCE_REQUIRED` off it advances with confidence = null, which keeps it out of the Brier and the calibration table and is counted on the summary.

## The summary

Overall score and Brier, the calibration table, then one line per module that came up: its score and its Brier for this session. The weakest module is named — the lowest score, with the Brier breaking a tie. Ten reps across ten modules is one rep each, so the per-module line is a pointer, not a measurement: it says go back and drill that one, not that you are bad at it.

## Answer key

There isn't one here. Each rep's answer key is the source module's, computed by the source module on the chart it built. This module never decides an answer, never re-implements a rule, and never draws a chart. It calls, per rep:

- `buildPlanAttempt(rng, fam, family)` — the source module's generator, one attempt, and one non-null rep taken from it at random;
- `startRep(0, false)` — the source module's own rep screen, into a host element this module owns;
- `submitAnswer(value)` — the source module's own grading and reveal.

## Choices made where the spec was silent

- **`buildPlanAttempt`, not `buildSessionPlan`.** `buildSessionPlan` retries a whole 20-rep session until `tallyOk` passes, and `tallyOk` is a property of a *session's mix* — the case shares across twenty reps of one module. This module takes one rep, so the session tally is not its constraint; its mix is across modules. The rep is the same rep either way (`buildPlanAttempt` is the generator; `buildSessionPlan` only decides which attempt to keep), and the cost is the difference between 0.2 ms and 7,500 ms for the conflict module. Attempts can contain null reps; a null is skipped and the draw retries.
- **Families are inherited.** A drill session draws each rep from that module's drill family; a holdout session draws from its holdout family. The two recipes differ because the source modules' recipes differ — this module adds no parameters of its own to vary.
- **Module display names come from the source module's `<title>`.** Nothing is duplicated here that already exists there.
- **`CONFIDENCE_REQUIRED` is propagated.** The constant is this module's, and it is patched into each source module as it is loaded, so the two can never disagree.
- **Modules are loaded over HTTP** from their own `index.html` — the script for the generator and grading, the stylesheet for the chart, the `<title>` for the name. The gym must be served for this module to run; `file://` will not do it.

## Modules composed

Twenty: acceptance, bracket-preview, conflict, dead-tape, effort-vs-result, efficiency, fresh-or-burned, gap, golden-pocket, opening-range, point-at-the-bar, points-are-not-risk, premium-discount, runway, session-vwap, stop-vs-noise, structure, trapped-or-not-trapped, value, value-migration.

## Modules skipped

- **module-1-scale.** It predates the build convention: no `FAMILIES`, no `buildPlanAttempt`, no `buildChart`, a different rep shape and a `startRep(i)` that takes no resume flag. Composing it would mean writing a second adapter for one module — copying its logic in all but name. It comes back into Ten Reps the day it is rebuilt to the convention.
