Your data
Eklavya stores personal state under ~/.eklavya/. It has no account. It sends anonymous daily usage counts, which you can turn off; Usage analytics lists every field. Memory capture, storage and search run locally. New installs use claude-sonnet-5 through your Claude Code login to write summaries and review prompts, sending captured session evidence to that model.
Set providers.observer to null for local summaries and no prompt review. Notifications and shared-folder sync are off by default and can send selected data elsewhere when enabled. Configuration describes the controls. The normal update check contacts npm; the usage ping contacts Google Analytics; artifact templates can load Google Fonts. Local data storage does not mean every feature makes zero network requests.
| Path | Contents |
|---|---|
~/.eklavya/knowledge.db | Quiz attempts (with the right option and each option’s note, for multiple choice), every pick made when correcting a missed answer (attempt_retries), questions set aside as the tutor’s mistake (invalid_questions: the stem and the tutor’s reason, never scored), a count of each time the option-length check sent a question back for a rewrite (option_checks: session, concept, where it was asked and the outcome, never the question or options), concepts, mastery, review schedules, gates and project levels; also memory evidence, observations, search indexes, receipts, a log of memory read tool calls (IDs, outcome, latency and size, never the query or content), collections and candidates; and each project’s git root commits, so a moved checkout keeps its history. With the experimental quiz.panel on, it also holds each question handed to the side panel (panel_questions: the question, its options, the grade the asking model gave each option, the explanation and, once answered, the stored reply). A question unanswered after 24 hours is marked expired and recorded as nothing. A short heartbeat per session is kept for 24 hours. Once feedback has run, it also holds the reviews of your prompts (feedback_items: your prompt as memory recorded it, the better prompt, a note per D with the short quote from a later prompt when one was used, the tips and the observer model’s name) and a record of which sessions were already looked at (feedback_reviewed, with the error and the start of its message when a review failed, never prompt text). Neither table refers to your scores. |
~/.eklavya/config.json | Your global settings. |
~/.eklavya/projects/<checkout>/config.json | Your personal settings for one checkout and its worktrees. |
~/.eklavya/packs/*.json | Global concept packs. |
~/.eklavya/projects/<checkout>/packs/*.json | Personal project packs. |
~/.eklavya/artifacts/<checkout>/*.html | Saved explanations and other pages. |
~/.eklavya/spool/events.jsonl | Sanitised evidence waiting for replay after a busy or unavailable database. Usually absent. |
~/.eklavya/update.json, update.log | Update state and output from the last background update. |
~/.eklavya/dashboard.log | Errors from the background dashboard’s latest start. |
~/.eklavya/runtime/ | Installed runtime and dependencies. |
The dashboard keeps a few display choices in your browser’s own storage, never in ~/.eklavya/ and never sent anywhere: the ink/paper ground, opened or closed sections, collapsed sidebar groups, the last project you picked, open artifact tabs, which tips you have seen or switched off (eklavya-dash-tips), the daily card’s memory (eklavya-dash-daily: the day it last showed, which cards and milestones you have seen, the last line the archer said, and whether you switched it off), and whether you dismissed the Feedback page’s “Found a problem with Eklavya?” line (eklavya-dash-feedback-tip).
Concepts a session logged but never asked about are deleted at a later session start, at least 12 hours after they were logged. Asked questions, their answers and review dates are kept.
Prompt feedback
Prompt feedback is on for new installs and uses the observer model, claude-sonnet-5 by default. Existing installs keep saved settings. Older configs keep the previous defaults for these settings: no observer model and feedback off, unless explicitly set. Set feedback.enabled to false to stop prompt reviews.
A review keeps the text of one of your own prompts, already redacted when memory captured it, so it stays after memory.retention_days prunes the evidence it came from. Delete an item from the dashboard’s Feedback page (Delete this feedback removes a waiting item), or remove everything with eklavya uninstall --purge. Feedback is read from memory, so with memory.enabled off nothing new is made, and the prompt text goes to your observer model and nowhere else; see prompt feedback. A moved checkout takes its items with it, as it does the rest of its history.
Who can read it
Eklavya requests private filesystem permissions: 0700 for its home directory and 0600 for the database and sidecars, spool, configuration and memory exports. Existing installations are tightened when the database opens. On Windows, access also depends on the user’s filesystem permissions.
The database uses SQLite’s write-ahead log (WAL). Its -wal and -shm sidecars can contain active state; do not treat the main file alone as a live backup.
Backups of your own files
For a full database backup, including learning history, use SQLite’s backup operation. This example requires the sqlite3 CLI:
sqlite3 "$(eklavya db-path)" ".backup '$HOME/eklavya-backup.db'"Keep copies of your configuration, packs and artifacts separately. A memory-only export is useful for moving or restoring entries:
eklavya memory export ~/eklavya-memory-backup.jsoneklavya memory restore ~/eklavya-memory-backup.jsonMemory restore is additive and idempotent. It does not restore quiz attempts, mastery or gates, remove later data, or reverse all edits. Learning history cannot be reconstructed from memories or repository history.
When Eklavya changes a user-owned JSON file, it keeps the previous version beside it as <file>.eklavya-bak. This is one previous version, not a backup history. Malformed files are left untouched.
Database schema migrations run automatically when the database opens and are forward-only. Keep a full backup before testing an older runtime against newer data.
Looking inside
eklavya db-pathsqlite3 "$(eklavya db-path)" '.tables'sqlite3 "$(eklavya db-path)" 'select domain, count(*) from concepts group by domain'Use the dashboard for a readable history without SQL.
Experimenting safely
Use a separate directory for a disposable test, or override only the database:
export EKLAVYA_HOME=/tmp/eklavya-testexport EKLAVYA_DB=/tmp/eklavya-test.dbTo run a hook by hand, set it for that one command, or the run writes into your real database:
echo '{"session_id":"t-1","cwd":"'$PWD'"}' | EKLAVYA_HOME=$(mktemp -d) node hooks/run.mjs session-startA hook that receives a short, hand-typed session_id while neither variable is set prints a warning to stderr and still runs.
EKLAVYA_HOME redirects Eklavya’s state, not Claude Code’s own settings or plugin registry. Running the installer can still change Claude Code registration; these variables are for isolating data, not a complete installation sandbox.
For testing question wording, EKLAVYA_SURFACE=code or cowork overrides surface detection. It applies only to processes that inherit that environment. A shell inside Cowork’s sandbox cannot change the environment of the host’s hooks or server.
The two halves are separable
eklavya config set quiz.enabled falseeklavya config set memory.enabled falseThe first stops questions and leaves memory running. The second stops memory capture and recall; by itself it leaves questions running. memory.capture: off stops only new capture, keeping old entries searchable.
Deleting it
eklavya uninstall keeps your history. To remove the installation and all data under the active Eklavya home, including artifacts, use:
eklavya uninstall --purgeBack up anything you want to keep first. A separately configured EKLAVYA_DB outside that directory requires separate deletion.
Never commit a learner database or personal Eklavya state. New settings and packs stay under your home directory. Legacy checkout settings are migrated there; legacy pack files are still read. The opt-in git gate is installed separately under .git/hooks/. See Uninstalling for removal details.