The alix book
alix is your personal AI tutor — built for understanding, not just
memorizing. It has two faces: a fast, plain-text flashcard core, and an AI layer
woven through it — a tutor on any card, AI-generated decks and curricula, and an
exam that gates your progress on verified understanding.
This book is the manual. The project README’s Directives at a glance table is the quick index; here each feature is expanded with worked examples and the reasoning behind it.
Start with Why alix exists for the motivation, or jump
straight to Getting started.
1 · Why alix exists
Most study tools are built to help you remember. alix is built to help you
understand — and the gap between those two is the reason it exists.
Spaced repetition is one of the few genuinely proven ideas in learning: review a fact just as you’re about to forget it, and it sticks. Tools like Anki turned that into a daily habit for millions. But they share a blind spot. They optimize the retention of isolated facts, and they quietly accept a failure mode every serious user eventually feels: you can answer every card correctly and still not understand the thing. Recognizing an answer is not the same skill as being able to derive it, explain it, or see why it follows. You can have a deck at 100% and a head full of trivia you can’t actually use.
alix starts from that gap. It keeps the proven core — drilling facts on a spaced
schedule — but treats it as only the first step: the part that loads the raw
material. On top of it sit two things ordinary flashcards can’t do.
Traces teach you to follow a mechanism, not just recall a fact. A trace is a walk along a real chain of reasoning through a real source — a data flow through code, the steps of a proof, the clauses of a contract — where at each step you predict what comes next before it’s revealed. It trains the thing experts actually have: not a bag of facts, but the chain of because this, therefore that.
The exam checks that you understood, not that you memorized. Once you’ve
drilled a topic, alix examines you with fresh questions generated from the
source material itself — never from your cards, because grading you on your own
cards is circular and trivially passable. An AI examiner reads your answers
against the source and decides whether you’ve actually got it. Only then does the
topic count as mastered, and only then does it unlock what depends on it.
That last word is load-bearing. alix only calls something mastered when your
understanding has been tested against the ground truth and held up. A green
checkmark you didn’t earn is worse than none — it’s false confidence — so the
examiner is built to be a real examiner, not a flatterer.
Who this is for
alix asks more of you than a flashcard app, and gives more back. It removes the
tedious part — an AI can generate decks, build traces, and lay out a whole
curriculum from sources you point it at — but the work it asks of you is
harder: predicting, explaining, deriving, being examined. It’s a power tool for
people who want to understand something difficult on purpose and want proof that
they do — a new codebase, a field, a hard paper. If you mainly want to cram names
and dates, a simpler tool will serve you better.
The bet
There’s a wager underneath all of this. As AI gets better at holding and
retrieving facts, the scarce thing for a human mind shifts — away from
retention, toward understanding and judgment. The facts you can always look
up. What you can’t outsource is the structure in your own head: reasoning through
a problem, knowing when an answer is wrong, moving fast because you genuinely
grasp the terrain. alix is a tool for deliberately building that structure — and
for using AI not to do your thinking, but to teach and to test it.
The rest of this book is how.
2 · Getting started
Install
alix is a single Rust binary, built from source — you need a Rust toolchain
(install rustup if you don’t have one):
git clone <repo-url> alix
cd alix
make install # or: cargo install --path .
That puts alix on your PATH. Check it:
alix --help
The flashcard core — reviewing, scheduling, every answer mode, browse, the
terminal UI and the web app — runs with nothing else installed, no accounts, no
network. The AI features (deck generation, the exam, traces, explore, and the
ask-Claude tutor) shell out to the Claude Code
CLI, so for those you need it installed and logged in — run claude once to
authenticate (it needs a Claude subscription or API access). You can use the
entire core without ever touching the AI layer.
Your first deck
A deck is a plain .txt file. A card is a # line — the question — with its
answer on the indented lines beneath it:
# What does SRS stand for?
Spaced repetition system.
! It schedules each card just before you'd forget it.
# Which scheduler does alix use by default?
Leitner — a six-stage box with growing cooldowns.
Save it as srs.txt. Indentation is optional (lines are trimmed) — it’s just for
readability. A line starting with ! is a note, shown after you answer.
Review it
alix srs.txt
alix shows the question; you recall the answer, press a key to reveal it, then
grade yourself — again (you missed it), good, or easy. Your grade
moves the card along its schedule, so cards you know come back rarely and cards
you miss come back soon. That self-graded reveal is flip mode, the default;
later chapters cover the modes that make you type the answer, pick from
choices, or reveal it line by line.
When nothing is due, alix says so and exits — come back when cards mature, or
pass --cram to review everything regardless of cooldowns.
The deck picker
Run alix with no arguments to open the picker over your decks directory
(~/decks by default; change it with decks_dir in the config). It groups your
decks into Workspaces, Recent, and Folders and is driven by Vim-style keys
(j/k to move, Enter to open, / to filter by name). This is what the
desktop launcher opens.
The everyday commands
alix browse srs.txt # read through the cards — no grading, no scheduling
alix stats srs.txt # a progress overview
alix list srs.txt # every card with its stage and due time
alix check srs.txt # lint the deck (syntax errors, duplicate cards)
alix reset srs.txt # clear stored progress (also --card / --all)
Give several decks at once and their due cards merge into one session. From here the book goes deep: the next chapter is the deck format in full, then the answer modes and scheduling.
3 · The deck format
A deck is a plain-text file, and the format is deliberately small — you can write
one in any editor with no tooling, and read it back at a glance. It’s loosely
modeled on Markdown: a # heads each card the way it heads a Markdown section,
and a note can hold a fenced code block — so the syntax is already familiar and
most editors highlight it sensibly.
Cards
A card starts with a # at column 0 — the front (the question). The indented
lines beneath it are the answer (the back), and may span several lines:
# What is the capital of France?
Paris.
# Name the three additive primary colors.
Red
Green
Blue
A # only starts a new card at column 0. An indented # is ordinary
answer content — so shell comments, Rust attributes, or Dockerfile lines need no
escaping:
# What does this script print?
echo hi
# this # is just part of the answer
Notes
A line beginning with ! is a note — shown after you answer, never part of
what’s tested:
# Why does TCP open with a three-way handshake?
To agree on initial sequence numbers in both directions.
! SYN, SYN-ACK, ACK — each side learns the other's starting sequence.
Notes render as a quoted block, one sentence per line. A fenced ``` code
block inside a note is shown verbatim — indentation preserved, not reflowed — so
code stays readable. Use notes generously: keep the answer to the thing you
want to recall, and put the why, the example, or the mnemonic in the note.
Comments
A line beginning with % is a comment — ignored, unless it’s one of the
directives covered in later chapters. Use plain % lines to annotate a deck:
% Chapter 4 vocabulary. Reviewed weekly.
Escaping
Lines are trimmed, so you never have to type indentation — it’s purely for
readability. Because #, !, and % are markers, an answer line that must
start with one is escaped with a leading backslash:
# How do you start a comment in Python?
\# like this
The backslash is consumed; the line displays as # like this.
Why editing a deck is safe
A card’s identity is derived from its answer lines (together with the deck’s name) — not from its question, its notes, or its comments. Two consequences are worth knowing:
- You can freely edit comments, notes, and directives, reorder cards, and even reword a question without losing any review history — none of those feed the identity.
- Changing an answer line makes a new card with fresh progress. Two cards
with identical answers in the same deck collide;
alix checkwarns about those.
So a deck is safe to refactor: rephrase, annotate, reorder, add directives — your progress rides on the answers.
Deck directives, in one line
A deck can set its own defaults — the answer mode, the scheduler, and more — with
% key: value lines in the header (before the first card):
% mode: typing
% scheduler: sm2
Because they’re just comments, directives don’t affect card identity, and an explicit command-line flag always overrides them. The full set gets its own Directives reference chapter; the next two chapters cover the ones you’ll reach for first — the answer modes and scheduling.
4 · Review modes
A mode decides how a card is tested — from “reveal it and be honest with
yourself” to “type it exactly.” alix has six. Set one with --mode on the
command line, or per deck or card with a % mode: directive; the effective mode
resolves --mode flag > card’s % mode: > deck’s % mode: > the default
(flip). A small badge above the answer always shows which mode is in play.
The point of having several is to match the test to what you’re training — recognition, exact recall, or understanding.
flip — reveal and self-grade (default)
You read the question, recall the answer, reveal it, and grade yourself: again (missed), good, or easy (easy jumps the card two Leitner stages instead of one). It’s the Anki-style default, and the right choice whenever you can fairly judge your own answer — conceptual questions, explanations, anything open-ended.
# Why is UDP described as connectionless?
It sends datagrams with no handshake and no delivery guarantee.
typing — type it exactly
You type the back of the card character by character, with instant green/red
feedback. Tab reveals the next two characters as a hint (press again for two
more), but a card you needed a hint on counts as failed. Use it where the answer
must be exact — syntax, spellings, command flags, a formula.
# Stage every change in git, including deletions?
git add -A
% mode: typing
fuzzy — type it, typos forgiven
Like typing, but you submit a whole line with Enter and small typos are
tolerated (the tolerance is configurable; --max-typos defaults to 2). When the
answer is several lines, each is checked and their order doesn’t matter. Reach for
it when you want the effort of producing the answer without being failed for a
slipped key.
A wrong answer in typing or fuzzy drops the card to stage 1 and brings it back
later in the same session until you get it.
choice — pick from four
You choose the answer from four options with 1–4. The three wrong options are
sampled automatically from the other cards’ answers (preferring similar-looking
ones — years compete with years), so you never have to write distractors.
Recognition is easier than recall, so a correct pick grades good (never easy)
and a wrong pick fails. If a session has fewer than four distinct answers, the
card falls back to flip.
line — one line at a time
The back is revealed one line at a time: press the reveal key (Space), recalling
each line before you uncover it; once the whole card is shown you grade yourself
like flip. It’s for ordered material — lyrics, poems, a sequence of steps. Pair it
with % order: sequential so the deck walks top to bottom (one card per verse,
say).
explain — open prompt, key points
The back lines aren’t a string to reproduce — they’re the key points a good
answer should cover. You optionally type an explanation, reveal the points, and
grade yourself on whether you hit them. It’s for cards aimed at understanding
rather than recall. The typing is never checked — a self-graded mode can’t verify
your answer, so it doesn’t pretend to; it’s there to make you commit before you
peek. explain pairs with the ask-Claude tutor and is the everyday, self-graded
tier beneath the AI exam (a later chapter).
# Explain why spaced repetition beats massed review.
Retrieval just before forgetting strengthens memory the most.
Spacing forces effortful recall; cramming lets you coast on short-term memory.
% mode: explain
To drop a card mid-session, press the remove key (Ctrl-X by default) instead
of grading it: it leaves the session and is deleted from the deck file when you
finish.
5 · Scheduling, stages & completion
Spaced repetition is really just bookkeeping: each card remembers how well you know it and when to show it next. This chapter is that bookkeeping — the scheduler, the stages, and how a whole deck reaches “done.”
Pick a scheduler with --scheduler or a deck’s % scheduler: directive (it’s
deck-level only).
Leitner (default)
A box system. Each card sits at a stage, and each stage has a cooldown before the card comes due again:
| Stage | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
| Cooldown | now | 1 hour | 6 hours | 1 day | 1 week |
Grading moves the card between stages:
- again (fail) → back to stage 1
- good (pass) → up one stage
- easy → up two stages
So a card you keep getting right climbs to longer and longer intervals, and a miss sends it back to the bottom of the ladder. It’s predictable and needs no tuning — a good default.
SM-2
SuperMemo-2 spacing, with a per-card ease factor. Passing grows the interval
(roughly 1 day, then 6 days, then interval × ease); the ease nudges up or down
with each grade and never drops below 1.3; and a fail sends the card to a short
10-minute relearn. It adapts the spacing to each card’s difficulty instead of
using fixed steps. Switching schedulers is safe: SM-2 seeds itself from your
existing Leitner progress and keeps the Leitner stage in sync, so you can move
between the two without losing your place.
Retiring cards
A card doesn’t climb forever. Once it reaches the top stage (5) by passing, it
retires: it rests and is no longer scheduled, not even under --cram, until
you alix reset. A deck is finished once all its cards have retired.
Completion states
A deck’s state is derived from its cards’ stages, and shown in the picker and
alix stats:
- not started — you haven’t reviewed any card yet
- started — somewhere in between
- finished (
done ✓) — every card has retired at the top stage
A deck that declares a % source: adds one state in between — exam due. For
those decks, drilling the cards no longer finishes them: passing the AI exam
does, which marks the deck mastered. That’s the subject of a later chapter.
Unlocks, in one line
Completion also drives dependencies, with no extra syntax: a deck is locked
while any deck it % requires: isn’t finished, so finishing a foundation unlocks
what builds on it. The lock is advisory and recomputed live — the dependencies
chapter covers it in full.
Cramming
Need to review everything now, schedule be damned — the night before an exam?
--cram ignores cooldowns and shows every card that isn’t retired:
alix --cram mydeck.txt
Retired cards stay out (that’s what retirement is for); everything else is fair game regardless of when it’s next due.
6 · Cloze, dual-direction & image cards
Three extensions to the basic card, each just a small directive on top of the format from chapter 3.
Cloze cards — fill in the blank
Mark a front with #? (no space) and the card becomes a cloze: every {{...}}
span in its answer lines is a blank, and the card expands into one sub-card per
blank.
#? Complete the Rust declaration
let {{mut}} x: {{u64}} = 0;
This makes two cards. One blanks mut and shows the rest; the other blanks u64.
The asked blank shows as ____; the other blanks are hidden as […], so no
card gives away its siblings’ answers — you only produce the hidden text.
Only the doubled braces are special: a lone { or } is literal, so an answer
like let p = Foo {}; is fine inside a cloze (and if you ever need a literal
{{, write \{\{).
alix keeps a card’s cloze siblings apart in the queue when other cards are
available, so you don’t see mut right after u64. Cloze progress is forgiving:
rewording the front — or even a later change to the blank markup — keeps your
history, while editing the answer text or what’s inside a blank resets the
affected blanks.
Reach for cloze when the context is the cue: a definition with its key term removed, a line of code with the operative token blanked.
Dual-direction cards — % direction:
A % direction: directive reviews a card both ways — exactly what you want for
vocabulary and other reversible facts:
# purported
angeblich
% direction: both
bothmakes two cards —purported → angeblichand the swapangeblich → purported.reversekeeps only the swapped one.forward(the default) is the card as written.
Like mode, it works per card or deck-wide (a % direction: both header with
per-card overrides). The two directions get distinct progress, are kept apart
in the queue (you won’t be shown one right after the other), and are removed
together; the reversed card keeps the note. It’s best for single-line cards, and
it doesn’t apply to cloze cards.
Image cards — % img:, % img-back:
A card can carry an image on the question side, the answer side, or both:
% img-dir: ~/decks/img
# What phase is the moon in?
% img: moon-waxing.png
Waxing gibbous
# Play this chord.
G major
% img-back: g-major-tab.png
% img: shows on the front, % img-back: on the back (revealed with the answer)
— one image per side. Filenames resolve against the deck’s % img-dir: (a
header-only directive, absolute or relative to the deck file); without one they
resolve next to the deck file, and an absolute path written on the card is used
as-is.
One catch worth knowing: images render in the web frontend only — a terminal
can’t draw them. So an image card is automatically web-only (as if it declared
% frontend: web): alix review in the terminal skips it with a note, and if a
whole deck is images it points you at --serve to open it in the browser. alix check warns about an image file it can’t find, but doesn’t fail on it.
Source citations
A plain fact card can show where its answer comes from. Give the card a % at:
locator into the deck’s % source:, and on reveal it offers to swap the worded
answer for the exact source lines:
% source: src/string.rs
# What does the `String` struct hold?
A `Vec<u8>` (its bytes).
% at: src/string.rs:1-3
The locator is the same shape a trace checkpoint uses:
file:lines (e.g. src/string.rs:1-3), or just lines when the % source: is
a single file. On reveal a </> marker appears on the answer — in the web,
click the answer (or press s) to flip it to the line-numbered excerpt and
back; in the terminal, press s. The lines are read live from the source,
so a moved or deleted file shows “source unavailable” rather than a stale quote.
This is the same machinery trace walks use to reveal source, brought to ordinary
fact cards — so a card that asks what a thing is can also show you where it
lives. Like all % directives, % at: is invisible to the identity hash: adding
a citation to an existing card never resets its progress.
You rarely have to write these by hand. Generating a deck from a local source —
alix deck <path> or
alix explore --build — cites the lines each fact came from,
and alix check warns about a citation that no
longer resolves, so a moved or shrunk file is caught before you next review the
card. A workspace built with alix explore --into --build goes one further and
freezes the cited excerpts into its assets/ (just like trace excerpts), so
the citations never drift and the workspace travels without the original source.
7 · Directives reference
Every card marker and % key: value directive in one place. Scope is where
each may appear — deck = the header (before the first card), card = after a
card’s front, anywhere = both. Each links to the chapter that explains it in
full.
| Token | Scope | What it does |
|---|---|---|
# front | card | Starts a card at column 0; the indented lines below are the answer. → ch 3 |
#? front | card | A cloze card; blanks are {{spans}} in the answer line. |
! line | card | A note, shown after you answer. → ch 3 |
% line | anywhere | A comment — ignored, unless it’s one of the directives below. |
% mode: | deck · card | Answer mode: flip, typing, fuzzy, choice, line, explain. |
% order: | deck | Card order: scheduled (default) or sequential. → ch 5 |
% scheduler: | deck | Scheduler: leitner (default) or sm2. |
% direction: | deck · card | Review direction: forward, reverse, both. |
% unlock-stage: | deck | Stage that opens the gate 1–5: the exam/unlock fires once every card reaches it (cards keep drilling). |
% frontend: | deck · card | Restrict to any, tui, or web. → ch 6 |
% img: / % img-back: | card | Image on the front / back (web only). |
% img-dir: | deck | Base directory image filenames resolve against. → ch 6 |
% title: | deck | Display name shown instead of the file name. |
% requires: | deck | Prerequisite deck that gates unlocks (repeatable). |
% link: | deck | ask-Claude reference URL — tutor-only (repeatable). |
% source: | deck | Exam ground truth (URL/file, repeatable); also a trace’s path origin, and a tutor reference. |
% strictness: | deck | Exam grading rigor: strict, balanced, lenient. |
% trace: | deck | What a trace walks; its presence makes the deck a trace. |
% at: | card | A locator into the % source: (file:lines): a trace checkpoint’s reveal target, or a fact card’s source citation shown on reveal. |
% given: | card | A trace checkpoint’s off-screen symbol, as name — meaning (repeatable). |
% link: vs % source:
Two that look similar but aren’t. Both point at material a deck is about, but
% source: is the exam’s ground truth — questions are generated from it and
answers graded against it — and a URL source doubles as a tutor reference.
% link: is only a tutor reference and never becomes exam material; use it for
supplementary reading the exam should ignore. The implication runs one way: a
% source: URL is offered to the tutor, but a % link: is never promoted to a
source.
Precedence
Where a setting can come from several places, the more specific wins:
CLI flag > card
%directive > deck%directive > workspace[defaults]> built-in default
So --mode on the command line overrides a card’s % mode:, which overrides the
deck’s, which overrides a workspace’s [defaults], which overrides alix’s default.
8 · Workspaces
As your decks multiply, you’ll want to treat a cluster of them as a unit — all your Spanish decks, or every deck about one codebase. A workspace is that unit: a folder of decks reviewed together, sharing settings and a name, with its own progress.
Making a workspace
Any folder of .txt decks becomes a workspace the moment you drop a alix.toml
in it — a scoped version of the global config file. It sets a title and a
[defaults] table of directives that every deck in the folder inherits:
# ~/decks/spanish/alix.toml
title = "Spanish"
[defaults]
direction = "both"
mode = "typing"
Now review the whole cluster at once:
alix review ~/decks/spanish/
Shared directives
The [defaults] keys are exactly the deck-directive names from
the deck format — mode, direction, scheduler, and
the rest. They fill in only what a deck doesn’t set for itself, so the
precedence is one level deeper than before:
CLI flag > card
%> deck%> workspace[defaults]> built-in default
Set direction = "both" once for the whole folder, and a single irregular deck
can still override it with its own % direction: forward. It’s the same directive
system from chapter 3, just sourced from one more place.
Its own progress
A workspace keeps its progress inside the folder, in a progress.json next to
the decks (override the location with a store = "..." line in the alix.toml),
separate from the global store that loose decks share. That makes a workspace a
self-contained, portable unit: its decks, its assets/ (frozen trace
excerpts — covered with traces later), and its history all live in one folder you
can move, copy, or share, with its progress isolated from everything else. Decks
outside any workspace keep using the global store; --store <path> overrides
either.
In the picker
Folders show up in the picker (terminal and web) in two flavors: a folder with a
alix.toml appears under Workspaces, one without as a plain Folder.
Opening either drills in to its decks, drawn as a dependency tree — each deck
nested under the prerequisite that gates it, foundations at the roots (the
next chapter). Each row is badged · deck · or · trace ·,
and the drill-in is a single-launch list: Enter on a facts deck reviews it,
Enter on a trace walks it. Typing a filter flattens the tree to a plain
search.
alix workspace <dir> jumps straight into that drill-in view, routing each
member to the right experience — a facts deck to a review, a trace to a walk — and
returning you to the picker when you finish one. (alix review <dir>, by
contrast, flattens the whole folder into one merged review, so trace decks get
quizzed as plain cards — usually not what you want for a workspace that holds
traces.)
A folder without a manifest is still reviewable with alix review <folder>; it
just applies no shared directives.
Titles
A title in the alix.toml — or a % title: directive on a single deck — gives
a display name, shown in the picker, the session header, alix list, and alix stats, instead of the file name. It’s display-only: you still refer to decks by
file path on the command line, and a title never affects a card’s identity.
9 · Dependencies & unlocks
Real subjects have an order: you can’t grasp borrowing before ownership, or a
derived rule before its axioms. alix lets a deck declare what it builds on, and
uses that both to sequence your study and to gate decks until you’re ready.
Declaring prerequisites — % requires:
A deck names its prerequisites with % requires: lines in the header
(repeatable):
% requires: rust-ownership
% requires: rust-references
# What does the borrow checker prevent?
Aliasing a value while it's mutably borrowed.
A name resolves next to the requiring deck or in your decks directory, with or
without the .txt. Like all directives these are plain comments, so adding or
changing them never touches card progress. A missing prerequisite or a dependency
cycle is reported as an error.
Foundations first
When you review a deck, its prerequisites are pulled into the session
automatically — transitively and de-duplicated — and ordered foundations
first: a prerequisite’s cards (both due reviews and freshly introduced ones)
come before the cards of the deck that depends on it, while each deck keeps its
normal scheduler order internally. So reviewing borrowing quietly refreshes
ownership first.
A prerequisite contributes only its cards, not its settings — the mode,
order, and scheduler come from the deck you actually asked to review, so
requiring a % mode: line lyrics deck won’t switch your session into line mode.
(Dependencies apply to review only; browse and stats work on exactly the
decks you name.)
Editing without typos — alix deps
To change a deck’s prerequisites without hand-editing, use alix deps <deck>
(alias alix require):
alix deps borrowing.txt
It opens the deck picker over your decks directory, pre-ticked to the current
prerequisites: Space toggles, Enter saves (rewriting the % requires: lines),
Esc cancels, and unticking everything clears them. Because the lines are
comments, editing dependencies never disturbs card progress.
Unlocks
The same % requires: graph drives unlocks, with no extra syntax. A deck is
locked while any of its prerequisites isn’t finished — every card retired,
the completion state from chapter 5. Finish a foundation and
the decks that build on it open up; locked decks show dimmed with a 🔒 in the
picker.
The lock is advisory, not a wall: you can still pick a locked deck, and its prerequisite cards are pulled in foundations-first anyway, so you’re never truly stuck. And it’s recomputed live — if a finished deck later lapses below the top stage, its dependents lock again, nudging you to shore up the foundation before moving on.
This is what turns a folder of decks into a curriculum: order the material by
% requires:, and alix walks you through it foundations-first, gating each step
on the last. It’s also the backbone of the AI exam’s notion of mastery (a later
chapter) and of how alix explore lays out a generated learning plan.
10 · Ask-Claude — the tutor
This is where the AI layer begins. Everything so far — drilling, scheduling,
workspaces — runs entirely offline. From here on alix can call Claude, and the
first place it does is the most useful: a tutor on any card.
(One reminder: every AI feature shells out to the Claude Code CLI, so it needs the CLI installed and logged in — see chapter 2. The flashcard core never calls it.)
Asking about a card
On any post-answer screen — a revealed flip card, the feedback after a typed
answer, an answered choice — press ?. alix hands Claude the card (its front,
answer, note, and deck name) as context, and you can ask “why is that the
answer?”, “what’s a simpler way to see this?”, or anything else, and follow up.
While Claude thinks the session stays responsive; Esc drops you back exactly
where you were.
One conversation spans the whole review run (alix uses --session-id for the
first question and --resume after), so Claude remembers the earlier cards and
questions — you can ask how the current card relates to one from ten minutes ago,
and it knows.
In the browser
It works in the web frontend (--serve) too: an Ask button (or the ? key)
on an answered card opens a chat panel — type a question, Send, Save note,
Close. The server runs claude -p on a background thread and the page polls
for the reply, so the single-threaded server never blocks. Ask is available
wherever you serve, including over --lan — but the request runs claude on the
host machine, so, like --lan in general, only enable it on a network you trust.
Saving what you learn — Ctrl-N
When an exchange clears something up, press Ctrl-N: Claude condenses the
conversation into at most three short note lines and appends them to the card in
its deck file. Notes aren’t hashed, so the card’s progress is untouched — you just
keep the insight. (In the web panel, Save note does the same.)
Reference links — % link:
A deck can point the tutor at background reading with % link: comment lines:
% link: https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
% link: https://tokio.rs/tokio/tutorial
These are handed to Claude with your first question as material to consult when
useful — fetched once and remembered for the rest of the run. They’re tutor-only:
unlike % source: (the exam’s ground truth, covered next chapter), a % link:
never becomes exam material. And like every directive, they don’t affect card
hashes.
How it’s sandboxed
Because the CLI runs headless (claude -p), it can’t show interactive permission
prompts — an unanswerable prompt would just hang the call. So alix runs it locked
down: --permission-mode dontAsk plus an exclusive tool allowlist (WebFetch,
WebSearch by default). The listed tools work without prompting; every other tool
is silently denied. That means a malicious page behind a deck link can’t make the
tutor run shell commands or touch your files. Both the permission mode and the
allowlist live in the [ask] section of the config, along with the command, a
--model override, and the timeout.
11 · Generating decks — alix deck
Authoring cards by hand is the slow part of any flashcard habit. alix deck
removes it: point it at a source and Claude drafts a deck of fact cards for you.
alix deck https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
alix deck src/scheduler.rs # a local file (or a whole directory)
The source is a web page URL or a local file/directory — the deck-side
mirror of alix trace (a later chapter), which builds traces from the same
kinds of source.
What you get
Claude reads the source and returns a deck spread across four layers of
understanding — facts → concepts → application → connections — using cloze
(#?) cards for terminology. The prompt has it draft, then re-read the whole set
and merge or drop cards that test the same fact, so the deck doesn’t repeat
itself. alix validates the text it gets back (it only ever accepts cards, never a
write or shell command) and writes it to ~/decks/<slug>.txt.
How the source is recorded depends on its kind, and it matters later:
- A web page is read with the
WebFetchtool, and the deck opens with a% link:line back to it — so the ask-Claude tutor can consult the page on your cards. - A local source is explored read-only with
Read/Glob/Grep, and the deck opens with a% source:line — so the AI exam can later grade your understanding against that same source (next chapter). Each fact that maps to specific lines also gets a% at:citation, so you can flip the card to its source on reveal.
Useful flags
alix deck <source> -o ownership # choose the output file name
alix deck <source> --cards 15 # cap the number of cards
alix deck <source> --review # a 2nd pass that dedups and tightens
alix deck <source> --print # print to stdout instead of writing a file
--review runs a second Claude call that takes the draft and returns a
deduplicated, tightened version. It costs an extra call, but it’s worth it when
the source is repetitive. The prompt and limits — model, timeout_secs
(default 300), max_cards (default 30), and an extra instruction field — live
in the [generate] section of the config.
Generate, then own it
A generated deck is just a plain-text deck like any other: read it, edit it, cut
the weak cards, add your own. Treat the output as a strong first draft, not
gospel — the point is to skip the blank page, not to outsource judgment. That’s
the same division the whole tool runs on (see how alix was made).
12 · The AI exam — alix exam
This is the feature the whole tool is built around. Drilling cards loads a deck’s material into memory; the AI exam checks that you actually understood it — and passing the exam, not merely finishing the cards, is what marks a deck done and unlocks what depends on it.
The reasoning: recall isn’t understanding. You can drill every card and still not see how the ideas connect. So a deck can name a ground-truth source and require you to pass an exam against that source before it counts.
Declaring a source — % source:
Name one or more sources in the deck header — a URL or a local file path, repeatable:
% source: https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
% source: notes/ownership.md
A URL % source: doubles as an ask-Claude reference, so you
needn’t repeat it as a % link:. The reverse doesn’t hold: a % link: stays
tutor-only and never becomes exam ground truth — keep supplementary reading (a
blog post, an SO answer) as % link: so the exam ignores it.
Once every card in a sourced deck reaches the top stage, the deck is exam due
rather than finished — drilled, but not yet counted, so it doesn’t unlock its
dependents yet. To open the exam earlier, while the cards keep drilling, set
% unlock-stage: N: the deck turns exam due once every card reaches stage N
(a source-less deck becomes finished at that stage instead, unlocking its
dependents directly).
Sitting the exam
The exam is a guided, one-question-at-a-time flow — answer, move Back/Next, then a per-question breakdown — identical in the terminal and the browser. You reach it three ways:
- Directly:
alix exam ownership.txt(with--questions 8,--strictness …if you like). - From the picker: choosing an
exam duedeck starts the exam instead of an empty review. - From the summary: when you drill a deck’s last cards and it turns exam due,
the session-end summary offers it — press
xin the terminal (orbto browse the deck instead), a button in the browser.
alix asks Claude to read the source (URLs via WebFetch, local files embedded)
and write fresh understanding questions — application and connections, not
the card facts — each with the key points a correct answer must hit. You type a
prose answer per question, and an examiner grades each Pass / Partial / Fail
against the source’s rubric, never against your cards (grading the cards would
be circular). The Claude calls run on a background thread, so the UI stays
responsive while it thinks.
- Pass (every question by default — tune with
pass_threshold) marks the deck mastered (mastered ✓). Mastery, not mere drilling, is what unlocks decks that% requires:this one. Source-less decks are unaffected: finishing them just means drilled (done ✓). - Fail lists the gaps and offers to turn them into remediation cards
appended to the deck — a cloze/plain card for a missed fact, a
% mode: explaincard for a missed concept, with overlapping gaps merged. Re-drill those and re-sit.
Resetting a whole deck (alix reset <deck>) also clears its mastered state, so a
re-drilled deck must pass again; resetting only individual cards (--card /
--cards) leaves mastery intact.
Strictness — match the rigor to the material
How hard each answer is judged is a property of the material, so it’s per deck. A
checklist topic — a procedure, exact syntax, a security drill — should fail you for
omitting a step; a conceptual topic shouldn’t. Set it with a % strictness:
header directive (or alix exam --strictness …, or the [exam] default):
- strict — completeness required: every rubric point must be present, so omitting one is a gap.
- balanced (default) — judges understanding, not phrasing: a point counts if your answer shows you grasp it, even briefly; only a wrong or genuinely-absent idea is a gap.
- lenient — benefit of the doubt: only clearly wrong or unanswered points are gaps.
This dial (how hard each answer is judged) is independent of pass_threshold (how
many answers must pass). Both, plus model, timeout_secs (default 300),
num_questions (default 5), and an extra guidance field, live in the [exam]
config section.
Why this is the centerpiece
Everything else serves this. The drilling loads the facts; the exam is the gate
that turns “I reviewed it” into “I understood it, and here’s the check.” It’s also
why mastery — not completion — drives unlocks: a curriculum
should open the next door only when you’ve genuinely passed through the last. The
everyday, self-graded rehearsal for it is explain mode
(chapter 4); the exam is the real thing.
13 · Trace decks — alix trace
Experimental. Traces are new and still evolving — the deck format and the flow may still change.
Cards drill facts — the nodes of what you know. A trace drills the connections between them — the edges — by walking a path through a real source and making you predict each hop before it’s revealed. Where the AI exam verifies a set of independent answers, a trace verifies you can follow one chain of reasoning, and the gap between your prediction and the truth is where the understanding forms.
This is the most direct expression of the book’s opening bet: understanding is the chain of because-this-therefore-that, and a trace makes you build that chain yourself.
What a trace looks like
A trace is a deck with a % trace: (a path description — what it walks, and the
thing that marks the deck a trace) and a % source: (the path’s origin), then a
sequence of checkpoint cards. Each checkpoint is an explain-style card — an
open predict prompt and the key points a good prediction should hit — plus a
% at: locator pointing at the real lines in the source:
% trace: how pressing the Good key in the browser becomes a saved grade
% source: ..
# You press Good. What does the page send the server — and what does it not?
grade(g) POSTs to /api/grade with a body of just { grade: g } — no card id.
% at: assets/serve/review.html:338-341
! The page is a thin view; it doesn't even track card identity.
# So the request has no card id. How does the server know which card you graded?
The handler grabs the live, server-side review session and grades on it.
% at: src/serve.rs:682-689
! State lives server-side; the page only ever names the grade.
The % at: locator is a single contiguous range file:start-end (or just line
numbers when % source: is one file) — never comma-separated, since a stitched
excerpt makes disjoint code look adjacent. The lines are read live from the
source each walk, so the excerpt is always current and the deck stays small —
the source is the oracle, not an invented answer. When a tight excerpt leans on a
symbol defined off-screen, name it with a % given: line (% given: state — the parser's position so far, repeatable); these show as a list under the question,
so the excerpt stays focused without orphaning the names it needs.
Building it with Claude — --build
You don’t have to hand-write checkpoints. Declare just the % trace: and
% source:, then:
alix trace --build mytrace.txt
Claude explores the source — read-only Read/Glob/Grep, source root as
its working directory, no write or shell access — finds the single load-bearing
path, and writes the checkpoints (with their % at: locators) back into the deck.
The result is cached and version-controlled there, so review it (especially the
locators) and edit freely; re-run --build to regenerate.
Building is one-shot, correctness-critical, and fails silently when the model
is weak — you still get parseable checkpoints, just a loose chain you then drill.
So the [trace] config defaults the build to a strong model (model = "opus")
and high reasoning effort (effort = "high"): slower than the other AI features,
but it runs once and is amortized over many reviews. --suggest shares those
settings; --grade does not (it’s a light per-hop call at the tutor tier).
Don’t know what to trace? — --suggest
alix trace --suggest .
does a single read-only recon pass over a source (a repo ., a directory, a file,
or a URL) and prints a ranked menu of candidate traces — each a path-question,
a one-line spine sketch, and a suggested % source: scope. The list is sized by
coverage (the central spine plus one main path per major subsystem), so it’s
as long as the source needs. It also names the node-shaped subsystems it skips —
a config table, a store’s on-disk format — as facts-deck material, because
facts are a deck’s job and edges are a trace’s. It writes nothing: pick one, paste
its header into a new deck, and --build it. Knowing what is worth tracing (and
how deep) is the genuinely hard part — it needs you to already understand the
source — so this hands that judgment to Claude.
Write it as a chain, not a quiz
A trace’s whole value is that it’s a path: each checkpoint picks up where the last reveal left off (notice how hop 2 above opens with hop 1’s conclusion, “the request has no card id”), so you follow one thread — a data flow, a control flow, a derivation — to an outcome. If the checkpoints are independent facts hanging off one thing, you’ve written a set, which is what cards and the exam already do; choose a subject with a real sequence instead.
Walking it
alix trace keypress-to-grade.txt
goes hop by hop:
- Predict — type a guess before anything reveals (committing is the point).
- Reveal —
alixprints the real excerpt from the source, then the key points and note. - Gap — you judge yourself Got it / Partial / Missed. Self-judged and
offline by default; pass
--gradeto have Claude judge your typed prediction against the key points and return a verdict plus a line of feedback (a model call per hop). Either way, a Partial or Missed is a weak edge that resets and resurfaces sooner; a nailed hop advances and fades. Each checkpoint is an ordinary card underneath, so this is the normal per-card SRS. - Compress — after the last hop, restate the whole path in two sentences. If you can re-derive it, you understood it.
In the browser: alix trace <deck> --serve walks it in the web frontend — a
path rail you descend (nodes coloring in by Got / Partial / Missed) with each
checkpoint’s source shown in a line-numbered excerpt; --serve --grade does the
live grading. Progress saves to the same store, so a walk started in the terminal
continues in the browser.
alix trace <deck> --map prints the route — every prompt, key points, and
locator — without quizzing. And the generic alix exam refuses a trace (it points
you here): a trace’s verification is its predict-verify walk plus the
compression, scoped to the path.
Snapshotting
Because % at: file:lines reads the live source, editing a traced file would
shift every excerpt to the wrong lines. So when you create a workspace by exploring
a source (alix explore --into --build), its final step
freezes the cited excerpts into the workspace’s assets/ folder — one tiny
snippet per checkpoint — and repoints each % at: at them, so they never drift and
the workspace is self-contained, without copying whole files. (A re-based snippet
loses its original line numbers, so when those matter the original is kept in the
card’s note: ! from scheduler.rs:90-98.) It’s automatic for explored workspaces;
a loose trace over a live source is left as-is. The rationale is in
docs/traces.md.
Checking the locators
For a trace that isn’t frozen — a loose .txt over a live % source: —
alix check validates that every % at: still
resolves into its source: it warns about a locator that names a missing file,
runs past the end of the file, or (for a single-file source) gives bare line
numbers it can’t place. It’s a quick structural check — does this excerpt still
exist? — so a moved or trimmed source is caught before you walk into it, not
mid-hop. (Frozen snapshots don’t move, but their snippets are validated the same
way.)
A trace deck degrades gracefully — even without alix trace it’s a valid deck of
explain cards. See examples/keypress-to-grade.txt for a complete trace over
this repo’s own source.
14 · Explore — goals & curricula
alix trace --suggest lists central traces. alix explore goes a layer
up: give it a goal and it prints an ordered learning plan — the facts decks
and traces worth authoring to reach that goal, dependency-ordered.
alix explore . # a plan to understand the whole source
alix explore . --goal "how review scheduling works" # a narrow goal → a focused subset
Each item is tagged [trace] or [deck], chosen by the shape of the
knowledge: a path you predict hop by hop becomes a trace; a table of facts —
a config’s knobs, a store’s on-disk format — becomes a facts deck. Each carries its
% requires: prerequisites (the list is a valid dependency order, foundations
first) and a % source: scope. The --goal scopes coverage: a broad goal spans
every subsystem; a narrow one collapses to its slice and traces it in more detail.
By default it’s read-only — it prints the plan and you author the items yourself
(alix trace --build a trace, alix deck a facts deck).
Materializing a workspace — --into
alix explore . --goal "how review scheduling works" --into ~/decks/scheduling/
writes a ready-made workspace: an alix.toml (carrying the
goal) and one stub per item — a % trace: deck per trace, a % title: facts
deck per deck — wired together with % requires: so they unlock in dependency
order, each % source: pointing back at the real source. (It refuses a non-empty
folder unless --force.) You then fill the stubs at your own pace.
Filling it in one shot — --into --build
alix explore . --goal "…" --into ~/decks/scheduling/ --build
goes all the way: alix explores the source once, then reuses that single
session to fill every item — predict-verify checkpoints for the traces, fact cards
for the decks — so the workspace comes out review-ready in one command. Writing the
whole set from one understanding keeps the items coherent (each builds on its
prerequisites instead of repeating them). As a final step it
freezes the cited excerpts of every cited deck — traces and
fact decks with % at: citations
alike — into the workspace’s assets/, so it’s self-contained and its locators
never drift.
This is the tool’s high-water mark: name what you want to understand, and alix
assembles a dependency-ordered curriculum of facts and traces — gated by
mastery — that you climb.
The explore walk — --walk
Before you even know what to trace, alix explore --walk <source> builds a short
tour of the source’s shape and walks it like a trace: you predict what kind of
program it is (from the manifest), its domain nouns (from the module list), how
it’s driven (the entry point), its spine (the central file), and finally the first
paths worth tracing — each hop revealing the real lines. It’s written to a file
(-o, default explore.txt), so alix trace explore.txt re-walks it.
15 · The web app — --serve
Everything alix does in the terminal it can also do in a browser. Add --serve
to review or browse (or run alix --serve with no decks) and it runs the same
session logic over a tiny local web server, writing to the same progress store
— so a card you grade or remove in the browser shows up on the command line and
vice versa. It’s handy on a tablet or phone, where touch (and images) beat a TUI.
alix review rust.txt --serve # open http://127.0.0.1:7777
alix review rust.txt --serve --port 8080
alix review rust.txt --serve --lan # reachable from other devices on your network
alix browse rust.txt --serve
alix --serve # no decks → pick them in the browser
Choosing decks in the browser
Run --serve without naming decks and the page opens the deck-selection
screen — the same list as the terminal picker. Tap a deck to start it (in review
a locked deck won’t start; browse ignores locking), or tick several checkboxes
and Confirm to start them as a merged session. After a session, “Choose other
decks” (on the summary or the ⋮ menu) returns here, so you can switch decks without
restarting. Naming decks on the command line skips this screen.
Every mode, plus the AI features
All answer modes work in the browser — flip, line (it auto-scrolls to the newest line), typing/fuzzy (each line marked ✓/✗ with the correct answer shown), and choice (tap an option). Controls are big tap targets and follow your configured key bindings (the page reads them from the server). The ⋮ menu holds Remove and Choose decks.
The AI features come along too: the ask-Claude tutor, the AI exam, and trace walks all have a web surface, each running its Claude call on a background thread while the page polls — so the single-threaded server never blocks.
Local by design
The server is deliberately local-only — no accounts, no database. By default it
binds to 127.0.0.1 (this machine only). --lan binds all interfaces so another
device on your network can reach it at http://<your-ip>:<port>, but there’s no
authentication, and AI requests run claude on the host — so only use --lan on
a network you trust. The default port lives in the [serve] config section;
--port overrides it.
16 · Configuration
alix works out of the box; the config file is for when you want to change key
bindings, point at a different decks directory, or tune the AI features. It lives
at ~/.config/alix/config.toml — create it with alix config --init, and
inspect the active key bindings with alix config.
Key bindings
Every action takes a list of keys (the first is shown in the footer). To grade flip
cards with j/k/l:
[keys]
again = ["j"]
good = ["k"]
easy = ["l"]
Keys are a single character ("j"), a special name ("space", "enter", "tab",
"esc", "backspace"), or either with a ctrl- prefix ("ctrl-s"). The
rebindable actions are again, good, easy, reveal, hint, submit, skip,
remove (default ctrl-x), continue, restart (default r), and quit. While
you’re typing an answer (typing/fuzzy mode), plain-character bindings are ignored so
they can’t shadow your input — use ctrl-/special keys for hint, skip, and
quit there. Pass a different file with --config <path>.
alix browse has its own [browse] bindings, and the web server reads its
default port from [serve]:
[browse]
next = ["l", "n", "space"]
prev = ["h", "p"]
remove = ["x"]
quit = ["q", "esc", "ctrl-c"]
[serve]
port = 7777
(Jump-to-first/last stays fixed at g/G, and the arrow keys always move.)
The AI sections
Each AI feature has its own section, all reusing the [ask] command and permission
settings:
[ask]— the tutor:command(how to invoke Claude),permission_mode, the tool allowlist, amodeloverride,timeout_secs, and aneffort.[generate]—alix deck:model,timeout_secs(300),max_cards(30),extra, a fullpromptoverride, andreview.[exam]—alix exam:model,timeout_secs(300),num_questions(5),pass_threshold(1.0),strictness(balanced),extra.[trace]—alix trace --build/--suggest: defaultsmodel = "opus"andeffort = "high"(the build is correctness-critical and amortized); alsotimeout_secs.--gradeinstead uses the[ask]tier.
Decks directory and storage
By default alix looks for decks in ~/decks; set decks_dir to change it.
Progress is stored at ~/.local/share/alix/progress.json (a workspace keeps its
own inside its folder; --store <path> overrides).
Card identity is an XxHash64 over the deck file name plus the card’s back lines — so your progress survives editing a front or adding notes, but renaming a deck file or changing a back line resets the affected cards. (That’s the “editing is safe” rule from chapter 3, stated precisely.)
alix reset <deck> clears progress so cards go “new” again — a whole deck, a
single card (--card <id-or-front>), or the entire store (--all); it confirms
first unless you pass -y.
17 · Command reference
A quick index of the alix commands. Each links to the chapter that covers it in
depth, where there is one. Run any command with --help for its full flags.
Reviewing
alix— open the deck picker (recent +~/decks).alix <deck>...— review due cards; several decks merge into one session.alix review <deck-or-folder>...— the same, explicit, and how you review a workspace folder.alix browse <deck>...— read through cards with no grading or scheduling.alix workspace <dir>— open a workspace, routing each member to a review or a walk.
Common flags: --mode <m> (modes), --scheduler <s>
(scheduling), --cram, --new N, --limit N, --max-typos N,
and --serve / --port / --lan (the web app).
Progress
alix stats <deck>...— progress overview and completion state.alix list <deck>...— every card with its stage and due time.alix reset <deck>...— clear progress (--card,--cards,--all;-yto skip the prompt).alix check <deck>...— lint a deck (syntax, duplicate cards, trace% at:locators).alix deps <deck>(aliasrequire) — edit% requires:with a checkbox picker (dependencies).
The AI features
alix deck <url-or-path>— generate a facts deck.alix import <file.tsv>— import an Anki TSV export (no Claude needed).alix exam <deck>— the AI exam (--questions,--strictness).alix trace <deck>— walk a trace (--build,--suggest,--grade,--map,--serve).alix explore <source>— an ordered learning plan (--goal,--into,--build,--walk).- Ask-Claude —
?in a session,Ctrl-Nto save a note (the tutor).
Config
alix config— show the active key bindings;alix config --initwrites the file.--config <path>— use a different config file.
How alix was made — written by the actual human
TBD