The dashboard
Open your learning history, project memory, saved pages, prompt feedback and settings in a local browser:
eklavya dashboardCounts of 1,000 or more read short across the dashboard: 1K, 1.2K, 1M.
The dashboard lives at http://127.0.0.1:41729 and keeps running in the background, so the command opens your browser and returns. Use --no-open to print the URL without opening a browser.
Your archer companion
The mascot smiles while pages load and appears beside empty lists, missing records, errors and settings feedback. Text still explains each state. Motion stops when your system requests reduced motion.
Open Settings, then the Companion tab, and choose Open the companion gallery to open the local mascot studio. Preview its 13 expressions, switch between face and full-body views, and pause the loading animation. The studio and mascot assets load from the dashboard itself. The same tab holds the Tips and Daily card switches (tips, daily card); they change this browser only, so they are the same on the User page and on every project page.
Keeping it running
Each session start checks the dashboard and starts it if nothing is answering, so it comes back after a crash or a restart of your computer. When a session starts it, the greeting says so:
Dashboard http://127.0.0.1:41729 started in the background · off: eklavya config set dashboard_autostart falseWhile it rebuilds its data for an open page, a dashboard with a long history can answer a few hundred milliseconds late. Session start waits 150 ms for the answer and then leaves it alone. eklavya dashboard, eklavya dashboard stop and eklavya artifacts open wait up to 1.5 seconds, and eklavya dashboard status waits one second, so a busy dashboard is not taken for another program.
After an update, the next session replaces a dashboard running an older version. A dashboard started from a newer version is left alone, and so is one serving a different database (EKLAVYA_DB) or another program on the port.
eklavya dashboard status # version, process id and database of the running copyeklavya dashboard stop # stop it; the next session starts it againTo keep it off, set dashboard_autostart to false (global only). eklavya dashboard then runs in the foreground as before, and Ctrl+C stops it. With --port <n> it always runs in the foreground on that port; a busy requested port returns an error. Without --port, a foreground dashboard whose default port is busy falls back to an available one.
The background copy writes errors to ~/.eklavya/dashboard.log, cleared each time it starts.
/eklavya:progress gives a short summary in chat. The dashboard is where you inspect full histories and follow links between a concept, its questions, the session and the memory behind it.
Open it as an app
Install the dashboard as an app to open it in its own window from Spotlight, Launchpad, the Dock or the Start menu instead of a browser tab. Open http://127.0.0.1:41729, then:
- Chrome or Edge: choose the install icon at the end of the address bar, or Install Eklavya Dashboard in the browser menu.
- Safari on macOS: choose File → Add to Dock.
On a Mac, press Command+Space and type Eklavya Dashboard to open it.
The app is the page at that exact address, so install it from 127.0.0.1:41729, not from a --port dashboard or localhost. It shows live data only while the dashboard is running; if the window cannot connect, run eklavya dashboard or start a Claude Code session. Safari keeps the app’s browser storage separate, so choose the ground there once.
Switching workflow
Use the caret beside the workflow name to choose Learning, Memory, Artifacts, Feedback or Settings. While feedback and memory are on and an item is waiting, the caret carries a small 1 and a screen reader says “Switch workflow, 1 feedback unread”; see Feedback. Clicking the name or Eklavya wordmark returns to that workflow’s Dashboard.
Project and theme choices survive a workflow switch. Page-specific filters do not. The address records the workflow, page, filters and project, so bookmarks and Back/Forward return to the same view. A new-style link without ?project= means all projects.
The sidebars
| Learning | Memory | Artifacts | Feedback | Settings |
|---|---|---|---|---|
| Dashboard | Dashboard | Dashboard | Dashboard | Overview |
| Concepts, Review | Timeline, Sessions, Projects | Projects | History | User, Project |
| Sessions, Projects, Domains | Reuse, Health |
At the bottom of every sidebar, under the project and ground controls, the dashboard shows the version of Eklavya it is running and links to the dashboard guide, the manual and the updates page. The version is the one this dashboard process loaded when it started. If it is older than the version you installed, your next Claude Code session (with dashboard_autostart on) or eklavya update restarts it on the new one; eklavya dashboard stop followed by eklavya dashboard does it now. The links open in a new tab and are the only addresses the page points at: it still loads nothing from another host.
Groups can be collapsed and are remembered per workflow. At 900 px or narrower, navigation moves into a menu drawer. Keyboard navigation supports Tab and Enter; the workflow picker also supports arrows and Escape. Escape or clicking outside closes the drawer.
Reading a page
Every page is one column at most 1,080 pixels wide, centred in the space beside the sidebar, so on a wide window it does not hug the left edge. Every page follows the same order, so the answer comes before the detail:
- The title and one line of counts. For example,
85 concepts asked of 334 · 96 answers · since 26 Aug. A count that needs attention, such as pending evidence, is a link. - How this works, folded. Open it for the arithmetic behind the page: mastery thresholds, decay, how savings are estimated.
- The one next step, when there is one: concepts due for review (questions you declined, did not know or got wrong), with a link to the review page, where each concept has its start steps, or a stalled memory job.
- The lists, one line per item. Open a line, or its page, for the rest.
- Secondary sections, folded. Grade history, capture settings and similar detail sit in closed sections whose summary line still shows a count or verdict. Open one with a click, Enter or Space.
The dashboard remembers which sections you opened or closed, in this browser only.
Tabs, chips, selects, date ranges, pagers and the search boxes change the list in front of you and nothing else. The page does not scroll, the heading and the sidebar stay, and whatever you had open, focused or typed stays as it is, including a date you are still typing into a custom range. Tabs, chips, the Domain, Type, Tag and When selects and date ranges also change the address, so a filtered list is still a link and Back returns to the earlier list. A pager, the Sort select and a search box change the list only. Opening another page, concept, entry or project, or switching workflow, opens at the top.
A page you have already seen comes back at once. Going Back, going Forward or opening it again draws it from what the dashboard already read, with no request, until something the page shows changes. A page you have not seen holds a box for its list while the answer comes, sized from how many rows the dashboard already knows it has, at most one page of them, so with a short history the footer barely moves. The box is an estimate: when the rows take more or less room, the footer moves by the difference, once. The archer companion shows in the box if the answer takes more than a moment. When a pager or filter fetches new rows, the old rows stay on screen and out of reach, and dim if the answer takes more than a moment, until the new ones arrive.
Learning
| Page | What you can inspect |
|---|---|
Dashboard (#/learning/dashboard) | Four tiles (accuracy, mastery, due reviews, and To be corrected: missed answers whose explainer still waits for a correction, linking to the To correct list), the next step when there is one, then the open streak card and, once a day, the daily card; recorded versus assessed concepts in the counts line; 30 days of answers, split into right, corrected, missed and skipped (a miss corrected from its explainer also shows as “corrected” with its try in question lists); the weakest five concepts and recent sessions. Where you stand is folded. |
Concepts (#/learning/concepts) | Search, sort and filter the graph by domain, tag or state: due, learning, mastered or unseen. A row shows the concept’s tags; search matches them. A tag filter is part of the link (?tag=cookies). A concept’s own page shows its description and its tags, each a link to that filter. |
Review (#/learning/review) | A short introduction (it can be hidden for good), then Pick a concept to review: one card per due concept, most overdue first, with Start here and the archer beside the first. Five cards show and up to 20 more fold under Show N more. Open a card for the steps to start one quiz on that concept (see Starting your reviews). Then tips, due reviews, upcoming reviews with a 14-day forecast, and skipped questions. Due and upcoming list only concepts whose latest answer was declined, blank or wrong; a correct answer is never owed. Tabs use /upcoming and /skipped. |
Sessions (#/learning/sessions) | Sessions that logged concepts or asked questions. Memory-only sessions are listed in Memory. |
Projects (#/learning/projects) | One line per project: level, accuracy and last activity. Open it for logged and assessed concepts, promotion conditions and 30 days of answers. Each project’s level and promotion conditions come from its own settings, as /eklavya:progress reports them from inside it, whichever folder the dashboard was started in; a checkout that has gone keeps its own settings. Projects with logged work but no answers say “not assessed”. |
Domains (#/learning/domains) | Concept coverage and the spread of question tiers. |
The streak
A day counts toward your streak when you answered at least one question that day, whether right, missed or skipped. A miss you correct later stays on the day you first answered it. Days are your computer’s local calendar days, so an answer at 01:00 counts for the day it is where you are, not the UTC date. The card shows the current run (it still counts while today has no answer yet, and asks for one to extend it), your longest run, and a calendar with one cell per day: four shades, relative to the busiest day on screen, and an outline around the days of the current run. Beside the count the archer says one line, picked at random each time you arrive and chosen to match the run (a short one for a new streak, a bigger cheer from 7 days, a calm start when there is none); it never states a streak you do not have, and a tab or new activity keeps the line it has. Hover a cell for its date and its answers; corrected misses count as right there, as they do in Accuracy. On a narrow screen the calendar shows fewer weeks and the ‹ › arrows page back up to a year. With a project selected, the streak counts only that project’s answers.
Starting your reviews
A bare /eklavya:quiz serves reviews only from the project it runs in. Each card on the review page therefore opens a side sheet with the steps for that one concept, so the answer counts in the right project. Choose Claude Code (terminal) or Claude desktop (Code tab); the dashboard remembers your choice in this browser.
In Claude Code the steps are to open a terminal in the project, then run:
cd '/Users/you/code/api'claude "/eklavya:quiz csrf"In Claude desktop the steps are to open the project folder in the Code tab, start a new session, and send /eklavya:quiz csrf. Each command has its own Copy button (Copy path for the folder); the sheet also lists why the concept is due. A run quizzes that one concept and asks up to your max_questions_per_task limit of questions on it. If the browser refuses the copy, the command is selected for ⌘C or Ctrl+C and a caution toast says so. On Windows the folder step uses PowerShell’s Set-Location -LiteralPath. When the project’s checkout is gone, or Eklavya recorded no project for that concept, the sheet shows no folder: run it inside the project you want the answer counted in. If questions are off for that project, the quiz says so and /eklavya:mode turns them back on. A concept’s own page has the same one-concept command under This one is due.
Toasts and dialogs
Every Copy button, on every page, answers with a toast at the bottom right (full width on a phone): the archer’s face, a title and one line saying what to do next. A success or caution toast leaves after four seconds and an alert after eight; it stays while the pointer or focus is on it, and its × closes it. A refused copy shows a caution toast. A repeat of the same message replaces the earlier one, and three show at most. Confirmations that need a decision use one shared dialog with the same faces, a button that names the action and focus on Cancel when the action cannot be undone.
Memory pages
| Page | What you can inspect |
|---|---|
Dashboard (#/memory/dashboard) | Memory counts, a two-line pipeline status (estimated reuse and health, each linking to its page), recent observations and sessions. |
Timeline (#/memory/timeline) | Entries by day, one line each; open a line for its summary and a link to the full entry. Filter by type, tag or date, and search titles, narratives, facts and file paths. |
Sessions (#/memory/sessions) | Sessions with evidence or observations, including pending evidence and questions from the same session. |
Projects (#/memory/projects) | Every project with captured memory, including evidence not yet summarised. |
Reuse (#/memory/reuse) | A receipt for each recall and its context-volume arithmetic. |
Health (#/memory/health) | Capture heartbeat, processing queue, stalled jobs and provider configuration. |
Type filters use paths such as #/memory/timeline/bugfix; tag and date filters use ?tag=auth&from=2026-09-01&to=2026-09-23. The date menu’s Today, Last 7 days and Last 30 days set only from; Custom range shows both date boxes.
Artifacts
Artifacts are HTML pages saved under ~/.eklavya/artifacts/<project>/: requested explanations and background explainers created after a missed question while explain_on_wrong is on (the default).
| Page | What you can inspect |
|---|---|
Dashboard (#/artifacts/dashboard) | Three tiles (pages, explainers and To be corrected, the same count the Learning Dashboard shows), each opening its filtered list, then a gallery of cards grouped by project, newest first, 20 to a page. Each card shows the page’s first diagram as its thumbnail. Search title, description, concept and project; filter with /explainer, /artifact or /to-correct. |
Viewer (#/artifacts/view/<id>) | One page, opened as a tab. An explainer for a missed question also has a Correct your answer bar. Reached from its card or from eklavya artifacts open; it has no sidebar entry. |
Projects (#/artifacts/projects) | Page and explainer counts and the latest page in each project. |
An explainer’s concept links to its Learning page. A card’s thumbnail or title opens the page in the viewer, inside the dashboard. The thumbnail is the first inline SVG inside a <figure>, drawn in the ground you have chosen, with its category colours; a page with no diagram shows a plain sheet instead. Thumbnails are read from the file, not rendered from the page, so they fetch nothing and run no script. The file list is read again each time the dashboard updates, so a page added or deleted changes the library while you have it open. A project with artifacts but no other recorded activity appears here but cannot be selected as a global project scope.
Tabs
Each page you open stays open as a tab in a strip above the viewer, pinned to the top of the window while you scroll. All artifacts, the gallery, is always the first tab. Each page tab shows the title, an amber dot while its correction is open or a verdigris dot once corrected, and a close button.
- Opening a page that is already open switches to its tab. A new tab opens to the right of the tab you were on.
- Up to 8 page tabs stay open. Opening a ninth closes the least recently viewed tab that has no open correction; when all 8 have one, the least recently viewed tab closes. Reopen any page from the gallery.
- Closing the visible tab shows its right neighbour, then its left one, then All artifacts. Closing a tab with an open correction does not ask; the page stays under To correct.
- A middle click on a tab closes it. From the keyboard, Tab reaches the strip, ←/→ and Home/End move along it, Enter or Space opens a tab and Delete closes it.
- The address names the visible tab, so Back and Forward move between tabs. The list of open tabs is kept in this browser only (
localStorage, keyeklavya-dash-tabs), and comes back after a reload. Each tab returns to where you were reading while the dashboard stays open.
Open in new browser tab, above the page on the right, opens the saved HTML on its own. Pages served by the dashboard are sandboxed: their inline scripts and downloads work, but they cannot read dashboard history. Only files under the artifacts directory are served. Opened on its own, a page’s Google Fonts requests are allowed; offline it uses system fonts. The Eklavya link in the header and footer opens the website in a normal tab. Opening the same file directly does not add the dashboard sandbox.
Correcting a missed answer
An explainer written for a missed question (a wrong answer, or “I don’t know”) is linked to that answer when the tutor recorded the right option. Its card is tagged To correct, and its tab has an amber dot. In the viewer, a bar pinned to the bottom of the window shows Eklavya’s face, worried while the miss is open, and says “You missed this one.”, with Correct your answer on the right. At the end of the page the bar sits under it, so it never covers the last lines.
- Read the page, then select Correct your answer. A dialog shows the question with each option and its one-line note, in a new order each time.
- Pick an option. A wrong pick says “Still incorrect. Please correct your answer.” and that option is disabled; pick again.
- The right pick says “Corrected. Your accuracy now counts this as right.” The question and the options stay on screen, and the dialog closes itself after 3 seconds: Close reads “Closing in 3…”, then 2 and 1, with a fill sweeping across it. A Stay open button appears beside it and takes the focus; select it to keep the dialog open. Escape or Close closes it at once, and the count waits while the tab is hidden. With reduced motion set, the fill is dropped and the number still counts down. The bar then reads “Corrected on try 2 · ” and the date (or whichever try it was), its face turns happy, the tab’s dot turns verdigris and the card is tagged Corrected. The tiles, the accuracy and the rest of the dashboard’s counts follow within about a second, without reloading the page you are reading.
Every pick is stored and checked on the server; the correction request never returns the right answer. A correction is a pass at grade 3 for the concept’s score, and the corrected miss counts as right in the dashboard’s accuracy (overall, per project and per session) and toward your level. A concept’s page still lists it apart, as corrected. It does not count toward a commit gate, and the concept still comes back for review. See grading.
Closing the browser tab while the visible page’s correction is still open makes the browser ask whether to leave. Browsers show their own wording for that prompt, so the bar says the rest: not now, and it stays under To correct. If the question cannot be loaded, the bar shows the reason and a Retry button. Explainers made before this feature, explainers for a question recorded without its right option, and pages not linked to a missed answer have no bar.
In the viewer, the framed page loads no web fonts and uses system fonts, so the dashboard still makes no request to another host. The dashboard adds a small script to every page it frames, old or new: the page reports its height and stops scrolling on its own, so the window has the only scrollbar. Until it reports, the frame holds the height that tab last reported, or 80% of the window’s height the first time, with the loader over it, so the content below it moves once when the real height arrives. A page taller than 20,000 pixels scrolls inside its frame past that point. If a page reports no height within 1.5 seconds, its frame is 80% of the window’s height and the page scrolls inside it. So does a page whose content grows with its frame, such as a section set to the full window height (min-height: 100vh): inside the frame, the window is the frame, so that page could never stop growing. Pages made from the Eklavya template have no such section. That script leaves nothing in the page for its HTML button to save: a file downloaded from the viewer is the page as saved, with no frame code, and it scrolls on its own; like the framed page, it carries no web font links, so it uses system fonts.
Feedback
Feedback reviews one prompt you wrote, at a time: what your later prompts in that session had to add or correct shows what it left out, and you get a version that would have made those follow-ups unnecessary. New installs have it on, with memory and claude-sonnet-5 as the observer model. Existing installs keep their choices. If it is off, use Settings or eklavya config set feedback.enabled true; it needs memory and an observer model. It never changes your mastery. How feedback is made says when it runs and what leaves your machine.
While nothing is waiting, the rule is written at the top of the page: Eklavya reviews one prompt at a time. When one is ready it appears here, and the next waits until you press Acknowledge. While one is waiting, it sits beside the button instead: The next review waits until you acknowledge this one. It moves to History.
| Page | What it shows |
|---|---|
Dashboard (#/feedback/dashboard) | The waiting item, or why there is none: feedback is off (with a button to Settings), memory is off, no observer model is set (with the command to set one and a Copy button), the last session could not be reviewed (the page says it will try again at a later start; that session is not retried, and the next start reviews the next one), or nothing to review yet. Once you have acknowledged any item, that last case instead says the next feedback will be shared once it is available. |
History (#/feedback/history) | The items you acknowledged: date, project, the first 80 characters of your prompt and the areas it left out. It follows the project selector. Open a row for the item without the buttons. |
Item (#/feedback/item/<id>) | One item. |
An item reads top to bottom in the order you take in feedback: the conclusion, the evidence, what went well, what to fix, what to do next time.
- The verdict. One sentence built from the areas it left out, costliest first, such as The agent had to guess the context and the check., or Nothing here left the agent guessing. Under it, a strip names each of the four areas with a word: Left out, Clear (the prompt said it) or Not needed (this task did not need it). Items reviewed before Eklavya asked for all four say Not flagged for an area their review did not name.
- Your prompt as you wrote it, beside A better prompt with a Copy button. The better prompt may use details you gave later in the same session, because you wrote them, and never invents others: where it needs one you never gave, it shows a highlighted placeholder such as
[the failing test], for you to fill in before you reuse it. Copy copies the plain text. A long prompt is cut short behind Show the whole prompt. - What worked, in one sentence.
- What it left out: up to three gaps, the costliest first, each named by area: Outcome (what done looks like), Context (files, systems, prior facts), Scope (the limits) or Check (how the agent proves it worked). When a later prompt of yours supplied the missing detail, the gap quotes it under You, later. A prompt that left nothing to guess says Nothing the agent had to guess.
- Next time: one to three habits, numbered.
There are no scores or counts anywhere in a review. Items reviewed by an earlier version of Eklavya open with An older review: the prompt, the rewrite and the tips are below. and then show only those.
Beside the item, Where you said it gives the project (and its path), the checkout when the session ran in a worktree, the session with its prompt count and first and last event times, linked to the session in Memory, when you sent the prompt and from which host, and what the session was about (its first real prompt, cut to 160 characters). It is read from the session’s stored memory when you open the item, so older items show it too; if that memory was deleted, the rows it can’t fill are left out. Under it, Done reading? holds the rule, Acknowledge and Delete this feedback, and stays in view while you scroll, unless it is taller than the window. Its last line says how many items are waiting and how many are in History. At 900px and narrower it follows the item, and a bar fixed to the bottom of the window holds Acknowledge. An acknowledged item says when it was acknowledged instead.
Acknowledge is a button you press on purpose, and nothing else acknowledges: opening the page, reloading it, opening it in another tab, going Back or following a link to an item never does. Pressing it clears the badge without a reload, says “Acknowledged. Feedback resumes at your next session.” to a screen reader and moves focus to the page heading. Delete this feedback asks Delete this feedback for good?, then Delete removes the waiting item. Deleting it lets the next one be made, and it does not count as acknowledged.
The badge is on the workflow control of every workflow, not only this one, and only while feedback and memory are both on. If quiet is set, the session greeting does not mention feedback, but the badge still shows. The greeting otherwise adds an amber Feedback waiting segment with a link to the Feedback page to the Dashboard line, in place of the Observations link. If the dashboard is not running, the line is just Feedback waiting · run: eklavya dashboard. Without colour, the segment starts with ! . It does not show while feedback or memory is off.
When nothing is waiting, the Dashboard page ends with a line, Found a problem with Eklavya? While an item is waiting, the line follows its tips. It says: tell Claude File feedback for Eklavya and it shows you the issue before posting (how reporting works). Dismiss hides it in this browser (eklavya-dash-feedback-tip). If the browser blocks site storage it stays, because it is information and not a nudge. It is not a tip, so the Tips switch does not touch it, and the Feedback pages have no tips of their own.
Settings
Settings changes the same two files as eklavya config set: your user settings in ~/.eklavya/config.json, and one project’s settings in ~/.eklavya/projects/<checkout>/config.json. Both interfaces use one write path, so they accept and refuse the same values.
Settings is a switchboard of two panes. On the right, a full-height panel lists the scopes. Choose User (the default, what opens first) or one of your projects. On the left, that scope’s settings are split into tabs, one category at a time: Questions, Pacing, Levels, Memory, Feedback, Privacy, This machine, Terminal, Companion and Changed. A small number on a tab counts the settings that scope’s file sets in it. Choosing another scope keeps the tab you are on. On a narrow window the scopes become a row above the tabs.
| Page | What you can do |
|---|---|
User (#/settings/dashboard/<tab>, also #/settings/user/<tab>) | Change a setting everywhere. Reset to default removes it from your file. Leave out <tab> for Questions; the others are pacing, levels, memory, feedback, privacy, this-machine, terminal, companion and changed. |
Project (#/settings/project/<tab>?project=<checkout>) | Change a setting for one project. Each row says whether its value is set for this project, inherited from your user settings, or the default. Inherit removes the project’s value so your user setting applies again. Without a project selected, it asks you to pick one on the right. |
The Changed tab lists the keys the scope’s own file sets and, for a project, what your user settings say for each; each line opens its tab. The Terminal tab shows providers, notifications and sync with their current value instead of a control.
A control saves when you change it; a text or number box saves when you leave it or press Enter. The row reports saved or inherited. Each field states what it accepts, and a value outside that is refused under the field before anything is sent, keeping what you typed; the server checks again with the same rules and reports a refusal, such as focus: learn with no topic, in the same place. auto_update, telemetry and dashboard_autostart apply to the whole machine, so a project shows them read-only with a link to User. The dashboard counts which workflows you open, whether an explainer was scrolled to the end, and which setting you changed (never the value) in the anonymous usage counts. Providers, notifications and sync send work off the machine or run a command, so they stay a typed command.
Choosing a tab is instant: the page draws it from the settings it already holds and makes no request. Choosing another project reads that project’s settings.
Only projects with a git checkout on this machine can be configured. The footer’s dial line shows your user settings, not any one project’s, and follows a change made with eklavya config set within about a second.
Opening one thing
| Detail page | Contains |
|---|---|
Concept (#/learning/concept/<slug>) | Score and decay, review schedule, a copyable command for this concept alone when it is due, and every recorded question as one line that opens to its options and feedback. Grade history, logged context and connected concepts are folded. |
Session (#/learning/session/<id> or #/memory/session/<id>) | Logged work and the questions asked, then folded sections for review concepts, observations and proposed concepts. Both routes show the same session with the originating workflow’s sidebar. |
Domain (#/learning/domain/<name>) | Concepts ordered by weakness, with mastery and learning state. |
Observation (#/memory/entry/<id>) | Narrative, facts, files, tags, summariser, confidence, concept candidates, reuse receipts and expandable raw evidence. Corrections link to the replacement. |
Invalid routes show an error with links back to the Dashboards. Rows and relevant count tiles are links you can reach with the keyboard.
Reading the timeline
The timeline is an audit trail. Superseded and soft-deleted entries remain labelled and struck through there, although retrieval excludes them. Search treats %, _ and \ as literal characters.
The timeline groups entries under a heading for each local day and says when a stretch of days has nothing. When a session’s summary is on the same page as its observations, they fold under one session line; open it to see them. Grouping is per page, so a session whose summary is on another page shows its observations as ordinary lines.
The Memory Dashboard shows observations, sessions, pending evidence and reuse as tiles, and the distilled, indexed, reused, delivered and assessed totals on one line under its title. The timeline shows observations, sessions and pending evidence on one line.
| Count | Meaning |
|---|---|
| Observations | Live entries, excluding superseded and deleted ones; also reports how many are indexed as vectors. |
| Pending | Captured raw events not yet summarised into an observation, out of all evidence events. |
| Sessions | Sessions that captured evidence or wrote observations. |
| Reused | Entries selected for recall and those in a block a hook emitted. |
| Assessed | Concepts proposed from evidence that you actually answered a question about. |
With a project selected, observations, evidence and sessions are scoped to it. Indexing, reuse, delivery and assessment totals that remain database-wide are labelled “all projects”. Captured or recalled material does not count as understanding.
Reuse: what B and D mean
A recall receipt compares base (B), the raw evidence behind the entries, with delivered (D), the context actually supplied, including later detail fetches. Both use the same four-characters-per-token estimate. Estimated reduction is (B − D) / B.
Receipts can be prepared, emitted, confirmed or unknown. emitted means the hook wrote the context to Claude Code, which does not acknowledge it; older receipts say confirmed for the same thing. Only emitted and confirmed receipts contribute to headline savings. Prepared and unknown receipts stay visible without a saving claim. Longer summaries can produce overhead, which is reported rather than hidden. The page also counts explicit memory reads, including those made without a receipt.
This measures estimated context volume compared with raw evidence, not your bill, API cache hits or model spend. See Memory.
Health
Use the health page to locate a gap between capture, processing, indexing, retrieval and delivery:
| Signal | Meaning or next step |
|---|---|
| Last capture | Old despite recent work: inspect capture and installation. |
| Queued, paused or failed jobs | Check the oldest job and error class. Transient failures retry. Auth, quota and missing-command problems pause the queue: it rechecks itself at most every 30 minutes, or run eklavya memory process after fixing the cause. |
| Verdict | The same ok, warn or stalled verdict as eklavya memory status, with its reasons in the banner above the tiles and stalled or warn on the Memory overview’s Health row. See the memory health verdict. |
| Dropped events | Evidence could not be retained while the database was unavailable. eklavya memory replay can recover eligible transcript history. |
| Provider settings | Shows what is configured. Only the observer currently runs a model; an embeddings setting does not change the local search implementation. |
Provider error classes are shown without raw messages, which can quote captured content. eklavya memory status gives the terminal view of the same health information.
Tips
On your first visits, a dot marks each feature the current page has a tip for (it pulses unless your system asks for reduced motion). The page’s first tip opens by itself, once, about half a second after the page draws: a bubble pointing at the feature that says what it does, with the companion’s face beside the words (a wink for most tips, and a matching expression for a few). The others stay dots. For example, the Learning Dashboard points at the caret beside the workflow name and marks How this works with a dot. Once you dismiss a page’s first tip, the next one opens by itself on a later visit.
| You do | What happens |
|---|---|
| Click Got it | The tip and its dot go for good. |
| Press Escape, click × or click elsewhere | The bubble closes and the dot stays. Click the dot, or Tab to it and press Enter, to open it again. |
| Use the feature itself | The tip counts as seen and goes for good. |
Only one bubble is open at a time, and moving to another page closes it. No dot or bubble shows while the menu drawer, a dropdown or the correction dialog is open, and at 900 px or narrower, where the sidebar becomes the drawer, its features get no tips. A dot hides while its feature is scrolled out of view, and a tip does not open by itself until its feature is on screen. A tip that has opened once does not open by itself again; its dot stays until you dismiss it.
The Tips switch on the Settings page’s Companion tab sets it: off hides every dot and bubble, and on shows every tip again from the start. Which tips you have seen is remembered in this browser only, so another browser, or a dashboard on a different --port, shows them again. If the browser blocks site storage, the dashboard shows no tips.
The daily card
The first time you arrive at the Learning Dashboard each day, a card opens over it, about half a second after the page draws. It has the archer, a line in a speech bubble, one number or goal, an action button and Not now, and a last line that says why this card was chosen. Close it with Not now, the close button, Esc or a click outside, and it does not come back until tomorrow. A day is your computer’s local calendar day, as it is for the streak.
The page behind the card is blurred and dimmed so the card has your whole attention, and the speech bubble’s tail points at the archer.
The card does not run quizzes. They run in your Claude session, so its button takes you to the page that shows the command, or opens the concept’s review sheet. Each card’s button is in the table below.
Which card you get
One engine decides, from numbers the page already holds: it checks whether anything should show, scores every card whose condition holds, and shows the highest.
| Card | It qualifies when | Base score | Button |
|---|---|---|---|
| Milestone | Your streak has reached 7, 14, 30, 60, 100, 200 or 365 days within the last 2 days, and you have not seen that milestone in this run. Only the highest one passed shows | 100 | Keep going (closes the card) |
| Welcome back | Your last answer was 3 or more days ago | 90 | Review the most overdue concept (opens its review sheet), or See your concepts |
| Last week | It is Monday, Tuesday or Wednesday, you answered at least 5 questions last week, and you have not seen this card this week | 70 | See your weakest domain (the Concepts page filtered to it), or See your concepts |
| Due now | A concept is due. The card names the most overdue one and links to its review sheet | 60, plus 1 per day overdue, up to 85 | Review this concept (opens its review sheet) |
| Daily goals | You have answered fewer than 3 questions today | 45 | Open the review queue |
| Week ahead | Something is due or scheduled in the next 6 days. Mondays add 15 | 35 | Open the review queue |
| Daily check-in | Always, once you have any answers. Streak, this week’s active days and today’s goal | 40, plus 10 with a streak of 3 or more | Open the review queue when something is due, otherwise See your concepts |
A milestone is remembered for the run it was reached in: if the streak breaks, the same milestone is celebrated again when you reach it again. A card shown yesterday loses 25 points, 2 days ago 15, 3 days ago 8, so the same card does not greet you every morning. A tie goes to the card higher in the table. Last week shows its accuracy against the week before it and names your strongest and weakest domain when at least two domains each have two concepts you have answered.
The card never shows when any of these holds, It does not wait for a busy page: the next arrival tries again.
- It already showed today, or you switched it off. A stored day later than today (a clock set back, or travel west) also counts as shown.
- You have no answers yet, so there is nothing to report.
- You did not land on the Learning Dashboard. An explainer page an agent opens, or any other page, gets no card, and nothing is remembered. A day’s card is still available when you next arrive at the Learning Dashboard.
- A dialog, the menu drawer, a dropdown or the review sheet is open, or the page is still loading. A tab hidden in the background decides when you switch to it.
- The page is only redrawing: a tab, a filter, a resize, or new activity arriving by itself.
With a project selected, the card reads that project’s answers and streak, as the page does.
The Daily card switch on the Settings page’s Companion tab, below Tips, sets it. What it showed and when is remembered in this browser only (eklavya-dash-daily), so another browser, or a dashboard on a different --port, shows a card again. If the browser blocks site storage, no card shows, because a card that cannot remember would open on every visit.
Projects, scope, ground, tips and paging
The project selector includes projects with attempts, logged concepts, evidence, observations, reuse receipts or earned levels. Folder names identify projects; duplicate names include a parent folder. Worktrees resolve to their main checkout when that relationship is known. Missing checkouts remain listed as “checkout gone”. No repository means work outside git; Unattributed means older rows without a project.
Selecting a project scopes lists and activity, but concept mastery and review dates remain shared. The selected project is saved in the URL. The ink/paper theme, the tips switch and the daily card switch are remembered in your browser.
Most lists show 20 rows per page; the memory timeline shows 25, and a concept’s question history shows ten, one line each.
The dashboard loads your newest 800 answers and your newest 800 logged context lines. Totals, mastery, the per-day counts, each project’s counts and the Learning Dashboard’s answer count, accuracy and recorded-concept counts, and the number of skipped answers on the Review page, come from every row in the database, so a cap shortens a history list and changes no number. When a cap cuts a list, the footer says how many it shows out of how many. A session whose rows fall outside the caps still opens with what it logged and was asked.
While you leave it open
An open dashboard is live. When something it shows changes, it reads the new numbers and redraws that part of the page in place, usually within about a second. Nothing asks you to refresh.
A change is anything the page would show: an answer, captured evidence, a memory entry added, rewritten or removed (including a session summary updated while that session runs), a memory read, a recall receipt, a feedback item arriving, acknowledged or deleted, a change to your user settings or to the settings of a project you have answered questions in, or an artifact page written or removed. Numbers, rows, the sidebar’s counts and the Feedback badge change in place. An unchanged database never starts an update. The memory health panel’s last-prune time and dropped-capture count, and the Feedback page’s note that the last session could not be reviewed, do not start one on their own.
An update does not move what you are reading or using:
- The page does not scroll, and the heatmap stays on the weeks you paged to.
- Folds, timeline entries and questions you opened stay open.
- The focus stays on the control you are on, whichever it is (a section’s summary, a Copy button, a row, a pager button), and the caret stays in the search box you are typing in.
- Text you selected, a delete confirmation you opened on Feedback and an evidence event you opened on an observation stay as they are while the page around them changes: what the new data did not change is not touched.
- A tip you are reading stays open.
- A choice list you opened stays open on any page, and a date you are typing into the Timeline’s custom range stays where you are typing. What waited for them, such as the counts in the list’s choices, is drawn when you close the list or leave the box.
- A Settings field you are editing keeps its text. The rows wait to redraw until you leave the field, while the tab strip, its counts and the scope rail update.
- An explainer you are reading is not reloaded, and its correction bar and dialog keep their state.
Changes that arrive while the page is still reading the last one, such as a session logging several concepts, are read together. A tab you cannot see stops listening and makes no requests. When you return to it, the page catches up in one go, however long you were away. If the dashboard stops, the page keeps what it was showing, shows no banner and reconnects by itself when the dashboard is back. The write token belongs to the dashboard start that served the page, so after a restart a setting you save is refused with “Stale or missing dashboard token. Reload the page.” until you reload.
Old links still work
Legacy bookmarks are rewritten without adding a history entry. Their filters and item IDs are preserved.
Legacy route mapping
| Old route | Current route |
|---|---|
#/, #/overview | #/learning/dashboard |
#/concepts, #/concept/<slug> | #/learning/concepts, #/learning/concept/<slug> |
#/review, #/review/<tab> | #/learning/review, #/learning/review/<tab> |
#/sessions, #/session/<id> | #/learning/sessions, #/learning/session/<id> |
#/projects, #/domains, #/domain/<name> | The corresponding /learning/ route. |
#/memory, #/memory/<type> | #/memory/timeline, #/memory/timeline/<type> |
#/entry/<id> | #/memory/entry/<id> |
#/reuse, #/health | #/memory/reuse, #/memory/health |
An old link without a project can pick up the previous saved project once. New-style links carry their scope explicitly.
What it is, underneath
The dashboard reads the local database and binds to 127.0.0.1. It accepts only GET and HEAD, except its five writes, validates loopback request addresses, escapes stored content and refuses framing by other pages. A request whose address is not a valid URL gets a 400 reply, and the server keeps running. Only the dashboard itself may frame an artifact page, for the viewer. Dashboard views load no external fonts or other remote resources; an artifact opened in its own tab has the font exception described above. The tips library (Driver.js) ships inside the package, and the dashboard serves it itself at /vendor/driver-hints.js and /vendor/driver-hints.css. The daily card’s engine is also a local script, served at /daily-card.js.
Its read-only JSON endpoints serve summary state (/api/state), the change cursor on its own (/api/cursor), project inventory (/api/projects), paged memory (/api/memory), entry detail (/api/memory/entry), memory sessions (/api/memory/sessions, which also returns what one session logged and was asked when you pass ?session=), settings (/api/settings), a missed question to correct (/api/attempts/correction?id=, without its answer), and feedback: one item (/api/feedback, the waiting one without ?id=) and the acknowledged list (/api/feedback/list). /api/events is a stream of the change cursor, described below. The state payload carries only whether an item is waiting, its id and counts, never your prompt. There are five writes:
| Write | What it does |
|---|---|
POST /api/settings | Changes one setting. Body at most 256 KB. |
POST /api/attempts/retry | Records one pick on the correction dialog and checks it. Body at most 16 KB. |
POST /api/feedback/acknowledge | Acknowledges an item by id; a repeat answers already and changes nothing. Body at most 16 KB. |
POST /api/feedback/delete | Deletes an item by id. Body at most 16 KB. |
POST /api/feedback/opened | Counts one opening of the Feedback page with an item waiting, as greeting, badge or direct. Body at most 16 KB. |
Each needs a loopback Origin, a JSON body and a random token the server puts in the page each time it starts, so another site open in your browser cannot write. Settings never edit learning or memory data, and feedback never touches your scores; a correction adds rows, updates the concept’s score and review date, and never changes the original answer.
/api/events takes a GET only and is held to the same loopback check as every other read. It is a text/event-stream that sends the current cursor when it connects, then one cursor event each time the cursor changes, and a comment line every 25 seconds so nothing closes a quiet stream. It carries nothing else: the page reads /api/state and /api/projects to learn what changed. While at least one stream is open, the server reads the cursor every second, and it also watches the database’s -wal file, your user config file, each project’s config file and the artifacts folder, waiting 150 ms after the last file event so a burst of writes is one check. A write made through the dashboard’s own routes is checked at once. With no stream open, nothing watches and no timer runs. At most 32 streams are open at once; the 33rd gets a 503, and the page tries again after a pause that starts at 5 seconds and doubles to a minute.
The server keeps the build it made of the state, the project list, the settings pages and the paged memory and feedback lists, and rebuilds one when the cursor has moved. It builds the state and the project list once when it starts listening, so a page opened within a minute of the start does not wait for them. Scores decay with the clock and a project’s checkout can disappear without a database write, so the state, the project list and the settings pages also expire after 60 seconds, and a page opened after that waits for one rebuild. Until the next change or expiry, a reload, a second tab or a Settings click is answered from memory. The browser never keeps the JSON. It keeps the tokens, the mascot files, the tips library and the thumbnails for an hour, and it asks the server on every load whether the page is still the one it holds: the check is an ETag that changes at each start, because the write token is part of the page.