Cosimo is a spaced-repetition system for learning prompt/response pairs with a screen-reader-accessible desktop interface. Accessibility is a hard project requirement, not a later polish step.
The current application uses wxdragon on top of wxWidgets for the GUI,
stores editable learning content in a plain-text deck file, and stores review
history in SQLite.
Project Goals
- Make the full review flow usable with screen readers and keyboard input.
- Keep learning content human-editable without pushing users through a database editor.
- Keep review history, ratings, and scheduling state separate from the editable deck content.
- Favour native controls and platform accessibility APIs over custom-drawn UI.
Current State
The repository currently contains:
- a deck format for prompt/response pairs
- a typed Rust data model for review ratings
- SQLite-backed review event storage
- scheduled review sessions with configurable minimum session size and daily new-card intake
- a wxdragon desktop review UI for a single deck file
- pre-cycle deck review with a prompt list on the start screen
- ready-list filtering, including duplicate prompt/response filters, problem-card and direction-asymmetry filters, multiple sort criteria, sort direction, and per-card details
- card management from the GUI: add, batch add, edit, remove, flag, defer, suspend, and mark non-reversible
- reversible cards with independent reverse-direction review history and scheduling
- deck format v2 metadata, deck properties, editable deck properties, and deck-stored non-reversible markers
- basic Anki
.apkgimport into new Cosimo decks, with fresh Cosimo card IDs and supported MP3 prompt/response audio copied into sidecar files - a learning dashboard with a concise summary, recall distribution, diagnostics, workload forecasts, study activity, and standard/reverse comparison when a deck contains reverse cards
- report-only exam mode with random active-card sampling, optional time limits, exact or adjudicated grading, summaries, and saved exam reports
- report-only quiz mode with random active-card sampling, configurable study direction, four-choice questions, delayed feedback, answer review, optional quiz audio, and saved reports
- optional Opus, MP3, or legacy WAV audio for ordinary review, ready-list preview, exam question prompts, exam grading/review, and quiz sessions
- a Windows
voice.exehelper for generating review audio as Opus by default, or WAV when selected, from installed OneCore or SAPI voices - snapshot deck sync through a Cosimo sync server, with Mastodon-compatible login, owner study-history upload/download, public or unlisted content-only downloads, and remote deck deletion by the owner
- a public project sync server currently running the release-candidate line;
clients using that server should run
0.1.11-rc.1or a later RC/stable build, not an older beta - recent-deck reopening from
File -> Recent Decks - automatic deck, review-database, and full-deck bundle backup options
- language selection for English, Spanish, and Galician
- end-of-session statistics and saved text reports
- flagged-card review, deferral, suspension, and non-reversible card markers
- optional sound notifications and minimise-to-system-tray behaviour
Licence
Cosimo is released under the GNU General Public Licence version 3. See LICENSE.
Review Model
For a user-facing introduction to studying with Cosimo, see docs/user-guide.md.
Release notes are kept in CHANGELOG.md.
Each datum contains:
- a prompt or question
- a response or answer
User-facing documentation uses these terms:
study session: one run from Start, Force Start, or Study Flagged through to the summaryquestion: one prompt presentation inside a study sessionattempt: one stored answer with recall feedback and optional confidence ratingstudy item: one schedulable direction of a card, either the standard direction or a generated reverse direction
Established phrases such as review database, review history, scheduled
review, and review audio still use review for the broader spaced-repetition
process and stored study history.
Before seeing the response, the user may record a guess:
1Don't know2Probably don't know3Probably know4Certainly know- Space /
Reveal Responserecords no guess and storesNot answered
After seeing the response, the user records feedback:
1Again2Hard3Good4Easy
The review UI also supports:
0End this session noweEdit the current card after its response has been revealedCtrl-FFlag or unflag the current card during reviewCtrl-DDefer the current card until tomorrow before revealing the responseCtrl-PPlay or stop prompt/response audio when review audio is available; on the ready list this previews the selected card's prompt and response
Before a study session starts, Cosimo shows:
- the number of cards that would be scheduled now
- the configured minimum cards per session
- a navigable list of cards labelled by prompt
- a text filter for narrowing the prompt list by prompt or response
Add Card,Edit Selected, andRemove SelectedcontrolsAlt-Sto start the scheduled study sessionAlt-Xto start an exam sessionAlt-Zto start a quiz sessionAlt-Lto move to the text filterF5to refresh the ready summary, ready-list filters, and status barCtrl-Fto flag or unflag the selected cardAlt-Tto force-start a full-deck study session in random orderAlt-Qto quit from the ready screen in English, orAlt-Sin Spanish and Galician
The normal Add Card dialogue can mark a new card as non-reversible while it
is created. Batch add deliberately omits that checkbox so repeated entry stays
quick.
Cards can be marked reversible before a study session starts. A generated reverse card
asks for the original response and expects the original prompt, using separate
review history and scheduling state from its parent card. Cosimo blocks reverse
generation when another card with the same response already has an active
generated reverse card, because the reverse prompt would be ambiguous. Duplicate
responses are otherwise allowed. The ready-list duplicate-response filter helps
find those cards before using bulk reversal, and Deck -> Undo Last Bulk
Reversal can remove the reverse cards created by the latest bulk batch while
leaving manual reverse cards and review history in place.
The ready summary, ready-list filters, and status bar refresh about once per minute while the ready screen is open, so newly due cards become available for scheduled start without reopening the deck.
At the end of a study session, or when the session is ended early, Cosimo shows
a summary dialogue for that session. The dialogue reports counts, percentages,
and timing, then offers Continue to return to the ready screen and
Save Report to save the summary under reports/.
Scheduling
Normal Start builds a scheduled review queue:
- due cards are reviewed first
- new cards are introduced in deck order up to the configured
New cards per dayrolling 24-hour allowance - if fewer due or newly introduced cards are available than the configured minimum cards per session, Cosimo randomly fills the queue from already introduced remaining cards
- if the minimum is
0, only due cards are scheduled
Cosimo uses an FSRS-6 spaced-repetition scheduler. It stores per-card memory
state in the review database, including difficulty, stability, due date,
repetitions, and scheduled lapses. Missed or wrong answers move a card back
toward learning; correct answers increase stability and make later intervals
longer. A lapse means Again on a card that had already reached review state,
not every Again answer while a card is still being learned. Existing schedule
rows from older beta versions are migrated by replaying stored review history
with the current FSRS-6 scheduler when the review database is opened.
The recall buttons are state-dependent scheduling inputs. In learning and
relearning, they mostly control short steps and graduation back to review; in
review state, they control the next spaced interval, with Again moving the
card into relearning. The user guide gives the detailed state-by-state meaning.
For review-state cards, longer intervals are varied slightly and deterministically to avoid several cards repeatedly coming due on exactly the same day. Short learning and relearning steps are not varied.
Force Start ignores due status and builds a randomised queue containing all
cards that are not suspended or deferred. This gives the user a way to study
even when no cards are due, while still respecting cards the user has
explicitly set aside.
Suspended cards are marked in the ready list, can be toggled from the Card
menu, the ready-list context menu, or Ctrl+S while the ready list has focus,
and are ignored by the status bar when it reports the next due review.
Flagged cards are also marked in the ready list and can be shown with the
flagged-card filter, but flags do not affect scheduling. Flagging is available
from Ctrl-F, the Card menu, the ready-list context menu, and review buttons
after the confidence or recall ratings.
The Card menu can also flag, unflag, suspend, or unsuspend all cards currently
shown in the ready list, which is useful after choosing a filter such as
Problem cards.
Study Flagged starts an unscheduled study session through flagged cards that are not
suspended or deferred. Deferral is also available from the ready list and
during the prompt phase of a session before the answer has been revealed.
The minimum cards per session, new cards per day, automatic deck-backup policy,
review database backup policy, sound notifications, review audio,
learning-dashboard calibration rule, and minimise-to-tray behaviour are set in
Tools -> Options and are persisted in cosimo.ini.
Repository Layout
For a fuller map of the codebase, see docs/code-walkthrough.md.
- src/model.rs: datum, rating, and review types
- src/deck_format.rs: human-editable deck parser and formatter
- src/deck_import.rs: Anki
.apkgimport and MP3 sidecar extraction - src/review_store.rs: SQLite review storage
- src/scheduler.rs: due-card scheduling and minimum-session fill
- src/exam_mode.rs: report-only exam setup, answer collection, grading, and summaries
- src/review_audio.rs: Opus/MP3/WAV sidecar audio resolution and playback state
- src/sync.rs, src/sync_http.rs, and src/sync_http_client.rs: sync storage, HTTP routing, and client protocol
- src/sync_oauth.rs: Mastodon-compatible sync login, account verification, and temporary Fediverse token revocation
- src/localization.rs: message catalogue and locale selection
- src/main.rs: wxdragon startup and event wiring
- src/app_state.rs: loaded-deck state and state mutations
- src/ready_screen.rs: main screen rendering, ready-list synchronisation, refresh, and menu state
- src/resident_tray.rs: minimise-to-system-tray lifecycle
- decks/deck.cosimo-deck: default deck file used by the GUI
- ui/main.xrc: main review window
- ui/card_editor_dialog.xrc: add/edit card dialogue
- ui/options_dialog.xrc: language and session options
- ui/stats_dialog.xrc: study-session statistics dialogue
User-facing documentation lives in docs/user-guide.md, docs/troubleshooting.md, and docs/sync-deployment.md for running a sync server.
Deck Format
Cosimo uses a plain-text deck format designed to stay editable by hand.
Example:
deck_version=2
title=Spanish capitals
author=Example author
:::
Capital of Spain
---
Madrid
=1=
Translate this sentence:
I opened the window.
---
Abri la ventana.
=2=
Rules:
- current decks begin with a v2 metadata header ending in
::: ---separates prompt from response=number=ends one card and stores its stable card identity=numberi=marks a card as non-reversible- when adding new cards by hand, use
===instead of choosing a number; Cosimo will assign a safe unused ID when it next opens the deck Deck -> Deck Propertiesshows deck metadata, andDeck -> Edit Deck Metadatacan edit the standard metadata fields- a same-stem directory beside the deck file can contain optional Opus, MP3, or
WAV review audio keyed by card ID, such as
1.prompt.opus,1.prompt.mp3, and1.response.opus; these sidecar files are included only in full-deck bundle exports/backups, not in automatic deck-content or review-database backups - legacy
===terminators are accepted and upgraded automatically when the app opens the deck - prompts and responses may span multiple lines
- prompts should be unique; Cosimo refuses normal add and edit actions that
would create duplicate prompts, and
Deck -> Resolve Duplicate Promptscan repair duplicate prompts introduced by manual deck edits - duplicate responses are allowed, but from each group of cards with the same response, at most one card may have an active generated reverse card
- editing prompt or response text preserves the numbered identity
- keep existing numbered markers when editing existing cards by hand, so review history remains attached to the same card
- review history does not live in the deck file
Generated reverse cards reuse the parent card's audio with prompt and response
swapped. Ordinary review can use prompt and response audio, including optional
guiding tones for automatic playback and a ready-list preview command. Exam
mode can use prompt audio while the learner is answering questions, and can
optionally play prompt audio, response audio, or both during grading and answer
review.
voice.exe can use OneCore or SAPI voices. Deck metadata can store
prompt_voice, response_voice, prompt_voice_engine, and
response_voice_engine defaults for voice.exe; command-line voice and engine
options override those defaults. Deck -> Edit Deck Metadata lists voices from
voice.exe when available, but the fields remain editable for manual filters.
The helper maintains audio-manifest.tsv in the sidecar audio directory so it
can skip already tracked files. Generation is conservative: manifest-tracked
files are treated as Cosimo-managed and may be regenerated or converted to the
selected format, while existing untracked .opus or legacy .wav files are
left untouched as user-owned recordings. The generate audio command on the
Tools menu starts the helper for the current deck when prompt and response
voice metadata are present and generation is allowed, shows progress, and
keeps its command output in the logs directory for troubleshooting. The Tools menu can also
remove inoperative Cosimo audio files for removed card IDs or lower-priority
formats hidden by a preferred playable file. If the generate audio menu item is
disabled, choose prompt/response voices and engines in
Deck -> Edit Deck Metadata, and check whether the deck is marked as manual
audio. If you keep your own recordings, use the manual-audio checkbox in
Deck -> Edit Deck Metadata to write audio_generation=disabled, and back up
the sidecar directory yourself or with a full-deck bundle backup; tracked files
can be overwritten after card text or voice-selection changes when generation
is allowed.
Runtime Files
decks/: default portable deck directory beside the applicationdecks/deck.cosimo-deck: default editable learning contentdecks/deck.reviews.sqlite3: review history and scheduling database for the default deckdecks/deck/or another same-stem directory: optional Opus, MP3, or WAV review audio for that deck, when present; full-deck bundle exports/backups include these files, but automatic deck-content and review-database backups do notvoice.exe: optional Windows helper for generating sidecar Opus or WAV files from installed OneCore or SAPI voicesreports/: saved review, exam, and learning-dashboard reportslogs/: operational logs such as audio-generation helper outputcosimo.ini: persisted application settings, the most recently opened deck path, and the recent-decks list
These default runtime paths are resolved relative to the application executable, not the shell or shortcut working directory. If the default deck is missing, Cosimo creates an empty one on startup.
Older beta builds used cosimo-settings.txt and cosimo-last-open-deck.txt.
When Cosimo finds either file, it migrates their contents into cosimo.ini and
then removes the old file.
SQLite review databases are runtime state and are ignored by Fossil.
Backup and Recovery
Back up each .cosimo-deck file, its matching .reviews.sqlite3 file, and its
same-stem audio directory if you use review audio. The deck file contains the
editable prompts and responses. The review database contains scheduling state,
ratings, and review history. The audio directory contains Opus, MP3, or WAV
recordings and the generated-audio manifest.
Cosimo also keeps automatic deck-content backups. Before it overwrites an
existing deck file, it copies the current version into the app-level backups
directory beside the executable. Backup names use a global rising number and
the deck name, such as backups/000001-deck.cosimo-deck. The
backups/index.txt file records each backup filename and the original deck
path. These automatic backups protect card text from accidental edits or
migration mistakes, but they do not include review history or sidecar audio.
For a portable copy of a deck and its sidecar files, use File -> Export Full
Deck. This writes a zip archive containing the .cosimo-deck file and its
same-stem sidecar directory, including audio and the generated-audio manifest,
but not the review database. File -> Export Full Deck with Study History
adds a consistent review-database snapshot for personal migration or a complete
manual backup. That archive contains personal study data, so use the no-history
export for sharing deck content. File -> Full Deck Backup writes the
deck-and-sidecar bundle into backups/ with a timestamped name and records it
in backups/deck-bundle-index.txt.
File -> Restore Full Deck validates one of these bundles, previews its card,
audio, file, and study-history counts, and restores it into the decks
directory. If existing files would be overwritten, Cosimo warns first and writes
a full compressed backup of the existing target deck. Restoring a bundle can
still lose newer data if it overwrites newer card text, sidecar audio, manifest,
or review-database files.
The deck backup option in Tools -> Options controls automatic deck-content
backups:
Full: keep every automatic deck backup.Last only: keep only the newest automatic backup for each original deck path.None: do not create automatic deck backups.
The review database backup option controls whether Cosimo keeps one automatic
review-database backup per review database. When set to On session start,
Cosimo refreshes that retained backup in the app-level backups directory when
a study session starts. The database backup index is
backups/review-db-index.txt. When set to Off, Cosimo does not create or
refresh review-database backups. Bulk reversible-card creation is also treated
as a significant database change: when review-database backups are enabled,
Cosimo refreshes the retained backup before writing and warns that the retained
backup will be overwritten.
The automatic full deck backup option is separate from both of those. When set
to Daily, Cosimo keeps one retained compressed bundle per deck path, refreshed
at most once every 24 hours when the program starts or opens a deck. This
full-deck backup includes the deck file, same-stem sidecar directory, and a
review-database snapshot.
Tools -> Reclaim Database Space runs SQLite VACUUM on the review database
without deleting dormant review data and without overwriting the retained
review-database backup.
For the default deck, back up:
decks/deck.cosimo-deckdecks/deck.reviews.sqlite3, if it existsdecks/deck/, if you use review audio
For another deck such as spanish.cosimo-deck, back up the neighbouring
spanish.reviews.sqlite3 file and any same-stem sidecar audio directory as
well. Close Cosimo before copying or restoring these files so SQLite is not in
the middle of a write.
Restoring only the .cosimo-deck file restores the cards but loses scheduling
history. Restoring both files preserves the cards and their review history.
The optional cosimo.ini file can also be backed up to preserve language,
session settings, backup policy, the last opened deck, and the recent-decks
list.
When Cosimo opens a review database, it runs SQLite's quick integrity check
before applying schema setup or deck migrations. It also checks higher-level
consistency after opening, including stored rating and schedule values,
study-session links, and active reversible cards whose responses have become
ambiguous. Duplicate prompts introduced by manual deck edits are reported as a
deck warning rather than a database failure; use the duplicate prompt filter or
Deck -> Resolve Duplicate Prompts to repair them. If either database check
fails, close Cosimo and restore the matching .reviews.sqlite3 file from an
external backup, or fix the active deck if the error is caused by multiple
active reversed cards in the same duplicated-response set.
To restore an automatic deck backup, close Cosimo and copy the chosen backup
over the active .cosimo-deck file. If you also need to recover scheduling
history, restore the matching .reviews.sqlite3 file from an external backup
or from Cosimo's retained review-database backup.
Use Tools -> Delete Old Backups to keep only the newest numbered
deck backup and the newest automatic full-deck backup for each original deck
path. Cosimo asks for confirmation, including the number of files that would be
deleted, before deleting or renumbering backup files.
Localisation
The current message catalogue supports English, Spanish, and Galician. Runtime messages and most control labels go through the localisation layer in src/localization.rs.
Language is chosen in this order:
COSIMO_LANGUAGE, when set to a recognised code- the persisted language in
cosimo.ini - the system locale
- English
en, en-US, and similar English codes resolve to English. es, es-ES,
es-MX, and similar Spanish codes resolve to Spanish. gl, gl-ES, and
similar Galician codes resolve to Galician. Unknown codes fall back to English.
On Windows, Cosimo reads the user's default locale through the platform locale
API. On other platforms, it checks LC_ALL, LC_MESSAGES, LANG, and
LANGUAGE.
Build
The default build artifact is the GUI application.
cargo build
wxdragon and native wxWidgets pieces can take time to compile the first time.
Avoid cargo clean unless you actually need to throw away cached build output.
Test
Fast library-only tests:
cargo test --lib --no-default-features
Check the GUI binary:
cargo check --bin cosimo
Release preparation should also exercise the Windows audio helper and release package metadata:
cargo test --bin voice
cargo check --no-default-features --features release-tool --bin cosimo-release
cargo package --locked --offline --allow-dirty
Assess Anki import compatibility without writing decks:
cargo run --bin cosimo-anki-assess -- path/to/decks-or-package.apkg
Fossil also runs pre-commit verification through tools/pre-commit-check.sh, which executes both test commands before a normal commit.
Run
cargo run
The application defaults to decks/deck.cosimo-deck beside the executable.
Review history is stored beside each deck, using the deck stem plus
.reviews.sqlite3; for example, decks/spanish.cosimo-deck uses
decks/spanish.reviews.sqlite3.
Review Flow
- On startup, review the ready-screen summary and the list of card prompts.
- Add, edit, or remove cards before starting the session.
- Start the scheduled session with
Alt-S, or force-start the whole deck withAlt-T. - For each prompt, enter
1through4for the pre-response guess, or press Space to reveal the response without recording a guess. - After the response is shown, enter
1through4for recall feedback. If the card text needs correction, presseto edit it before rating recall. - Enter
0during either rating phase to end the session early. - Review the statistics and continue back to the ready screen.
Exam mode is started separately with Alt-X or Start Exam. It samples active
cards randomly, excludes suspended and deferred cards, collects typed answers,
and produces a report-only summary. It can also run with a simple minute-based
time limit; the current answer is submitted when time expires, then Cosimo
pauses on a time-out notice before moving to grading, answer review, or the
summary. Exam mode does not record review events or update schedules.
Accessibility Notes
The current review flow is built around native text and button controls:
- the ready screen exposes the card set through a native list box
- the ready screen supports keyboard access to start, force-start, and quit via mnemonics
- the prompt content is focusable and read by screen readers before rating
- Space can reveal the response without a pre-response rating
- the response content becomes focusable after the pre-response rating or direct reveal
- numeric keys activate ratings directly
eopens the current card for editing after reveal and returns focus to the previous post-response control- the statistics dialogue focuses the summary text first
- the card editor uses normal text controls for prompt and response editing
- informative messages are intentionally concise and avoid repeating focus information that the screen reader already announces
Accessibility regressions should be treated as blocking defects.
The accessibility acceptance check is recorded in docs/accessibility-acceptance.md.
Known defect: on the target Windows screen-reader stack, tabbing or shift-tabbing into the ready-screen prompt list can announce the selected item twice. Arrow-key navigation inside the list, selection, edit, remove, and review startup remain functional. This is currently treated as a known native list accessibility defect rather than a release blocker.
Known defect: when the ready list is empty, some screen reader and wxWidgets combinations announce the empty list as "unknown". The ready summary and filter counts remain the reliable way to confirm that the current view has no cards.
Version Control
This repository uses Fossil, not Git.
Useful commands in this checkout:
FOSSIL_HOME="$PWD" fossil status
FOSSIL_HOME="$PWD" fossil diff
FOSSIL_HOME="$PWD" fossil add path/to/file
FOSSIL_HOME="$PWD" fossil commit --nosync path/to/file -m "Describe the change"
--nosync is currently relevant because this checkout may try to autosync
against a readonly peer checkout and fail before the local commit completes.
This checkout also carries a Fossil before-commit hook in
.fossil-settings/hooks.
If you absolutely have to bypass that hook, Fossil supports --no-verify.
If you add a new file such as an XRC resource, remember to fossil add it
before committing.