Configuration
Use /eklavya:mode for guided changes, the CLI for an exact setting, or the dashboard’s Settings pages to see and change your user settings and each project’s, one scope at a time:
eklavya config geteklavya config get quiz.enabled # just one settingeklavya config set cadence end --projecteklavya config set focus learn --topic cachingeklavya config unset cadence --project # this project inherits your setting againThe CLI and the dashboard write through the same code, so they accept and refuse the same values. The dashboard leaves providers, notifications and sync to the CLI, because each sends work off the machine or runs a command.
Where settings live
| Layer | Location | Scope |
|---|---|---|
| Defaults | Built into Eklavya | Used when no setting overrides them. |
| Global | ~/.eklavya/config.json | You, across projects. |
| Project | ~/.eklavya/projects/<checkout>/config.json | You, in one codebase; overrides global keys. |
| Session | Database state; no configuration file | Temporarily silence questions only. |
Files merge key by key, including nested settings. A project file containing only memory.capture leaves your other settings intact. providers, auto_update, telemetry and dashboard_autostart are global only and ignored in project files.
Project folders encode the main checkout’s absolute path, such as -Users-you-code-api. Git worktrees share their main checkout’s settings. A directory containing a repository is not itself that project. Missing or malformed files fall back to defaults; eklavya config get and eklavya doctor report malformed files.
Turning it off for one session
Say “Turn the questions off for this session”, or run /eklavya:skip (the same as /eklavya:mode off --session). Questions, checkpoints, the banner and the status line stay silent until the session ends. Ask to turn Eklavya back on to resume sooner. No configuration file changes. Concepts logged while silent are not carried into later sessions.
Memory keeps recording, and recall still reaches Claude: a silenced session that resumes or compacts still gets its session-start memory, without the banner. An enforced commit gate also remains active and can accumulate work while questions are silenced. Change memory.enabled to stop recording; change quiz.enforced at project or global scope to remove enforcement.
Every key
These are the learning and general settings. Memory-related namespaces follow below.
| Key | Default | Meaning |
|---|---|---|
quiz.enabled | true | Enables questions, checkpoints and the gate. false leaves memory running; the banner reports “memory on · questions off” when memory is enabled. |
quiz.enforced | false | Requires passing answers before committing. Ignores quiz cooldowns and the as-you-go one-question cap. Has no effect when quiz.enabled is false. Terminal commits also need the git hook. |
quiz.only_on_changes | true | Automatic questions wait until this session changes code: an Edit, Write, MultiEdit or NotebookEdit call on a file inside any git repository and not ignored, including a sibling worktree; a shell command that starts with cd <dir> into a git repository where a file changed since the session began, which is how Claude edits a sibling worktree through Bash; or any change to the git working tree the session started in (an edit, a new file or a commit, made by any tool). With delegate_work on, the main conversation starting an agent that is not read-only (Explore, Plan, the tutor or the explainer) also counts, so questions can start while that agent builds. Sessions that only read, search or answer questions are not quizzed. A git pull or branch switch alone is not a change; a commit, merge, rebase or cherry-pick since the session began is. Files under artifacts/ or reports/ never count. A session started outside any git repository, such as a folder that holds several, counts those edit-tool writes and shell commands that touch a repository (through cd, or, for repositories inside the folder the session started in, git -C, a path in the command, or the folder an earlier cd moved into; not when the session started in your home directory or above it, and symlinks and .git files that lead outside the folder are not followed), so asking and answering questions there is not quizzed. false asks about any logged work. Enforced quizzing and /eklavya:quiz ignore it. |
quiz.panel | true | Experimental. Shows questions in a side panel beside the transcript instead of Claude’s question card, on a supported Claude Code build; elsewhere, or when no panel is showing, the card is used. false uses the question card everywhere. Settable at user and project scope; see the quiz side panel. |
focus | "concept" | Subject: concept, project or learn. |
focus_topic | null | Required topic for learn; ignored by other focus values. An unmet enforced gate still asks about current work first. |
cadence | "as-you-go" | as-you-go offers one question at a time during work; end waits for task completion. Explicit and enforced plans are exempt from the one-question cap. Older configs that say interleaved read as as-you-go, and the next change to that file saves the new name; config set accepts only the new name. |
difficulty | "auto" | Earn a level per project, or pin easy, medium or hard. Pins stop progression. |
level_up_after | 100 | Passing answers needed at the current level in this project. Promotion also needs accuracy and distinct concepts. |
level_up_accuracy | 0.7 | Required fraction of passing answers at that level. Declines are excluded. |
pass_threshold | 0.7 | Gate passes needed: ceil(required concepts × threshold). At default settings, at most three passes out of four required concepts. |
max_questions_per_task | 4 | Automatic-question budget shared by checkpoints, questions asked while delegated agents build (delegate_work), and the final sweep. Also the maximum size of each explicit /eklavya:quiz round; a requested round can continue after the automatic budget is spent. |
min_minutes_between_quizzes | 20 | Spacing for offered end quizzes. Explicit requests and enforcement bypass it. |
min_minutes_between_checkpoints | 4 | Spacing between offered as-you-go questions, including the final sweep. At 0, checkpoints can ask at each eligible seam; the final sweep retains a one-minute floor. |
max_new_concepts_per_session | 8 | Maximum new concepts the agent may create in a session. |
max_stop_blocks_per_session | 3 | Maximum times the end-of-task hook can hold a session open for questions. |
domains_enabled | ["*"] | Filters the learner profile (including its due list) and memory-derived concept candidates. * includes all. It is not a strict block on explicitly selected or logged concepts. |
quiet | false | Suppresses the banner and status line. Logging, memory and questions continue. |
explain_on_wrong | true | Writes a background explainer page after a wrong or “I don’t know” answer. The page opens with the question, its options, your pick in red and the right answer highlighted. When the background dashboard is running, the page opens in its viewer, where you can correct your answer if the right option was recorded. Skips and declines do not create pages. |
delegate_work | true | Asks Claude to hand a code change across several files to a background agent working in the task’s directory, ask you questions while it builds, then review, run your checks, commit and write the task answer last. A staged plan goes one stage per agent, in order. Questions, lookups, docs or design-only work, fixes of a line or two and anything you ask to have done inline stay in the main conversation. Where background agents cannot run, Claude says so and works inline. It is said at session start, next to each prompt of 25 characters or more (not Eklavya’s own slash commands, or the messages the host sends when a background agent reports), and once more the first time Claude changes a second file itself (with an edit tool or, in a git repository, a shell command), unless Claude has already started a building agent. Questions while agents build need cadence: as-you-go; under end they wait for the end of the task. The session-start part takes effect at the next session start; the prompt line and the reminder read the setting each time. Has no effect when quiz.enabled is false. |
auto_update | true | Global only. Checks for a newer release at session start, at most hourly, and permits runtime catch-up. A missing runtime is still installed when false; manual eklavya update remains available. |
telemetry | true | Global only. Sends anonymous daily usage counts: numbers and setting values, never paths, names or text. EKLAVYA_TELEMETRY=0 or DO_NOT_TRACK=1 turns it off whatever this says. See Usage analytics. |
dashboard_autostart | true | Global only. Session start keeps the dashboard running in the background, replacing an older version after an update. When false, eklavya dashboard runs in the foreground until Ctrl+C. |
Older files may still use mode: ambient enables unenforced questions, enforced enables the gate, and off disables questions. A quiz object in the same file takes precedence. Use quiz in new files.
Setting a namespaced key
Dotted paths change one value without replacing the rest of the namespace:
eklavya config set memory.capture minimaleklavya config set retrieval.cross_project trueeklavya config set privacy.exclude_paths "/internal/, /vendor/"eklavya config set providers.observer nullLists accept comma-separated strings or JSON. Other values use the key’s expected type. Whole objects require JSON. The CLI rejects unknown keys and refuses to overwrite malformed files; it backs up valid files before changing them.
What each setting accepts
eklavya config set, the dashboard’s Settings pages and the set_config tool check one table of rules, so each refuses the same value with the same message and writes nothing. Text is trimmed and blank list lines are dropped before the check.
| Keys | Accepts |
|---|---|
max_questions_per_task | Whole number, 1–10 |
min_minutes_between_quizzes | Whole number, 0–1440 |
min_minutes_between_checkpoints | Whole number, 0–120 |
max_new_concepts_per_session | Whole number, 0–50 |
max_stop_blocks_per_session | Whole number, 0–20 |
level_up_after | Whole number, 1–1000 |
level_up_accuracy, pass_threshold | Number, 0–1 |
memory.batch_max_events | Whole number, 1–500 |
memory.retention_days | Whole number, 1–36500, or null |
retrieval.max_items | Whole number, 1–50 |
retrieval.max_tokens | Whole number, 100–20000 |
focus_topic, sync.device_id | Text up to 200 characters, or null |
sync.target | Text up to 1000 characters, or null |
privacy.exclude_paths | Up to 100 lines of 500 characters |
privacy.redact_patterns | Up to 100 lines of 500 characters, each a valid regular expression |
privacy.exclude_tools | Up to 100 lines of 200 characters |
domains_enabled | Up to 100 lines of 100 characters |
focus, cadence, difficulty, memory.capture, retrieval.mode | One of the listed values |
switches such as quiz.enabled, quiet | true or false |
A change that would not take effect is refused too: focus learn when no focus_topic is in force at that scope (or clearing the topic while learn is set), and, from the CLI and dashboard, quiz.enforced true while quiz.enabled is false. The set_config tool keeps its documented behaviour for a call that sends quiz.enabled: false: enforcement is switched off with it.
The memory namespaces
memory
| Key | Default | Meaning |
|---|---|---|
memory.enabled | true | Enables capture and recall independently of quizzes. |
memory.capture | "full" | full: prompts, tool activity, edits, reads and session events. minimal: prompts, assistant messages, session events and notes. off: stop capture while keeping stored history searchable. |
memory.batch_max_events | 40 | Maximum events per observation batch. A turn end also closes batches at eight events or 20 minutes old; a session start closes leftovers, and any seam closes other projects’ leftovers once they are 20 minutes old. |
memory.file_hold | true | Holds a whole-file Read of a code file of 32 KB or more that has memory history, every time in the session, and shows its entry titles with the memory_get call and the way to read less (code_outline, code_find_symbol, then a Read with offset and limit). A Read that stops short of the end or starts later is never held, nor is a Markdown, YAML, JSON or other file code_outline cannot outline. Settable at user and project scope. |
memory.retention_days | null | Days to keep summarised raw evidence, finished jobs, reuse receipts and the memory read log. Observations survive. Applies per project, automatically at most every six hours or through eklavya memory prune. null keeps everything. |
feedback
| Key | Default | Meaning |
|---|---|---|
feedback.enabled | true | Reviews one of your prompts from a finished session, using later prompts to show what it left out. Runs in the background, one item at a time. Needs memory.enabled and providers.observer; the Feedback page reports either missing setting. Settable at user and project scope. Uses the observer model through your Claude Code login. Older config files without this setting keep feedback off. See prompt feedback. |
privacy
These extend the built-in privacy rules.
| Key | Default | Meaning |
|---|---|---|
privacy.exclude_paths | [] | Additional path fragments to exclude; matched as substrings. |
privacy.exclude_tools | [] | Tool names whose activity must not be captured. |
privacy.redact_patterns | [] | Additional regular expressions; matches become [redacted:configured]. A pattern that does not compile is refused when set; one already in a hand-edited file is skipped. |
retrieval
| Key | Default | Meaning |
|---|---|---|
retrieval.mode | "hybrid" | keyword, local-vector semantic, or both (hybrid). Searches can override this. See retrieval limits. |
retrieval.max_items | 6 | Maximum entries proposed at session recall and default search limit. Mid-session prompt recall gets a third of it (at least one). |
retrieval.max_tokens | 1200 | Estimated-token budget for the complete recalled block, including its wrapper. Mid-session prompt recall gets a third of it. |
retrieval.cross_project | false | Includes other projects in search and session-start recall. |
providers
Provider settings are global because one worker processes all projects on the machine. Project-level writes are refused.
| Key | Default | Meaning |
|---|---|---|
providers.observer | { "kind": "anthropic", "model": "claude-sonnet-5" } | Writes observation summaries and reviews prompts through claude -p, using your Claude Code login. Captured session evidence goes to this model. Set to null for local summaries and no prompt feedback. Older config files without this setting keep null. |
providers.embeddings | null | Accepted configuration field, but no external embedding provider is wired into current retrieval. Search still uses the local embedder; leave this unset. |
New installs use the defaults without a settings walkthrough. Reinstalling keeps saved choices. Older user configs keep the previous defaults for these settings: no observer model and feedback off, unless explicitly set. With no observer, summaries are generated locally.
eklavya config set providers.observer claude-sonnet-5A bare model name is shorthand for {"kind":"anthropic","model":"<name>"}, which still works, and null clears it. anthropic on its own is refused: it is the kind, not a model.
notifications — what gets sent out
| Key | Default | Meaning |
|---|---|---|
notifications.enabled | false | Enables delivery to configured sinks. |
notifications.sinks | [] | Objects with kind (webhook, command or file), target, optional command args and optional events filter. |
Events are session_summary and queue_paused. Payloads are redacted; duplicate delivery is prevented and sinks share a five-second budget per seam. Commands receive JSON on standard input without shell expansion. Delivery to another service cannot be undone by deleting local history.
{ "notifications": { "enabled": true, "sinks": [ { "kind": "file", "target": "~/eklavya-wrapups.jsonl" } ] }}sync — memory across your machines
| Key | Default | Meaning |
|---|---|---|
sync.enabled | false | Enables exchange through the configured folder. |
sync.target | null | Shared directory, such as a mounted share or synced folder. |
sync.device_id | null | Optional device identity. Normally leave unset: an identity is generated once and stored in the database. |
Sync exchanges entries, tags, corrections and deletions. Attempts, mastery, review schedules, gates, raw evidence and reuse receipts stay on their original machine. Eklavya does not supply the shared-folder transport.
eklavya config set sync.target ~/Dropbox/eklavya-synceklavya config set sync.enabled trueeklavya memory sync pusheklavya memory sync pulleklavya memory sync statusConflicting edits are quarantined: your local version stays active and the incoming version is retained. sync status reports conflicts. Deletions propagate as tombstones so a device with an older copy cannot restore them accidentally. A correction travels with the entry it replaced, naming the replacement by its portable ID, so other devices recall only the replacement; when the corrected entry arrives first, it stays live until its replacement does. A device running a release from before corrections synced stops at the first correction record (sync pull reports that it stopped early on an unreadable record) until it is updated. Do not copy a pinned device_id between machines.
Synced folders do not always deliver files in the order they were written. A pull applies every record it can read, and remembers any earlier revision that has not arrived yet or cannot be read yet; the next pull applies it when it does. sync pull names the devices still owed records, and sync status shows the count from the last pull beside each peer that still owes records, as in laptop@41 (2 outstanding). When a push could never write a revision, for example because the entry changed again after an interrupted push, it lists that revision number in void.json beside its records so other devices stop waiting for it. The file holds the format version, the device ID and revision numbers, and no memory content.
Earlier releases could step over a record that arrived late. The first pull after updating reads those older records once more and applies the ones that need no decision: an entry or deletion this device never received, or a newer version of one it holds unchanged. An entry with an open conflict is left alone. sync pull reports them as recovered. A record that would conflict with your copy is left as it is rather than quarantined.
Nothing Eklavya configures lives in your repository
Project settings are personal files under your home directory, not team policy. Legacy <repo>/.eklavya.json files are moved there on the next session; existing personal project settings win. The migration excludes providers, notifications, sync and cross-project retrieval from the cloned file.
New packs also live under your home directory. Legacy <repo>/.eklavya/packs/ files are still read but are neither moved nor written. See Concept packs. The opt-in git hook is the separate exception under .git/hooks/.
A complete file
Every key is optional. This project configuration enables a gate and keeps questions about the codebase in the easy band:
{ "quiz": { "enabled": true, "enforced": true }, "focus": "project", "cadence": "as-you-go", "difficulty": "easy"}A pinned difficulty selects a range of tiers, not one question difficulty. See Levels and tiers.