@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.
- package/dist/index.js +445 -9
- package/dist/index.js.map +4 -4
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +448 -9
- package/dist/internal.js.map +4 -4
- package/dist/memory/brain-lifecycle.d.ts +7 -0
- package/dist/memory/brain-lifecycle.d.ts.map +1 -1
- package/dist/memory/brain-stdp.d.ts +122 -0
- package/dist/memory/brain-stdp.d.ts.map +1 -0
- package/dist/memory/decision-cross-link.d.ts +70 -0
- package/dist/memory/decision-cross-link.d.ts.map +1 -0
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/memory/edge-types.d.ts +24 -0
- package/dist/memory/edge-types.d.ts.map +1 -0
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/store/brain-schema.d.ts +134 -3
- package/dist/store/brain-schema.d.ts.map +1 -1
- package/dist/store/brain-sqlite.d.ts.map +1 -1
- package/dist/store/validation-schemas.d.ts +1 -0
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/migrations/drizzle-brain/20260415000001_t626-normalize-co-retrieved-edge-type/migration.sql +14 -0
- package/package.json +8 -8
- package/src/internal.ts +7 -0
- package/src/memory/__tests__/brain-stdp.test.ts +452 -0
- package/src/memory/__tests__/decision-cross-link.test.ts +240 -0
- package/src/memory/brain-lifecycle.ts +23 -4
- package/src/memory/brain-stdp.ts +448 -0
- package/src/memory/decision-cross-link.ts +276 -0
- package/src/memory/decisions.ts +7 -0
- package/src/memory/edge-types.ts +31 -0
- package/src/memory/index.ts +2 -0
- package/src/store/brain-schema.ts +50 -0
- package/src/store/brain-sqlite.ts +17 -0
package/dist/index.js
CHANGED
|
@@ -9046,12 +9046,13 @@ __export(brain_schema_exports, {
|
|
|
9046
9046
|
brainPageEdges: () => brainPageEdges,
|
|
9047
9047
|
brainPageNodes: () => brainPageNodes,
|
|
9048
9048
|
brainPatterns: () => brainPatterns,
|
|
9049
|
+
brainPlasticityEvents: () => brainPlasticityEvents,
|
|
9049
9050
|
brainRetrievalLog: () => brainRetrievalLog,
|
|
9050
9051
|
brainSchemaMeta: () => brainSchemaMeta,
|
|
9051
9052
|
brainStickyNotes: () => brainStickyNotes
|
|
9052
9053
|
});
|
|
9053
9054
|
import { sql as sql2 } from "drizzle-orm";
|
|
9054
|
-
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;
|
|
9055
|
+
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;
|
|
9055
9056
|
var init_brain_schema = __esm({
|
|
9056
9057
|
"packages/core/src/store/brain-schema.ts"() {
|
|
9057
9058
|
"use strict";
|
|
@@ -9480,8 +9481,11 @@ var init_brain_schema = __esm({
|
|
|
9480
9481
|
// Graph bridging (memory ↔ code)
|
|
9481
9482
|
"references",
|
|
9482
9483
|
// observation → references → symbol
|
|
9483
|
-
"modified_by"
|
|
9484
|
+
"modified_by",
|
|
9484
9485
|
// file → modified_by → session
|
|
9486
|
+
// Plasticity (Hebbian + STDP co-retrieval)
|
|
9487
|
+
"co_retrieved"
|
|
9488
|
+
// A → co_retrieved → B (Hebbian: frequently retrieved together)
|
|
9485
9489
|
];
|
|
9486
9490
|
brainPageNodes = sqliteTable(
|
|
9487
9491
|
"brain_page_nodes",
|
|
@@ -9578,6 +9582,37 @@ var init_brain_schema = __esm({
|
|
|
9578
9582
|
index("idx_retrieval_log_source").on(table.source)
|
|
9579
9583
|
]
|
|
9580
9584
|
);
|
|
9585
|
+
brainPlasticityEvents = sqliteTable(
|
|
9586
|
+
"brain_plasticity_events",
|
|
9587
|
+
{
|
|
9588
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
9589
|
+
/** from_id of the affected brain_page_edges row. */
|
|
9590
|
+
sourceNode: text("source_node").notNull(),
|
|
9591
|
+
/** to_id of the affected brain_page_edges row. */
|
|
9592
|
+
targetNode: text("target_node").notNull(),
|
|
9593
|
+
/**
|
|
9594
|
+
* Signed weight delta applied to the edge.
|
|
9595
|
+
* Positive = potentiation (LTP), negative = depression (LTD).
|
|
9596
|
+
*/
|
|
9597
|
+
deltaW: real("delta_w").notNull(),
|
|
9598
|
+
/**
|
|
9599
|
+
* STDP event kind: `ltp` (Long-Term Potentiation) or `ltd` (Long-Term
|
|
9600
|
+
* Depression).
|
|
9601
|
+
*/
|
|
9602
|
+
kind: text("kind", { enum: ["ltp", "ltd"] }).notNull(),
|
|
9603
|
+
/** ISO 8601 timestamp when this event was applied. */
|
|
9604
|
+
timestamp: text("timestamp").notNull().default(sql2`(datetime('now'))`),
|
|
9605
|
+
/** Session ID that triggered the STDP pass, if available. */
|
|
9606
|
+
sessionId: text("session_id")
|
|
9607
|
+
},
|
|
9608
|
+
(table) => [
|
|
9609
|
+
index("idx_plasticity_source").on(table.sourceNode),
|
|
9610
|
+
index("idx_plasticity_target").on(table.targetNode),
|
|
9611
|
+
index("idx_plasticity_timestamp").on(table.timestamp),
|
|
9612
|
+
index("idx_plasticity_session").on(table.sessionId),
|
|
9613
|
+
index("idx_plasticity_kind").on(table.kind)
|
|
9614
|
+
]
|
|
9615
|
+
);
|
|
9581
9616
|
}
|
|
9582
9617
|
});
|
|
9583
9618
|
|
|
@@ -14444,6 +14479,14 @@ function runBrainMigrations(nativeDb, db) {
|
|
|
14444
14479
|
);
|
|
14445
14480
|
}
|
|
14446
14481
|
ensureColumns(nativeDb, "brain_observations", [{ name: "agent", ddl: "text" }], "brain");
|
|
14482
|
+
if (tableExists(nativeDb, "brain_page_edges")) {
|
|
14483
|
+
nativeDb.prepare(
|
|
14484
|
+
`UPDATE brain_page_edges
|
|
14485
|
+
SET edge_type = 'co_retrieved'
|
|
14486
|
+
WHERE edge_type = 'relates_to'
|
|
14487
|
+
AND provenance LIKE 'consolidation:%'`
|
|
14488
|
+
).run();
|
|
14489
|
+
}
|
|
14447
14490
|
}
|
|
14448
14491
|
function loadBrainVecExtension(nativeDb) {
|
|
14449
14492
|
try {
|
|
@@ -20956,6 +20999,160 @@ var init_anthropic_key_resolver = __esm({
|
|
|
20956
20999
|
}
|
|
20957
21000
|
});
|
|
20958
21001
|
|
|
21002
|
+
// packages/core/src/memory/decision-cross-link.ts
|
|
21003
|
+
function extractReferencedSymbols(text3) {
|
|
21004
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21005
|
+
const refs = [];
|
|
21006
|
+
for (const match of text3.matchAll(FILE_PATH_RE)) {
|
|
21007
|
+
const raw = match[1];
|
|
21008
|
+
if (!raw) continue;
|
|
21009
|
+
const nodeId = `file:${raw}`;
|
|
21010
|
+
if (seen.has(nodeId)) continue;
|
|
21011
|
+
seen.add(nodeId);
|
|
21012
|
+
refs.push({ raw, nodeId, nodeType: "file", label: raw });
|
|
21013
|
+
}
|
|
21014
|
+
for (const match of text3.matchAll(SYMBOL_RE)) {
|
|
21015
|
+
const raw = match[0];
|
|
21016
|
+
if (!raw || raw.length < 4) continue;
|
|
21017
|
+
if (SYMBOL_STOP_WORDS.has(raw.toLowerCase())) continue;
|
|
21018
|
+
const nodeId = `symbol:${raw}`;
|
|
21019
|
+
if (seen.has(nodeId)) continue;
|
|
21020
|
+
seen.add(nodeId);
|
|
21021
|
+
refs.push({ raw, nodeId, nodeType: "symbol", label: raw });
|
|
21022
|
+
}
|
|
21023
|
+
return refs;
|
|
21024
|
+
}
|
|
21025
|
+
async function linkDecisionToTargets(projectRoot, decisionId, refs) {
|
|
21026
|
+
const fromId = `decision:${decisionId}`;
|
|
21027
|
+
const writes = refs.map(async (ref) => {
|
|
21028
|
+
await upsertGraphNode(
|
|
21029
|
+
projectRoot,
|
|
21030
|
+
ref.nodeId,
|
|
21031
|
+
ref.nodeType,
|
|
21032
|
+
ref.label,
|
|
21033
|
+
0.5,
|
|
21034
|
+
// placeholder quality until nexus indexes it
|
|
21035
|
+
ref.raw
|
|
21036
|
+
);
|
|
21037
|
+
await addGraphEdge(
|
|
21038
|
+
projectRoot,
|
|
21039
|
+
fromId,
|
|
21040
|
+
ref.nodeId,
|
|
21041
|
+
"applies_to",
|
|
21042
|
+
1,
|
|
21043
|
+
"auto:decision-cross-link"
|
|
21044
|
+
);
|
|
21045
|
+
});
|
|
21046
|
+
await Promise.allSettled(writes);
|
|
21047
|
+
}
|
|
21048
|
+
async function autoCrossLinkDecision(projectRoot, decisionId, decisionText, rationale) {
|
|
21049
|
+
try {
|
|
21050
|
+
const combined = `${decisionText} ${rationale}`;
|
|
21051
|
+
const refs = extractReferencedSymbols(combined);
|
|
21052
|
+
if (refs.length === 0) return;
|
|
21053
|
+
await linkDecisionToTargets(projectRoot, decisionId, refs);
|
|
21054
|
+
} catch {
|
|
21055
|
+
}
|
|
21056
|
+
}
|
|
21057
|
+
var FILE_PATH_RE, SYMBOL_RE, SYMBOL_STOP_WORDS;
|
|
21058
|
+
var init_decision_cross_link = __esm({
|
|
21059
|
+
"packages/core/src/memory/decision-cross-link.ts"() {
|
|
21060
|
+
"use strict";
|
|
21061
|
+
init_graph_auto_populate();
|
|
21062
|
+
FILE_PATH_RE = /(?:^|[\s`"'([\]{,])((\/[\w.\-/]+|[\w.-]+(?:\/[\w.-]+)+)\.(ts|tsx|js|jsx|rs|json))(?=$|[\s`"')[\]{,])/gm;
|
|
21063
|
+
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;
|
|
21064
|
+
SYMBOL_STOP_WORDS = /* @__PURE__ */ new Set([
|
|
21065
|
+
"this",
|
|
21066
|
+
"that",
|
|
21067
|
+
"with",
|
|
21068
|
+
"from",
|
|
21069
|
+
"into",
|
|
21070
|
+
"when",
|
|
21071
|
+
"then",
|
|
21072
|
+
"also",
|
|
21073
|
+
"both",
|
|
21074
|
+
"each",
|
|
21075
|
+
"such",
|
|
21076
|
+
"over",
|
|
21077
|
+
"after",
|
|
21078
|
+
"before",
|
|
21079
|
+
"always",
|
|
21080
|
+
"never",
|
|
21081
|
+
"should",
|
|
21082
|
+
"must",
|
|
21083
|
+
"will",
|
|
21084
|
+
"would",
|
|
21085
|
+
"could",
|
|
21086
|
+
"have",
|
|
21087
|
+
"been",
|
|
21088
|
+
"there",
|
|
21089
|
+
"their",
|
|
21090
|
+
"they",
|
|
21091
|
+
"them",
|
|
21092
|
+
"these",
|
|
21093
|
+
"those",
|
|
21094
|
+
"some",
|
|
21095
|
+
"only",
|
|
21096
|
+
"just",
|
|
21097
|
+
"more",
|
|
21098
|
+
"most",
|
|
21099
|
+
"many",
|
|
21100
|
+
"much",
|
|
21101
|
+
"well",
|
|
21102
|
+
"very",
|
|
21103
|
+
"here",
|
|
21104
|
+
"where",
|
|
21105
|
+
"which",
|
|
21106
|
+
"what",
|
|
21107
|
+
"why",
|
|
21108
|
+
"how",
|
|
21109
|
+
"the",
|
|
21110
|
+
"and",
|
|
21111
|
+
"but",
|
|
21112
|
+
"for",
|
|
21113
|
+
"not",
|
|
21114
|
+
"are",
|
|
21115
|
+
"was",
|
|
21116
|
+
"were",
|
|
21117
|
+
"has",
|
|
21118
|
+
"had",
|
|
21119
|
+
"its",
|
|
21120
|
+
"the",
|
|
21121
|
+
"data",
|
|
21122
|
+
"true",
|
|
21123
|
+
"false",
|
|
21124
|
+
"null",
|
|
21125
|
+
"none",
|
|
21126
|
+
"type",
|
|
21127
|
+
"test",
|
|
21128
|
+
"spec",
|
|
21129
|
+
"todo",
|
|
21130
|
+
"fixme",
|
|
21131
|
+
"note",
|
|
21132
|
+
"example",
|
|
21133
|
+
"index",
|
|
21134
|
+
"config",
|
|
21135
|
+
"error",
|
|
21136
|
+
"value",
|
|
21137
|
+
"input",
|
|
21138
|
+
"output",
|
|
21139
|
+
"result",
|
|
21140
|
+
"return",
|
|
21141
|
+
"default",
|
|
21142
|
+
"source",
|
|
21143
|
+
"target",
|
|
21144
|
+
"import",
|
|
21145
|
+
"export",
|
|
21146
|
+
"class",
|
|
21147
|
+
"interface",
|
|
21148
|
+
"function",
|
|
21149
|
+
"const",
|
|
21150
|
+
"async",
|
|
21151
|
+
"await"
|
|
21152
|
+
]);
|
|
21153
|
+
}
|
|
21154
|
+
});
|
|
21155
|
+
|
|
20959
21156
|
// packages/core/src/memory/decisions.ts
|
|
20960
21157
|
var decisions_exports = {};
|
|
20961
21158
|
__export(decisions_exports, {
|
|
@@ -21094,6 +21291,8 @@ async function storeDecision(projectRoot, params) {
|
|
|
21094
21291
|
"auto:store-decision"
|
|
21095
21292
|
);
|
|
21096
21293
|
}
|
|
21294
|
+
autoCrossLinkDecision(projectRoot, saved.id, saved.decision, saved.rationale).catch(() => {
|
|
21295
|
+
});
|
|
21097
21296
|
} catch {
|
|
21098
21297
|
}
|
|
21099
21298
|
detectSupersession(projectRoot, {
|
|
@@ -21162,6 +21361,7 @@ var init_decisions2 = __esm({
|
|
|
21162
21361
|
init_brain_accessor();
|
|
21163
21362
|
init_cross_db_cleanup();
|
|
21164
21363
|
init_sqlite2();
|
|
21364
|
+
init_decision_cross_link();
|
|
21165
21365
|
init_graph_auto_populate();
|
|
21166
21366
|
init_quality_scoring();
|
|
21167
21367
|
init_temporal_supersession();
|
|
@@ -42232,6 +42432,30 @@ var init_auto_extract = __esm({
|
|
|
42232
42432
|
}
|
|
42233
42433
|
});
|
|
42234
42434
|
|
|
42435
|
+
// packages/core/src/memory/edge-types.ts
|
|
42436
|
+
var EDGE_TYPES;
|
|
42437
|
+
var init_edge_types = __esm({
|
|
42438
|
+
"packages/core/src/memory/edge-types.ts"() {
|
|
42439
|
+
"use strict";
|
|
42440
|
+
EDGE_TYPES = {
|
|
42441
|
+
// Plasticity (Hebbian / STDP co-retrieval)
|
|
42442
|
+
CO_RETRIEVED: "co_retrieved",
|
|
42443
|
+
// Temporal supersession
|
|
42444
|
+
SUPERSEDES: "supersedes",
|
|
42445
|
+
// Task / decision / pattern → target context
|
|
42446
|
+
APPLIES_TO: "applies_to",
|
|
42447
|
+
// Provenance
|
|
42448
|
+
DERIVED_FROM: "derived_from",
|
|
42449
|
+
// Observation → symbol/file impact
|
|
42450
|
+
AFFECTS: "affects",
|
|
42451
|
+
// Observation → symbol name mention
|
|
42452
|
+
MENTIONS: "mentions",
|
|
42453
|
+
// Observation → symbol/file structural link
|
|
42454
|
+
DOCUMENTS: "documents"
|
|
42455
|
+
};
|
|
42456
|
+
}
|
|
42457
|
+
});
|
|
42458
|
+
|
|
42235
42459
|
// packages/core/src/memory/brain-consolidator.ts
|
|
42236
42460
|
var brain_consolidator_exports = {};
|
|
42237
42461
|
__export(brain_consolidator_exports, {
|
|
@@ -42465,7 +42689,7 @@ function extractSymbolCandidates(text3) {
|
|
|
42465
42689
|
const syms = /* @__PURE__ */ new Set();
|
|
42466
42690
|
for (const m of text3.matchAll(SYMBOL_PATTERN)) {
|
|
42467
42691
|
const s = m[1];
|
|
42468
|
-
if (s && s.length >= 4 && !
|
|
42692
|
+
if (s && s.length >= 4 && !SYMBOL_STOP_WORDS2.has(s.toLowerCase())) {
|
|
42469
42693
|
syms.add(s);
|
|
42470
42694
|
}
|
|
42471
42695
|
}
|
|
@@ -42774,7 +42998,7 @@ async function listCodeLinks(projectRoot, limit = 100) {
|
|
|
42774
42998
|
}
|
|
42775
42999
|
return entries;
|
|
42776
43000
|
}
|
|
42777
|
-
var FILE_PATH_PATTERN, SYMBOL_PATTERN,
|
|
43001
|
+
var FILE_PATH_PATTERN, SYMBOL_PATTERN, SYMBOL_STOP_WORDS2;
|
|
42778
43002
|
var init_graph_memory_bridge = __esm({
|
|
42779
43003
|
"packages/core/src/memory/graph-memory-bridge.ts"() {
|
|
42780
43004
|
"use strict";
|
|
@@ -42784,7 +43008,7 @@ var init_graph_memory_bridge = __esm({
|
|
|
42784
43008
|
init_typed_query();
|
|
42785
43009
|
FILE_PATH_PATTERN = /(?:^|\s|['"`(])([a-zA-Z0-9_\-./]+\.(?:ts|tsx|js|jsx|rs|go|py|mjs|cjs))(?:$|\s|['"`)])/g;
|
|
42786
43010
|
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;
|
|
42787
|
-
|
|
43011
|
+
SYMBOL_STOP_WORDS2 = /* @__PURE__ */ new Set([
|
|
42788
43012
|
"true",
|
|
42789
43013
|
"false",
|
|
42790
43014
|
"null",
|
|
@@ -42828,6 +43052,207 @@ var init_graph_memory_bridge = __esm({
|
|
|
42828
43052
|
}
|
|
42829
43053
|
});
|
|
42830
43054
|
|
|
43055
|
+
// packages/core/src/memory/brain-stdp.ts
|
|
43056
|
+
var brain_stdp_exports = {};
|
|
43057
|
+
__export(brain_stdp_exports, {
|
|
43058
|
+
applyStdpPlasticity: () => applyStdpPlasticity,
|
|
43059
|
+
getPlasticityStats: () => getPlasticityStats
|
|
43060
|
+
});
|
|
43061
|
+
async function applyStdpPlasticity(projectRoot, sessionWindowMs = 5 * 60 * 1e3) {
|
|
43062
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
43063
|
+
await getBrainDb2(projectRoot);
|
|
43064
|
+
const nativeDb = getBrainNativeDb2();
|
|
43065
|
+
const result = {
|
|
43066
|
+
ltpEvents: 0,
|
|
43067
|
+
ltdEvents: 0,
|
|
43068
|
+
edgesCreated: 0,
|
|
43069
|
+
pairsExamined: 0
|
|
43070
|
+
};
|
|
43071
|
+
if (!nativeDb) return result;
|
|
43072
|
+
try {
|
|
43073
|
+
nativeDb.prepare("SELECT 1 FROM brain_retrieval_log LIMIT 1").get();
|
|
43074
|
+
} catch {
|
|
43075
|
+
return result;
|
|
43076
|
+
}
|
|
43077
|
+
try {
|
|
43078
|
+
nativeDb.prepare("SELECT 1 FROM brain_plasticity_events LIMIT 1").get();
|
|
43079
|
+
} catch {
|
|
43080
|
+
return result;
|
|
43081
|
+
}
|
|
43082
|
+
const now = Date.now();
|
|
43083
|
+
const cutoffMs = now - sessionWindowMs;
|
|
43084
|
+
const cutoffIso = new Date(cutoffMs).toISOString().replace("T", " ").slice(0, 19);
|
|
43085
|
+
const nowIso = new Date(now).toISOString().replace("T", " ").slice(0, 19);
|
|
43086
|
+
let logRows = [];
|
|
43087
|
+
try {
|
|
43088
|
+
logRows = typedAll(
|
|
43089
|
+
nativeDb.prepare(
|
|
43090
|
+
`SELECT id, entry_ids, created_at, retrieval_order, delta_ms
|
|
43091
|
+
FROM brain_retrieval_log
|
|
43092
|
+
WHERE created_at >= ?
|
|
43093
|
+
ORDER BY created_at ASC, id ASC
|
|
43094
|
+
LIMIT 2000`
|
|
43095
|
+
),
|
|
43096
|
+
cutoffIso
|
|
43097
|
+
);
|
|
43098
|
+
} catch {
|
|
43099
|
+
return result;
|
|
43100
|
+
}
|
|
43101
|
+
if (logRows.length === 0) return result;
|
|
43102
|
+
const spikes = [];
|
|
43103
|
+
let globalOrder = 0;
|
|
43104
|
+
for (const row of logRows) {
|
|
43105
|
+
let ids;
|
|
43106
|
+
try {
|
|
43107
|
+
ids = JSON.parse(row.entry_ids);
|
|
43108
|
+
} catch {
|
|
43109
|
+
continue;
|
|
43110
|
+
}
|
|
43111
|
+
const rowTime = (/* @__PURE__ */ new Date(row.created_at.replace(" ", "T") + "Z")).getTime();
|
|
43112
|
+
for (const rawId of ids) {
|
|
43113
|
+
const entryId = rawId.includes(":") ? rawId : `observation:${rawId}`;
|
|
43114
|
+
spikes.push({
|
|
43115
|
+
entryId,
|
|
43116
|
+
rowId: row.id,
|
|
43117
|
+
retrievedAt: rowTime,
|
|
43118
|
+
order: row.retrieval_order ?? globalOrder
|
|
43119
|
+
});
|
|
43120
|
+
globalOrder++;
|
|
43121
|
+
}
|
|
43122
|
+
}
|
|
43123
|
+
spikes.sort((a, b) => a.retrievedAt - b.retrievedAt || a.order - b.order);
|
|
43124
|
+
const prepareGetEdge = nativeDb.prepare(
|
|
43125
|
+
`SELECT weight FROM brain_page_edges
|
|
43126
|
+
WHERE from_id = ? AND to_id = ? AND edge_type = 'co_retrieved'`
|
|
43127
|
+
);
|
|
43128
|
+
const prepareUpdateEdge = nativeDb.prepare(
|
|
43129
|
+
`UPDATE brain_page_edges
|
|
43130
|
+
SET weight = MAX(?, MIN(?, weight + ?))
|
|
43131
|
+
WHERE from_id = ? AND to_id = ? AND edge_type = 'co_retrieved'`
|
|
43132
|
+
);
|
|
43133
|
+
const prepareInsertEdge = nativeDb.prepare(
|
|
43134
|
+
`INSERT OR IGNORE INTO brain_page_edges
|
|
43135
|
+
(from_id, to_id, edge_type, weight, provenance, created_at)
|
|
43136
|
+
VALUES (?, ?, 'co_retrieved', ?, 'plasticity:stdp-ltp', ?)`
|
|
43137
|
+
);
|
|
43138
|
+
const prepareLogEvent = nativeDb.prepare(
|
|
43139
|
+
`INSERT INTO brain_plasticity_events
|
|
43140
|
+
(source_node, target_node, delta_w, kind, timestamp)
|
|
43141
|
+
VALUES (?, ?, ?, ?, ?)`
|
|
43142
|
+
);
|
|
43143
|
+
for (let i = 0; i < spikes.length; i++) {
|
|
43144
|
+
const spikeA = spikes[i];
|
|
43145
|
+
for (let j = i + 1; j < spikes.length; j++) {
|
|
43146
|
+
const spikeB = spikes[j];
|
|
43147
|
+
const deltaT = spikeB.retrievedAt - spikeA.retrievedAt;
|
|
43148
|
+
if (deltaT > sessionWindowMs) break;
|
|
43149
|
+
if (spikeA.entryId === spikeB.entryId) continue;
|
|
43150
|
+
result.pairsExamined++;
|
|
43151
|
+
const deltaW = A_PRE * Math.exp(-deltaT / TAU_PRE_MS);
|
|
43152
|
+
if (deltaW < 1e-6) continue;
|
|
43153
|
+
const existingEdge = prepareGetEdge.get(spikeA.entryId, spikeB.entryId);
|
|
43154
|
+
try {
|
|
43155
|
+
if (existingEdge !== void 0) {
|
|
43156
|
+
prepareUpdateEdge.run(WEIGHT_MIN, WEIGHT_MAX, deltaW, spikeA.entryId, spikeB.entryId);
|
|
43157
|
+
} else {
|
|
43158
|
+
const initialWeight = Math.min(WEIGHT_MAX, deltaW);
|
|
43159
|
+
prepareInsertEdge.run(spikeA.entryId, spikeB.entryId, initialWeight, nowIso);
|
|
43160
|
+
result.edgesCreated++;
|
|
43161
|
+
}
|
|
43162
|
+
prepareLogEvent.run(spikeA.entryId, spikeB.entryId, deltaW, "ltp", nowIso);
|
|
43163
|
+
result.ltpEvents++;
|
|
43164
|
+
} catch {
|
|
43165
|
+
}
|
|
43166
|
+
const deltaWNeg = -(A_POST * Math.exp(-deltaT / TAU_POST_MS));
|
|
43167
|
+
const existingReverseEdge = prepareGetEdge.get(spikeB.entryId, spikeA.entryId);
|
|
43168
|
+
if (existingReverseEdge !== void 0 && Math.abs(deltaWNeg) >= 1e-6) {
|
|
43169
|
+
try {
|
|
43170
|
+
prepareUpdateEdge.run(WEIGHT_MIN, WEIGHT_MAX, deltaWNeg, spikeB.entryId, spikeA.entryId);
|
|
43171
|
+
prepareLogEvent.run(spikeB.entryId, spikeA.entryId, deltaWNeg, "ltd", nowIso);
|
|
43172
|
+
result.ltdEvents++;
|
|
43173
|
+
} catch {
|
|
43174
|
+
}
|
|
43175
|
+
}
|
|
43176
|
+
}
|
|
43177
|
+
}
|
|
43178
|
+
return result;
|
|
43179
|
+
}
|
|
43180
|
+
async function getPlasticityStats(projectRoot, limit = 20) {
|
|
43181
|
+
const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_brain_sqlite(), brain_sqlite_exports));
|
|
43182
|
+
await getBrainDb2(projectRoot);
|
|
43183
|
+
const nativeDb = getBrainNativeDb2();
|
|
43184
|
+
const empty = {
|
|
43185
|
+
totalEvents: 0,
|
|
43186
|
+
ltpCount: 0,
|
|
43187
|
+
ltdCount: 0,
|
|
43188
|
+
netDeltaW: 0,
|
|
43189
|
+
lastEventAt: null,
|
|
43190
|
+
recentEvents: []
|
|
43191
|
+
};
|
|
43192
|
+
if (!nativeDb) return empty;
|
|
43193
|
+
try {
|
|
43194
|
+
nativeDb.prepare("SELECT 1 FROM brain_plasticity_events LIMIT 1").get();
|
|
43195
|
+
} catch {
|
|
43196
|
+
return empty;
|
|
43197
|
+
}
|
|
43198
|
+
let agg;
|
|
43199
|
+
try {
|
|
43200
|
+
agg = nativeDb.prepare(
|
|
43201
|
+
`SELECT
|
|
43202
|
+
COUNT(*) AS total,
|
|
43203
|
+
SUM(CASE WHEN kind = 'ltp' THEN 1 ELSE 0 END) AS ltp_count,
|
|
43204
|
+
SUM(CASE WHEN kind = 'ltd' THEN 1 ELSE 0 END) AS ltd_count,
|
|
43205
|
+
SUM(delta_w) AS net_delta_w,
|
|
43206
|
+
MAX(timestamp) AS last_event_at
|
|
43207
|
+
FROM brain_plasticity_events`
|
|
43208
|
+
).get();
|
|
43209
|
+
} catch {
|
|
43210
|
+
return empty;
|
|
43211
|
+
}
|
|
43212
|
+
let recentRows = [];
|
|
43213
|
+
try {
|
|
43214
|
+
recentRows = typedAll(
|
|
43215
|
+
nativeDb.prepare(
|
|
43216
|
+
`SELECT id, source_node, target_node, delta_w, kind, timestamp, session_id
|
|
43217
|
+
FROM brain_plasticity_events
|
|
43218
|
+
ORDER BY timestamp DESC, id DESC
|
|
43219
|
+
LIMIT ?`
|
|
43220
|
+
),
|
|
43221
|
+
limit
|
|
43222
|
+
);
|
|
43223
|
+
} catch {
|
|
43224
|
+
}
|
|
43225
|
+
return {
|
|
43226
|
+
totalEvents: agg?.total ?? 0,
|
|
43227
|
+
ltpCount: agg?.ltp_count ?? 0,
|
|
43228
|
+
ltdCount: agg?.ltd_count ?? 0,
|
|
43229
|
+
netDeltaW: agg?.net_delta_w ?? 0,
|
|
43230
|
+
lastEventAt: agg?.last_event_at ?? null,
|
|
43231
|
+
recentEvents: recentRows.map((r) => ({
|
|
43232
|
+
id: r.id,
|
|
43233
|
+
sourceNode: r.source_node,
|
|
43234
|
+
targetNode: r.target_node,
|
|
43235
|
+
deltaW: r.delta_w,
|
|
43236
|
+
kind: r.kind,
|
|
43237
|
+
timestamp: r.timestamp,
|
|
43238
|
+
sessionId: r.session_id
|
|
43239
|
+
}))
|
|
43240
|
+
};
|
|
43241
|
+
}
|
|
43242
|
+
var TAU_PRE_MS, TAU_POST_MS, A_PRE, A_POST, WEIGHT_MIN, WEIGHT_MAX;
|
|
43243
|
+
var init_brain_stdp = __esm({
|
|
43244
|
+
"packages/core/src/memory/brain-stdp.ts"() {
|
|
43245
|
+
"use strict";
|
|
43246
|
+
init_typed_query();
|
|
43247
|
+
TAU_PRE_MS = 2e4;
|
|
43248
|
+
TAU_POST_MS = 2e4;
|
|
43249
|
+
A_PRE = 0.05;
|
|
43250
|
+
A_POST = 0.06;
|
|
43251
|
+
WEIGHT_MIN = 0;
|
|
43252
|
+
WEIGHT_MAX = 1;
|
|
43253
|
+
}
|
|
43254
|
+
});
|
|
43255
|
+
|
|
42831
43256
|
// packages/core/src/memory/brain-lifecycle.ts
|
|
42832
43257
|
var brain_lifecycle_exports = {};
|
|
42833
43258
|
__export(brain_lifecycle_exports, {
|
|
@@ -43133,6 +43558,13 @@ async function runConsolidation(projectRoot) {
|
|
|
43133
43558
|
} catch (err) {
|
|
43134
43559
|
console.warn("[consolidation] Step 8 graph memory bridge failed:", err);
|
|
43135
43560
|
}
|
|
43561
|
+
try {
|
|
43562
|
+
const { applyStdpPlasticity: applyStdpPlasticity2 } = await Promise.resolve().then(() => (init_brain_stdp(), brain_stdp_exports));
|
|
43563
|
+
const stdpResult = await applyStdpPlasticity2(projectRoot);
|
|
43564
|
+
result.stdpPlasticity = stdpResult;
|
|
43565
|
+
} catch (err) {
|
|
43566
|
+
console.warn("[consolidation] Step 9 STDP plasticity failed:", err);
|
|
43567
|
+
}
|
|
43136
43568
|
return result;
|
|
43137
43569
|
}
|
|
43138
43570
|
async function deduplicateByEmbedding(projectRoot) {
|
|
@@ -43294,16 +43726,16 @@ async function strengthenCoRetrievedEdges(projectRoot) {
|
|
|
43294
43726
|
const updateStmt = nativeDb.prepare(`
|
|
43295
43727
|
UPDATE brain_page_edges
|
|
43296
43728
|
SET weight = MIN(1.0, weight + 0.1)
|
|
43297
|
-
WHERE from_id = ? AND to_id = ? AND edge_type =
|
|
43729
|
+
WHERE from_id = ? AND to_id = ? AND edge_type = ?
|
|
43298
43730
|
`);
|
|
43299
|
-
const updateResult = updateStmt.run(nodeFrom, nodeTo);
|
|
43731
|
+
const updateResult = updateStmt.run(nodeFrom, nodeTo, EDGE_TYPES.CO_RETRIEVED);
|
|
43300
43732
|
const changes = typeof updateResult.changes === "number" ? updateResult.changes : 0;
|
|
43301
43733
|
if (changes === 0) {
|
|
43302
43734
|
nativeDb.prepare(`
|
|
43303
43735
|
INSERT OR IGNORE INTO brain_page_edges
|
|
43304
43736
|
(from_id, to_id, edge_type, weight, provenance, created_at)
|
|
43305
|
-
VALUES (?, ?,
|
|
43306
|
-
`).run(nodeFrom, nodeTo, now);
|
|
43737
|
+
VALUES (?, ?, ?, 0.3, 'consolidation:co-retrieval', ?)
|
|
43738
|
+
`).run(nodeFrom, nodeTo, EDGE_TYPES.CO_RETRIEVED, now);
|
|
43307
43739
|
}
|
|
43308
43740
|
strengthened++;
|
|
43309
43741
|
} catch {
|
|
@@ -43317,6 +43749,7 @@ var init_brain_lifecycle = __esm({
|
|
|
43317
43749
|
"use strict";
|
|
43318
43750
|
init_brain_accessor();
|
|
43319
43751
|
init_typed_query();
|
|
43752
|
+
init_edge_types();
|
|
43320
43753
|
STOP_WORDS3 = /* @__PURE__ */ new Set([
|
|
43321
43754
|
"the",
|
|
43322
43755
|
"a",
|
|
@@ -61645,6 +62078,7 @@ async function listEpicsWithLifecycle(cwd) {
|
|
|
61645
62078
|
// packages/core/src/memory/index.ts
|
|
61646
62079
|
var memory_exports = {};
|
|
61647
62080
|
__export(memory_exports, {
|
|
62081
|
+
EDGE_TYPES: () => EDGE_TYPES,
|
|
61648
62082
|
RRF_K: () => RRF_K,
|
|
61649
62083
|
addResearch: () => addResearch,
|
|
61650
62084
|
appendExtendedManifest: () => appendExtendedManifest,
|
|
@@ -61842,6 +62276,7 @@ function mapImpact(impact) {
|
|
|
61842
62276
|
init_brain_retrieval();
|
|
61843
62277
|
init_brain_search();
|
|
61844
62278
|
init_decisions2();
|
|
62279
|
+
init_edge_types();
|
|
61845
62280
|
|
|
61846
62281
|
// packages/core/src/memory/extraction-gate.ts
|
|
61847
62282
|
init_brain_embedding();
|
|
@@ -70734,6 +71169,7 @@ async function getSyncStatus(remote = "origin", cwd) {
|
|
|
70734
71169
|
// packages/core/src/research/index.ts
|
|
70735
71170
|
var research_exports = {};
|
|
70736
71171
|
__export(research_exports, {
|
|
71172
|
+
EDGE_TYPES: () => EDGE_TYPES,
|
|
70737
71173
|
RRF_K: () => RRF_K,
|
|
70738
71174
|
addResearch: () => addResearch,
|
|
70739
71175
|
appendExtendedManifest: () => appendExtendedManifest,
|