@nxuss/lemma 1.19.0 → 1.21.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 (50) hide show
  1. package/.agents/skills/lemma/SKILL.md +124 -0
  2. package/README.md +5 -1
  3. package/bin/init.js +109 -29
  4. package/bin/lemma-call.js +269 -0
  5. package/dist/cjs/mcp/index.js +4 -2
  6. package/dist/cjs/mcp/index.js.map +1 -1
  7. package/dist/cjs/mcp/prompts.d.ts +1 -1
  8. package/dist/cjs/mcp/prompts.d.ts.map +1 -1
  9. package/dist/cjs/mcp/prompts.js +1 -1
  10. package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -1
  11. package/dist/cjs/mcp/tool-profiles.js +9 -0
  12. package/dist/cjs/mcp/tool-profiles.js.map +1 -1
  13. package/dist/cjs/mcp/tools/analysis.d.ts.map +1 -1
  14. package/dist/cjs/mcp/tools/analysis.js +51 -20
  15. package/dist/cjs/mcp/tools/analysis.js.map +1 -1
  16. package/dist/cjs/mcp/tools/memory.d.ts +4 -4
  17. package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
  18. package/dist/cjs/mcp/tools/memory.js +217 -11
  19. package/dist/cjs/mcp/tools/memory.js.map +1 -1
  20. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  21. package/dist/cjs/mcp/tools.js +4 -1
  22. package/dist/cjs/mcp/tools.js.map +1 -1
  23. package/dist/cjs/subconscious/TheBrainV2.d.ts +102 -1
  24. package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
  25. package/dist/cjs/subconscious/TheBrainV2.js +255 -10
  26. package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
  27. package/dist/esm/mcp/index.js +4 -2
  28. package/dist/esm/mcp/index.js.map +1 -1
  29. package/dist/esm/mcp/prompts.d.ts +1 -1
  30. package/dist/esm/mcp/prompts.d.ts.map +1 -1
  31. package/dist/esm/mcp/prompts.js +1 -1
  32. package/dist/esm/mcp/tool-profiles.d.ts.map +1 -1
  33. package/dist/esm/mcp/tool-profiles.js +9 -0
  34. package/dist/esm/mcp/tool-profiles.js.map +1 -1
  35. package/dist/esm/mcp/tools/analysis.d.ts.map +1 -1
  36. package/dist/esm/mcp/tools/analysis.js +52 -21
  37. package/dist/esm/mcp/tools/analysis.js.map +1 -1
  38. package/dist/esm/mcp/tools/memory.d.ts +4 -4
  39. package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
  40. package/dist/esm/mcp/tools/memory.js +217 -11
  41. package/dist/esm/mcp/tools/memory.js.map +1 -1
  42. package/dist/esm/mcp/tools.d.ts.map +1 -1
  43. package/dist/esm/mcp/tools.js +4 -1
  44. package/dist/esm/mcp/tools.js.map +1 -1
  45. package/dist/esm/subconscious/TheBrainV2.d.ts +102 -1
  46. package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
  47. package/dist/esm/subconscious/TheBrainV2.js +253 -10
  48. package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
  49. package/lemma-proxy.cjs +12 -0
  50. package/package.json +11 -2
@@ -176,8 +176,15 @@ export interface ClaimFreshness {
176
176
  * gets for a purged entry, a renamed symbol's old claim, or an id from another project.
177
177
  */
178
178
  export interface VerifyMemoryResult {
179
+ /**
180
+ * 'fresh' means every tracked artifact still hashes the same. 'untracked' means the memory
181
+ * tracks nothing at all, so there was nothing to check — never folded into 'fresh', because
182
+ * a caller reading 'fresh' is being told the memory was validated against current code.
183
+ */
184
+ status: 'fresh' | 'stale' | 'unverified' | 'unknown' | 'untracked';
179
185
  id: string;
180
- status: 'fresh' | 'stale' | 'unverified' | 'unknown';
186
+ /** Files/symbols/upstream memories this id is judged against. 0 on 'untracked'. */
187
+ trackedArtifacts?: number;
181
188
  staleFiles?: string[];
182
189
  /** Only set when `id` resolved to an entry that itself has per-claim tracking. */
183
190
  claimBreakdown?: ClaimFreshness[];
@@ -287,6 +294,12 @@ export interface BrainStats {
287
294
  staleEntries?: number;
288
295
  /** Only under { deep: true }: staleEntries as a fraction of entries that track anything. */
289
296
  staleRatio?: number;
297
+ /**
298
+ * Entries tracking no file, symbol, claim evidence or upstream memory at all — the ones
299
+ * `verify_memory` reports as `untracked` because there is nothing there to check. Cheap
300
+ * (no hashing), so it is always computed, unlike staleEntries.
301
+ */
302
+ untrackedEntries?: number;
290
303
  }
291
304
  /**
292
305
  * Union two views of the corpus. Never subtracts: an id present in either side survives
@@ -419,6 +432,18 @@ export interface FreshnessOutcome {
419
432
  * `fresh`.
420
433
  */
421
434
  export declare function checkEntryFreshness(entry: BrainEntry, resolver: EvidenceResolver, resolveNode?: (id: string) => FreshnessNode | undefined, depth?: number, visited?: Set<string>, semanticDiff?: boolean): FreshnessOutcome;
435
+ /**
436
+ * How many artifacts an entry's freshness is actually judged against: tracked files, tracked
437
+ * symbols, upstream memories, and each claim's own evidence.
438
+ *
439
+ * Zero means a freshness check has nothing to compare — and reporting that as `fresh` conflates
440
+ * "validated against the code" with "there was nothing to validate", which are opposite
441
+ * guarantees for a caller about to act on the memory. `verify_memory` reports those as
442
+ * `untracked` instead; see VerifyMemoryResult.
443
+ */
444
+ export declare function trackedArtifactCount(entry: BrainEntry): number;
445
+ /** Claim-level counterpart to trackedArtifactCount. */
446
+ export declare function trackedClaimArtifactCount(claim: Claim): number;
422
447
  /**
423
448
  * Same hash-compare as checkEntryFreshness, scoped to one claim's own evidence — a claim
424
449
  * with no fileHashes/symbolHashes at all is always fresh (nothing tracked to go stale).
@@ -439,9 +464,20 @@ export declare class TheBrainV2 {
439
464
  private diskStamp;
440
465
  /** id -> ISO deletion time, for ids that must not come back through a merge. */
441
466
  private tombstones;
467
+ /**
468
+ * id -> terms of that entry's own `query` field. Derived state, never persisted: `terms`
469
+ * covers query+response together, so scoring the query field on its own (see the
470
+ * QUERY_FIELD_BOOST block in search()) needs it split back out. Memoized because a search
471
+ * touches every candidate and re-tokenizing a prompt per candidate per search is pure waste.
472
+ * Dropped whenever the entry changes or leaves the corpus — a stale entry here would boost
473
+ * a memory for words its prompt no longer contains.
474
+ */
475
+ private queryTermCache;
442
476
  constructor();
443
477
  private ensureDir;
444
478
  private load;
479
+ /** Terms of an entry's own `query`, memoized. See queryTermCache. */
480
+ private queryTermsOf;
445
481
  /** Recomputes the inverted index from scratch over the current entries. */
446
482
  private rebuildIndex;
447
483
  /**
@@ -551,6 +587,28 @@ export declare class TheBrainV2 {
551
587
  * without deleting the entry — a bad-fit-today memory may still be exactly right for a
552
588
  * differently-phrased query tomorrow.
553
589
  */
590
+ /**
591
+ * One memory, by id, body included.
592
+ *
593
+ * The Brain had no deterministic read: `verifyByIds` answers "is it still true" without
594
+ * returning the text, and `search()` — the only path to the body — is a ranking, so an agent
595
+ * holding an id could still fail to retrieve the memory it had just written. Editing a
596
+ * long-lived entry under those conditions means reconstructing its text from whatever a
597
+ * search happened to surface, which is how the accumulated content in it gets lost.
598
+ *
599
+ * Returns a copy: callers must not mutate the corpus by holding a reference. Use update()
600
+ * to change a memory.
601
+ */
602
+ getEntry(id: string): BrainEntry | undefined;
603
+ /**
604
+ * The entry a claim id belongs to, plus the claim itself. Claim ids and entry ids are handed
605
+ * back side by side by search_memory and verify_memory, so an id pasted into a read is as
606
+ * likely to be one as the other — resolving only entries would report a live claim as missing.
607
+ */
608
+ getClaim(id: string): {
609
+ entry: BrainEntry;
610
+ claim: Claim;
611
+ } | undefined;
554
612
  downvote(id: string): {
555
613
  ok: boolean;
556
614
  message: string;
@@ -575,9 +633,11 @@ export declare class TheBrainV2 {
575
633
  forgotten?: {
576
634
  id: string;
577
635
  query: string;
636
+ response: string;
578
637
  timestamp: string;
579
638
  hits: number;
580
639
  };
640
+ archivePath?: string;
581
641
  };
582
642
  /**
583
643
  * Re-verify a memory against the code as it stands now, keeping its identity.
@@ -598,6 +658,13 @@ export declare class TheBrainV2 {
598
658
  * a memory that is itself stale is exactly what Fase B exists to catch, and silently
599
659
  * clearing that would defeat it. Those come back in `stillStale` instead.
600
660
  */
661
+ /**
662
+ * Re-hash an entry's evidence, either in place or against newly named files/symbols.
663
+ * Shared by refresh() ("I checked, this is still true") and update() ("here is the corrected
664
+ * text"), which make the same assertion about the same code and so must anchor identically.
665
+ * Mutates `entry`; returns the labels of what it now tracks.
666
+ */
667
+ private reanchorEvidence;
601
668
  refresh(id: string, opts?: {
602
669
  filePaths?: string[];
603
670
  symbols?: SymbolRef[];
@@ -608,6 +675,40 @@ export declare class TheBrainV2 {
608
675
  retracked?: string[];
609
676
  stillStale?: string[];
610
677
  };
678
+ /**
679
+ * Replace an existing memory's content, keeping its identity.
680
+ *
681
+ * The Brain could add and it could delete, but it could not correct: store() mints a new id
682
+ * per call, so re-storing a corrected version under the same query left the outdated one in
683
+ * place, and a later search returned an arbitrary slice of every historical version —
684
+ * including the ones that contradict each other. That is the mechanism behind an
685
+ * append-only pile of near-duplicate "canonical index" entries: not a convention nobody
686
+ * followed, a convention the API could not express. refresh() keeps identity but only
687
+ * re-hashes evidence, and has no way to accept new text. This is that missing operation.
688
+ *
689
+ * Kept: id, hits, demerits, creation timestamp, projectId, source, and every `derivedFrom`
690
+ * edge elsewhere in the corpus that points at this id. Replaced: whatever the patch names.
691
+ * Evidence is re-anchored exactly as refresh() does — rewriting a memory's content asserts
692
+ * the same thing refresh() records, that the caller checked it against the code as it is now.
693
+ */
694
+ update(id: string, patch?: {
695
+ query?: string;
696
+ response?: string;
697
+ filePaths?: string[];
698
+ symbols?: SymbolRef[];
699
+ claims?: ClaimInput[];
700
+ outcome?: 'confirmed' | 'failed';
701
+ domain?: string;
702
+ derivedFrom?: string[];
703
+ }): {
704
+ ok: boolean;
705
+ message: string;
706
+ id?: string;
707
+ fresh?: boolean;
708
+ retracked?: string[];
709
+ stillStale?: string[];
710
+ charDelta?: number;
711
+ };
611
712
  /**
612
713
  * Revalidate ids from a prior search_memory/store_memory result via hash-compare only —
613
714
  * no BM25, no `search()`. `ids` may mix entry ids and claim ids freely; each resolves
@@ -1 +1 @@
1
- {"version":3,"file":"TheBrainV2.d.ts","sourceRoot":"","sources":["../../../src/subconscious/TheBrainV2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TheBrainV2.d.ts","sourceRoot":"","sources":["../../../src/subconscious/TheBrainV2.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,15 @@ const defaultLocalResolver = new LocalFsResolver();
26
26
  // ─── BM25 Constants ───────────────────────────────────────────────────────────
27
27
  const BM25_K1 = 1.5; // Term saturation (1.2-2.0)
28
28
  const BM25_B = 0.75; // Length normalization (0-1)
29
+ /**
30
+ * Ceiling on the document-length term in BM25's normalization, in multiples of the average
31
+ * document. Uncapped, the divisor grows with the document forever, so a memory is buried for
32
+ * being long rather than for being a worse match — which is precisely what happened to the
33
+ * one entry a "living document" convention keeps rewriting and growing: it ranked below the
34
+ * 2 KB fragments it was written to supersede, under its own query. Past 3x average, extra
35
+ * length says nothing more about relevance, so the penalty stops there.
36
+ */
37
+ const MAX_LENGTH_NORM_RATIO = 3;
29
38
  // ─── Recency decay ────────────────────────────────────────────────────────────
30
39
  //
31
40
  // Deliberately gentle and grace-periodded. Age is a weak proxy for "no longer true" —
@@ -39,6 +48,18 @@ const RECENCY_GRACE_DAYS = 30;
39
48
  const RECENCY_FULL_DECAY_DAYS = 365;
40
49
  /** Cap, in the same 0-1 similarity space as the popularity/outcome/demerit adjustments. */
41
50
  const MAX_RECENCY_PENALTY = 0.10;
51
+ // ─── Retrieval blend ──────────────────────────────────────────────────────────
52
+ //
53
+ // Three signals, weights summing to 1 so the blend stays a 0-1 similarity the caller can hold
54
+ // against a floor. The third is new: an entry's `terms` cover query and response together, so
55
+ // "these words are the memory's own prompt" scored exactly like "these words appear somewhere
56
+ // in a long body", and a document that keeps growing dilutes its own prompt out of contention.
57
+ // That is a retrieval signal, not a tie-break like the small additive adjustments in search(),
58
+ // so it takes its share of the blend rather than being added on top of it.
59
+ const BM25_WEIGHT = 0.55;
60
+ const JACCARD_WEIGHT = 0.20;
61
+ /** Share of the blend decided by how much of the search query the entry's own query covers. */
62
+ const QUERY_FIELD_WEIGHT = 0.25;
42
63
  // ─── Storage Paths ────────────────────────────────────────────────────────────
43
64
  /**
44
65
  * LEMMA_BRAIN_DIR redirects storage — required so tests never write into the user's real
@@ -53,6 +74,14 @@ const META_FILE = path.join(BRAIN_DIR, 'meta.json');
53
74
  const LOCK_FILE = path.join(BRAIN_DIR, '.write.lock');
54
75
  /** Sidecar vector cache for the optional semantic re-rank. See BrainEmbeddings.ts. */
55
76
  const EMBEDDINGS_FILE = path.join(BRAIN_DIR, 'embeddings.ndjson');
77
+ /**
78
+ * Append-only archive of everything forget() destroyed. Deletion is the one Brain operation
79
+ * with no undo, and the deleted body is by definition the only copy of that text — telling the
80
+ * caller "nothing else can recover it" and then handing back metadata only is the worst of both
81
+ * worlds. The id stays tombstoned (a deliberate deletion must not come back through a merge),
82
+ * so this file is an archive to read, not a bundle to re-import.
83
+ */
84
+ const FORGOTTEN_FILE = path.join(BRAIN_DIR, 'forgotten.ndjson');
56
85
  // ─── Cross-process durability ─────────────────────────────────────────────────
57
86
  //
58
87
  // Every MCP client session starts its own server process, and each one holds the whole
@@ -526,13 +555,16 @@ export class BloomFilter {
526
555
  // ─── BM25 Scorer ─────────────────────────────────────────────────────────────
527
556
  export function bm25Score(queryTerms, docTermFreq, docLength, avgDocLength, idf) {
528
557
  let score = 0;
558
+ // Bounded: see MAX_LENGTH_NORM_RATIO. A document 20x the average was effectively
559
+ // unretrievable next to a short one sharing the same rare term.
560
+ const lengthRatio = Math.min(docLength / avgDocLength, MAX_LENGTH_NORM_RATIO);
529
561
  for (const term of queryTerms) {
530
562
  if (!(term in docTermFreq))
531
563
  continue;
532
564
  const tf = docTermFreq[term];
533
565
  const termIdf = idf[term] || 0;
534
566
  const numerator = tf * (BM25_K1 + 1);
535
- const denominator = tf + BM25_K1 * (1 - BM25_B + BM25_B * (docLength / avgDocLength));
567
+ const denominator = tf + BM25_K1 * (1 - BM25_B + BM25_B * lengthRatio);
536
568
  score += termIdf * (numerator / denominator);
537
569
  }
538
570
  return score;
@@ -833,6 +865,28 @@ export function checkEntryFreshness(entry, resolver, resolveNode, depth = 0, vis
833
865
  ...(cosmeticChanges.length > 0 ? { cosmeticChanges } : {}),
834
866
  };
835
867
  }
868
+ /**
869
+ * How many artifacts an entry's freshness is actually judged against: tracked files, tracked
870
+ * symbols, upstream memories, and each claim's own evidence.
871
+ *
872
+ * Zero means a freshness check has nothing to compare — and reporting that as `fresh` conflates
873
+ * "validated against the code" with "there was nothing to validate", which are opposite
874
+ * guarantees for a caller about to act on the memory. `verify_memory` reports those as
875
+ * `untracked` instead; see VerifyMemoryResult.
876
+ */
877
+ export function trackedArtifactCount(entry) {
878
+ let n = Object.keys(entry.fileHashes || {}).length;
879
+ n += Object.keys(entry.symbolHashes || {}).length;
880
+ n += (entry.derivedFrom || []).length;
881
+ for (const claim of entry.claims || []) {
882
+ n += Object.keys(claim.fileHashes || {}).length + Object.keys(claim.symbolHashes || {}).length;
883
+ }
884
+ return n;
885
+ }
886
+ /** Claim-level counterpart to trackedArtifactCount. */
887
+ export function trackedClaimArtifactCount(claim) {
888
+ return Object.keys(claim.fileHashes || {}).length + Object.keys(claim.symbolHashes || {}).length;
889
+ }
836
890
  /** Builds the persisted `Claim[]` for an entry from the caller-supplied claim inputs. */
837
891
  function buildClaims(inputs) {
838
892
  return inputs
@@ -921,6 +975,15 @@ export class TheBrainV2 {
921
975
  this.diskStamp = null;
922
976
  /** id -> ISO deletion time, for ids that must not come back through a merge. */
923
977
  this.tombstones = new Map();
978
+ /**
979
+ * id -> terms of that entry's own `query` field. Derived state, never persisted: `terms`
980
+ * covers query+response together, so scoring the query field on its own (see the
981
+ * QUERY_FIELD_BOOST block in search()) needs it split back out. Memoized because a search
982
+ * touches every candidate and re-tokenizing a prompt per candidate per search is pure waste.
983
+ * Dropped whenever the entry changes or leaves the corpus — a stale entry here would boost
984
+ * a memory for words its prompt no longer contains.
985
+ */
986
+ this.queryTermCache = new Map();
924
987
  this.sidecar = null;
925
988
  this.ensureDir();
926
989
  this.load();
@@ -959,9 +1022,21 @@ export class TheBrainV2 {
959
1022
  this.tombstones = new Map();
960
1023
  }
961
1024
  }
1025
+ /** Terms of an entry's own `query`, memoized. See queryTermCache. */
1026
+ queryTermsOf(entry) {
1027
+ let set = this.queryTermCache.get(entry.id);
1028
+ if (!set) {
1029
+ set = new Set(tokenize(entry.query));
1030
+ this.queryTermCache.set(entry.id, set);
1031
+ }
1032
+ return set;
1033
+ }
962
1034
  /** Recomputes the inverted index from scratch over the current entries. */
963
1035
  rebuildIndex() {
964
1036
  this.invertedIndex = new Map();
1037
+ // A merge can replace an id's entry with a peer's newer version whose query differs, so
1038
+ // the memo is rebuilt alongside the index rather than trusted across one.
1039
+ this.queryTermCache.clear();
965
1040
  for (const entry of this.entries.values()) {
966
1041
  for (const term of entry.terms) {
967
1042
  let ids = this.invertedIndex.get(term);
@@ -1110,6 +1185,7 @@ export class TheBrainV2 {
1110
1185
  /** Removes an entry from the in-memory corpus and the inverted index. No persistence. */
1111
1186
  dropEntry(entry) {
1112
1187
  this.entries.delete(entry.id);
1188
+ this.queryTermCache.delete(entry.id);
1113
1189
  for (const term of entry.terms) {
1114
1190
  const ids = this.invertedIndex.get(term);
1115
1191
  if (!ids)
@@ -1331,8 +1407,24 @@ export class TheBrainV2 {
1331
1407
  // see on their own: a memory's own track record. Small and additive by design — none of
1332
1408
  // these can turn an unrelated result into a top hit, they only reorder among already-
1333
1409
  // relevant candidates.
1410
+ const normalizedQuery = query.trim().toLowerCase();
1334
1411
  const combined = scored.map(s => {
1335
- let similarity = (s.bm25 / maxBm25) * 0.7 + s.jaccard * 0.3;
1412
+ // How much of the search query appears in the entry's own prompt — see the weights above.
1413
+ const entryQueryTerms = this.queryTermsOf(s.entry);
1414
+ let covered = 0;
1415
+ for (const term of queryTermSet)
1416
+ if (entryQueryTerms.has(term))
1417
+ covered++;
1418
+ const queryFieldMatch = covered / queryTermSet.size;
1419
+ // A prompt that matches character for character is not one signal among three — it is
1420
+ // the entry filed under exactly this question. Blended, it could still lose to a short
1421
+ // fragment that repeated one rare term, which is how a memory became unfindable under
1422
+ // its own query. The adjustments below still apply on top: a downvoted or dead-end
1423
+ // exact match must not outrank a clean one.
1424
+ const exactPrompt = s.entry.query.trim().toLowerCase() === normalizedQuery;
1425
+ let similarity = exactPrompt
1426
+ ? 1
1427
+ : (s.bm25 / maxBm25) * BM25_WEIGHT + s.jaccard * JACCARD_WEIGHT + queryFieldMatch * QUERY_FIELD_WEIGHT;
1336
1428
  // Popularity prior: entries other searches actually reused are more likely to be
1337
1429
  // reused again. Log-scaled and capped at +0.08 so a handful of hits can't outrank a
1338
1430
  // much better textual match.
@@ -1519,6 +1611,38 @@ export class TheBrainV2 {
1519
1611
  * without deleting the entry — a bad-fit-today memory may still be exactly right for a
1520
1612
  * differently-phrased query tomorrow.
1521
1613
  */
1614
+ // ─── Read by id ─────────────────────────────────────────────────────────────
1615
+ /**
1616
+ * One memory, by id, body included.
1617
+ *
1618
+ * The Brain had no deterministic read: `verifyByIds` answers "is it still true" without
1619
+ * returning the text, and `search()` — the only path to the body — is a ranking, so an agent
1620
+ * holding an id could still fail to retrieve the memory it had just written. Editing a
1621
+ * long-lived entry under those conditions means reconstructing its text from whatever a
1622
+ * search happened to surface, which is how the accumulated content in it gets lost.
1623
+ *
1624
+ * Returns a copy: callers must not mutate the corpus by holding a reference. Use update()
1625
+ * to change a memory.
1626
+ */
1627
+ getEntry(id) {
1628
+ this.syncIfChanged();
1629
+ const entry = this.entries.get(id);
1630
+ return entry ? { ...entry } : undefined;
1631
+ }
1632
+ /**
1633
+ * The entry a claim id belongs to, plus the claim itself. Claim ids and entry ids are handed
1634
+ * back side by side by search_memory and verify_memory, so an id pasted into a read is as
1635
+ * likely to be one as the other — resolving only entries would report a live claim as missing.
1636
+ */
1637
+ getClaim(id) {
1638
+ this.syncIfChanged();
1639
+ for (const entry of this.entries.values()) {
1640
+ const claim = entry.claims?.find((c) => c.id === id);
1641
+ if (claim)
1642
+ return { entry: { ...entry }, claim };
1643
+ }
1644
+ return undefined;
1645
+ }
1522
1646
  downvote(id) {
1523
1647
  this.syncIfChanged();
1524
1648
  const entry = this.entries.get(id);
@@ -1548,6 +1672,19 @@ export class TheBrainV2 {
1548
1672
  const entry = this.entries.get(id);
1549
1673
  if (!entry)
1550
1674
  return { ok: false, message: `No entry with id "${id}" in the Brain.` };
1675
+ // Archived before it is dropped: the body is the only copy of that text anywhere, and
1676
+ // "nothing else can recover it" has to be a description of the archive, not of a gap.
1677
+ let archivePath;
1678
+ try {
1679
+ this.ensureDir();
1680
+ const { terms: _terms, ...persisted } = entry;
1681
+ fs.appendFileSync(FORGOTTEN_FILE, JSON.stringify({ ...persisted, forgottenAt: new Date().toISOString() }) + '\n', 'utf8');
1682
+ archivePath = FORGOTTEN_FILE;
1683
+ }
1684
+ catch {
1685
+ // An unwritable archive must not block a deletion the user asked for — the body still
1686
+ // comes back in the result below, which is the copy that matters in the moment.
1687
+ }
1551
1688
  this.dropEntry(entry);
1552
1689
  this.tombstone(id);
1553
1690
  this.recalcAvgDocLength();
@@ -1557,7 +1694,10 @@ export class TheBrainV2 {
1557
1694
  message: `Deleted memory "${id}". It will not come back from another session's copy.`,
1558
1695
  // Echoed back so a deletion is auditable: the caller (and the user reading the
1559
1696
  // transcript) can see exactly what was destroyed, since nothing else can recover it.
1560
- forgotten: { id, query: entry.query, timestamp: entry.timestamp, hits: entry.hits },
1697
+ // The response is included, not just its metadata — a record of a deletion that omits
1698
+ // the deleted content is not a record of anything.
1699
+ forgotten: { id, query: entry.query, response: entry.response, timestamp: entry.timestamp, hits: entry.hits },
1700
+ ...(archivePath ? { archivePath } : {}),
1561
1701
  };
1562
1702
  }
1563
1703
  // ─── Re-anchoring ───────────────────────────────────────────────────────────
@@ -1580,11 +1720,13 @@ export class TheBrainV2 {
1580
1720
  * a memory that is itself stale is exactly what Fase B exists to catch, and silently
1581
1721
  * clearing that would defeat it. Those come back in `stillStale` instead.
1582
1722
  */
1583
- refresh(id, opts = {}) {
1584
- this.syncIfChanged();
1585
- const entry = this.entries.get(id);
1586
- if (!entry)
1587
- return { ok: false, message: `No entry with id "${id}" in the Brain.` };
1723
+ /**
1724
+ * Re-hash an entry's evidence, either in place or against newly named files/symbols.
1725
+ * Shared by refresh() ("I checked, this is still true") and update() ("here is the corrected
1726
+ * text"), which make the same assertion about the same code and so must anchor identically.
1727
+ * Mutates `entry`; returns the labels of what it now tracks.
1728
+ */
1729
+ reanchorEvidence(entry, opts) {
1588
1730
  const retracked = [];
1589
1731
  const rel = (abs) => {
1590
1732
  const r = path.relative(process.cwd(), abs);
@@ -1637,6 +1779,14 @@ export class TheBrainV2 {
1637
1779
  }
1638
1780
  }
1639
1781
  }
1782
+ return retracked;
1783
+ }
1784
+ refresh(id, opts = {}) {
1785
+ this.syncIfChanged();
1786
+ const entry = this.entries.get(id);
1787
+ if (!entry)
1788
+ return { ok: false, message: `No entry with id "${id}" in the Brain.` };
1789
+ const retracked = this.reanchorEvidence(entry, opts);
1640
1790
  // Re-stamp git context and the age clock: this memory was just re-verified here, now.
1641
1791
  const git = currentGitContext();
1642
1792
  if (git.commit)
@@ -1658,6 +1808,89 @@ export class TheBrainV2 {
1658
1808
  `A "derived:" entry here means an upstream memory it was built on is stale — refresh that one first.`,
1659
1809
  };
1660
1810
  }
1811
+ // ─── In-place rewrite ───────────────────────────────────────────────────────
1812
+ /**
1813
+ * Replace an existing memory's content, keeping its identity.
1814
+ *
1815
+ * The Brain could add and it could delete, but it could not correct: store() mints a new id
1816
+ * per call, so re-storing a corrected version under the same query left the outdated one in
1817
+ * place, and a later search returned an arbitrary slice of every historical version —
1818
+ * including the ones that contradict each other. That is the mechanism behind an
1819
+ * append-only pile of near-duplicate "canonical index" entries: not a convention nobody
1820
+ * followed, a convention the API could not express. refresh() keeps identity but only
1821
+ * re-hashes evidence, and has no way to accept new text. This is that missing operation.
1822
+ *
1823
+ * Kept: id, hits, demerits, creation timestamp, projectId, source, and every `derivedFrom`
1824
+ * edge elsewhere in the corpus that points at this id. Replaced: whatever the patch names.
1825
+ * Evidence is re-anchored exactly as refresh() does — rewriting a memory's content asserts
1826
+ * the same thing refresh() records, that the caller checked it against the code as it is now.
1827
+ */
1828
+ update(id, patch = {}) {
1829
+ this.syncIfChanged();
1830
+ const entry = this.entries.get(id);
1831
+ if (!entry)
1832
+ return { ok: false, message: `No entry with id "${id}" in the Brain.` };
1833
+ const beforeChars = entry.charCount;
1834
+ // Out of the index before its terms change: a posting list built from the old text would
1835
+ // keep serving this entry under words the new text no longer contains.
1836
+ this.dropEntry(entry);
1837
+ if (typeof patch.query === 'string' && patch.query.trim())
1838
+ entry.query = patch.query.trim();
1839
+ if (typeof patch.response === 'string' && patch.response.trim())
1840
+ entry.response = patch.response.trim();
1841
+ if (patch.outcome)
1842
+ entry.outcome = patch.outcome;
1843
+ if (patch.domain !== undefined)
1844
+ entry.domain = patch.domain.trim() || undefined;
1845
+ if (patch.derivedFrom !== undefined) {
1846
+ entry.derivedFrom = patch.derivedFrom.length > 0 ? patch.derivedFrom : undefined;
1847
+ }
1848
+ if (patch.claims !== undefined) {
1849
+ entry.claims = patch.claims.length > 0 ? buildClaims(patch.claims) : undefined;
1850
+ }
1851
+ const terms = tokenize(entry.query + ' ' + entry.response);
1852
+ entry.terms = [...new Set(terms)];
1853
+ entry.termFreq = termFrequencies(terms);
1854
+ entry.charCount = entry.query.length + entry.response.length;
1855
+ // Claims supplied in this patch were just hashed by buildClaims; the helper re-anchors the
1856
+ // ones carried over, so either way the entry's evidence describes the code as it is now.
1857
+ const retracked = this.reanchorEvidence(entry, { filePaths: patch.filePaths, symbols: patch.symbols });
1858
+ const git = currentGitContext();
1859
+ if (git.commit)
1860
+ entry.gitCommit = git.commit;
1861
+ if (git.branch)
1862
+ entry.gitBranch = git.branch;
1863
+ // Same clock reset as refresh(): re-verified content really is current again. `timestamp`
1864
+ // is left alone so provenance is never rewritten.
1865
+ entry.refreshedAt = new Date().toISOString();
1866
+ this.entries.set(id, entry);
1867
+ for (const term of entry.terms) {
1868
+ let ids = this.invertedIndex.get(term);
1869
+ if (!ids) {
1870
+ ids = new Set();
1871
+ this.invertedIndex.set(term, ids);
1872
+ }
1873
+ ids.add(id);
1874
+ }
1875
+ this.bloom.add(entry.query.trim().toLowerCase().substring(0, 200));
1876
+ this.recalcAvgDocLength();
1877
+ this.scheduleSave();
1878
+ const claimIndex = buildClaimIndex(this.entries);
1879
+ const { fresh, staleFiles } = checkEntryFreshness(entry, defaultLocalResolver, (depId) => resolveFreshnessNode(this.entries, claimIndex, depId));
1880
+ const charDelta = entry.charCount - beforeChars;
1881
+ return {
1882
+ ok: true,
1883
+ id,
1884
+ fresh,
1885
+ retracked,
1886
+ charDelta,
1887
+ ...(staleFiles.length > 0 ? { stillStale: staleFiles } : {}),
1888
+ message: fresh
1889
+ ? `Memory "${id}" updated in place, keeping its id, ${entry.hits} hit(s) and every derivedFrom edge pointing at it.`
1890
+ : `Memory "${id}" updated in place, but still stale: ${staleFiles.join(', ')}. ` +
1891
+ `A "derived:" entry here means an upstream memory it was built on is stale — refresh that one first.`,
1892
+ };
1893
+ }
1661
1894
  // ─── Batch verification ─────────────────────────────────────────────────────
1662
1895
  /**
1663
1896
  * Revalidate ids from a prior search_memory/store_memory result via hash-compare only —
@@ -1681,9 +1914,13 @@ export class TheBrainV2 {
1681
1914
  if (entry) {
1682
1915
  const { fresh, staleFiles, unverifiedFiles, cosmeticChanges } = checkEntryFreshness(entry, resolver, resolveNode, 0, new Set(), semanticDiff);
1683
1916
  const unverified = unverifiedFiles.length > 0;
1917
+ // An entry that tracks nothing cannot be checked, and saying 'fresh' would answer a
1918
+ // question ("does this still match the code?") that was never asked of it.
1919
+ const tracked = trackedArtifactCount(entry);
1684
1920
  return {
1685
1921
  id,
1686
- status: unverified ? 'unverified' : fresh ? 'fresh' : 'stale',
1922
+ status: unverified ? 'unverified' : !fresh ? 'stale' : tracked === 0 ? 'untracked' : 'fresh',
1923
+ trackedArtifacts: tracked,
1687
1924
  ...(unverified || fresh ? {} : attributeStaleness(entry, git)),
1688
1925
  ...(staleFiles.length > 0 ? { staleFiles } : {}),
1689
1926
  ...(unverified ? { unverifiedFiles } : {}),
@@ -1695,9 +1932,11 @@ export class TheBrainV2 {
1695
1932
  if (claim) {
1696
1933
  const cf = checkClaimFreshness(claim, resolver, semanticDiff);
1697
1934
  const unverified = (cf.unverifiedFiles?.length ?? 0) > 0;
1935
+ const trackedClaim = trackedClaimArtifactCount(claim);
1698
1936
  return {
1699
1937
  id,
1700
- status: cf.fresh ? 'fresh' : unverified ? 'unverified' : 'stale',
1938
+ status: unverified ? 'unverified' : !cf.fresh ? 'stale' : trackedClaim === 0 ? 'untracked' : 'fresh',
1939
+ trackedArtifacts: trackedClaim,
1701
1940
  ...(cf.staleFiles ? { staleFiles: cf.staleFiles } : {}),
1702
1941
  ...(cf.unverifiedFiles ? { unverifiedFiles: cf.unverifiedFiles } : {}),
1703
1942
  ...(cf.cosmeticChanges ? { cosmeticChanges: cf.cosmeticChanges } : {}),
@@ -1879,6 +2118,7 @@ export class TheBrainV2 {
1879
2118
  let neverHit = 0;
1880
2119
  let downvoted = 0;
1881
2120
  let unscoped = 0;
2121
+ let untracked = 0;
1882
2122
  let oldest = '';
1883
2123
  const bySource = {};
1884
2124
  const projects = new Set();
@@ -1891,6 +2131,8 @@ export class TheBrainV2 {
1891
2131
  unscoped++;
1892
2132
  else
1893
2133
  projects.add(entry.projectId);
2134
+ if (trackedArtifactCount(entry) === 0)
2135
+ untracked++;
1894
2136
  const src = entrySource(entry);
1895
2137
  bySource[src] = (bySource[src] || 0) + 1;
1896
2138
  if (entry.timestamp && (!oldest || entry.timestamp < oldest))
@@ -1901,6 +2143,7 @@ export class TheBrainV2 {
1901
2143
  base.bySource = bySource;
1902
2144
  base.projects = projects.size;
1903
2145
  base.unscopedEntries = unscoped;
2146
+ base.untrackedEntries = untracked;
1904
2147
  base.tombstones = this.tombstones.size;
1905
2148
  if (oldest)
1906
2149
  base.oldestEntry = oldest;