@timmeck/brain-core 2.36.24 → 2.36.26

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 (117) hide show
  1. package/dist/active-learning/__tests__/active-learning.test.d.ts +1 -0
  2. package/dist/active-learning/__tests__/active-learning.test.js +132 -0
  3. package/dist/active-learning/__tests__/active-learning.test.js.map +1 -0
  4. package/dist/active-learning/active-learner.d.ts +79 -0
  5. package/dist/active-learning/active-learner.js +224 -0
  6. package/dist/active-learning/active-learner.js.map +1 -0
  7. package/dist/active-learning/index.d.ts +2 -0
  8. package/dist/active-learning/index.js +2 -0
  9. package/dist/active-learning/index.js.map +1 -0
  10. package/dist/code-health/__tests__/code-health.test.d.ts +1 -0
  11. package/dist/code-health/__tests__/code-health.test.js +123 -0
  12. package/dist/code-health/__tests__/code-health.test.js.map +1 -0
  13. package/dist/code-health/health-monitor.d.ts +55 -0
  14. package/dist/code-health/health-monitor.js +180 -0
  15. package/dist/code-health/health-monitor.js.map +1 -0
  16. package/dist/code-health/index.d.ts +2 -0
  17. package/dist/code-health/index.js +2 -0
  18. package/dist/code-health/index.js.map +1 -0
  19. package/dist/consensus/__tests__/consensus.test.d.ts +1 -0
  20. package/dist/consensus/__tests__/consensus.test.js +159 -0
  21. package/dist/consensus/__tests__/consensus.test.js.map +1 -0
  22. package/dist/consensus/consensus-engine.d.ts +81 -0
  23. package/dist/consensus/consensus-engine.js +237 -0
  24. package/dist/consensus/consensus-engine.js.map +1 -0
  25. package/dist/consensus/index.d.ts +2 -0
  26. package/dist/consensus/index.js +2 -0
  27. package/dist/consensus/index.js.map +1 -0
  28. package/dist/feedback/__tests__/feedback-engine.test.d.ts +1 -0
  29. package/dist/feedback/__tests__/feedback-engine.test.js +156 -0
  30. package/dist/feedback/__tests__/feedback-engine.test.js.map +1 -0
  31. package/dist/feedback/feedback-engine.d.ts +61 -0
  32. package/dist/feedback/feedback-engine.js +203 -0
  33. package/dist/feedback/feedback-engine.js.map +1 -0
  34. package/dist/feedback/index.d.ts +2 -0
  35. package/dist/feedback/index.js +2 -0
  36. package/dist/feedback/index.js.map +1 -0
  37. package/dist/index.d.ts +32 -0
  38. package/dist/index.js +27 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/knowledge-graph/__tests__/knowledge-graph.test.d.ts +1 -0
  41. package/dist/knowledge-graph/__tests__/knowledge-graph.test.js +215 -0
  42. package/dist/knowledge-graph/__tests__/knowledge-graph.test.js.map +1 -0
  43. package/dist/knowledge-graph/fact-extractor.d.ts +23 -0
  44. package/dist/knowledge-graph/fact-extractor.js +70 -0
  45. package/dist/knowledge-graph/fact-extractor.js.map +1 -0
  46. package/dist/knowledge-graph/graph-engine.d.ts +78 -0
  47. package/dist/knowledge-graph/graph-engine.js +276 -0
  48. package/dist/knowledge-graph/graph-engine.js.map +1 -0
  49. package/dist/knowledge-graph/index.d.ts +4 -0
  50. package/dist/knowledge-graph/index.js +3 -0
  51. package/dist/knowledge-graph/index.js.map +1 -0
  52. package/dist/proactive/__tests__/proactive-engine.test.d.ts +1 -0
  53. package/dist/proactive/__tests__/proactive-engine.test.js +183 -0
  54. package/dist/proactive/__tests__/proactive-engine.test.js.map +1 -0
  55. package/dist/proactive/index.d.ts +2 -0
  56. package/dist/proactive/index.js +2 -0
  57. package/dist/proactive/index.js.map +1 -0
  58. package/dist/proactive/proactive-engine.d.ts +86 -0
  59. package/dist/proactive/proactive-engine.js +252 -0
  60. package/dist/proactive/proactive-engine.js.map +1 -0
  61. package/dist/rag/__tests__/rag-engine.test.d.ts +1 -0
  62. package/dist/rag/__tests__/rag-engine.test.js +235 -0
  63. package/dist/rag/__tests__/rag-engine.test.js.map +1 -0
  64. package/dist/rag/index.d.ts +4 -0
  65. package/dist/rag/index.js +3 -0
  66. package/dist/rag/index.js.map +1 -0
  67. package/dist/rag/rag-engine.d.ts +98 -0
  68. package/dist/rag/rag-engine.js +310 -0
  69. package/dist/rag/rag-engine.js.map +1 -0
  70. package/dist/rag/rag-indexer.d.ts +52 -0
  71. package/dist/rag/rag-indexer.js +144 -0
  72. package/dist/rag/rag-indexer.js.map +1 -0
  73. package/dist/research/__tests__/semantic-compressor.test.d.ts +1 -0
  74. package/dist/research/__tests__/semantic-compressor.test.js +153 -0
  75. package/dist/research/__tests__/semantic-compressor.test.js.map +1 -0
  76. package/dist/research/semantic-compressor.d.ts +55 -0
  77. package/dist/research/semantic-compressor.js +227 -0
  78. package/dist/research/semantic-compressor.js.map +1 -0
  79. package/dist/teaching/__tests__/teaching.test.d.ts +1 -0
  80. package/dist/teaching/__tests__/teaching.test.js +151 -0
  81. package/dist/teaching/__tests__/teaching.test.js.map +1 -0
  82. package/dist/teaching/curriculum.d.ts +32 -0
  83. package/dist/teaching/curriculum.js +89 -0
  84. package/dist/teaching/curriculum.js.map +1 -0
  85. package/dist/teaching/index.d.ts +4 -0
  86. package/dist/teaching/index.js +3 -0
  87. package/dist/teaching/index.js.map +1 -0
  88. package/dist/teaching/teaching-protocol.d.ts +74 -0
  89. package/dist/teaching/teaching-protocol.js +164 -0
  90. package/dist/teaching/teaching-protocol.js.map +1 -0
  91. package/dist/tool-learning/__tests__/tool-learning.test.d.ts +1 -0
  92. package/dist/tool-learning/__tests__/tool-learning.test.js +187 -0
  93. package/dist/tool-learning/__tests__/tool-learning.test.js.map +1 -0
  94. package/dist/tool-learning/index.d.ts +4 -0
  95. package/dist/tool-learning/index.js +3 -0
  96. package/dist/tool-learning/index.js.map +1 -0
  97. package/dist/tool-learning/tool-patterns.d.ts +47 -0
  98. package/dist/tool-learning/tool-patterns.js +125 -0
  99. package/dist/tool-learning/tool-patterns.js.map +1 -0
  100. package/dist/tool-learning/tool-tracker.d.ts +58 -0
  101. package/dist/tool-learning/tool-tracker.js +135 -0
  102. package/dist/tool-learning/tool-tracker.js.map +1 -0
  103. package/dist/user-model/__tests__/user-model.test.d.ts +1 -0
  104. package/dist/user-model/__tests__/user-model.test.js +142 -0
  105. package/dist/user-model/__tests__/user-model.test.js.map +1 -0
  106. package/dist/user-model/adaptive-context.d.ts +18 -0
  107. package/dist/user-model/adaptive-context.js +46 -0
  108. package/dist/user-model/adaptive-context.js.map +1 -0
  109. package/dist/user-model/index.d.ts +4 -0
  110. package/dist/user-model/index.js +3 -0
  111. package/dist/user-model/index.js.map +1 -0
  112. package/dist/user-model/user-model.d.ts +53 -0
  113. package/dist/user-model/user-model.js +204 -0
  114. package/dist/user-model/user-model.js.map +1 -0
  115. package/dist/utils/logger.js +4 -3
  116. package/dist/utils/logger.js.map +1 -1
  117. package/package.json +1 -1
@@ -0,0 +1,55 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { ThoughtStream } from '../consciousness/thought-stream.js';
3
+ export interface CodeHealthConfig {
4
+ brainName: string;
5
+ maxFileSize?: number;
6
+ }
7
+ export interface ScanResult {
8
+ id?: number;
9
+ projectPath: string;
10
+ complexityScore: number;
11
+ duplicationScore: number;
12
+ depHealthScore: number;
13
+ testRatio: number;
14
+ techDebtScore: number;
15
+ fileCount: number;
16
+ createdAt?: string;
17
+ }
18
+ export interface TrendEntry {
19
+ scan: ScanResult;
20
+ deltas: {
21
+ complexityScore: number;
22
+ duplicationScore: number;
23
+ depHealthScore: number;
24
+ testRatio: number;
25
+ techDebtScore: number;
26
+ fileCount: number;
27
+ } | null;
28
+ }
29
+ export interface CodeHealthStatus {
30
+ totalScans: number;
31
+ lastScan: ScanResult | null;
32
+ avgTechDebt: number;
33
+ }
34
+ export declare function runCodeHealthMigration(db: Database.Database): void;
35
+ export declare class CodeHealthMonitor {
36
+ private readonly db;
37
+ private readonly config;
38
+ private readonly log;
39
+ private ts;
40
+ private readonly stmtInsertScan;
41
+ private readonly stmtGetScans;
42
+ private readonly stmtTotalScans;
43
+ private readonly stmtLastScan;
44
+ private readonly stmtAvgTechDebt;
45
+ constructor(db: Database.Database, config: CodeHealthConfig);
46
+ setThoughtStream(stream: ThoughtStream): void;
47
+ scan(projectPath: string): ScanResult;
48
+ trends(projectPath: string, limit?: number): TrendEntry[];
49
+ getStatus(): CodeHealthStatus;
50
+ private estimateFileStats;
51
+ private computeComplexityScore;
52
+ private computeDepHealthScore;
53
+ private computeTestRatio;
54
+ private toScanResult;
55
+ }
@@ -0,0 +1,180 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ // ── Migration ───────────────────────────────────────────
3
+ export function runCodeHealthMigration(db) {
4
+ db.exec(`
5
+ CREATE TABLE IF NOT EXISTS code_health_scans (
6
+ id INTEGER PRIMARY KEY,
7
+ project_path TEXT NOT NULL,
8
+ complexity_score REAL,
9
+ duplication_score REAL,
10
+ dep_health_score REAL,
11
+ test_ratio REAL,
12
+ tech_debt_score REAL,
13
+ file_count INTEGER,
14
+ created_at TEXT DEFAULT (datetime('now'))
15
+ );
16
+ CREATE INDEX IF NOT EXISTS idx_code_health_project ON code_health_scans(project_path);
17
+ `);
18
+ }
19
+ // ── Engine ──────────────────────────────────────────────
20
+ export class CodeHealthMonitor {
21
+ db;
22
+ config;
23
+ log = getLogger();
24
+ ts = null;
25
+ // Prepared statements
26
+ stmtInsertScan;
27
+ stmtGetScans;
28
+ stmtTotalScans;
29
+ stmtLastScan;
30
+ stmtAvgTechDebt;
31
+ constructor(db, config) {
32
+ this.db = db;
33
+ this.config = {
34
+ brainName: config.brainName,
35
+ maxFileSize: config.maxFileSize ?? 100000,
36
+ };
37
+ runCodeHealthMigration(db);
38
+ this.stmtInsertScan = db.prepare(`INSERT INTO code_health_scans (project_path, complexity_score, duplication_score, dep_health_score, test_ratio, tech_debt_score, file_count)
39
+ VALUES (?, ?, ?, ?, ?, ?, ?)`);
40
+ this.stmtGetScans = db.prepare('SELECT * FROM code_health_scans WHERE project_path = ? ORDER BY id DESC LIMIT ?');
41
+ this.stmtTotalScans = db.prepare('SELECT COUNT(*) as cnt FROM code_health_scans');
42
+ this.stmtLastScan = db.prepare('SELECT * FROM code_health_scans ORDER BY id DESC LIMIT 1');
43
+ this.stmtAvgTechDebt = db.prepare('SELECT AVG(tech_debt_score) as avg FROM code_health_scans');
44
+ this.log.debug(`[CodeHealthMonitor] Initialized for ${this.config.brainName}`);
45
+ }
46
+ // ── Setters ──────────────────────────────────────────
47
+ setThoughtStream(stream) {
48
+ this.ts = stream;
49
+ }
50
+ // ── Core: Scan ───────────────────────────────────────
51
+ scan(projectPath) {
52
+ this.ts?.emit('code-health', 'analyzing', `Scanning project: ${projectPath}`, 'routine');
53
+ // 1. Count files by extension (estimate from project path)
54
+ const fileStats = this.estimateFileStats(projectPath);
55
+ const fileCount = fileStats.totalFiles;
56
+ // 2. Complexity score: average line count per file normalized 0-100
57
+ const complexityScore = this.computeComplexityScore(fileStats);
58
+ // 3. Duplication score: placeholder (real detection needs embeddings)
59
+ const duplicationScore = 0;
60
+ // 4. Dep health score: devDeps vs deps ratio
61
+ const depHealthScore = this.computeDepHealthScore(fileStats);
62
+ // 5. Test ratio: test files / source files
63
+ const testRatio = this.computeTestRatio(fileStats);
64
+ // 6. Tech debt score: weighted composite
65
+ const techDebtScore = complexityScore * 0.3 +
66
+ duplicationScore * 0.3 +
67
+ (1 - testRatio) * 100 * 0.2 +
68
+ (1 - depHealthScore) * 100 * 0.2;
69
+ // Store
70
+ const info = this.stmtInsertScan.run(projectPath, complexityScore, duplicationScore, depHealthScore, testRatio, techDebtScore, fileCount);
71
+ const result = {
72
+ id: Number(info.lastInsertRowid),
73
+ projectPath,
74
+ complexityScore,
75
+ duplicationScore,
76
+ depHealthScore,
77
+ testRatio,
78
+ techDebtScore,
79
+ fileCount,
80
+ };
81
+ this.ts?.emit('code-health', 'discovering', `Scan complete: techDebt=${techDebtScore.toFixed(1)}, files=${fileCount}`, techDebtScore > 60 ? 'notable' : 'routine');
82
+ this.log.debug(`[CodeHealthMonitor] Scan: ${projectPath} → techDebt=${techDebtScore.toFixed(1)}`);
83
+ return result;
84
+ }
85
+ // ── Core: Trends ─────────────────────────────────────
86
+ trends(projectPath, limit = 10) {
87
+ const rows = this.stmtGetScans.all(projectPath, limit);
88
+ const scans = rows.map(r => this.toScanResult(r));
89
+ // Compute deltas (each scan vs previous)
90
+ const entries = [];
91
+ for (let i = 0; i < scans.length; i++) {
92
+ const current = scans[i];
93
+ const previous = i + 1 < scans.length ? scans[i + 1] : null;
94
+ entries.push({
95
+ scan: current,
96
+ deltas: previous
97
+ ? {
98
+ complexityScore: current.complexityScore - previous.complexityScore,
99
+ duplicationScore: current.duplicationScore - previous.duplicationScore,
100
+ depHealthScore: current.depHealthScore - previous.depHealthScore,
101
+ testRatio: current.testRatio - previous.testRatio,
102
+ techDebtScore: current.techDebtScore - previous.techDebtScore,
103
+ fileCount: current.fileCount - previous.fileCount,
104
+ }
105
+ : null,
106
+ });
107
+ }
108
+ return entries;
109
+ }
110
+ // ── Core: Status ─────────────────────────────────────
111
+ getStatus() {
112
+ const totalScans = this.stmtTotalScans.get().cnt;
113
+ const lastRow = this.stmtLastScan.get();
114
+ const lastScan = lastRow ? this.toScanResult(lastRow) : null;
115
+ const avgRow = this.stmtAvgTechDebt.get();
116
+ const avgTechDebt = avgRow.avg ?? 0;
117
+ return { totalScans, lastScan, avgTechDebt };
118
+ }
119
+ // ── Private: Estimation Helpers ──────────────────────
120
+ estimateFileStats(projectPath) {
121
+ // Try to read file info from DB if available, otherwise use estimates
122
+ // In a real implementation this would walk the filesystem
123
+ // For now, estimate based on project path heuristics
124
+ const pathParts = projectPath.replace(/\\/g, '/').split('/');
125
+ const projectName = pathParts[pathParts.length - 1] || 'unknown';
126
+ // Base estimates - can be overridden by actual filesystem scans
127
+ const baseFiles = projectName.length * 5 + 20;
128
+ const sourceFiles = Math.floor(baseFiles * 0.7);
129
+ const testFiles = Math.floor(baseFiles * 0.2);
130
+ return {
131
+ totalFiles: baseFiles,
132
+ sourceFiles,
133
+ testFiles,
134
+ avgLinesPerFile: 80 + (projectName.length % 10) * 10,
135
+ depCount: 10 + (projectName.length % 5),
136
+ devDepCount: 5 + (projectName.length % 3),
137
+ };
138
+ }
139
+ computeComplexityScore(stats) {
140
+ // Normalize: 0-50 lines = 0-25, 50-200 = 25-75, 200+ = 75-100
141
+ const avg = stats.avgLinesPerFile;
142
+ if (avg <= 50)
143
+ return (avg / 50) * 25;
144
+ if (avg <= 200)
145
+ return 25 + ((avg - 50) / 150) * 50;
146
+ return Math.min(100, 75 + ((avg - 200) / 300) * 25);
147
+ }
148
+ computeDepHealthScore(stats) {
149
+ const total = stats.depCount + stats.devDepCount;
150
+ if (total === 0)
151
+ return 1.0;
152
+ // Good health: balanced deps, not too many
153
+ // Score decreases if total deps > 50 or devDeps dominate
154
+ const sizeScore = Math.max(0, 1 - total / 100);
155
+ const balanceScore = stats.devDepCount > 0
156
+ ? Math.min(1, stats.depCount / stats.devDepCount)
157
+ : 1.0;
158
+ return (sizeScore + balanceScore) / 2;
159
+ }
160
+ computeTestRatio(stats) {
161
+ if (stats.sourceFiles === 0)
162
+ return 0;
163
+ return Math.min(1, stats.testFiles / stats.sourceFiles);
164
+ }
165
+ // ── Private: Row Mapping ─────────────────────────────
166
+ toScanResult(row) {
167
+ return {
168
+ id: row.id,
169
+ projectPath: row.project_path,
170
+ complexityScore: row.complexity_score,
171
+ duplicationScore: row.duplication_score,
172
+ depHealthScore: row.dep_health_score,
173
+ testRatio: row.test_ratio,
174
+ techDebtScore: row.tech_debt_score,
175
+ fileCount: row.file_count,
176
+ createdAt: row.created_at,
177
+ };
178
+ }
179
+ }
180
+ //# sourceMappingURL=health-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-monitor.js","sourceRoot":"","sources":["../../src/code-health/health-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { CodeHealthMonitor, runCodeHealthMigration } from './health-monitor.js';
2
+ export type { CodeHealthConfig, ScanResult, ScanResult as HealthScanResult, TrendEntry, TrendEntry as HealthTrend, CodeHealthStatus, } from './health-monitor.js';
@@ -0,0 +1,2 @@
1
+ export { CodeHealthMonitor, runCodeHealthMigration } from './health-monitor.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/code-health/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,159 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ import { ConsensusEngine, runConsensusMigration } from '../consensus-engine.js';
4
+ vi.mock('../../utils/logger.js', () => ({
5
+ getLogger: () => ({
6
+ info: vi.fn(),
7
+ warn: vi.fn(),
8
+ error: vi.fn(),
9
+ debug: vi.fn(),
10
+ }),
11
+ }));
12
+ describe('ConsensusEngine', () => {
13
+ let db;
14
+ let engine;
15
+ beforeEach(() => {
16
+ db = new Database(':memory:');
17
+ engine = new ConsensusEngine(db, { brainName: 'brain' });
18
+ });
19
+ afterEach(() => {
20
+ db.close();
21
+ });
22
+ it('propose creates a record', () => {
23
+ const result = engine.propose({
24
+ type: 'feature_decision',
25
+ description: 'Should we add caching?',
26
+ options: ['yes', 'no', 'defer'],
27
+ context: 'Performance is degrading',
28
+ });
29
+ expect(result.id).toBeDefined();
30
+ expect(result.type).toBe('feature_decision');
31
+ expect(result.status).toBe('open');
32
+ // Verify persisted
33
+ const proposal = engine.getProposal(result.id);
34
+ expect(proposal).not.toBeNull();
35
+ expect(proposal.description).toBe('Should we add caching?');
36
+ expect(proposal.options).toEqual(['yes', 'no', 'defer']);
37
+ expect(proposal.context).toBe('Performance is degrading');
38
+ });
39
+ it('vote records a choice', () => {
40
+ const proposal = engine.propose({
41
+ type: 'decision',
42
+ description: 'Test vote',
43
+ options: ['A', 'B'],
44
+ });
45
+ const vote = engine.vote(proposal.id, 'A', 0.8, 'I prefer A');
46
+ expect(vote.voter).toBe('brain');
47
+ expect(vote.chosenOption).toBe('A');
48
+ expect(vote.confidence).toBe(0.8);
49
+ expect(vote.reasoning).toBe('I prefer A');
50
+ // Verify persisted
51
+ const full = engine.getProposal(proposal.id);
52
+ expect(full.votes.length).toBe(1);
53
+ expect(full.votes[0].chosenOption).toBe('A');
54
+ });
55
+ it('vote upserts for same voter', () => {
56
+ const proposal = engine.propose({
57
+ type: 'decision',
58
+ description: 'Upsert test',
59
+ options: ['A', 'B'],
60
+ });
61
+ engine.vote(proposal.id, 'A', 0.5);
62
+ engine.vote(proposal.id, 'B', 0.9, 'Changed my mind');
63
+ const full = engine.getProposal(proposal.id);
64
+ expect(full.votes.length).toBe(1); // Still one vote from same voter
65
+ expect(full.votes[0].chosenOption).toBe('B');
66
+ expect(full.votes[0].confidence).toBe(0.9);
67
+ });
68
+ it('resolve determines simple majority winner', () => {
69
+ const proposal = engine.propose({
70
+ type: 'decision',
71
+ description: 'Majority test',
72
+ options: ['A', 'B'],
73
+ });
74
+ // Insert votes from different "brains" directly into DB
75
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'brain', 'A', 0.7);
76
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'trading-brain', 'A', 0.6);
77
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'marketing-brain', 'B', 0.5);
78
+ const result = engine.resolve(proposal.id);
79
+ expect(result.winner).toBe('A');
80
+ expect(result.vetoed).toBe(false);
81
+ expect(result.votes.length).toBe(3);
82
+ });
83
+ it('resolve requires 2/3 majority for selfmod_approval', () => {
84
+ const proposal = engine.propose({
85
+ type: 'selfmod_approval',
86
+ description: 'Self-mod vote',
87
+ options: ['approve', 'reject'],
88
+ });
89
+ // 2 approve, 1 reject → 66.7% which equals 2/3
90
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'brain', 'approve', 0.8);
91
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'trading-brain', 'approve', 0.7);
92
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'marketing-brain', 'reject', 0.4);
93
+ const result = engine.resolve(proposal.id);
94
+ // 2/3 = 0.667, votes are 2/3 = 0.667 which matches >= requiredMajority
95
+ expect(result.winner).toBe('approve');
96
+ expect(result.vetoed).toBe(false);
97
+ });
98
+ it('veto detection when lone dissenter has high confidence', () => {
99
+ const proposal = engine.propose({
100
+ type: 'decision',
101
+ description: 'Veto test',
102
+ options: ['go', 'stop'],
103
+ });
104
+ // Two agree, one dissents with very high confidence
105
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'brain', 'go', 0.6);
106
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'trading-brain', 'go', 0.5);
107
+ db.prepare('INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence) VALUES (?, ?, ?, ?)').run(proposal.id, 'marketing-brain', 'stop', 0.8); // > 0.67 vetoThreshold
108
+ const result = engine.resolve(proposal.id);
109
+ expect(result.vetoed).toBe(true);
110
+ expect(result.winner).toBeNull();
111
+ });
112
+ it('timeout status can be set', () => {
113
+ const proposal = engine.propose({
114
+ type: 'decision',
115
+ description: 'Timeout test',
116
+ options: ['A', 'B'],
117
+ });
118
+ const success = engine.timeoutProposal(proposal.id);
119
+ expect(success).toBe(true);
120
+ const updated = engine.getProposal(proposal.id);
121
+ expect(updated.status).toBe('timeout');
122
+ });
123
+ it('getProposal returns proposal with all votes', () => {
124
+ const proposal = engine.propose({
125
+ type: 'test',
126
+ description: 'Full proposal',
127
+ options: ['X', 'Y'],
128
+ });
129
+ engine.vote(proposal.id, 'X', 0.9, 'Strong preference');
130
+ const full = engine.getProposal(proposal.id);
131
+ expect(full).not.toBeNull();
132
+ expect(full.type).toBe('test');
133
+ expect(full.votes.length).toBe(1);
134
+ expect(full.votes[0].chosenOption).toBe('X');
135
+ expect(full.votes[0].reasoning).toBe('Strong preference');
136
+ });
137
+ it('getHistory returns proposals in order', () => {
138
+ engine.propose({ type: 'a', description: 'First', options: ['1'] });
139
+ engine.propose({ type: 'b', description: 'Second', options: ['2'] });
140
+ const p3 = engine.propose({ type: 'c', description: 'Third', options: ['3'] });
141
+ const all = engine.getHistory();
142
+ expect(all.length).toBe(3);
143
+ // Most recent first
144
+ expect(all[0].description).toBe('Third');
145
+ // Test status filter
146
+ engine.vote(p3.id, 'yes', 0.9);
147
+ const open = engine.getHistory('open');
148
+ expect(open.length).toBe(3); // All still open (resolve not called)
149
+ });
150
+ it('migration is idempotent', () => {
151
+ runConsensusMigration(db);
152
+ runConsensusMigration(db);
153
+ const tables = db
154
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'consensus%'")
155
+ .all();
156
+ expect(tables.length).toBe(2); // proposals + votes
157
+ });
158
+ });
159
+ //# sourceMappingURL=consensus.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus.test.js","sourceRoot":"","sources":["../../../src/consensus/__tests__/consensus.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { ThoughtStream } from '../consciousness/thought-stream.js';
3
+ export interface ConsensusConfig {
4
+ brainName: string;
5
+ timeoutMs?: number;
6
+ requiredMajority?: number;
7
+ vetoThreshold?: number;
8
+ }
9
+ export type ProposalStatus = 'open' | 'resolved' | 'timeout';
10
+ export interface Proposal {
11
+ id?: number;
12
+ type: string;
13
+ description: string;
14
+ options: string[];
15
+ context?: string;
16
+ status: ProposalStatus;
17
+ result?: string;
18
+ votes: Vote[];
19
+ createdAt?: string;
20
+ resolvedAt?: string;
21
+ }
22
+ export interface ProposalInput {
23
+ type: string;
24
+ description: string;
25
+ options: string[];
26
+ context?: string;
27
+ }
28
+ export interface Vote {
29
+ id?: number;
30
+ proposalId: number;
31
+ voter: string;
32
+ chosenOption: string;
33
+ confidence: number;
34
+ reasoning?: string;
35
+ createdAt?: string;
36
+ }
37
+ export interface ResolutionResult {
38
+ winner: string | null;
39
+ votes: Vote[];
40
+ vetoed: boolean;
41
+ }
42
+ export interface ConsensusStatus {
43
+ totalProposals: number;
44
+ openCount: number;
45
+ resolvedCount: number;
46
+ avgParticipation: number;
47
+ }
48
+ export declare function runConsensusMigration(db: Database.Database): void;
49
+ export declare class ConsensusEngine {
50
+ private readonly db;
51
+ private readonly config;
52
+ private readonly log;
53
+ private ts;
54
+ private readonly stmtInsertProposal;
55
+ private readonly stmtGetProposal;
56
+ private readonly stmtUpdateProposalStatus;
57
+ private readonly stmtUpsertVote;
58
+ private readonly stmtGetVotes;
59
+ private readonly stmtListProposals;
60
+ private readonly stmtListByStatus;
61
+ private readonly stmtTotalProposals;
62
+ private readonly stmtOpenCount;
63
+ private readonly stmtResolvedCount;
64
+ private readonly stmtAvgVotesPerProposal;
65
+ constructor(db: Database.Database, config: ConsensusConfig);
66
+ setThoughtStream(stream: ThoughtStream): void;
67
+ propose(decision: ProposalInput): {
68
+ id: number;
69
+ type: string;
70
+ status: ProposalStatus;
71
+ };
72
+ vote(proposalId: number, option: string, confidence: number, reasoning?: string): Vote;
73
+ resolve(proposalId: number): ResolutionResult;
74
+ getProposal(id: number): Proposal | null;
75
+ getHistory(status?: ProposalStatus, limit?: number): Proposal[];
76
+ getStatus(): ConsensusStatus;
77
+ timeoutProposal(proposalId: number): boolean;
78
+ private loadVotes;
79
+ private toProposal;
80
+ private toVote;
81
+ }