eklavya 1.18.2 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/assets/dashboard.html +559 -14
  2. package/dist/assets/tutor/references/focus-and-level.md +29 -0
  3. package/dist/cli.js +648 -20
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config-path.js +156 -0
  6. package/dist/config-path.js.map +1 -0
  7. package/dist/config.js +231 -2
  8. package/dist/config.js.map +1 -1
  9. package/dist/dashboard.js +355 -0
  10. package/dist/dashboard.js.map +1 -1
  11. package/dist/eval/retrieval-score.js +77 -0
  12. package/dist/eval/retrieval-score.js.map +1 -0
  13. package/dist/hooks/capture-tool.js +107 -0
  14. package/dist/hooks/capture-tool.js.map +1 -0
  15. package/dist/hooks/checkpoint-quiz.js +5 -6
  16. package/dist/hooks/checkpoint-quiz.js.map +1 -1
  17. package/dist/hooks/lib.js +7 -33
  18. package/dist/hooks/lib.js.map +1 -1
  19. package/dist/hooks/memory-lib.js +181 -0
  20. package/dist/hooks/memory-lib.js.map +1 -0
  21. package/dist/hooks/prompt-submit-nudge.js +56 -20
  22. package/dist/hooks/prompt-submit-nudge.js.map +1 -1
  23. package/dist/hooks/session-start.js +73 -74
  24. package/dist/hooks/session-start.js.map +1 -1
  25. package/dist/hooks/stop-quiz-check.js +44 -7
  26. package/dist/hooks/stop-quiz-check.js.map +1 -1
  27. package/dist/install.js +37 -0
  28. package/dist/install.js.map +1 -1
  29. package/dist/memory/capture.js +123 -0
  30. package/dist/memory/capture.js.map +1 -0
  31. package/dist/memory/code.js +186 -0
  32. package/dist/memory/code.js.map +1 -0
  33. package/dist/memory/collections.js +87 -0
  34. package/dist/memory/collections.js.map +1 -0
  35. package/dist/memory/embed.js +81 -0
  36. package/dist/memory/embed.js.map +1 -0
  37. package/dist/memory/hosts.js +71 -0
  38. package/dist/memory/hosts.js.map +1 -0
  39. package/dist/memory/identity.js +74 -0
  40. package/dist/memory/identity.js.map +1 -0
  41. package/dist/memory/import.js +916 -0
  42. package/dist/memory/import.js.map +1 -0
  43. package/dist/memory/learning.js +148 -0
  44. package/dist/memory/learning.js.map +1 -0
  45. package/dist/memory/notify.js +220 -0
  46. package/dist/memory/notify.js.map +1 -0
  47. package/dist/memory/privacy.js +117 -0
  48. package/dist/memory/privacy.js.map +1 -0
  49. package/dist/memory/provider.js +155 -0
  50. package/dist/memory/provider.js.map +1 -0
  51. package/dist/memory/recall.js +327 -0
  52. package/dist/memory/recall.js.map +1 -0
  53. package/dist/memory/replay.js +174 -0
  54. package/dist/memory/replay.js.map +1 -0
  55. package/dist/memory/search.js +143 -0
  56. package/dist/memory/search.js.map +1 -0
  57. package/dist/memory/spool.js +93 -0
  58. package/dist/memory/spool.js.map +1 -0
  59. package/dist/memory/store.js +399 -0
  60. package/dist/memory/store.js.map +1 -0
  61. package/dist/memory/summarize.js +178 -0
  62. package/dist/memory/summarize.js.map +1 -0
  63. package/dist/memory/sync.js +595 -0
  64. package/dist/memory/sync.js.map +1 -0
  65. package/dist/memory/tokens.js +55 -0
  66. package/dist/memory/tokens.js.map +1 -0
  67. package/dist/memory/worker.js +207 -0
  68. package/dist/memory/worker.js.map +1 -0
  69. package/dist/migrations/009_memory.sql +226 -0
  70. package/dist/migrations/010_import.sql +26 -0
  71. package/dist/migrations/011_sync.sql +76 -0
  72. package/dist/migrations/012_job_backoff.sql +13 -0
  73. package/dist/migrations/013_batch_provenance.sql +18 -0
  74. package/dist/migrations/014_batch_events_index.sql +18 -0
  75. package/dist/plugin/.claude-plugin/plugin.json +1 -1
  76. package/dist/plugin/agents/tutor.md +3 -1
  77. package/dist/plugin/hooks/CLAUDE.md +30 -6
  78. package/dist/plugin/hooks/hooks.json +10 -0
  79. package/dist/plugin/skills/CLAUDE.md +17 -7
  80. package/dist/plugin/skills/memory/SKILL.md +88 -0
  81. package/dist/plugin/skills/setup/SKILL.md +16 -2
  82. package/dist/plugin/skills/tutor/references/focus-and-level.md +29 -0
  83. package/dist/time.js +41 -0
  84. package/dist/time.js.map +1 -0
  85. package/dist/tools/code_tools.js +73 -0
  86. package/dist/tools/code_tools.js.map +1 -0
  87. package/dist/tools/collection_tools.js +92 -0
  88. package/dist/tools/collection_tools.js.map +1 -0
  89. package/dist/tools/config_tools.js +104 -1
  90. package/dist/tools/config_tools.js.map +1 -1
  91. package/dist/tools/index.js +15 -0
  92. package/dist/tools/index.js.map +1 -1
  93. package/dist/tools/memory_read_tools.js +277 -0
  94. package/dist/tools/memory_read_tools.js.map +1 -0
  95. package/dist/tools/memory_write_tools.js +115 -0
  96. package/dist/tools/memory_write_tools.js.map +1 -0
  97. package/dist/user-skill/eklavya/SKILL.md +64 -8
  98. package/package.json +2 -1
package/dist/dashboard.js CHANGED
@@ -27,6 +27,10 @@ import { decayedScore, isDue, isKnown, MS_PER_DAY } from './srs.js';
27
27
  import { GLOBAL_PROJECT, levelStanding, PASSING_GRADE, projectKey } from './store.js';
28
28
  import { loadConfig, DEFAULT_CONFIG } from './config.js';
29
29
  import { dbPath } from './paths.js';
30
+ import { receiptTotals } from './memory/store.js';
31
+ import { ESTIMATOR, savingsFrom, savingsLine } from './memory/tokens.js';
32
+ import { queueDepth } from './memory/worker.js';
33
+ import { droppedCount } from './memory/spool.js';
30
34
  const moduleDir = path.dirname(fileURLToPath(import.meta.url));
31
35
  /**
32
36
  * High, unassigned, and deliberately boring to collide with.
@@ -51,6 +55,29 @@ const TIMELINE_DAYS = 365;
51
55
  * history list, never make a number wrong.
52
56
  */
53
57
  const ATTEMPT_LIMIT = 2000;
58
+ /**
59
+ * The memory corpus does not travel in `/api/state`.
60
+ *
61
+ * Attempts are short rows with a bounded question on them; an observation
62
+ * carries a narrative and the tool output it was distilled from, and a year of
63
+ * them is megabytes. So the overview gets counts — aggregated in SQL, because
64
+ * the page cannot honestly derive a total it was never sent — and the timeline
65
+ * itself is paged over `/api/memory` (PRD DASH-02). One resource endpoint with
66
+ * filters, not one query per card.
67
+ */
68
+ const MEMORY_PER = 25;
69
+ /** Hard ceiling on one page of the memory resource, whatever `per` asks for. */
70
+ const MEMORY_PER_MAX = 200;
71
+ /**
72
+ * Receipts are one row per injection and the arithmetic has to be checkable
73
+ * line by line, so they do travel — capped like `attempts`, with the total
74
+ * alongside so a truncated ledger cannot read as the whole one.
75
+ */
76
+ const RECEIPT_LIMIT = 200;
77
+ /** One row per session that captured evidence, newest first. */
78
+ const MEMORY_SESSION_LIMIT = 500;
79
+ /** Longest narrative excerpt a timeline row carries; the detail page has it all. */
80
+ const SNIPPET = 150;
54
81
  /**
55
82
  * Two timestamp shapes live in this database and both have to parse.
56
83
  * `attempts.ts` defaults to SQLite's `2026-09-05 21:04:00` — UTC, no zone
@@ -75,6 +102,244 @@ function readConfig() {
75
102
  return DEFAULT_CONFIG;
76
103
  }
77
104
  }
105
+ const one = (db, sql, ...args) => db.prepare(sql).get(...args);
106
+ const many = (db, sql, ...args) => db.prepare(sql).all(...args);
107
+ /**
108
+ * The memory half of the overview, as counts rather than rows.
109
+ *
110
+ * Six numbers that a single "memories" figure would conflate, and the
111
+ * conflation is the dishonest part: evidence can be captured and never
112
+ * processed, an entry can be indexed and never retrieved, retrieved and never
113
+ * delivered, and delivered without anyone ever being asked about it. Exposure
114
+ * is not assessment (PRD LRN-02) — `assessed` is the only one of these that
115
+ * required the developer to answer something.
116
+ */
117
+ function memorySummary(db) {
118
+ const entries = one(db, `SELECT count(*) AS total,
119
+ COALESCE(SUM(deleted_at IS NULL AND superseded_by IS NULL), 0) AS live,
120
+ COALESCE(SUM(superseded_by IS NOT NULL), 0) AS superseded,
121
+ COALESCE(SUM(deleted_at IS NOT NULL), 0) AS deleted,
122
+ COALESCE(SUM(kind = 'note'), 0) AS notes
123
+ FROM memory_entries`);
124
+ const events = one(db, `SELECT count(*) AS captured,
125
+ COALESCE(SUM(status = 'summarized'), 0) AS processed,
126
+ COALESCE(SUM(status <> 'summarized'), 0) AS pending,
127
+ COALESCE(SUM(redacted), 0) AS redacted,
128
+ max(occurred_at) AS newest
129
+ FROM evidence_events`);
130
+ const candidates = many(db, 'SELECT status, count(*) AS n FROM learning_sources GROUP BY status');
131
+ return {
132
+ // What the hooks accepted from the host.
133
+ captured: events.captured,
134
+ // How much of that an observation job has already distilled.
135
+ processed: events.processed,
136
+ pending: events.pending,
137
+ redacted: events.redacted,
138
+ newest_event: events.newest,
139
+ entries: entries.live,
140
+ entries_total: entries.total,
141
+ superseded: entries.superseded,
142
+ deleted: entries.deleted,
143
+ notes: entries.notes,
144
+ // Live entries carrying a vector: what semantic recall can actually reach.
145
+ indexed: one(db, `SELECT count(DISTINCT v.entry_id) AS n FROM memory_vectors v
146
+ JOIN memory_entries e ON e.id = v.entry_id WHERE e.deleted_at IS NULL`).n,
147
+ // Entries a receipt ever selected …
148
+ reused: one(db, 'SELECT count(DISTINCT entry_id) AS n FROM context_receipt_items').n,
149
+ // … and the subset that a *confirmed* delivery actually put in front of the agent.
150
+ exposed: one(db, `SELECT count(DISTINCT i.entry_id) AS n FROM context_receipt_items i
151
+ JOIN context_receipts r ON r.id = i.receipt_id WHERE r.delivery = 'confirmed'`).n,
152
+ // Concepts that came out of evidence and were then actually answered on.
153
+ assessed: one(db, `SELECT count(DISTINCT ls.concept_id) AS n FROM learning_sources ls
154
+ JOIN attempts a ON a.concept_id = ls.concept_id
155
+ WHERE ls.concept_id IS NOT NULL`).n,
156
+ candidates: Object.fromEntries(candidates.map((c) => [c.status, c.n])),
157
+ types: many(db, `SELECT COALESCE(type, 'untyped') AS type, count(*) AS n FROM memory_entries
158
+ WHERE deleted_at IS NULL GROUP BY type ORDER BY n DESC`),
159
+ tags: many(db, `SELECT t.tag, count(*) AS n FROM memory_entry_tags t
160
+ JOIN memory_entries e ON e.id = t.entry_id AND e.deleted_at IS NULL
161
+ GROUP BY t.tag ORDER BY n DESC, t.tag LIMIT 60`),
162
+ projects: many(db, `SELECT project, count(*) AS n FROM memory_entries GROUP BY project ORDER BY n DESC`),
163
+ per_page: MEMORY_PER,
164
+ };
165
+ }
166
+ /**
167
+ * The savings ledger, receipt by receipt.
168
+ *
169
+ * `B` is what the same material would have cost read from source; `D` is what
170
+ * was actually delivered. Only a *confirmed* delivery contributes to the
171
+ * headline — `receiptTotals` sums the confirmed rows alone, and `savingsFrom`
172
+ * refuses to divide at all unless the delivery was confirmed, so an optimistic
173
+ * "prepared" receipt can never be shown as a saving.
174
+ */
175
+ function reuseSummary(db) {
176
+ const totals = receiptTotals(db);
177
+ const savings = savingsFrom({
178
+ baseTokens: totals.base,
179
+ deliveredTokens: totals.delivered,
180
+ delivery: totals.confirmed > 0 ? 'confirmed' : 'unknown',
181
+ });
182
+ return {
183
+ ...totals,
184
+ savings,
185
+ line: savingsLine(savings),
186
+ estimator: ESTIMATOR,
187
+ by_delivery: many(db, `SELECT delivery, count(*) AS n,
188
+ COALESCE(SUM(base_tokens), 0) AS base,
189
+ COALESCE(SUM(delivered_tokens), 0) AS delivered
190
+ FROM context_receipts GROUP BY delivery`),
191
+ receipts_shown: Math.min(totals.receipts, RECEIPT_LIMIT),
192
+ rows: many(db, `SELECT r.id, r.receipt_uid, r.project, r.session_id, r.scope, r.method,
193
+ r.base_tokens, r.delivered_tokens, r.item_count, r.delivery, r.created_at,
194
+ (SELECT COALESCE(SUM(sent_tokens), 0) FROM context_receipt_items i
195
+ WHERE i.receipt_id = r.id AND i.stage = 'index') AS index_tokens,
196
+ (SELECT COALESCE(SUM(sent_tokens), 0) FROM context_receipt_items i
197
+ WHERE i.receipt_id = r.id AND i.stage = 'detail') AS detail_tokens,
198
+ (SELECT count(*) FROM context_receipt_items i
199
+ WHERE i.receipt_id = r.id AND i.stage = 'detail') AS detail_items
200
+ FROM context_receipts r ORDER BY r.id DESC LIMIT ?`, RECEIPT_LIMIT),
201
+ };
202
+ }
203
+ /**
204
+ * Capture heartbeat, queue, failures and provider state.
205
+ *
206
+ * Bounded and redacted by construction: error *classes* and counts, never
207
+ * `last_error`, never a key, never a log dump (PRD DASH-03). A class is what
208
+ * tells the reader whether to re-authenticate or wait.
209
+ */
210
+ function healthSummary(db, config) {
211
+ const beat = one(db, 'SELECT max(occurred_at) AS newest, max(received_at) AS received FROM evidence_events');
212
+ return {
213
+ capture: {
214
+ enabled: config.memory.enabled,
215
+ mode: config.memory.capture,
216
+ newest_event: beat.newest,
217
+ newest_received: beat.received,
218
+ retention_days: config.memory.retention_days,
219
+ pruned_at: one(db, "SELECT value FROM meta WHERE key = 'memory_pruned_at'")?.value ?? null,
220
+ },
221
+ queue: queueDepth(db),
222
+ stalled: many(db, `SELECT status, COALESCE(error_class, 'unclassified') AS error_class, count(*) AS n, max(updated_at) AS last,
223
+ max(attempts) AS attempts
224
+ FROM memory_jobs WHERE status IN ('failed', 'paused')
225
+ GROUP BY status, error_class ORDER BY n DESC`),
226
+ spool_dropped: droppedCount(),
227
+ // Whether a provider exists and which model it names. The key never appears
228
+ // here — only the environment variable it is read from is configured at all,
229
+ // and even that name stays out of the payload.
230
+ providers: {
231
+ observer: config.providers.observer
232
+ ? { kind: config.providers.observer.kind, model: config.providers.observer.model }
233
+ : null,
234
+ embeddings: config.providers.embeddings
235
+ ? { kind: config.providers.embeddings.kind, model: config.providers.embeddings.model }
236
+ : null,
237
+ retrieval_mode: config.retrieval.mode,
238
+ },
239
+ };
240
+ }
241
+ /** One row per session that captured evidence, so a session page can link the two halves. */
242
+ function memorySessions(db) {
243
+ return many(db, `SELECT e.session_id, e.project, count(*) AS events,
244
+ COALESCE(SUM(e.redacted), 0) AS redacted,
245
+ min(e.occurred_at) AS first, max(e.occurred_at) AS last,
246
+ (SELECT count(*) FROM memory_entries m WHERE m.session_id = e.session_id) AS entries,
247
+ (SELECT count(*) FROM learning_sources ls JOIN memory_entries m ON m.id = ls.entry_id
248
+ WHERE m.session_id = e.session_id) AS candidates
249
+ FROM evidence_events e
250
+ GROUP BY e.session_id, e.project
251
+ ORDER BY last DESC LIMIT ?`, MEMORY_SESSION_LIMIT);
252
+ }
253
+ /**
254
+ * One page of the memory timeline (PRD DASH-02).
255
+ *
256
+ * Deleted and superseded rows are *included* — the dashboard is the audit
257
+ * trail, and an entry that vanished when it was corrected is an entry nobody
258
+ * can check. They travel with `deleted_at` and `superseded_by` set so the page
259
+ * can mark them.
260
+ */
261
+ export function memoryPage(db, q = {}) {
262
+ const per = Math.min(MEMORY_PER_MAX, Math.max(1, Math.floor(q.per || MEMORY_PER)));
263
+ const page = Math.max(1, Math.floor(q.page || 1));
264
+ const where = [];
265
+ const args = [];
266
+ const eq = (sql, v) => {
267
+ if (v === undefined || v === null || v === '')
268
+ return;
269
+ where.push(sql);
270
+ args.push(v);
271
+ };
272
+ eq('e.project = ?', q.project);
273
+ eq('e.session_id = ?', q.session);
274
+ eq("COALESCE(e.type, 'untyped') = ?", q.type);
275
+ eq('e.occurred_at >= ?', q.since);
276
+ eq('e.occurred_at <= ?', q.until);
277
+ if (q.tag) {
278
+ where.push('EXISTS (SELECT 1 FROM memory_entry_tags t WHERE t.entry_id = e.id AND t.tag = ?)');
279
+ args.push(String(q.tag).toLowerCase());
280
+ }
281
+ // A search box is not FTS5 query syntax, and the corpus is small enough that
282
+ // a LIKE over the stored columns beats explaining a MATCH parse error to
283
+ // someone who typed `fix: auth (retry?)`.
284
+ if (q.q && String(q.q).trim()) {
285
+ where.push('(e.title LIKE ? OR e.narrative LIKE ? OR e.facts LIKE ? OR e.files LIKE ?)');
286
+ const like = `%${String(q.q).trim().replace(/[\\%_]/g, '\\$&')}%`;
287
+ args.push(like, like, like, like);
288
+ }
289
+ const clause = where.length ? `WHERE ${where.join(' AND ')}` : '';
290
+ const total = one(db, `SELECT count(*) AS n FROM memory_entries e ${clause}`, ...args).n;
291
+ const pages = Math.max(1, Math.ceil(total / per));
292
+ const p = Math.min(page, pages);
293
+ const rows = many(db, `SELECT e.id, e.entry_uid, e.project, e.session_id, e.kind, e.type, e.title,
294
+ substr(e.narrative, 1, ${SNIPPET}) AS snippet, length(e.narrative) AS narrative_length,
295
+ e.files, e.generator, e.confidence, e.occurred_at, e.created_at,
296
+ e.superseded_by, e.deleted_at, e.import_source,
297
+ (SELECT count(*) FROM memory_entry_events me WHERE me.entry_id = e.id) AS event_count,
298
+ (SELECT group_concat(t.tag, ',') FROM memory_entry_tags t WHERE t.entry_id = e.id) AS tag_list
299
+ FROM memory_entries e ${clause}
300
+ ORDER BY e.occurred_at DESC, e.id DESC LIMIT ? OFFSET ?`, ...args, per, (p - 1) * per).map((r) => ({ ...r, tags: r.tag_list ? String(r.tag_list).split(',') : [] }));
301
+ // Asking for one session is asking for that session's whole memory story, so
302
+ // the candidates it proposed ride along rather than costing a second round
303
+ // trip from the session page.
304
+ const candidates = q.session
305
+ ? many(db, `SELECT ls.id, ls.slug, ls.name, ls.domain, ls.confidence, ls.status, c.slug AS concept_slug
306
+ FROM learning_sources ls
307
+ JOIN memory_entries e ON e.id = ls.entry_id
308
+ LEFT JOIN concepts c ON c.id = ls.concept_id
309
+ WHERE e.session_id = ? ORDER BY ls.confidence DESC`, q.session)
310
+ : undefined;
311
+ return { total, page: p, pages, per, rows, ...(candidates ? { candidates } : {}) };
312
+ }
313
+ /** One entry with its tags, its raw evidence and the candidates it proposed. */
314
+ export function memoryEntry(db, id) {
315
+ const entry = one(db, 'SELECT * FROM memory_entries WHERE id = ?', id);
316
+ if (!entry)
317
+ return null;
318
+ return {
319
+ entry,
320
+ tags: many(db, 'SELECT tag FROM memory_entry_tags WHERE entry_id = ? ORDER BY tag', id).map((t) => t.tag),
321
+ // The raw evidence behind the claim. `body` is capped: an observation can be
322
+ // distilled from a 200KB tool dump and the drill-down is a check, not an export.
323
+ events: many(db, `SELECT ev.id, ev.event_uid, ev.kind, ev.tool, ev.title, ev.source, ev.host, ev.agent_id,
324
+ substr(ev.body, 1, 4000) AS body, length(ev.body) AS body_length,
325
+ ev.files, ev.occurred_at, ev.redacted, ev.status
326
+ FROM evidence_events ev
327
+ JOIN memory_entry_events me ON me.event_id = ev.id
328
+ WHERE me.entry_id = ? ORDER BY ev.occurred_at, ev.id`, id),
329
+ candidates: many(db, `SELECT ls.id, ls.slug, ls.name, ls.domain, ls.confidence, ls.status, ls.concept_id,
330
+ c.slug AS concept_slug
331
+ FROM learning_sources ls LEFT JOIN concepts c ON c.id = ls.concept_id
332
+ WHERE ls.entry_id = ? ORDER BY ls.confidence DESC`, id),
333
+ // The row that replaced this one, and the rows this one replaced.
334
+ replaced_by: entry.superseded_by
335
+ ? one(db, 'SELECT id, title, occurred_at FROM memory_entries WHERE id = ?', entry.superseded_by)
336
+ : null,
337
+ replaces: many(db, 'SELECT id, title, occurred_at FROM memory_entries WHERE superseded_by = ?', id),
338
+ receipts: many(db, `SELECT r.id, r.scope, r.delivery, r.created_at, i.stage, i.source_tokens, i.sent_tokens
339
+ FROM context_receipt_items i JOIN context_receipts r ON r.id = i.receipt_id
340
+ WHERE i.entry_id = ? ORDER BY r.id DESC LIMIT 20`, id),
341
+ };
342
+ }
78
343
  export function dashboardState(db) {
79
344
  const now = new Date();
80
345
  const config = readConfig();
@@ -246,9 +511,37 @@ export function dashboardState(db) {
246
511
  FROM attempts`)
247
512
  .get(PASSING_GRADE, PASSING_GRADE);
248
513
  const sessionCount = db.prepare('SELECT count(DISTINCT session_id) AS n FROM session_concepts').get().n;
514
+ const memory = memorySummary(db);
515
+ const reuse = reuseSummary(db);
249
516
  return {
250
517
  generated_at: now.toISOString(),
251
518
  db_path: dbPath(),
519
+ /**
520
+ * What an open page polls to notice that work landed while it was reading
521
+ * it (PRD DASH-01). Counts of rows the payload already carries, so it costs
522
+ * no extra query and moves exactly when the page's content does.
523
+ *
524
+ * Deliberately not `generated_at`, and not a hash of the payload: both
525
+ * change on every call — scores are decayed against the clock — and a page
526
+ * that announces new activity every minute is a page whose banner is
527
+ * ignored inside a day.
528
+ *
529
+ * Ceiling: counts cannot see an edit that leaves the counts alone. Every
530
+ * such edit here (a superseded entry, a deleted one) moves a *different*
531
+ * count in this list, so the gap is theoretical today; a real event cursor
532
+ * is the upgrade if that stops being true.
533
+ */
534
+ cursor: [
535
+ allTime.answers,
536
+ logged.length,
537
+ sessionCount,
538
+ memory.captured,
539
+ memory.processed,
540
+ memory.entries_total,
541
+ memory.superseded,
542
+ memory.deleted,
543
+ reuse.receipts,
544
+ ].join(':'),
252
545
  timeline_days: TIMELINE_DAYS,
253
546
  attempts_shown: attempts.length,
254
547
  attempts_total: allTime.answers,
@@ -298,6 +591,12 @@ export function dashboardState(db) {
298
591
  concepts,
299
592
  attempts,
300
593
  logged,
594
+ // The memory half. Additive: every key above kept its name and its shape,
595
+ // because `/api/state` is a contract an older page still reads.
596
+ memory,
597
+ reuse,
598
+ health: healthSummary(db, config),
599
+ memory_sessions: memorySessions(db),
301
600
  };
302
601
  }
303
602
  /**
@@ -349,16 +648,72 @@ function send(res, status, type, body) {
349
648
  * server; falling back to an ephemeral port beats failing with EADDRINUSE
350
649
  * when the caller does not care which port it gets.
351
650
  */
651
+ /** `127.0.0.1`, `[::1]` and `localhost`, with or without a port, and nothing else. */
652
+ const LOOPBACK_HOST = /^(?:127\.0\.0\.1|\[::1\]|::1|localhost)(?::\d+)?$/i;
653
+ export function fromLoopback(hostHeader, originHeader) {
654
+ // A request with no Host is HTTP/1.0 or a hand-rolled client, not a browser,
655
+ // and a browser is the only attacker this check has. Allow it.
656
+ if (hostHeader !== undefined && !LOOPBACK_HOST.test(hostHeader))
657
+ return false;
658
+ // An `Origin` only appears on a cross-origin or scripted request. If one is
659
+ // present it has to be a loopback origin too -- `null` included, which is
660
+ // what a sandboxed iframe or a `file://` page sends.
661
+ if (originHeader !== undefined && originHeader !== 'null') {
662
+ try {
663
+ if (!LOOPBACK_HOST.test(new URL(originHeader).host))
664
+ return false;
665
+ }
666
+ catch {
667
+ return false;
668
+ }
669
+ }
670
+ return true;
671
+ }
352
672
  export function startDashboard(db, opts = {}) {
353
673
  const host = opts.host ?? '127.0.0.1';
354
674
  const wanted = opts.port ?? DEFAULT_PORT;
355
675
  const assets = path.join(moduleDir, 'assets');
356
676
  const server = http.createServer((req, res) => {
677
+ // Loopback is not an authorisation boundary for a browser (PRD DASH-03).
678
+ // A page the developer happens to have open can point a hostname it
679
+ // controls at 127.0.0.1 and fetch from here -- DNS rebinding -- and the
680
+ // same-origin policy does not help, because the page's origin *is* that
681
+ // hostname. Nothing here mutates, so the risk is not a write; it is that
682
+ // this payload now contains the developer's prompts, code and project
683
+ // history, and a hostile page would be reading all of it.
684
+ //
685
+ // The check is the standard one: the request has to have been addressed to
686
+ // loopback by name, which a rebound hostname never is.
687
+ if (!fromLoopback(req.headers.host, req.headers.origin)) {
688
+ return send(res, 403, 'text/plain', 'Eklavya serves loopback only.\n');
689
+ }
357
690
  const url = new URL(req.url ?? '/', `http://${host}`);
358
691
  try {
359
692
  if (url.pathname === '/api/state') {
360
693
  return send(res, 200, 'application/json', JSON.stringify(dashboardState(db)));
361
694
  }
695
+ // The memory timeline is a paged resource rather than part of the state
696
+ // payload: the corpus is the one thing here that grows without bound.
697
+ if (url.pathname === '/api/memory') {
698
+ const g = (k) => url.searchParams.get(k);
699
+ return send(res, 200, 'application/json', JSON.stringify(memoryPage(db, {
700
+ project: g('project'),
701
+ session: g('session'),
702
+ type: g('type'),
703
+ tag: g('tag'),
704
+ q: g('q'),
705
+ since: g('since'),
706
+ until: g('until'),
707
+ page: Number(g('page')) || 1,
708
+ per: Number(g('per')) || MEMORY_PER,
709
+ })));
710
+ }
711
+ if (url.pathname === '/api/memory/entry') {
712
+ const entry = memoryEntry(db, Number(url.searchParams.get('id')));
713
+ if (!entry)
714
+ return send(res, 404, 'application/json', '{"error":"no such entry"}');
715
+ return send(res, 200, 'application/json', JSON.stringify(entry));
716
+ }
362
717
  if (url.pathname === '/tokens.css') {
363
718
  return send(res, 200, 'text/css', fs.readFileSync(path.join(assets, 'tokens.css')));
364
719
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Retrieval scoring: pure arithmetic over a ranked list and a labelled set.
3
+ *
4
+ * Lives here, beside the other eval scorers, for the same reason they do: no
5
+ * model, no I/O, so it is unit-testable and the harness has nothing to get
6
+ * subtly wrong. `eval/retrieval-harness.mjs` supplies the rankings.
7
+ *
8
+ * The metric set is small, standard, and read in a particular order.
9
+ *
10
+ * **Top-1** is the headline. On a corpus where most queries have one right
11
+ * answer, precision@5 is arithmetic about how many results a mode returned
12
+ * rather than about whether they were good: a mode that always fills the slate
13
+ * scores 0.2 however perfect its ranking. Top-1 asks the question the developer
14
+ * asks — was the first thing it showed me the right thing.
15
+ *
16
+ * **Recall@k** is the one a savings percentage cannot see. Omitting useful
17
+ * evidence looks like an excellent saving (PRD MET-01), so it is reported
18
+ * beside precision and never blended into it.
19
+ *
20
+ * **Precision@k** still earns its place at a tight budget, where returning four
21
+ * irrelevant entries costs four entries' worth of the token budget.
22
+ */
23
+ export function scoreQuery(ranked, relevant, k) {
24
+ const top = ranked.slice(0, k);
25
+ const wanted = new Set(relevant);
26
+ const hits = top.filter((id) => wanted.has(id)).length;
27
+ const firstHit = top.findIndex((id) => wanted.has(id));
28
+ return {
29
+ query: '',
30
+ relevant: relevant.length,
31
+ retrieved: top.length,
32
+ hits,
33
+ precision: top.length ? hits / top.length : 0,
34
+ recall: relevant.length ? hits / relevant.length : 0,
35
+ rr: firstHit === -1 ? 0 : 1 / (firstHit + 1),
36
+ top1: firstHit === 0 ? 1 : 0,
37
+ };
38
+ }
39
+ export function summarise(scores, k) {
40
+ const n = scores.length || 1;
41
+ return {
42
+ queries: scores.length,
43
+ k,
44
+ top1: round(scores.reduce((s, q) => s + q.top1, 0) / n),
45
+ precision: round(scores.reduce((s, q) => s + q.precision, 0) / n),
46
+ recall: round(scores.reduce((s, q) => s + q.recall, 0) / n),
47
+ mrr: round(scores.reduce((s, q) => s + q.rr, 0) / n),
48
+ misses: scores.filter((q) => q.hits === 0).map((q) => q.query),
49
+ };
50
+ }
51
+ function round(value) {
52
+ return Number(value.toFixed(3));
53
+ }
54
+ /**
55
+ * Compares two modes on the same labels.
56
+ *
57
+ * The comparison is the point of the whole eval: "hybrid is better" is a claim
58
+ * about two numbers on one corpus, and it belongs in the manual only once this
59
+ * has produced them. A mode that wins on precision and loses on recall has not
60
+ * won, which is why both are reported rather than one blended score.
61
+ */
62
+ export function compare(a, b) {
63
+ // Top-1 and recall, not precision@k: see the note at the top of the file for
64
+ // why precision@k on a one-answer corpus measures slate size, not quality.
65
+ const top1Delta = round(b.summary.top1 - a.summary.top1);
66
+ const recallDelta = round(b.summary.recall - a.summary.recall);
67
+ if (top1Delta > 0 && recallDelta >= 0)
68
+ return { better: b.mode, top1Delta, recallDelta };
69
+ if (top1Delta < 0 && recallDelta <= 0)
70
+ return { better: a.mode, top1Delta, recallDelta };
71
+ if (top1Delta === 0 && recallDelta > 0)
72
+ return { better: b.mode, top1Delta, recallDelta };
73
+ if (top1Delta === 0 && recallDelta < 0)
74
+ return { better: a.mode, top1Delta, recallDelta };
75
+ return { better: null, top1Delta, recallDelta };
76
+ }
77
+ //# sourceMappingURL=retrieval-score.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieval-score.js","sourceRoot":"","sources":["../../src/eval/retrieval-score.ts"],"names":[],"mappings":"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"}