@cleocode/core 2026.4.49 → 2026.4.51

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 (35) hide show
  1. package/dist/index.js +445 -9
  2. package/dist/index.js.map +4 -4
  3. package/dist/internal.d.ts +2 -0
  4. package/dist/internal.d.ts.map +1 -1
  5. package/dist/internal.js +448 -9
  6. package/dist/internal.js.map +4 -4
  7. package/dist/memory/brain-lifecycle.d.ts +7 -0
  8. package/dist/memory/brain-lifecycle.d.ts.map +1 -1
  9. package/dist/memory/brain-stdp.d.ts +122 -0
  10. package/dist/memory/brain-stdp.d.ts.map +1 -0
  11. package/dist/memory/decision-cross-link.d.ts +70 -0
  12. package/dist/memory/decision-cross-link.d.ts.map +1 -0
  13. package/dist/memory/decisions.d.ts.map +1 -1
  14. package/dist/memory/edge-types.d.ts +24 -0
  15. package/dist/memory/edge-types.d.ts.map +1 -0
  16. package/dist/memory/index.d.ts +1 -0
  17. package/dist/memory/index.d.ts.map +1 -1
  18. package/dist/store/brain-schema.d.ts +134 -3
  19. package/dist/store/brain-schema.d.ts.map +1 -1
  20. package/dist/store/brain-sqlite.d.ts.map +1 -1
  21. package/dist/store/validation-schemas.d.ts +1 -0
  22. package/dist/store/validation-schemas.d.ts.map +1 -1
  23. package/migrations/drizzle-brain/20260415000001_t626-normalize-co-retrieved-edge-type/migration.sql +14 -0
  24. package/package.json +8 -8
  25. package/src/internal.ts +7 -0
  26. package/src/memory/__tests__/brain-stdp.test.ts +452 -0
  27. package/src/memory/__tests__/decision-cross-link.test.ts +240 -0
  28. package/src/memory/brain-lifecycle.ts +23 -4
  29. package/src/memory/brain-stdp.ts +448 -0
  30. package/src/memory/decision-cross-link.ts +276 -0
  31. package/src/memory/decisions.ts +7 -0
  32. package/src/memory/edge-types.ts +31 -0
  33. package/src/memory/index.ts +2 -0
  34. package/src/store/brain-schema.ts +50 -0
  35. package/src/store/brain-sqlite.ts +17 -0
package/dist/internal.js CHANGED
@@ -9069,12 +9069,13 @@ __export(brain_schema_exports, {
9069
9069
  brainPageEdges: () => brainPageEdges,
9070
9070
  brainPageNodes: () => brainPageNodes,
9071
9071
  brainPatterns: () => brainPatterns,
9072
+ brainPlasticityEvents: () => brainPlasticityEvents,
9072
9073
  brainRetrievalLog: () => brainRetrievalLog,
9073
9074
  brainSchemaMeta: () => brainSchemaMeta,
9074
9075
  brainStickyNotes: () => brainStickyNotes
9075
9076
  });
9076
9077
  import { sql as sql2 } from "drizzle-orm";
9077
- var BRAIN_MEMORY_TIERS, BRAIN_COGNITIVE_TYPES, BRAIN_SOURCE_CONFIDENCE, BRAIN_DECISION_TYPES, BRAIN_CONFIDENCE_LEVELS, BRAIN_OUTCOME_TYPES, BRAIN_PATTERN_TYPES, BRAIN_IMPACT_LEVELS, BRAIN_LINK_TYPES, BRAIN_OBSERVATION_TYPES2, BRAIN_OBSERVATION_SOURCE_TYPES, BRAIN_MEMORY_TYPES, BRAIN_STICKY_STATUSES, BRAIN_STICKY_COLORS, BRAIN_STICKY_PRIORITIES, brainDecisions, brainPatterns, brainLearnings, brainObservations, brainStickyNotes, brainMemoryLinks, brainSchemaMeta, BRAIN_NODE_TYPES, BRAIN_EDGE_TYPES, brainPageNodes, brainPageEdges, brainRetrievalLog;
9078
+ var BRAIN_MEMORY_TIERS, BRAIN_COGNITIVE_TYPES, BRAIN_SOURCE_CONFIDENCE, BRAIN_DECISION_TYPES, BRAIN_CONFIDENCE_LEVELS, BRAIN_OUTCOME_TYPES, BRAIN_PATTERN_TYPES, BRAIN_IMPACT_LEVELS, BRAIN_LINK_TYPES, BRAIN_OBSERVATION_TYPES2, BRAIN_OBSERVATION_SOURCE_TYPES, BRAIN_MEMORY_TYPES, BRAIN_STICKY_STATUSES, BRAIN_STICKY_COLORS, BRAIN_STICKY_PRIORITIES, brainDecisions, brainPatterns, brainLearnings, brainObservations, brainStickyNotes, brainMemoryLinks, brainSchemaMeta, BRAIN_NODE_TYPES, BRAIN_EDGE_TYPES, brainPageNodes, brainPageEdges, brainRetrievalLog, brainPlasticityEvents;
9078
9079
  var init_brain_schema = __esm({
9079
9080
  "packages/core/src/store/brain-schema.ts"() {
9080
9081
  "use strict";
@@ -9503,8 +9504,11 @@ var init_brain_schema = __esm({
9503
9504
  // Graph bridging (memory ↔ code)
9504
9505
  "references",
9505
9506
  // observation → references → symbol
9506
- "modified_by"
9507
+ "modified_by",
9507
9508
  // file → modified_by → session
9509
+ // Plasticity (Hebbian + STDP co-retrieval)
9510
+ "co_retrieved"
9511
+ // A → co_retrieved → B (Hebbian: frequently retrieved together)
9508
9512
  ];
9509
9513
  brainPageNodes = sqliteTable(
9510
9514
  "brain_page_nodes",
@@ -9601,6 +9605,37 @@ var init_brain_schema = __esm({
9601
9605
  index("idx_retrieval_log_source").on(table.source)
9602
9606
  ]
9603
9607
  );
9608
+ brainPlasticityEvents = sqliteTable(
9609
+ "brain_plasticity_events",
9610
+ {
9611
+ id: integer("id").primaryKey({ autoIncrement: true }),
9612
+ /** from_id of the affected brain_page_edges row. */
9613
+ sourceNode: text("source_node").notNull(),
9614
+ /** to_id of the affected brain_page_edges row. */
9615
+ targetNode: text("target_node").notNull(),
9616
+ /**
9617
+ * Signed weight delta applied to the edge.
9618
+ * Positive = potentiation (LTP), negative = depression (LTD).
9619
+ */
9620
+ deltaW: real("delta_w").notNull(),
9621
+ /**
9622
+ * STDP event kind: `ltp` (Long-Term Potentiation) or `ltd` (Long-Term
9623
+ * Depression).
9624
+ */
9625
+ kind: text("kind", { enum: ["ltp", "ltd"] }).notNull(),
9626
+ /** ISO 8601 timestamp when this event was applied. */
9627
+ timestamp: text("timestamp").notNull().default(sql2`(datetime('now'))`),
9628
+ /** Session ID that triggered the STDP pass, if available. */
9629
+ sessionId: text("session_id")
9630
+ },
9631
+ (table) => [
9632
+ index("idx_plasticity_source").on(table.sourceNode),
9633
+ index("idx_plasticity_target").on(table.targetNode),
9634
+ index("idx_plasticity_timestamp").on(table.timestamp),
9635
+ index("idx_plasticity_session").on(table.sessionId),
9636
+ index("idx_plasticity_kind").on(table.kind)
9637
+ ]
9638
+ );
9604
9639
  }
9605
9640
  });
9606
9641
 
@@ -15012,6 +15047,14 @@ function runBrainMigrations(nativeDb, db) {
15012
15047
  );
15013
15048
  }
15014
15049
  ensureColumns(nativeDb, "brain_observations", [{ name: "agent", ddl: "text" }], "brain");
15050
+ if (tableExists(nativeDb, "brain_page_edges")) {
15051
+ nativeDb.prepare(
15052
+ `UPDATE brain_page_edges
15053
+ SET edge_type = 'co_retrieved'
15054
+ WHERE edge_type = 'relates_to'
15055
+ AND provenance LIKE 'consolidation:%'`
15056
+ ).run();
15057
+ }
15015
15058
  }
15016
15059
  function loadBrainVecExtension(nativeDb) {
15017
15060
  try {
@@ -21692,6 +21735,160 @@ var init_anthropic_key_resolver = __esm({
21692
21735
  }
21693
21736
  });
21694
21737
 
21738
+ // packages/core/src/memory/decision-cross-link.ts
21739
+ function extractReferencedSymbols(text3) {
21740
+ const seen = /* @__PURE__ */ new Set();
21741
+ const refs = [];
21742
+ for (const match of text3.matchAll(FILE_PATH_RE)) {
21743
+ const raw = match[1];
21744
+ if (!raw) continue;
21745
+ const nodeId = `file:${raw}`;
21746
+ if (seen.has(nodeId)) continue;
21747
+ seen.add(nodeId);
21748
+ refs.push({ raw, nodeId, nodeType: "file", label: raw });
21749
+ }
21750
+ for (const match of text3.matchAll(SYMBOL_RE)) {
21751
+ const raw = match[0];
21752
+ if (!raw || raw.length < 4) continue;
21753
+ if (SYMBOL_STOP_WORDS.has(raw.toLowerCase())) continue;
21754
+ const nodeId = `symbol:${raw}`;
21755
+ if (seen.has(nodeId)) continue;
21756
+ seen.add(nodeId);
21757
+ refs.push({ raw, nodeId, nodeType: "symbol", label: raw });
21758
+ }
21759
+ return refs;
21760
+ }
21761
+ async function linkDecisionToTargets(projectRoot, decisionId, refs) {
21762
+ const fromId = `decision:${decisionId}`;
21763
+ const writes = refs.map(async (ref) => {
21764
+ await upsertGraphNode(
21765
+ projectRoot,
21766
+ ref.nodeId,
21767
+ ref.nodeType,
21768
+ ref.label,
21769
+ 0.5,
21770
+ // placeholder quality until nexus indexes it
21771
+ ref.raw
21772
+ );
21773
+ await addGraphEdge(
21774
+ projectRoot,
21775
+ fromId,
21776
+ ref.nodeId,
21777
+ "applies_to",
21778
+ 1,
21779
+ "auto:decision-cross-link"
21780
+ );
21781
+ });
21782
+ await Promise.allSettled(writes);
21783
+ }
21784
+ async function autoCrossLinkDecision(projectRoot, decisionId, decisionText, rationale) {
21785
+ try {
21786
+ const combined = `${decisionText} ${rationale}`;
21787
+ const refs = extractReferencedSymbols(combined);
21788
+ if (refs.length === 0) return;
21789
+ await linkDecisionToTargets(projectRoot, decisionId, refs);
21790
+ } catch {
21791
+ }
21792
+ }
21793
+ var FILE_PATH_RE, SYMBOL_RE, SYMBOL_STOP_WORDS;
21794
+ var init_decision_cross_link = __esm({
21795
+ "packages/core/src/memory/decision-cross-link.ts"() {
21796
+ "use strict";
21797
+ init_graph_auto_populate();
21798
+ FILE_PATH_RE = /(?:^|[\s`"'([\]{,])((\/[\w.\-/]+|[\w.-]+(?:\/[\w.-]+)+)\.(ts|tsx|js|jsx|rs|json))(?=$|[\s`"')[\]{,])/gm;
21799
+ SYMBOL_RE = /(?<![`"'/\w.])(?:[A-Z][a-zA-Z0-9]{2,}|[a-z][a-zA-Z0-9]*(?:[A-Z][a-zA-Z0-9]*)+|[a-z][a-z0-9]*(?:_[a-z][a-z0-9]*){2,})(?![`"'/\w])/g;
21800
+ SYMBOL_STOP_WORDS = /* @__PURE__ */ new Set([
21801
+ "this",
21802
+ "that",
21803
+ "with",
21804
+ "from",
21805
+ "into",
21806
+ "when",
21807
+ "then",
21808
+ "also",
21809
+ "both",
21810
+ "each",
21811
+ "such",
21812
+ "over",
21813
+ "after",
21814
+ "before",
21815
+ "always",
21816
+ "never",
21817
+ "should",
21818
+ "must",
21819
+ "will",
21820
+ "would",
21821
+ "could",
21822
+ "have",
21823
+ "been",
21824
+ "there",
21825
+ "their",
21826
+ "they",
21827
+ "them",
21828
+ "these",
21829
+ "those",
21830
+ "some",
21831
+ "only",
21832
+ "just",
21833
+ "more",
21834
+ "most",
21835
+ "many",
21836
+ "much",
21837
+ "well",
21838
+ "very",
21839
+ "here",
21840
+ "where",
21841
+ "which",
21842
+ "what",
21843
+ "why",
21844
+ "how",
21845
+ "the",
21846
+ "and",
21847
+ "but",
21848
+ "for",
21849
+ "not",
21850
+ "are",
21851
+ "was",
21852
+ "were",
21853
+ "has",
21854
+ "had",
21855
+ "its",
21856
+ "the",
21857
+ "data",
21858
+ "true",
21859
+ "false",
21860
+ "null",
21861
+ "none",
21862
+ "type",
21863
+ "test",
21864
+ "spec",
21865
+ "todo",
21866
+ "fixme",
21867
+ "note",
21868
+ "example",
21869
+ "index",
21870
+ "config",
21871
+ "error",
21872
+ "value",
21873
+ "input",
21874
+ "output",
21875
+ "result",
21876
+ "return",
21877
+ "default",
21878
+ "source",
21879
+ "target",
21880
+ "import",
21881
+ "export",
21882
+ "class",
21883
+ "interface",
21884
+ "function",
21885
+ "const",
21886
+ "async",
21887
+ "await"
21888
+ ]);
21889
+ }
21890
+ });
21891
+
21695
21892
  // packages/core/src/memory/decisions.ts
21696
21893
  var decisions_exports = {};
21697
21894
  __export(decisions_exports, {
@@ -21830,6 +22027,8 @@ async function storeDecision(projectRoot, params) {
21830
22027
  "auto:store-decision"
21831
22028
  );
21832
22029
  }
22030
+ autoCrossLinkDecision(projectRoot, saved.id, saved.decision, saved.rationale).catch(() => {
22031
+ });
21833
22032
  } catch {
21834
22033
  }
21835
22034
  detectSupersession(projectRoot, {
@@ -21898,6 +22097,7 @@ var init_decisions2 = __esm({
21898
22097
  init_brain_accessor();
21899
22098
  init_cross_db_cleanup();
21900
22099
  init_sqlite2();
22100
+ init_decision_cross_link();
21901
22101
  init_graph_auto_populate();
21902
22102
  init_quality_scoring();
21903
22103
  init_temporal_supersession();
@@ -42968,6 +43168,30 @@ var init_auto_extract = __esm({
42968
43168
  }
42969
43169
  });
42970
43170
 
43171
+ // packages/core/src/memory/edge-types.ts
43172
+ var EDGE_TYPES;
43173
+ var init_edge_types = __esm({
43174
+ "packages/core/src/memory/edge-types.ts"() {
43175
+ "use strict";
43176
+ EDGE_TYPES = {
43177
+ // Plasticity (Hebbian / STDP co-retrieval)
43178
+ CO_RETRIEVED: "co_retrieved",
43179
+ // Temporal supersession
43180
+ SUPERSEDES: "supersedes",
43181
+ // Task / decision / pattern → target context
43182
+ APPLIES_TO: "applies_to",
43183
+ // Provenance
43184
+ DERIVED_FROM: "derived_from",
43185
+ // Observation → symbol/file impact
43186
+ AFFECTS: "affects",
43187
+ // Observation → symbol name mention
43188
+ MENTIONS: "mentions",
43189
+ // Observation → symbol/file structural link
43190
+ DOCUMENTS: "documents"
43191
+ };
43192
+ }
43193
+ });
43194
+
42971
43195
  // packages/core/src/memory/brain-consolidator.ts
42972
43196
  var brain_consolidator_exports = {};
42973
43197
  __export(brain_consolidator_exports, {
@@ -43201,7 +43425,7 @@ function extractSymbolCandidates(text3) {
43201
43425
  const syms = /* @__PURE__ */ new Set();
43202
43426
  for (const m2 of text3.matchAll(SYMBOL_PATTERN)) {
43203
43427
  const s3 = m2[1];
43204
- if (s3 && s3.length >= 4 && !SYMBOL_STOP_WORDS.has(s3.toLowerCase())) {
43428
+ if (s3 && s3.length >= 4 && !SYMBOL_STOP_WORDS2.has(s3.toLowerCase())) {
43205
43429
  syms.add(s3);
43206
43430
  }
43207
43431
  }
@@ -43510,7 +43734,7 @@ async function listCodeLinks(projectRoot, limit = 100) {
43510
43734
  }
43511
43735
  return entries;
43512
43736
  }
43513
- var FILE_PATH_PATTERN, SYMBOL_PATTERN, SYMBOL_STOP_WORDS;
43737
+ var FILE_PATH_PATTERN, SYMBOL_PATTERN, SYMBOL_STOP_WORDS2;
43514
43738
  var init_graph_memory_bridge = __esm({
43515
43739
  "packages/core/src/memory/graph-memory-bridge.ts"() {
43516
43740
  "use strict";
@@ -43520,7 +43744,7 @@ var init_graph_memory_bridge = __esm({
43520
43744
  init_typed_query();
43521
43745
  FILE_PATH_PATTERN = /(?:^|\s|['"`(])([a-zA-Z0-9_\-./]+\.(?:ts|tsx|js|jsx|rs|go|py|mjs|cjs))(?:$|\s|['"`)])/g;
43522
43746
  SYMBOL_PATTERN = /\b([a-zA-Z_][a-zA-Z0-9_]*(?:[A-Z][a-zA-Z0-9_]*)+|[a-zA-Z_]{4,}[a-zA-Z0-9_]*)\b/g;
43523
- SYMBOL_STOP_WORDS = /* @__PURE__ */ new Set([
43747
+ SYMBOL_STOP_WORDS2 = /* @__PURE__ */ new Set([
43524
43748
  "true",
43525
43749
  "false",
43526
43750
  "null",
@@ -43564,6 +43788,207 @@ var init_graph_memory_bridge = __esm({
43564
43788
  }
43565
43789
  });
43566
43790
 
43791
+ // packages/core/src/memory/brain-stdp.ts
43792
+ var brain_stdp_exports = {};
43793
+ __export(brain_stdp_exports, {
43794
+ applyStdpPlasticity: () => applyStdpPlasticity,
43795
+ getPlasticityStats: () => getPlasticityStats
43796
+ });
43797
+ async function applyStdpPlasticity(projectRoot, sessionWindowMs = 5 * 60 * 1e3) {
43798
+ const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
43799
+ await getBrainDb2(projectRoot);
43800
+ const nativeDb = getBrainNativeDb2();
43801
+ const result = {
43802
+ ltpEvents: 0,
43803
+ ltdEvents: 0,
43804
+ edgesCreated: 0,
43805
+ pairsExamined: 0
43806
+ };
43807
+ if (!nativeDb) return result;
43808
+ try {
43809
+ nativeDb.prepare("SELECT 1 FROM brain_retrieval_log LIMIT 1").get();
43810
+ } catch {
43811
+ return result;
43812
+ }
43813
+ try {
43814
+ nativeDb.prepare("SELECT 1 FROM brain_plasticity_events LIMIT 1").get();
43815
+ } catch {
43816
+ return result;
43817
+ }
43818
+ const now2 = Date.now();
43819
+ const cutoffMs = now2 - sessionWindowMs;
43820
+ const cutoffIso = new Date(cutoffMs).toISOString().replace("T", " ").slice(0, 19);
43821
+ const nowIso = new Date(now2).toISOString().replace("T", " ").slice(0, 19);
43822
+ let logRows = [];
43823
+ try {
43824
+ logRows = typedAll(
43825
+ nativeDb.prepare(
43826
+ `SELECT id, entry_ids, created_at, retrieval_order, delta_ms
43827
+ FROM brain_retrieval_log
43828
+ WHERE created_at >= ?
43829
+ ORDER BY created_at ASC, id ASC
43830
+ LIMIT 2000`
43831
+ ),
43832
+ cutoffIso
43833
+ );
43834
+ } catch {
43835
+ return result;
43836
+ }
43837
+ if (logRows.length === 0) return result;
43838
+ const spikes = [];
43839
+ let globalOrder = 0;
43840
+ for (const row of logRows) {
43841
+ let ids;
43842
+ try {
43843
+ ids = JSON.parse(row.entry_ids);
43844
+ } catch {
43845
+ continue;
43846
+ }
43847
+ const rowTime = (/* @__PURE__ */ new Date(row.created_at.replace(" ", "T") + "Z")).getTime();
43848
+ for (const rawId of ids) {
43849
+ const entryId = rawId.includes(":") ? rawId : `observation:${rawId}`;
43850
+ spikes.push({
43851
+ entryId,
43852
+ rowId: row.id,
43853
+ retrievedAt: rowTime,
43854
+ order: row.retrieval_order ?? globalOrder
43855
+ });
43856
+ globalOrder++;
43857
+ }
43858
+ }
43859
+ spikes.sort((a, b2) => a.retrievedAt - b2.retrievedAt || a.order - b2.order);
43860
+ const prepareGetEdge = nativeDb.prepare(
43861
+ `SELECT weight FROM brain_page_edges
43862
+ WHERE from_id = ? AND to_id = ? AND edge_type = 'co_retrieved'`
43863
+ );
43864
+ const prepareUpdateEdge = nativeDb.prepare(
43865
+ `UPDATE brain_page_edges
43866
+ SET weight = MAX(?, MIN(?, weight + ?))
43867
+ WHERE from_id = ? AND to_id = ? AND edge_type = 'co_retrieved'`
43868
+ );
43869
+ const prepareInsertEdge = nativeDb.prepare(
43870
+ `INSERT OR IGNORE INTO brain_page_edges
43871
+ (from_id, to_id, edge_type, weight, provenance, created_at)
43872
+ VALUES (?, ?, 'co_retrieved', ?, 'plasticity:stdp-ltp', ?)`
43873
+ );
43874
+ const prepareLogEvent = nativeDb.prepare(
43875
+ `INSERT INTO brain_plasticity_events
43876
+ (source_node, target_node, delta_w, kind, timestamp)
43877
+ VALUES (?, ?, ?, ?, ?)`
43878
+ );
43879
+ for (let i = 0; i < spikes.length; i++) {
43880
+ const spikeA = spikes[i];
43881
+ for (let j2 = i + 1; j2 < spikes.length; j2++) {
43882
+ const spikeB = spikes[j2];
43883
+ const deltaT = spikeB.retrievedAt - spikeA.retrievedAt;
43884
+ if (deltaT > sessionWindowMs) break;
43885
+ if (spikeA.entryId === spikeB.entryId) continue;
43886
+ result.pairsExamined++;
43887
+ const deltaW = A_PRE * Math.exp(-deltaT / TAU_PRE_MS);
43888
+ if (deltaW < 1e-6) continue;
43889
+ const existingEdge = prepareGetEdge.get(spikeA.entryId, spikeB.entryId);
43890
+ try {
43891
+ if (existingEdge !== void 0) {
43892
+ prepareUpdateEdge.run(WEIGHT_MIN, WEIGHT_MAX, deltaW, spikeA.entryId, spikeB.entryId);
43893
+ } else {
43894
+ const initialWeight = Math.min(WEIGHT_MAX, deltaW);
43895
+ prepareInsertEdge.run(spikeA.entryId, spikeB.entryId, initialWeight, nowIso);
43896
+ result.edgesCreated++;
43897
+ }
43898
+ prepareLogEvent.run(spikeA.entryId, spikeB.entryId, deltaW, "ltp", nowIso);
43899
+ result.ltpEvents++;
43900
+ } catch {
43901
+ }
43902
+ const deltaWNeg = -(A_POST * Math.exp(-deltaT / TAU_POST_MS));
43903
+ const existingReverseEdge = prepareGetEdge.get(spikeB.entryId, spikeA.entryId);
43904
+ if (existingReverseEdge !== void 0 && Math.abs(deltaWNeg) >= 1e-6) {
43905
+ try {
43906
+ prepareUpdateEdge.run(WEIGHT_MIN, WEIGHT_MAX, deltaWNeg, spikeB.entryId, spikeA.entryId);
43907
+ prepareLogEvent.run(spikeB.entryId, spikeA.entryId, deltaWNeg, "ltd", nowIso);
43908
+ result.ltdEvents++;
43909
+ } catch {
43910
+ }
43911
+ }
43912
+ }
43913
+ }
43914
+ return result;
43915
+ }
43916
+ async function getPlasticityStats(projectRoot, limit = 20) {
43917
+ const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
43918
+ await getBrainDb2(projectRoot);
43919
+ const nativeDb = getBrainNativeDb2();
43920
+ const empty = {
43921
+ totalEvents: 0,
43922
+ ltpCount: 0,
43923
+ ltdCount: 0,
43924
+ netDeltaW: 0,
43925
+ lastEventAt: null,
43926
+ recentEvents: []
43927
+ };
43928
+ if (!nativeDb) return empty;
43929
+ try {
43930
+ nativeDb.prepare("SELECT 1 FROM brain_plasticity_events LIMIT 1").get();
43931
+ } catch {
43932
+ return empty;
43933
+ }
43934
+ let agg;
43935
+ try {
43936
+ agg = nativeDb.prepare(
43937
+ `SELECT
43938
+ COUNT(*) AS total,
43939
+ SUM(CASE WHEN kind = 'ltp' THEN 1 ELSE 0 END) AS ltp_count,
43940
+ SUM(CASE WHEN kind = 'ltd' THEN 1 ELSE 0 END) AS ltd_count,
43941
+ SUM(delta_w) AS net_delta_w,
43942
+ MAX(timestamp) AS last_event_at
43943
+ FROM brain_plasticity_events`
43944
+ ).get();
43945
+ } catch {
43946
+ return empty;
43947
+ }
43948
+ let recentRows = [];
43949
+ try {
43950
+ recentRows = typedAll(
43951
+ nativeDb.prepare(
43952
+ `SELECT id, source_node, target_node, delta_w, kind, timestamp, session_id
43953
+ FROM brain_plasticity_events
43954
+ ORDER BY timestamp DESC, id DESC
43955
+ LIMIT ?`
43956
+ ),
43957
+ limit
43958
+ );
43959
+ } catch {
43960
+ }
43961
+ return {
43962
+ totalEvents: agg?.total ?? 0,
43963
+ ltpCount: agg?.ltp_count ?? 0,
43964
+ ltdCount: agg?.ltd_count ?? 0,
43965
+ netDeltaW: agg?.net_delta_w ?? 0,
43966
+ lastEventAt: agg?.last_event_at ?? null,
43967
+ recentEvents: recentRows.map((r) => ({
43968
+ id: r.id,
43969
+ sourceNode: r.source_node,
43970
+ targetNode: r.target_node,
43971
+ deltaW: r.delta_w,
43972
+ kind: r.kind,
43973
+ timestamp: r.timestamp,
43974
+ sessionId: r.session_id
43975
+ }))
43976
+ };
43977
+ }
43978
+ var TAU_PRE_MS, TAU_POST_MS, A_PRE, A_POST, WEIGHT_MIN, WEIGHT_MAX;
43979
+ var init_brain_stdp = __esm({
43980
+ "packages/core/src/memory/brain-stdp.ts"() {
43981
+ "use strict";
43982
+ init_typed_query();
43983
+ TAU_PRE_MS = 2e4;
43984
+ TAU_POST_MS = 2e4;
43985
+ A_PRE = 0.05;
43986
+ A_POST = 0.06;
43987
+ WEIGHT_MIN = 0;
43988
+ WEIGHT_MAX = 1;
43989
+ }
43990
+ });
43991
+
43567
43992
  // packages/core/src/memory/brain-lifecycle.ts
43568
43993
  var brain_lifecycle_exports = {};
43569
43994
  __export(brain_lifecycle_exports, {
@@ -43869,6 +44294,13 @@ async function runConsolidation(projectRoot) {
43869
44294
  } catch (err) {
43870
44295
  console.warn("[consolidation] Step 8 graph memory bridge failed:", err);
43871
44296
  }
44297
+ try {
44298
+ const { applyStdpPlasticity: applyStdpPlasticity2 } = await Promise.resolve().then(() => (init_brain_stdp(), brain_stdp_exports));
44299
+ const stdpResult = await applyStdpPlasticity2(projectRoot);
44300
+ result.stdpPlasticity = stdpResult;
44301
+ } catch (err) {
44302
+ console.warn("[consolidation] Step 9 STDP plasticity failed:", err);
44303
+ }
43872
44304
  return result;
43873
44305
  }
43874
44306
  async function deduplicateByEmbedding(projectRoot) {
@@ -44030,16 +44462,16 @@ async function strengthenCoRetrievedEdges(projectRoot) {
44030
44462
  const updateStmt = nativeDb.prepare(`
44031
44463
  UPDATE brain_page_edges
44032
44464
  SET weight = MIN(1.0, weight + 0.1)
44033
- WHERE from_id = ? AND to_id = ? AND edge_type = 'relates_to'
44465
+ WHERE from_id = ? AND to_id = ? AND edge_type = ?
44034
44466
  `);
44035
- const updateResult = updateStmt.run(nodeFrom, nodeTo);
44467
+ const updateResult = updateStmt.run(nodeFrom, nodeTo, EDGE_TYPES.CO_RETRIEVED);
44036
44468
  const changes = typeof updateResult.changes === "number" ? updateResult.changes : 0;
44037
44469
  if (changes === 0) {
44038
44470
  nativeDb.prepare(`
44039
44471
  INSERT OR IGNORE INTO brain_page_edges
44040
44472
  (from_id, to_id, edge_type, weight, provenance, created_at)
44041
- VALUES (?, ?, 'relates_to', 0.3, 'consolidation:co-retrieval', ?)
44042
- `).run(nodeFrom, nodeTo, now2);
44473
+ VALUES (?, ?, ?, 0.3, 'consolidation:co-retrieval', ?)
44474
+ `).run(nodeFrom, nodeTo, EDGE_TYPES.CO_RETRIEVED, now2);
44043
44475
  }
44044
44476
  strengthened++;
44045
44477
  } catch {
@@ -44053,6 +44485,7 @@ var init_brain_lifecycle = __esm({
44053
44485
  "use strict";
44054
44486
  init_brain_accessor();
44055
44487
  init_typed_query();
44488
+ init_edge_types();
44056
44489
  STOP_WORDS3 = /* @__PURE__ */ new Set([
44057
44490
  "the",
44058
44491
  "a",
@@ -73091,6 +73524,7 @@ async function listEpicsWithLifecycle(cwd) {
73091
73524
  // packages/core/src/memory/index.ts
73092
73525
  var memory_exports = {};
73093
73526
  __export(memory_exports, {
73527
+ EDGE_TYPES: () => EDGE_TYPES,
73094
73528
  RRF_K: () => RRF_K,
73095
73529
  addResearch: () => addResearch,
73096
73530
  appendExtendedManifest: () => appendExtendedManifest,
@@ -73288,6 +73722,7 @@ function mapImpact(impact) {
73288
73722
  init_brain_retrieval();
73289
73723
  init_brain_search();
73290
73724
  init_decisions2();
73725
+ init_edge_types();
73291
73726
 
73292
73727
  // packages/core/src/memory/extraction-gate.ts
73293
73728
  init_brain_embedding();
@@ -81673,6 +82108,7 @@ async function getSyncStatus(remote = "origin", cwd) {
81673
82108
  // packages/core/src/research/index.ts
81674
82109
  var research_exports = {};
81675
82110
  __export(research_exports, {
82111
+ EDGE_TYPES: () => EDGE_TYPES,
81676
82112
  RRF_K: () => RRF_K,
81677
82113
  addResearch: () => addResearch,
81678
82114
  appendExtendedManifest: () => appendExtendedManifest,
@@ -97190,6 +97626,7 @@ async function purgeBrainNoise(projectRoot) {
97190
97626
 
97191
97627
  // packages/core/src/internal.ts
97192
97628
  init_brain_retrieval();
97629
+ init_brain_stdp();
97193
97630
 
97194
97631
  // packages/core/src/memory/claude-mem-migration.ts
97195
97632
  init_paths();
@@ -110309,6 +110746,7 @@ export {
110309
110746
  analyzeDependencies2 as analyzeDependencies,
110310
110747
  analyzeEpic,
110311
110748
  analyzeTaskImpact,
110749
+ applyStdpPlasticity,
110312
110750
  applyStrictnessPreset,
110313
110751
  applyTemporalDecay,
110314
110752
  archiveSessions,
@@ -110636,6 +111074,7 @@ export {
110636
111074
  getPackageRoot,
110637
111075
  getParallelStatus,
110638
111076
  getPipelineStageOrder,
111077
+ getPlasticityStats,
110639
111078
  getProjectAgentRef2 as getProjectAgentRef,
110640
111079
  getProjectInfo,
110641
111080
  getProjectInfoSync,