Mastery Ledger turns source material into cited lessons, exams, and a review schedule that stays on your computer.
The Codex skill reads and checks the material, then writes the course. The local app lets you read lessons, take exams, and revisit questions over time.
Built for OpenAI Dev Week.
Mastery Ledger has two parts. Install the app for reading and exams. Install the Codex skill to build courses.
You need Python 3.11 or newer, uv, Git, and Node.js with npx.
Clone the repository:
git clone https://github.com/Howard-Starfield/Mastery-Ledger.git
Set-Location Mastery-LedgerInstall the app:
uv tool install . --force --no-cache
mastery-ledger onboard --openDuring setup, choose one of these locations:
- A single course folder
- A folder whose direct children are courses
- A workspace that keeps its courses inside
courses/
The Import button is optional. To add a course without importing, extract its single top-level <course-slug>/ folder and place that folder directly in the active workspace or under workspace/courses/, then select Rescan. An unopened ZIP is not treated as a writable course folder; use Import when you want the app to validate and extract the ZIP for you.
ChatGPT-built draft bundles may include an AI self-checked practice test. The app labels it separately from a verified exam, saves the attempt for review, and does not use its result to update mastery or schedule reviews.
After setup, open the app from any drive or directory:
mastery-ledger openInstall the Codex skill:
npx.cmd skills add ./mastery-ledger -g -a codex -y --copy
npx.cmd skills list -g -a codexOpen a new Codex task after installation so Codex can load the skill.
Ask Codex to use Mastery Ledger:
Use Mastery Ledger to help me learn how large language models work.
If you already have material, include it:
Use Mastery Ledger to build a course from https://example.com/my-source
When you provide material, the skill uses it as the sole source by default. You may later ask Codex to check it against other sources. When you provide only a topic, Codex asks what you already know, then researches the subject.
Codex asks where to create the course before it writes any files. This course location is separate from the workspace saved by the app.
I used to finish a LinkedIn Learning course and feel that I understood it. A few days later, much of the detail was gone. Watching made the ideas familiar, but familiarity was not recall.
Research on retrieval practice supports a simple response: stop rereading for a moment and try to remember. In one experiment, students who read a passage once and then took three recall tests remembered 61 percent after one week. Students who read it four times remembered 40 percent. See Roediger and Karpicke.
A broad review also found that spaced practice improves retention, though the best interval depends on the material and how long it must be remembered. See Cepeda and colleagues.
These studies support retrieval and spacing. They do not prove one perfect calendar. Mastery Ledger therefore begins with an editable sequence:
1, 3, 7, 14, 28, 56, 112, 224, 448, 896, 1792, 3584 days
This sequence is a product default. It is not FSRS, SM 2, or a promise of permanent memory.
| Part | Purpose | Writes |
|---|---|---|
| Codex skill | Collects sources, checks claims, writes lessons, and builds exams | Course files in the folder you choose |
| Local app | Reads lessons and exams, scores attempts, and schedules reviews | Attempts, progress, review dates, and app settings |
The app does not search the web or generate lessons. The skill does not display exams or store progress. They exchange lessons, questions, and results through the course folder.
flowchart LR
Learner["Learner"] --> Codex["Codex skill"]
Sources["Topic, files, links, or video"] --> Codex
Codex --> Course["Course folder"]
Course --> Lessons["Lessons"]
Course --> Exam["Question bank and exam"]
Lessons --> App["Local app"]
Exam --> App
App --> Progress["Attempts and review dates"]
If you provide only a topic, Codex asks one question about what you already know. Your answer sets the lesson level. It does not count as source evidence.
If you provide a file, link, excerpt, video, or existing course, Codex begins with that material instead.
Codex records the goal, learner level, source policy, limits, and accepted related topics in study.yaml. The skill states what it will ask and what work it will run. You can change the scope before research begins.
Each source receives an ID, a content hash, a location, and a rights record in records/source-manifest.yaml.
Extracted notes go in records/source/. Captions, transcripts, audio, video, and other original material go in records/source/media/. Temporary work stays in .work/.
For video, the skill tries these methods in order:
- Use subtitles you supplied.
- Request permitted captions from the platform.
- Save permitted media only when captions are not enough.
- Transcribe locally only after you approve the model and download.
Remote-media acquisition is optional and is not installed with the reading and exam app. To let the skill use the Python yt-dlp package, reinstall the local project with its media extra:
uv tool install ".[media]" --force --no-cacheFor a GitHub installation, use:
uv tool install "mastery-ledger[media] @ git+https://github.com/Howard-Starfield/Mastery-Ledger.git@main" --force --no-cacheFFmpeg remains optional. Mastery Ledger does not fetch tools or media without permission.
Workers extract sources before review begins. A contradiction review removes weak or disputed claims. Citation checks run only on the claims that remain. The main agent then approves the evidence used in the course.
A separate assessment worker reviews the finished questions. It checks wording, citations, distractors, answer balance, and whether each question has one defensible answer. A worker cannot approve its own work.
If an independent check cannot finish, the skill keeps the drafts in .work/ and marks the course DRAFT_UNVERIFIED. It does not present an unchecked exam as ready.
Each published chapter contains a full lesson. A standard lesson has 1,200 to 1,800 words, two worked examples, retrieval pauses, common mistakes, limits, and exact source locations.
Each chapter has at least ten questions:
- Eight concise multiple choice questions
- Two short passages followed by multiple choice questions
Larger chapters may use 15 or 20 questions with the same balance. Every question has four choices, one correct answer, a short explanation, and a source reference. Correct answer positions must be spread across A, B, C, and D.
| Location | Contents |
|---|---|
index.md |
Course map and reading order |
lessons/ |
Chapter lessons and the course glossary |
questions/ |
Question bank and Markdown record |
exams/ |
Exams read by the app |
records/source/ |
Source notes and permitted media |
records/evidence/ |
Approved claims, conflicts, gaps, and validation receipts |
records/logs/events.jsonl |
Actions, decisions, evidence paths, and short reasons |
.work/ |
Drafts, worker reports, rejected work, and temporary files |
Logs record visible actions and decisions. They do not contain hidden reasoning.
The Study view lists published lessons and loads the course glossary beside them. The reader renders each lesson without showing its metadata header. The app never edits the lesson.
The Glossary view gathers published terms from every course into one searchable index. It opens on All courses, can be narrowed to one course, and links each term back to the lesson chapters that teach it.
The exam view shows one question at a time. Before you answer, the browser does not receive the answer key or explanation.
- A wrong answer gives no hint.
- A correct answer reveals the explanation.
- The source panel remains closed until you open it.
- Final review shows the answer and its supporting source.
The app saves partial attempts. It resumes an attempt only when the exam file has not changed. Completed attempts remain in the course history.
| Command | Use |
|---|---|
mastery-ledger open |
Open the saved workspace |
mastery-ledger onboard --open |
Complete first setup |
mastery-ledger repair --open |
Choose a different workspace |
mastery-ledger doctor --json |
Inspect app and workspace status |
mastery-ledger stop --json |
Stop the local app server |
Add --json to a launch command when another program needs structured status.
Download MasteryLedger-Setup-v0.1.3.exe from the latest GitHub release and run it. The per-user installer does not require administrator access, adds Start Menu and uninstall entries, and keeps the application runtime together under %LOCALAPPDATA%\Programs\Mastery Ledger.
The installer is not yet Authenticode-signed, so Windows may ask you to confirm that you trust it. The release also includes MasteryLedger-windows-x64-v0.1.3.zip as an optional portable build. If you use the portable build, extract the complete folder before running MasteryLedger.exe; do not move the EXE away from its adjacent _internal runtime files.
Alternatively, install the Python application from GitHub:
uv tool install "git+https://github.com/Howard-Starfield/Mastery-Ledger.git@main"
mastery-ledger onboard --openInstall the skill from GitHub:
npx.cmd skills add Howard-Starfield/Mastery-Ledger@mastery-ledger -g -a codex -y --copyThe Windows installer and portable application are unsigned previews. A signed installer remains a release-hardening goal.
The installed and portable Windows app checks the latest stable GitHub release when it opens. If a newer Windows build is available, an update card shows the installed and available versions. Select Update and restart once to download the portable update payload, verify its GitHub SHA-256 digest, replace the application files after the running EXE closes, and reopen Mastery Ledger. Course folders, attempts, progress, and settings live outside the application folder and are not replaced.
If the computer is offline or GitHub cannot be reached, no update card appears and the local app continues normally. Because the portable preview is not yet Authenticode-signed, Windows may still display its standard trust warning after an update.
For a source or uv tool installation, update manually:
Set-Location Mastery-Ledger
git pull --ff-only
mastery-ledger stop --json
uv tool install . --force --no-cache
npx.cmd skills update mastery-ledger -g -y
mastery-ledger doctor --jsonUse an editable install while changing the Python app:
mastery-ledger stop --json
uv tool install --editable . --force --no-cacheChanges under src/mastery_ledger/ then apply without another install. Frontend changes still require a new web build.
Older courses can be moved to the current layout:
python .\mastery-ledger\scripts\migrate_course_layout.py C:\path\to\courseThe migration moves source, evidence, and log records under records/. It converts study-guide.md to index.md and keeps retired files in .work/migration-backup/. It refuses to run while a worker plan is active.
Run every command below from a PowerShell prompt. Start at the repository root:
Set-Location C:\path\to\Mastery-Ledger
python -m venv .venv
uv pip install --python .\.venv\Scripts\python.exe -e ".[dev,desktop,desktop-build]"Build the frontend before starting the local app so FastAPI and the desktop host serve the current React bundle:
Set-Location .\web
npm.cmd ci
npm.cmd run build
Set-Location ..Run the native local development build:
& .\.venv\Scripts\mastery-ledger-desktop.exeThe desktop command uses the active workspace registered in the local app database. Complete onboarding first if this checkout has not registered a workspace.
Run the complete automated test suite from the repository root:
& .\.venv\Scripts\python.exe -m pytest -q tests mastery-ledger/tests
Set-Location .\web
npm.cmd test
npm.cmd run build
Set-Location ..The frontend build writes to src/mastery_ledger/web/. Commit those files with any frontend change.
The Windows desktop preview runs the FastAPI backend inside a native WebView2 window. The environment created above already includes the required desktop and PyInstaller build packages.
Run a backend and bundled-frontend smoke test without opening a window:
& .\.venv\Scripts\mastery-ledger-desktop.exe --smoke-test --jsonRun the native desktop application during development:
& .\.venv\Scripts\mastery-ledger-desktop.exeBuild the clean one-directory executable, add its Windows runtime configuration, then run both release smoke tests:
& .\.venv\Scripts\pyinstaller.exe --noconfirm --clean .\packaging\mastery-ledger.spec
Copy-Item .\packaging\MasteryLedger.exe.config .\dist\MasteryLedger\MasteryLedger.exe.config
& .\dist\MasteryLedger\MasteryLedger.exe --smoke-test --output .\.work\desktop-smoke.json
& .\dist\MasteryLedger\MasteryLedger.exe --webview-smoke-test --output .\.work\webview-smoke.json
Get-Content .\.work\desktop-smoke.json
Get-Content .\.work\webview-smoke.jsonThe webview smoke test loads Python.NET, Windows Forms, and the pywebview Windows backend without opening the application window. It protects the release against native runtime failures that the backend-only smoke test cannot detect.
The runnable application is dist\MasteryLedger\MasteryLedger.exe. Keep the complete dist\MasteryLedger\ directory together because the EXE uses its adjacent _internal runtime files. To reproduce the GitHub release archive locally:
New-Item -ItemType Directory -Force .\release | Out-Null
Compress-Archive -Path .\dist\MasteryLedger\* -DestinationPath .\release\MasteryLedger-windows-x64-v0.1.3.zip -ForceInstall Inno Setup 6, then compile the one-click installer:
& "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" "/DAppVersion=0.1.3" .\packaging\mastery-ledger.issThe resulting installer is release\MasteryLedger-Setup-v0.1.3.exe. It installs for the current user by default and can be tested without UI:
$testRoot = (Resolve-Path .\.work).Path + "\installer-smoke"
$installer = Resolve-Path .\release\MasteryLedger-Setup-v0.1.3.exe
$process = Start-Process -FilePath $installer -ArgumentList @(
"/VERYSILENT",
"/SUPPRESSMSGBOXES",
"/NORESTART",
"/CURRENTUSER",
"/DIR=$testRoot"
) -Wait -PassThru
if ($process.ExitCode -ne 0) { throw "Installer failed: $($process.ExitCode)" }
& "$testRoot\MasteryLedger.exe" --webview-smoke-test --json
& "$testRoot\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTARTThe installer and portable build include the automatic updater but do not yet have a custom icon or Authenticode signature.
- The review sequence is a product rule, not a proven memory model.
- Local transcription needs the optional
faster-whisperpackage and a model approved by the learner. - Lessons are Markdown files. The app reads them but does not create them.
- The Windows installer is not yet Authenticode-signed.
Mastery Ledger uses the MIT License.
