Two jobs, held apart on purpose.
learn is the learning organ of the constellation. Point it at your own material, notes, a textbook chapter, a paper gather already reached and receipted, a codebase, and it builds a course around it: a concept map, spaced review, retrieval drills, and a small set of graded checkpoints. The same engine is also a maximal learning aid. It will explain a concept five different ways, generate practice you did not ask for, walk through a worked example, and coach you toward the idea instead of handing it over.
What keeps those two jobs from collapsing into each other is a hard line at the graded step. An aid-render, an explanation, a hint, a worked example the tutor generated for you, carries a marker that says so, and that marker makes it structurally ineligible to stand in for your own graded work. The course does not trust you to leave the aid out of the submission. It checks.
Coaching has no ceiling. Grading has a floor, and the floor holds.The loop is spaced review, retrieval, predict, explain, target the gap.
Reading a summary twice feels like learning and mostly is not. learn is built around the study techniques that actually move material into long-term memory, run against your own source content instead of a generic deck.
The whole loop is one command away, live: learn tutor study opens a session against your current course, pulls whatever is due, and runs the loop above end to end, drills, predictions, explanations, and the concept map updating underneath you as you go.
The floor is quiet, and it does not move.
Every graded step in a course is an assess node, and every assess node halts. The engine stops generating, hands you the checkpoint, and waits. There is no configuration that skips this, because the halt is not a setting, it is the shape of the step. What you submit there, and only what you submit there, is hashed into a run ledger alongside the prior step's hash, so the ledger is a hash chain: altering an earlier answer after the fact breaks every seal after it, not just the one you touched.
An aid-render can help you understand. It can never stand in for the step where you show you did.
The provenance receipt is what makes the second half hold. Anything the tutor generated for you carries a tutor-render method on its receipt, the same shape gather uses for a fetched item, and the grading path refuses any submission whose content matches a stored tutor-render by hash. That is a mechanical check, not a policy reminder: a rendered explanation cannot quietly become a graded answer because the hash of the two would have to match, and the receipt would already have marked it. The ledger is witnessed the same way a crucible assessment is, re-derivable from the record on disk, not asserted from a log line you have to trust.
Zero-dep Node at the core. The rest of the constellation plugs in at the seams.
learn runs on Node's standard library with no third-party runtime dependency. Course content, the concept map, the spaced-repetition schedule, and the run ledger are all plain JSON on disk, so a course is portable and a ledger is inspectable with nothing more than a text editor. Three seams reach out to the rest of the constellation, each one a Null by default so learn stands alone with no course content wired in:
Clocks are injected wherever a review time or a ledger timestamp is recorded, so a run is deterministic and replayable from the same inputs. The scheduler, the misconception classifier, and the three interop seams are all swappable behind a small interface, so a peer organ can plug in without learn's core ever importing it directly.
Current state. How to run it.
Version 1.5.0, shipped. It installs the learn command and runs on Node's standard library, no third-party runtime dependency. A course is a directory of JSON, and a run ledger is a hash chain you can walk by hand. Point it at your own material, run a course, and watch it halt exactly where it should.
$ npm install -g @harperz9/learn $ learn course init ./my-course --source ./notes # builds the concept map from your material built course "my-course": 14 concepts, 6 prerequisite edges, 3 assess checkpoints $ learn course run my-course loop: retrieval drill (concept: binary-search-invariant) ... recalled, correct loop: predict-then-observe (telos render: sorted-array-partition) ... your prediction: HIGH; observed: LOW loop: self-explanation (concept: loop-invariant) ... crucible verdict: MATCH HALT: assess checkpoint "quiz-2" reached, awaiting your submission ledger: 4 steps witnessed, chain verifies True $ learn tutor study my-course # open-ended coaching session, no ceiling, nothing here can be submitted as an answer tutor: 2 due reviews, 1 known misconception on "loop-invariant" (off-by-one boundary) after editing a prior ledger entry, chain verifies: False <- caught
Node, zero runtime dependencies. Install it, point it at your own notes, and run the demo course to see the halt and the hash chain for yourself. If a tutor-render ever slips through as a graded submission, or a ledger verifies clean after tampering, that is exactly the kind of report I want.