@cleocode/core 2026.4.58 → 2026.4.60
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 +488 -11
- package/dist/index.js.map +3 -3
- package/dist/internal.js +497 -13
- package/dist/internal.js.map +3 -3
- package/dist/memory/graph-queries.d.ts.map +1 -1
- package/dist/store/agent-registry-accessor.d.ts +1 -1
- package/dist/store/brain-accessor.d.ts +57 -1
- package/dist/store/brain-accessor.d.ts.map +1 -1
- package/dist/store/brain-schema.d.ts +738 -0
- package/dist/store/brain-schema.d.ts.map +1 -1
- package/dist/store/brain-sqlite.d.ts.map +1 -1
- package/dist/store/nexus-schema.d.ts +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/validation/doctor/checks.d.ts +7 -0
- package/dist/validation/doctor/checks.d.ts.map +1 -1
- package/migrations/drizzle-brain/20260416000001_t673-retrieval-log-plasticity-columns/migration.sql +57 -0
- package/migrations/drizzle-brain/20260416000002_t673-plasticity-events-expand/migration.sql +44 -0
- package/migrations/drizzle-brain/20260416000003_t673-page-edges-plasticity-columns/migration.sql +44 -0
- package/migrations/drizzle-brain/20260416000004_t673-new-plasticity-tables/migration.sql +73 -0
- package/package.json +8 -8
- package/src/memory/__tests__/brain-retrieval-m1.test.ts +250 -0
- package/src/memory/__tests__/brain-schema-m2-m3.test.ts +418 -0
- package/src/memory/__tests__/brain-schema-m4.test.ts +494 -0
- package/src/memory/brain-retrieval.ts +1 -1
- package/src/memory/graph-queries.ts +14 -0
- package/src/store/agent-registry-accessor.ts +1 -1
- package/src/store/brain-accessor.ts +120 -0
- package/src/store/brain-schema.ts +373 -1
- package/src/store/brain-sqlite.ts +123 -0
- package/src/system/health.ts +4 -1
- package/src/validation/doctor/checks.ts +107 -0
- package/src/validation/protocols/protocols-markdown/research.md +1 -1
package/dist/internal.js
CHANGED
|
@@ -4,10 +4,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b2) => (typeof require !== "undefined" ? require : a)[b2]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
7
13
|
var __esm = (fn2, res) => function __init() {
|
|
8
14
|
return fn2 && (res = (0, fn2[__getOwnPropNames(fn2)[0]])(fn2 = 0)), res;
|
|
9
15
|
};
|
|
10
|
-
var __commonJS = (cb, mod) => function
|
|
16
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
11
17
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
12
18
|
};
|
|
13
19
|
var __export = (target, all) => {
|
|
@@ -9062,9 +9068,11 @@ __export(brain_schema_exports, {
|
|
|
9062
9068
|
BRAIN_STICKY_COLORS: () => BRAIN_STICKY_COLORS,
|
|
9063
9069
|
BRAIN_STICKY_PRIORITIES: () => BRAIN_STICKY_PRIORITIES,
|
|
9064
9070
|
BRAIN_STICKY_STATUSES: () => BRAIN_STICKY_STATUSES,
|
|
9071
|
+
brainConsolidationEvents: () => brainConsolidationEvents,
|
|
9065
9072
|
brainDecisions: () => brainDecisions,
|
|
9066
9073
|
brainLearnings: () => brainLearnings,
|
|
9067
9074
|
brainMemoryLinks: () => brainMemoryLinks,
|
|
9075
|
+
brainModulators: () => brainModulators,
|
|
9068
9076
|
brainObservations: () => brainObservations,
|
|
9069
9077
|
brainPageEdges: () => brainPageEdges,
|
|
9070
9078
|
brainPageNodes: () => brainPageNodes,
|
|
@@ -9072,10 +9080,11 @@ __export(brain_schema_exports, {
|
|
|
9072
9080
|
brainPlasticityEvents: () => brainPlasticityEvents,
|
|
9073
9081
|
brainRetrievalLog: () => brainRetrievalLog,
|
|
9074
9082
|
brainSchemaMeta: () => brainSchemaMeta,
|
|
9075
|
-
brainStickyNotes: () => brainStickyNotes
|
|
9083
|
+
brainStickyNotes: () => brainStickyNotes,
|
|
9084
|
+
brainWeightHistory: () => brainWeightHistory
|
|
9076
9085
|
});
|
|
9077
9086
|
import { sql as sql2 } from "drizzle-orm";
|
|
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;
|
|
9087
|
+
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, brainWeightHistory, brainModulators, brainConsolidationEvents;
|
|
9079
9088
|
var init_brain_schema = __esm({
|
|
9080
9089
|
"packages/core/src/store/brain-schema.ts"() {
|
|
9081
9090
|
"use strict";
|
|
@@ -9581,13 +9590,75 @@ var init_brain_schema = __esm({
|
|
|
9581
9590
|
* 'auto:contradiction-detected' | 'auto:consolidation' | 'manual'
|
|
9582
9591
|
*/
|
|
9583
9592
|
provenance: text("provenance"),
|
|
9584
|
-
createdAt: text("created_at").notNull().default(sql2`(datetime('now'))`)
|
|
9593
|
+
createdAt: text("created_at").notNull().default(sql2`(datetime('now'))`),
|
|
9594
|
+
// === T673-M3: Plasticity tracking columns ===
|
|
9595
|
+
/**
|
|
9596
|
+
* ISO 8601 timestamp of the last LTP event applied to this edge.
|
|
9597
|
+
* Used by the decay pass: edges with (now - last_reinforced_at) > decay_threshold_days
|
|
9598
|
+
* receive a per-day weight decay. Null = never reinforced (structural/semantic edges).
|
|
9599
|
+
* Only populated when plasticity_class IN ('hebbian', 'stdp').
|
|
9600
|
+
*
|
|
9601
|
+
* @task T706
|
|
9602
|
+
*/
|
|
9603
|
+
lastReinforcedAt: text("last_reinforced_at"),
|
|
9604
|
+
/**
|
|
9605
|
+
* Count of LTP (potentiation) events applied to this edge lifetime.
|
|
9606
|
+
* Incremented on every LTP write. Used to compute stability_score.
|
|
9607
|
+
*
|
|
9608
|
+
* @task T706
|
|
9609
|
+
*/
|
|
9610
|
+
reinforcementCount: integer("reinforcement_count").notNull().default(0),
|
|
9611
|
+
/**
|
|
9612
|
+
* Plasticity class governing which algorithm(s) write to this edge.
|
|
9613
|
+
*
|
|
9614
|
+
* - 'static': Non-plastic edge (structural, semantic, etc.). Immune to decay.
|
|
9615
|
+
* - 'hebbian': Written by strengthenCoRetrievedEdges. Subject to decay.
|
|
9616
|
+
* - 'stdp': Written or refined by applyStdpPlasticity. Subject to decay + LTD.
|
|
9617
|
+
*
|
|
9618
|
+
* Edges start 'static' for all non-co_retrieved types.
|
|
9619
|
+
* co_retrieved edges start 'hebbian' (seeded by M3 migration), can upgrade to 'stdp'.
|
|
9620
|
+
*
|
|
9621
|
+
* @task T706
|
|
9622
|
+
*/
|
|
9623
|
+
plasticityClass: text("plasticity_class", {
|
|
9624
|
+
enum: ["static", "hebbian", "stdp"]
|
|
9625
|
+
}).notNull().default("static"),
|
|
9626
|
+
/**
|
|
9627
|
+
* ISO 8601 timestamp of the last LTD (depression) event on this edge.
|
|
9628
|
+
* Null = never depressed. Used for debugging and Studio viz animation.
|
|
9629
|
+
*
|
|
9630
|
+
* @task T706
|
|
9631
|
+
*/
|
|
9632
|
+
lastDepressedAt: text("last_depressed_at"),
|
|
9633
|
+
/**
|
|
9634
|
+
* Count of LTD (depression) events applied to this edge lifetime.
|
|
9635
|
+
* Enables analysis of edges that are persistently weakened.
|
|
9636
|
+
*
|
|
9637
|
+
* @task T706
|
|
9638
|
+
*/
|
|
9639
|
+
depressionCount: integer("depression_count").notNull().default(0),
|
|
9640
|
+
/**
|
|
9641
|
+
* Biological-analog stability score: 0.0 (unstable) – 1.0 (consolidated).
|
|
9642
|
+
*
|
|
9643
|
+
* Computed by runConsolidation decay pass as:
|
|
9644
|
+
* stability = tanh(reinforcement_count / 10) × exp(-(days_since_reinforced / 30))
|
|
9645
|
+
*
|
|
9646
|
+
* Null = not yet computed (new edges). Enables fast filtering in decay pass:
|
|
9647
|
+
* edges with stability > 0.9 skip the full decay recalculation.
|
|
9648
|
+
* Updated at session-end consolidation, NOT per-event.
|
|
9649
|
+
*
|
|
9650
|
+
* @task T706
|
|
9651
|
+
*/
|
|
9652
|
+
stabilityScore: real("stability_score")
|
|
9585
9653
|
},
|
|
9586
9654
|
(table) => [
|
|
9587
9655
|
primaryKey({ columns: [table.fromId, table.toId, table.edgeType] }),
|
|
9588
9656
|
index("idx_brain_edges_from").on(table.fromId),
|
|
9589
9657
|
index("idx_brain_edges_to").on(table.toId),
|
|
9590
|
-
index("idx_brain_edges_type").on(table.edgeType)
|
|
9658
|
+
index("idx_brain_edges_type").on(table.edgeType),
|
|
9659
|
+
index("idx_brain_edges_last_reinforced").on(table.lastReinforcedAt),
|
|
9660
|
+
index("idx_brain_edges_plasticity_class").on(table.plasticityClass),
|
|
9661
|
+
index("idx_brain_edges_stability").on(table.stabilityScore)
|
|
9591
9662
|
]
|
|
9592
9663
|
);
|
|
9593
9664
|
brainRetrievalLog = sqliteTable(
|
|
@@ -9596,7 +9667,12 @@ var init_brain_schema = __esm({
|
|
|
9596
9667
|
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
9597
9668
|
/** The search query or fetch IDs that triggered this retrieval. */
|
|
9598
9669
|
query: text("query").notNull(),
|
|
9599
|
-
/**
|
|
9670
|
+
/**
|
|
9671
|
+
* JSON array of entry IDs returned in this retrieval.
|
|
9672
|
+
* Stored as JSON array string: '["obs:A","obs:B"]'.
|
|
9673
|
+
* Always write with JSON.stringify() — NEVER join(',').
|
|
9674
|
+
* Readers call JSON.parse(). Migration M1 converts any pre-existing CSV rows.
|
|
9675
|
+
*/
|
|
9600
9676
|
entryIds: text("entry_ids").notNull(),
|
|
9601
9677
|
/** Number of entries returned. */
|
|
9602
9678
|
entryCount: integer("entry_count").notNull(),
|
|
@@ -9606,12 +9682,26 @@ var init_brain_schema = __esm({
|
|
|
9606
9682
|
tokensUsed: integer("tokens_used"),
|
|
9607
9683
|
/** Session ID (soft FK to tasks.db sessions). Enables grouping retrievals by session for STDP analysis. */
|
|
9608
9684
|
sessionId: text("session_id"),
|
|
9609
|
-
createdAt: text("created_at").notNull().default(sql2`(datetime('now'))`)
|
|
9685
|
+
createdAt: text("created_at").notNull().default(sql2`(datetime('now'))`),
|
|
9686
|
+
// === T673-M1: STDP plasticity columns ===
|
|
9687
|
+
/** Sequence position of this retrieval within a batch query (0-based). */
|
|
9688
|
+
retrievalOrder: integer("retrieval_order"),
|
|
9689
|
+
/** Wall-clock ms since the previous retrieval row in the same batch. */
|
|
9690
|
+
deltaMs: integer("delta_ms"),
|
|
9691
|
+
/**
|
|
9692
|
+
* R-STDP reward signal: scalar [-1.0, +1.0], null = unlabeled.
|
|
9693
|
+
* Populated by backfillRewardSignals() at session end (Step 9a).
|
|
9694
|
+
* +1.0 = task verified and passed | +0.5 = done (unverified) | -0.5 = cancelled.
|
|
9695
|
+
* Per D-BRAIN-VIZ-13. backfillRewardSignals MUST skip rows where
|
|
9696
|
+
* session_id LIKE 'ses_backfill_%' (synthetic historical sessions, no task correlation).
|
|
9697
|
+
*/
|
|
9698
|
+
rewardSignal: real("reward_signal")
|
|
9610
9699
|
},
|
|
9611
9700
|
(table) => [
|
|
9612
9701
|
index("idx_retrieval_log_created").on(table.createdAt),
|
|
9613
9702
|
index("idx_retrieval_log_source").on(table.source),
|
|
9614
|
-
index("idx_retrieval_log_session").on(table.sessionId)
|
|
9703
|
+
index("idx_retrieval_log_session").on(table.sessionId),
|
|
9704
|
+
index("idx_retrieval_log_reward").on(table.rewardSignal)
|
|
9615
9705
|
]
|
|
9616
9706
|
);
|
|
9617
9707
|
brainPlasticityEvents = sqliteTable(
|
|
@@ -9635,14 +9725,182 @@ var init_brain_schema = __esm({
|
|
|
9635
9725
|
/** ISO 8601 timestamp when this event was applied. */
|
|
9636
9726
|
timestamp: text("timestamp").notNull().default(sql2`(datetime('now'))`),
|
|
9637
9727
|
/** Session ID that triggered the STDP pass, if available. */
|
|
9638
|
-
sessionId: text("session_id")
|
|
9728
|
+
sessionId: text("session_id"),
|
|
9729
|
+
// === T673-M2: Observability columns ===
|
|
9730
|
+
/**
|
|
9731
|
+
* Edge weight immediately BEFORE this plasticity event was applied.
|
|
9732
|
+
* Null on the first LTP event that inserts a new edge (edge didn't exist).
|
|
9733
|
+
* Enables "show learning history" in Studio viz without querying brain_weight_history.
|
|
9734
|
+
*
|
|
9735
|
+
* @task T696
|
|
9736
|
+
*/
|
|
9737
|
+
weightBefore: real("weight_before"),
|
|
9738
|
+
/**
|
|
9739
|
+
* Edge weight immediately AFTER this plasticity event was applied.
|
|
9740
|
+
* Computed as CLAMP(weight_before + delta_w, 0.0, 1.0).
|
|
9741
|
+
* Redundant with delta_w but enables fast before/after display without arithmetic.
|
|
9742
|
+
*
|
|
9743
|
+
* @task T696
|
|
9744
|
+
*/
|
|
9745
|
+
weightAfter: real("weight_after"),
|
|
9746
|
+
/**
|
|
9747
|
+
* Soft FK to brain_retrieval_log.id — the retrieval row that triggered this pair.
|
|
9748
|
+
* Null for externally-triggered or legacy events.
|
|
9749
|
+
* Enables: "which memory retrieval caused this edge to strengthen?"
|
|
9750
|
+
*
|
|
9751
|
+
* @task T696
|
|
9752
|
+
*/
|
|
9753
|
+
retrievalLogId: integer("retrieval_log_id"),
|
|
9754
|
+
/**
|
|
9755
|
+
* R-STDP reward signal active when this event fired.
|
|
9756
|
+
* Copied from the retrieval_log row's reward_signal at time of plasticity pass.
|
|
9757
|
+
* Null = unmodulated. Denormalized for fast filtering without a JOIN.
|
|
9758
|
+
*
|
|
9759
|
+
* @task T696
|
|
9760
|
+
*/
|
|
9761
|
+
rewardSignal: real("reward_signal"),
|
|
9762
|
+
/**
|
|
9763
|
+
* Wall-clock milliseconds between the two spikes that generated this event.
|
|
9764
|
+
* Pre-computed at INSERT time — avoids re-deriving from retrieval timestamps.
|
|
9765
|
+
* Enables analysis of STDP window distribution.
|
|
9766
|
+
*
|
|
9767
|
+
* @task T696
|
|
9768
|
+
*/
|
|
9769
|
+
deltaTMs: integer("delta_t_ms")
|
|
9639
9770
|
},
|
|
9640
9771
|
(table) => [
|
|
9641
9772
|
index("idx_plasticity_source").on(table.sourceNode),
|
|
9642
9773
|
index("idx_plasticity_target").on(table.targetNode),
|
|
9643
9774
|
index("idx_plasticity_timestamp").on(table.timestamp),
|
|
9644
9775
|
index("idx_plasticity_session").on(table.sessionId),
|
|
9645
|
-
index("idx_plasticity_kind").on(table.kind)
|
|
9776
|
+
index("idx_plasticity_kind").on(table.kind),
|
|
9777
|
+
index("idx_plasticity_retrieval_log").on(table.retrievalLogId),
|
|
9778
|
+
index("idx_plasticity_reward").on(table.rewardSignal)
|
|
9779
|
+
]
|
|
9780
|
+
);
|
|
9781
|
+
brainWeightHistory = sqliteTable(
|
|
9782
|
+
"brain_weight_history",
|
|
9783
|
+
{
|
|
9784
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
9785
|
+
/** from_id of the affected brain_page_edges row. */
|
|
9786
|
+
edgeFromId: text("edge_from_id").notNull(),
|
|
9787
|
+
/** to_id of the affected brain_page_edges row. */
|
|
9788
|
+
edgeToId: text("edge_to_id").notNull(),
|
|
9789
|
+
/** Edge type of the affected brain_page_edges row (e.g. 'co_retrieved'). */
|
|
9790
|
+
edgeType: text("edge_type").notNull(),
|
|
9791
|
+
/** Edge weight immediately before this event. Null if the edge was just created. */
|
|
9792
|
+
weightBefore: real("weight_before"),
|
|
9793
|
+
/** Edge weight after this event. CLAMP(weightBefore + deltaWeight, 0, 1). NOT NULL. */
|
|
9794
|
+
weightAfter: real("weight_after").notNull(),
|
|
9795
|
+
/**
|
|
9796
|
+
* Signed weight delta applied to the edge.
|
|
9797
|
+
* Positive = potentiation (LTP/Hebbian), negative = depression (LTD).
|
|
9798
|
+
* Prune events record the final weight that triggered deletion (negative).
|
|
9799
|
+
*/
|
|
9800
|
+
deltaWeight: real("delta_weight").notNull(),
|
|
9801
|
+
/**
|
|
9802
|
+
* Plasticity event kind.
|
|
9803
|
+
* 'ltp' — Long-Term Potentiation (STDP pre-before-post)
|
|
9804
|
+
* 'ltd' — Long-Term Depression (STDP post-before-pre)
|
|
9805
|
+
* 'hebbian' — Co-retrieval Hebbian strengthening
|
|
9806
|
+
* 'decay' — Temporal decay (only prune-triggering decays written here)
|
|
9807
|
+
* 'prune' — Edge deleted (weight fell below min_weight threshold)
|
|
9808
|
+
* 'external' — Manually-applied external weight change
|
|
9809
|
+
*/
|
|
9810
|
+
eventKind: text("event_kind").notNull(),
|
|
9811
|
+
/** Soft FK to brain_plasticity_events.id — the STDP event that caused this. */
|
|
9812
|
+
sourcePlasticityEventId: integer("source_plasticity_event_id"),
|
|
9813
|
+
/** Soft FK to brain_retrieval_log.id — the retrieval batch that triggered this. */
|
|
9814
|
+
retrievalLogId: integer("retrieval_log_id"),
|
|
9815
|
+
/** R-STDP reward signal at time of event (copied from retrieval_log.reward_signal). */
|
|
9816
|
+
rewardSignal: real("reward_signal"),
|
|
9817
|
+
/** ISO 8601 timestamp when this weight change was applied. */
|
|
9818
|
+
changedAt: text("changed_at").notNull().default(sql2`(datetime('now'))`)
|
|
9819
|
+
},
|
|
9820
|
+
(table) => [
|
|
9821
|
+
index("idx_weight_history_edge").on(table.edgeFromId, table.edgeToId, table.edgeType),
|
|
9822
|
+
index("idx_weight_history_from").on(table.edgeFromId),
|
|
9823
|
+
index("idx_weight_history_to").on(table.edgeToId),
|
|
9824
|
+
index("idx_weight_history_changed_at").on(table.changedAt),
|
|
9825
|
+
index("idx_weight_history_event_kind").on(table.eventKind),
|
|
9826
|
+
index("idx_weight_history_plasticity_event").on(table.sourcePlasticityEventId)
|
|
9827
|
+
]
|
|
9828
|
+
);
|
|
9829
|
+
brainModulators = sqliteTable(
|
|
9830
|
+
"brain_modulators",
|
|
9831
|
+
{
|
|
9832
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
9833
|
+
/**
|
|
9834
|
+
* Modulator event type. String (not enum constraint) for extensibility.
|
|
9835
|
+
* Expected values: 'task_verified'|'task_completed'|'task_cancelled'|
|
|
9836
|
+
* 'owner_verify'|'session_success'|'session_blocker'|'external'
|
|
9837
|
+
*/
|
|
9838
|
+
modulatorType: text("modulator_type").notNull(),
|
|
9839
|
+
/**
|
|
9840
|
+
* Reward valence in range [-1.0, +1.0].
|
|
9841
|
+
* +1.0 = strong reward (verified correct task)
|
|
9842
|
+
* +0.5 = moderate reward (done, unverified)
|
|
9843
|
+
* -0.5 = mild correction (cancelled task)
|
|
9844
|
+
* -1.0 = strong correction (explicit invalidation)
|
|
9845
|
+
* 0.0 = neutral signal
|
|
9846
|
+
*/
|
|
9847
|
+
valence: real("valence").notNull(),
|
|
9848
|
+
/**
|
|
9849
|
+
* Magnitude 0.0–1.0 confidence scaling.
|
|
9850
|
+
* Effective reward = valence × magnitude.
|
|
9851
|
+
* Defaults to 1.0 (full confidence).
|
|
9852
|
+
*/
|
|
9853
|
+
magnitude: real("magnitude").notNull().default(1),
|
|
9854
|
+
/** Polymorphic source event ID — task ID, memory entry ID, or other string ref. */
|
|
9855
|
+
sourceEventId: text("source_event_id"),
|
|
9856
|
+
/** Session ID (soft FK to tasks.db sessions). */
|
|
9857
|
+
sessionId: text("session_id"),
|
|
9858
|
+
/** Human-readable description of why this modulator was emitted. */
|
|
9859
|
+
description: text("description"),
|
|
9860
|
+
/** ISO 8601 timestamp when this modulator event was recorded. */
|
|
9861
|
+
createdAt: text("created_at").notNull().default(sql2`(datetime('now'))`)
|
|
9862
|
+
},
|
|
9863
|
+
(table) => [
|
|
9864
|
+
index("idx_modulators_type").on(table.modulatorType),
|
|
9865
|
+
index("idx_modulators_session").on(table.sessionId),
|
|
9866
|
+
index("idx_modulators_created_at").on(table.createdAt),
|
|
9867
|
+
index("idx_modulators_source_event").on(table.sourceEventId),
|
|
9868
|
+
index("idx_modulators_valence").on(table.valence)
|
|
9869
|
+
]
|
|
9870
|
+
);
|
|
9871
|
+
brainConsolidationEvents = sqliteTable(
|
|
9872
|
+
"brain_consolidation_events",
|
|
9873
|
+
{
|
|
9874
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
9875
|
+
/**
|
|
9876
|
+
* What triggered this consolidation run. String (not enum constraint) for
|
|
9877
|
+
* forward compatibility with T628 scheduler.
|
|
9878
|
+
* Expected values: 'session_end' | 'maintenance' | 'scheduled' | 'manual'
|
|
9879
|
+
*/
|
|
9880
|
+
trigger: text("trigger").notNull(),
|
|
9881
|
+
/** Session ID that initiated this consolidation (soft FK to tasks.db sessions). */
|
|
9882
|
+
sessionId: text("session_id"),
|
|
9883
|
+
/**
|
|
9884
|
+
* JSON-serialized ConsolidationResult — all per-step counts and metrics.
|
|
9885
|
+
* Shape: { [stepName: string]: { count: number, durationMs?: number } }
|
|
9886
|
+
* Required NOT NULL — every run must record its results for T628 scheduling.
|
|
9887
|
+
*/
|
|
9888
|
+
stepResultsJson: text("step_results_json").notNull(),
|
|
9889
|
+
/** Wall-clock milliseconds from start to completion. Null if run did not complete. */
|
|
9890
|
+
durationMs: integer("duration_ms"),
|
|
9891
|
+
/**
|
|
9892
|
+
* Whether the run succeeded.
|
|
9893
|
+
* Stored as integer(boolean) per Drizzle SQLite boolean convention.
|
|
9894
|
+
* true = completed without unhandled error, false = partial or error.
|
|
9895
|
+
*/
|
|
9896
|
+
succeeded: integer("succeeded", { mode: "boolean" }).notNull().default(true),
|
|
9897
|
+
/** ISO 8601 timestamp when this consolidation run started. */
|
|
9898
|
+
startedAt: text("started_at").notNull().default(sql2`(datetime('now'))`)
|
|
9899
|
+
},
|
|
9900
|
+
(table) => [
|
|
9901
|
+
index("idx_consolidation_events_started_at").on(table.startedAt),
|
|
9902
|
+
index("idx_consolidation_events_trigger").on(table.trigger),
|
|
9903
|
+
index("idx_consolidation_events_session").on(table.sessionId)
|
|
9646
9904
|
]
|
|
9647
9905
|
);
|
|
9648
9906
|
}
|
|
@@ -15061,6 +15319,108 @@ function runBrainMigrations(nativeDb, db) {
|
|
|
15061
15319
|
AND provenance LIKE 'consolidation:%'`
|
|
15062
15320
|
).run();
|
|
15063
15321
|
}
|
|
15322
|
+
if (tableExists(nativeDb, "brain_retrieval_log")) {
|
|
15323
|
+
ensureColumns(
|
|
15324
|
+
nativeDb,
|
|
15325
|
+
"brain_retrieval_log",
|
|
15326
|
+
[
|
|
15327
|
+
{ name: "session_id", ddl: "text" },
|
|
15328
|
+
{ name: "reward_signal", ddl: "real" },
|
|
15329
|
+
{ name: "retrieval_order", ddl: "integer" },
|
|
15330
|
+
{ name: "delta_ms", ddl: "integer" }
|
|
15331
|
+
],
|
|
15332
|
+
"brain"
|
|
15333
|
+
);
|
|
15334
|
+
}
|
|
15335
|
+
if (tableExists(nativeDb, "brain_plasticity_events")) {
|
|
15336
|
+
ensureColumns(
|
|
15337
|
+
nativeDb,
|
|
15338
|
+
"brain_plasticity_events",
|
|
15339
|
+
[
|
|
15340
|
+
{ name: "session_id", ddl: "text" },
|
|
15341
|
+
{ name: "weight_before", ddl: "real" },
|
|
15342
|
+
{ name: "weight_after", ddl: "real" },
|
|
15343
|
+
{ name: "retrieval_log_id", ddl: "integer" },
|
|
15344
|
+
{ name: "reward_signal", ddl: "real" },
|
|
15345
|
+
{ name: "delta_t_ms", ddl: "integer" }
|
|
15346
|
+
],
|
|
15347
|
+
"brain"
|
|
15348
|
+
);
|
|
15349
|
+
}
|
|
15350
|
+
ensureColumns(
|
|
15351
|
+
nativeDb,
|
|
15352
|
+
"brain_page_edges",
|
|
15353
|
+
[
|
|
15354
|
+
{ name: "last_reinforced_at", ddl: "text" },
|
|
15355
|
+
{ name: "reinforcement_count", ddl: "integer NOT NULL DEFAULT 0" },
|
|
15356
|
+
{ name: "plasticity_class", ddl: "text NOT NULL DEFAULT 'static'" },
|
|
15357
|
+
{ name: "last_depressed_at", ddl: "text" },
|
|
15358
|
+
{ name: "depression_count", ddl: "integer NOT NULL DEFAULT 0" },
|
|
15359
|
+
{ name: "stability_score", ddl: "real" }
|
|
15360
|
+
],
|
|
15361
|
+
"brain"
|
|
15362
|
+
);
|
|
15363
|
+
if (tableExists(nativeDb, "brain_page_edges")) {
|
|
15364
|
+
nativeDb.prepare(
|
|
15365
|
+
`UPDATE brain_page_edges SET plasticity_class = 'hebbian'
|
|
15366
|
+
WHERE edge_type = 'co_retrieved' AND plasticity_class = 'static'`
|
|
15367
|
+
).run();
|
|
15368
|
+
}
|
|
15369
|
+
nativeDb.exec(
|
|
15370
|
+
`CREATE TABLE IF NOT EXISTS brain_weight_history (
|
|
15371
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
15372
|
+
edge_from_id TEXT NOT NULL,
|
|
15373
|
+
edge_to_id TEXT NOT NULL,
|
|
15374
|
+
edge_type TEXT NOT NULL,
|
|
15375
|
+
weight_before REAL,
|
|
15376
|
+
weight_after REAL NOT NULL,
|
|
15377
|
+
delta_weight REAL NOT NULL,
|
|
15378
|
+
event_kind TEXT NOT NULL,
|
|
15379
|
+
source_plasticity_event_id INTEGER,
|
|
15380
|
+
retrieval_log_id INTEGER,
|
|
15381
|
+
reward_signal REAL,
|
|
15382
|
+
changed_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
15383
|
+
)`
|
|
15384
|
+
);
|
|
15385
|
+
nativeDb.exec(
|
|
15386
|
+
`CREATE INDEX IF NOT EXISTS idx_weight_history_edge
|
|
15387
|
+
ON brain_weight_history (edge_from_id, edge_to_id, edge_type)`
|
|
15388
|
+
);
|
|
15389
|
+
nativeDb.exec(
|
|
15390
|
+
`CREATE INDEX IF NOT EXISTS idx_weight_history_changed_at
|
|
15391
|
+
ON brain_weight_history (changed_at)`
|
|
15392
|
+
);
|
|
15393
|
+
nativeDb.exec(
|
|
15394
|
+
`CREATE TABLE IF NOT EXISTS brain_modulators (
|
|
15395
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
15396
|
+
modulator_type TEXT NOT NULL,
|
|
15397
|
+
valence REAL NOT NULL,
|
|
15398
|
+
magnitude REAL NOT NULL DEFAULT 1.0,
|
|
15399
|
+
source_event_id TEXT,
|
|
15400
|
+
session_id TEXT,
|
|
15401
|
+
description TEXT,
|
|
15402
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
15403
|
+
)`
|
|
15404
|
+
);
|
|
15405
|
+
nativeDb.exec(
|
|
15406
|
+
`CREATE INDEX IF NOT EXISTS idx_modulators_session
|
|
15407
|
+
ON brain_modulators (session_id)`
|
|
15408
|
+
);
|
|
15409
|
+
nativeDb.exec(
|
|
15410
|
+
`CREATE TABLE IF NOT EXISTS brain_consolidation_events (
|
|
15411
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
15412
|
+
trigger TEXT NOT NULL,
|
|
15413
|
+
session_id TEXT,
|
|
15414
|
+
step_results_json TEXT NOT NULL,
|
|
15415
|
+
duration_ms INTEGER,
|
|
15416
|
+
succeeded INTEGER NOT NULL DEFAULT 1,
|
|
15417
|
+
started_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
15418
|
+
)`
|
|
15419
|
+
);
|
|
15420
|
+
nativeDb.exec(
|
|
15421
|
+
`CREATE INDEX IF NOT EXISTS idx_consolidation_events_started_at
|
|
15422
|
+
ON brain_consolidation_events (started_at)`
|
|
15423
|
+
);
|
|
15064
15424
|
}
|
|
15065
15425
|
function loadBrainVecExtension(nativeDb) {
|
|
15066
15426
|
try {
|
|
@@ -17392,13 +17752,48 @@ var init_pagination = __esm({
|
|
|
17392
17752
|
var brain_accessor_exports = {};
|
|
17393
17753
|
__export(brain_accessor_exports, {
|
|
17394
17754
|
BrainDataAccessor: () => BrainDataAccessor,
|
|
17395
|
-
getBrainAccessor: () => getBrainAccessor
|
|
17755
|
+
getBrainAccessor: () => getBrainAccessor,
|
|
17756
|
+
insertModulatorRow: () => insertModulatorRow,
|
|
17757
|
+
insertWeightHistoryRow: () => insertWeightHistoryRow,
|
|
17758
|
+
logConsolidationComplete: () => logConsolidationComplete,
|
|
17759
|
+
logConsolidationStart: () => logConsolidationStart
|
|
17396
17760
|
});
|
|
17397
17761
|
import { and as and5, asc as asc2, desc as desc2, eq as eq7, gte as gte2, or as or4 } from "drizzle-orm";
|
|
17398
17762
|
async function getBrainAccessor(cwd) {
|
|
17399
17763
|
const db = await getBrainDb(cwd);
|
|
17400
17764
|
return new BrainDataAccessor(db);
|
|
17401
17765
|
}
|
|
17766
|
+
async function insertWeightHistoryRow(cwd, input) {
|
|
17767
|
+
const db = await getBrainDb(cwd);
|
|
17768
|
+
const result = await db.insert(brainWeightHistory).values(input).returning();
|
|
17769
|
+
return result[0];
|
|
17770
|
+
}
|
|
17771
|
+
async function insertModulatorRow(cwd, input) {
|
|
17772
|
+
const db = await getBrainDb(cwd);
|
|
17773
|
+
const result = await db.insert(brainModulators).values(input).returning();
|
|
17774
|
+
return result[0];
|
|
17775
|
+
}
|
|
17776
|
+
async function logConsolidationStart(cwd, trigger, sessionId) {
|
|
17777
|
+
const db = await getBrainDb(cwd);
|
|
17778
|
+
const result = await db.insert(brainConsolidationEvents).values({
|
|
17779
|
+
trigger,
|
|
17780
|
+
sessionId: sessionId ?? null,
|
|
17781
|
+
// stepResultsJson is required NOT NULL — use empty object as placeholder
|
|
17782
|
+
// until logConsolidationComplete updates it with final step results.
|
|
17783
|
+
stepResultsJson: "{}",
|
|
17784
|
+
succeeded: true
|
|
17785
|
+
}).returning({ id: brainConsolidationEvents.id });
|
|
17786
|
+
return result[0].id;
|
|
17787
|
+
}
|
|
17788
|
+
async function logConsolidationComplete(cwd, id, stats2, durationMs, succeeded = true) {
|
|
17789
|
+
const db = await getBrainDb(cwd);
|
|
17790
|
+
const result = await db.update(brainConsolidationEvents).set({
|
|
17791
|
+
stepResultsJson: JSON.stringify(stats2),
|
|
17792
|
+
durationMs,
|
|
17793
|
+
succeeded
|
|
17794
|
+
}).where(eq7(brainConsolidationEvents.id, id)).returning();
|
|
17795
|
+
return result[0];
|
|
17796
|
+
}
|
|
17402
17797
|
var BrainDataAccessor;
|
|
17403
17798
|
var init_brain_accessor = __esm({
|
|
17404
17799
|
"packages/core/src/store/brain-accessor.ts"() {
|
|
@@ -49591,7 +49986,7 @@ async function logRetrieval(projectRoot, query, entryIds, source, tokensUsed, se
|
|
|
49591
49986
|
"INSERT INTO brain_retrieval_log (query, entry_ids, entry_count, source, tokens_used, session_id) VALUES (?, ?, ?, ?, ?, ?)"
|
|
49592
49987
|
).run(
|
|
49593
49988
|
query,
|
|
49594
|
-
|
|
49989
|
+
JSON.stringify(entryIds),
|
|
49595
49990
|
entryIds.length,
|
|
49596
49991
|
source,
|
|
49597
49992
|
tokensUsed ?? null,
|
|
@@ -58547,7 +58942,14 @@ function mapEdge(raw) {
|
|
|
58547
58942
|
edgeType: raw.edge_type,
|
|
58548
58943
|
weight: raw.weight,
|
|
58549
58944
|
provenance: raw.provenance,
|
|
58550
|
-
createdAt: raw.created_at
|
|
58945
|
+
createdAt: raw.created_at,
|
|
58946
|
+
// T673-M3 plasticity columns (default to neutral values if absent from SELECT)
|
|
58947
|
+
lastReinforcedAt: raw.last_reinforced_at ?? null,
|
|
58948
|
+
reinforcementCount: raw.reinforcement_count ?? 0,
|
|
58949
|
+
plasticityClass: raw.plasticity_class ?? "static",
|
|
58950
|
+
lastDepressedAt: raw.last_depressed_at ?? null,
|
|
58951
|
+
depressionCount: raw.depression_count ?? 0,
|
|
58952
|
+
stabilityScore: raw.stability_score ?? null
|
|
58551
58953
|
};
|
|
58552
58954
|
}
|
|
58553
58955
|
async function traceBrainGraph(projectRoot, nodeId, maxDepth = 3) {
|
|
@@ -88774,6 +89176,85 @@ function checkLegacyAgentOutputs(projectRoot) {
|
|
|
88774
89176
|
fix: null
|
|
88775
89177
|
};
|
|
88776
89178
|
}
|
|
89179
|
+
function checkCanonicalRcasdPaths(projectRoot) {
|
|
89180
|
+
const root = projectRoot ?? process.cwd();
|
|
89181
|
+
const cleoDir = join92(root, ".cleo");
|
|
89182
|
+
const failures = [];
|
|
89183
|
+
const deprecatedDirs = ["research", "consensus", "specs", "decomposition"];
|
|
89184
|
+
for (const dir of deprecatedDirs) {
|
|
89185
|
+
const dirPath = join92(cleoDir, dir);
|
|
89186
|
+
if (existsSync91(dirPath)) {
|
|
89187
|
+
try {
|
|
89188
|
+
const entries = __require("node:fs").readdirSync(dirPath).filter(
|
|
89189
|
+
(e) => !e.startsWith(".")
|
|
89190
|
+
);
|
|
89191
|
+
if (entries.length > 0) {
|
|
89192
|
+
failures.push(
|
|
89193
|
+
`deprecated .cleo/${dir}/ contains files (should migrate to .cleo/rcasd/{epicId}/${dir}/)`
|
|
89194
|
+
);
|
|
89195
|
+
}
|
|
89196
|
+
} catch {
|
|
89197
|
+
}
|
|
89198
|
+
}
|
|
89199
|
+
}
|
|
89200
|
+
const rcasdPath = join92(cleoDir, "rcasd");
|
|
89201
|
+
if (existsSync91(rcasdPath)) {
|
|
89202
|
+
try {
|
|
89203
|
+
const rootFiles = __require("node:fs").readdirSync(rcasdPath).filter(
|
|
89204
|
+
(e) => e.endsWith(".md")
|
|
89205
|
+
);
|
|
89206
|
+
if (rootFiles.length > 0) {
|
|
89207
|
+
failures.push(
|
|
89208
|
+
`misplaced .md files in .cleo/rcasd/ root (audit-*.md, etc. should be in .cleo/agent-outputs/)`
|
|
89209
|
+
);
|
|
89210
|
+
}
|
|
89211
|
+
} catch {
|
|
89212
|
+
}
|
|
89213
|
+
}
|
|
89214
|
+
const claudedocsPath = join92(root, "claudedocs");
|
|
89215
|
+
if (existsSync91(claudedocsPath)) {
|
|
89216
|
+
try {
|
|
89217
|
+
const agentOutputs = join92(claudedocsPath, "agent-outputs");
|
|
89218
|
+
if (existsSync91(agentOutputs)) {
|
|
89219
|
+
failures.push(
|
|
89220
|
+
`legacy claudedocs/agent-outputs/ directory exists (should migrate to .cleo/agent-outputs/)`
|
|
89221
|
+
);
|
|
89222
|
+
}
|
|
89223
|
+
} catch {
|
|
89224
|
+
}
|
|
89225
|
+
}
|
|
89226
|
+
if (failures.length > 0) {
|
|
89227
|
+
return {
|
|
89228
|
+
id: "canonical_rcasd_paths",
|
|
89229
|
+
category: "configuration",
|
|
89230
|
+
status: "warning",
|
|
89231
|
+
message: `Canonical path drift detected (ADR-045): ${failures.join("; ")}`,
|
|
89232
|
+
details: {
|
|
89233
|
+
issues: failures,
|
|
89234
|
+
canonical: {
|
|
89235
|
+
rcasdStages: ".cleo/rcasd/{epicId}/{stage}/{epicId}-{stage}.md",
|
|
89236
|
+
agentOutputs: ".cleo/agent-outputs/{taskId}-{slug}.md",
|
|
89237
|
+
publishedSpecs: "docs/specs/SPEC-NAME.md"
|
|
89238
|
+
}
|
|
89239
|
+
},
|
|
89240
|
+
fix: "cleo upgrade (migrates old paths) or manually move files per ADR-045"
|
|
89241
|
+
};
|
|
89242
|
+
}
|
|
89243
|
+
return {
|
|
89244
|
+
id: "canonical_rcasd_paths",
|
|
89245
|
+
category: "configuration",
|
|
89246
|
+
status: "passed",
|
|
89247
|
+
message: "All artifacts at canonical RCASD paths (ADR-045 compliant)",
|
|
89248
|
+
details: {
|
|
89249
|
+
canonical: {
|
|
89250
|
+
rcasdStages: ".cleo/rcasd/{epicId}/{stage}/{epicId}-{stage}.md",
|
|
89251
|
+
agentOutputs: ".cleo/agent-outputs/{taskId}-{slug}.md",
|
|
89252
|
+
publishedSpecs: "docs/specs/SPEC-NAME.md"
|
|
89253
|
+
}
|
|
89254
|
+
},
|
|
89255
|
+
fix: null
|
|
89256
|
+
};
|
|
89257
|
+
}
|
|
88777
89258
|
function checkCaampMarkerIntegrity(projectRoot) {
|
|
88778
89259
|
const root = projectRoot ?? process.cwd();
|
|
88779
89260
|
const files = ["CLAUDE.md", "AGENTS.md"];
|
|
@@ -89086,6 +89567,8 @@ function runAllGlobalChecks(cleoHome, projectRoot) {
|
|
|
89086
89567
|
checkCoreFilesNotIgnored(projectRoot),
|
|
89087
89568
|
checkSqliteNotTracked(projectRoot),
|
|
89088
89569
|
checkLegacyAgentOutputs(projectRoot),
|
|
89570
|
+
// ADR-045 canonical paths check (T708)
|
|
89571
|
+
checkCanonicalRcasdPaths(projectRoot),
|
|
89089
89572
|
// Injection chain checks (T5153)
|
|
89090
89573
|
checkCaampMarkerIntegrity(projectRoot),
|
|
89091
89574
|
checkAtReferenceTargetExists(projectRoot),
|
|
@@ -89646,6 +90129,7 @@ async function coreDoctorReport(projectRoot) {
|
|
|
89646
90129
|
checks.push(mapCheckResult(checkVitalFilesTracked(projectRoot)));
|
|
89647
90130
|
checks.push(mapCheckResult(checkCoreFilesNotIgnored(projectRoot)));
|
|
89648
90131
|
checks.push(mapCheckResult(checkLegacyAgentOutputs(projectRoot)));
|
|
90132
|
+
checks.push(mapCheckResult(checkCanonicalRcasdPaths(projectRoot)));
|
|
89649
90133
|
const cleoGitHeadExists = existsSync92(join93(cleoDir, ".git", "HEAD"));
|
|
89650
90134
|
checks.push({
|
|
89651
90135
|
check: "cleo_git_repo",
|