Zain Dana Harperlearn · accountable credential and study engine

Study what you gave it. Prove what you kept.

A course platform can grade you on material it never checked you understood. A study aid can write the essay for you and call it help. learn is built to do neither. It is an accountable credential and coursework engine for material you provide, and at the same time the most capable learning aid it can be, because the two are kept structurally apart: the aid can explain, quiz, and coach without limit, but it can never sit the graded step for you.

Every graded ‘assess’ step halts and waits for you. What you did there is hashed into a witnessed ledger, so a credential from learn is a claim anyone can re-check, not a claim you have to take on faith.

learn · v1.5.0 · shipped · witnessed ledger · zero-dep Node

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.

spaced repetition a scheduler resurfaces each concept right before you would have forgotten it, tuned per item from your own recall history, not a fixed calendar
retrieval practice drills pull questions from your own material, not a stock bank, so what you rehearse is what you actually need to hold
predict, then observe state your prediction before the telos engine renders or runs the real thing, so the gap between guess and outcome is the lesson, not a caption under it
self-explanation, checked explain a concept back in your own words and crucible measures it against the source claim instead of a tutor's say-so
misconception targeting a wrong answer is classified against a bank of known failure patterns for that concept, so review time goes to the specific gap, not a generic re-read
concept and prerequisite map every concept in your material is linked to what it depends on, so the course sequences itself instead of assuming you already have the foundation

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.

A receipt you can re-check does not get to grade its own homework.

A study receipt carries a verified flag and a ledgerVerified flag. Both are written by whoever produced the receipt, which means neither is worth anything on its own. learn tutor reverify ignores them on purpose and re-derives the receipt from its own evidence instead: it walks the hash chain over the witnessed practice entries and recomputes it, and it re-runs the mastery verdict from the recorded attempts under the recorded policy. If either recomputation disagrees with what the receipt claims, the receipt fails, whatever its stored booleans say.

CHAIN_BROKEN the hash chain over the practice entries does not recompute; the failure names the offending entry's sequence number and hash, and a hash-consistent truncation is still caught by attempt accounting
VERDICT_MISMATCH the stored mastery verdict does not re-derive from the recorded attempts under the recorded policy; the failure carries both projections, the one on the receipt and the one recomputed, so the divergence is visible, not asserted
UNVERIFIED a receipt with no chain to walk cannot re-verify, so it is reported unverified, never verified; the absence of evidence is not treated as evidence

A verifier that cannot fail on a known-bad receipt is not a verifier. doctor re-checks that one at runtime: it must pass a clean receipt and reject a tampered chain, a hand-edited verdict, and a chainless receipt.

A failed proof is a lesson, not a dead end.

A proof-surface packet is a verified-claim record: a claim, its scope, its sources with hashes, and a MATCH, DRIFT, or UNVERIFIABLE verdict. learn tutor prooflesson turns one into something you study from, without turning it into an answer sheet. It preserves the packet's own evidence surface, source references and never their bodies, and derives three things around it.

explanation scaffold numbered prompts that ask you to derive the reasoning yourself; the packet's own decision reasoning is never dumped into the lesson, so the lesson coaches the derivation instead of handing it over
retrieval questions recall prompts built from the packet's own fields, including ‘what evidence would falsify this claim,’ so the drill rehearses the actual claim and its sources rather than a paraphrase
verifier binding the lesson's verdict, the packet id, and the source hashes are bound into the lesson; the lesson's verdict is copied from the packet and from nowhere else, so a lesson claiming MATCH from a DRIFT packet is impossible by construction and a forged verdict enum is rejected up front

When the proof attempt failed, the lesson also names why it failed. A DRIFT or UNVERIFIABLE packet yields a typed misconception record, contradicted for drift, overclaim for an unverifiable claim that still cited sources, missing_evidence for one that cited none, and its prompt asks you why the proof did not hold. A MATCH packet yields no misconception, because there is nothing there to correct. The lesson receipt is hash-chained the same way a study receipt is, and tutor reverify covers it: a tampered entry is CHAIN_BROKEN, a flipped verdict or edited lesson body is VERDICT_MISMATCH.

The lesson's verdict always equals the packet's. A wrong proof teaches you where you were wrong; it never gets promoted to right.

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:

telos the predict-then-observe step hands your prediction to the telos engine and renders or runs the real thing, so the checkpoint is a live comparison, not a static answer key
gather source material that already carries a provenance receipt, a paper, a transcript, a scanned chapter, imports straight into a course with that receipt intact, so the course cites where its content came from
crucible a self-explanation is registered as a claim against the source concept and measured, so ‘checked’ means a re-derivable verdict, MATCH, DRIFT, or UNVERIFIABLE, not a tutor's approval

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.

Everything the loop produces lands as a named artifact you can keep and re-check: a mastery-receipt that witnesses the practice log and states its own boundary, a study-receipt that wraps the composed plan, and a proof-packet lesson receipt, each a hash-chained record on disk that tutor reverify can walk. There is also a zero-dependency MCP server that exposes the advisory surface, learn_tutor_plan, learn_tutor_studyplan, learn_tutor_misconceptions, learn_tutor_reverify, learn_tutor_prooflesson, and the rest, all read-only: a connected agent can inspect a plan, a misconception ranking, or a re-verification, but it renders and writes nothing. Actuation, running a course, stays owner-driven on the CLI.

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)
wrote study-receipt: tutor/my-course.study.json (hash-chained)

$ learn tutor reverify my-course   # ignores the receipt's own verified flags; re-derives from evidence
chain recomputes, verdict re-derives from recorded attempts: VERIFIED
after editing a prior verdict, reverify: VERDICT_MISMATCH (stored: ready, recomputed: not-ready)
after editing a prior ledger entry, reverify: CHAIN_BROKEN (seq 3)   <- 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.

GitHubHarperZ9/learn  ·  ← all flagships  ·  the index