closed-loop-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of closed-loop-cli might be problematic. Click here for more details.

Files changed (86) hide show
  1. package/dist/dashboard/server.js +237 -0
  2. package/dist/index.js +272 -0
  3. package/dist/orchestrator/agent-prompts.js +42 -0
  4. package/dist/orchestrator/autogenesis.js +973 -0
  5. package/dist/orchestrator/dgm-archive.js +223 -0
  6. package/dist/orchestrator/event-stream.js +103 -0
  7. package/dist/orchestrator/fitness-evaluator.js +99 -0
  8. package/dist/orchestrator/meta-agent.js +421 -0
  9. package/dist/orchestrator/microagent-registry.js +134 -0
  10. package/dist/orchestrator/mutation-strategies.js +174 -0
  11. package/dist/orchestrator/prompt-benchmark.js +102 -0
  12. package/dist/orchestrator/prompt-optimizer.js +169 -0
  13. package/dist/orchestrator/refactor-scanner.js +222 -0
  14. package/dist/orchestrator/research-manager.js +104 -0
  15. package/dist/orchestrator/rulez.js +135 -0
  16. package/dist/orchestrator/sahoo-gateway.js +261 -0
  17. package/dist/orchestrator/state-manager.js +121 -0
  18. package/dist/orchestrator/task-agent.js +444 -0
  19. package/dist/orchestrator/telegram-bot.js +374 -0
  20. package/dist/orchestrator/types.js +2 -0
  21. package/dist/tests/dynamic/dependencies.test.js +37 -0
  22. package/dist/tests/dynamic/dummy.test.js +7 -0
  23. package/dist/tests/dynamic/fuzzy-patch.test.js +68 -0
  24. package/dist/tests/dynamic/indexer.test.js +60 -0
  25. package/dist/tests/dynamic/openhands.test.js +83 -0
  26. package/dist/tests/dynamic/skills.test.js +88 -0
  27. package/dist/tests/run-tests.js +294 -0
  28. package/dist/tools/diff-tools.js +24 -0
  29. package/dist/tools/file-tools.js +191 -0
  30. package/dist/tools/indexer.js +301 -0
  31. package/dist/tools/math-helper.js +6 -0
  32. package/dist/tools/repo-map.js +122 -0
  33. package/dist/tools/search-tools.js +271 -0
  34. package/dist/tools/shell-tools.js +75 -0
  35. package/dist/tools/skills.js +122 -0
  36. package/dist/tools/tui-tools.js +82 -0
  37. package/docs/AI_Arch_Opt_Anti_Gaming.md +227 -0
  38. package/docs/AI_Self_Improvement_Safety.md +457 -0
  39. package/docs/Anthropic AI Agents_ Capabilities and Concerns.md +134 -0
  40. package/docs/Auto_ClosedLoop_AI_Agent.md +415 -0
  41. package/docs/Autonomous AI Agents_ Closing the Loop.docx +0 -0
  42. package/docs/Secure_AI_Sandbox_Framework.md +358 -0
  43. package/docs/skills/add-file-existence-check-utility.json +9 -0
  44. package/docs/skills/add-utility-function-for-file-existence-check.json +9 -0
  45. package/docs/skills/add-utility-function-to-module.json +9 -0
  46. package/docs/skills/extract-command-runner-utility.json +9 -0
  47. package/docs/skills/file-existence-check-utility.json +9 -0
  48. package/package.json +36 -0
  49. package/src/dashboard/public/index.css +1334 -0
  50. package/src/dashboard/public/index.html +385 -0
  51. package/src/dashboard/public/index.js +1059 -0
  52. package/src/dashboard/server.ts +209 -0
  53. package/src/index.ts +256 -0
  54. package/src/orchestrator/agent-prompts.ts +43 -0
  55. package/src/orchestrator/autogenesis.ts +1078 -0
  56. package/src/orchestrator/dgm-archive.ts +257 -0
  57. package/src/orchestrator/event-stream.ts +90 -0
  58. package/src/orchestrator/fitness-evaluator.ts +154 -0
  59. package/src/orchestrator/meta-agent.ts +434 -0
  60. package/src/orchestrator/microagent-registry.ts +115 -0
  61. package/src/orchestrator/microagents/git-helper.md +11 -0
  62. package/src/orchestrator/microagents/test-fixer.md +10 -0
  63. package/src/orchestrator/microagents/typescript-expert.md +11 -0
  64. package/src/orchestrator/mutation-strategies.ts +214 -0
  65. package/src/orchestrator/research-manager.ts +88 -0
  66. package/src/orchestrator/rulez.ts +118 -0
  67. package/src/orchestrator/sahoo-gateway.ts +300 -0
  68. package/src/orchestrator/state-manager.ts +161 -0
  69. package/src/orchestrator/system-prompt.txt +1 -0
  70. package/src/orchestrator/task-agent.ts +461 -0
  71. package/src/orchestrator/telegram-bot.ts +358 -0
  72. package/src/tests/dynamic/dependencies.test.ts +48 -0
  73. package/src/tests/dynamic/dummy.test.ts +4 -0
  74. package/src/tests/dynamic/fuzzy-patch.test.ts +42 -0
  75. package/src/tests/dynamic/indexer.test.ts +31 -0
  76. package/src/tests/dynamic/openhands.test.ts +59 -0
  77. package/src/tests/dynamic/skills.test.ts +63 -0
  78. package/src/tests/run-tests.ts +296 -0
  79. package/src/tools/diff-tools.ts +27 -0
  80. package/src/tools/file-tools.ts +187 -0
  81. package/src/tools/indexer.ts +325 -0
  82. package/src/tools/repo-map.ts +96 -0
  83. package/src/tools/search-tools.ts +258 -0
  84. package/src/tools/shell-tools.ts +90 -0
  85. package/src/tools/skills.ts +101 -0
  86. package/src/tools/tui-tools.ts +87 -0
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ResearchManager = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ class ResearchManager {
40
+ static session = null;
41
+ static logPath = path.join(process.cwd(), 'research-log.json');
42
+ static startSession(task, effort) {
43
+ this.session = {
44
+ taskId: `task-${Date.now()}`,
45
+ task,
46
+ startedAt: new Date().toISOString(),
47
+ status: 'running',
48
+ effort,
49
+ decisions: []
50
+ };
51
+ this.logDecision('session_start', `Starting active research session for task: "${task}"`, 'info');
52
+ this.saveSession();
53
+ }
54
+ static logDecision(phase, action, result, details) {
55
+ if (!this.session)
56
+ return;
57
+ this.session.decisions.push({
58
+ timestamp: new Date().toISOString(),
59
+ phase,
60
+ action,
61
+ result,
62
+ details
63
+ });
64
+ this.saveSession();
65
+ }
66
+ static endSession(status) {
67
+ if (!this.session)
68
+ return;
69
+ this.session.status = status;
70
+ this.session.endedAt = new Date().toISOString();
71
+ this.logDecision('session_end', `Session ended with status: ${status}`, 'info');
72
+ this.saveSession();
73
+ this.session = null;
74
+ }
75
+ static saveSession() {
76
+ if (!this.session)
77
+ return;
78
+ try {
79
+ let sessions = [];
80
+ if (fs.existsSync(this.logPath)) {
81
+ try {
82
+ sessions = JSON.parse(fs.readFileSync(this.logPath, 'utf-8'));
83
+ }
84
+ catch (e) { }
85
+ }
86
+ const index = sessions.findIndex(s => s.taskId === this.session.taskId);
87
+ if (index !== -1) {
88
+ sessions[index] = this.session;
89
+ }
90
+ else {
91
+ sessions.push(this.session);
92
+ }
93
+ // Keep last 10 sessions to save space
94
+ if (sessions.length > 10) {
95
+ sessions.shift();
96
+ }
97
+ fs.writeFileSync(this.logPath, JSON.stringify(sessions, null, 2), 'utf-8');
98
+ }
99
+ catch (err) {
100
+ console.error('[ResearchManager] Failed to write research log:', err);
101
+ }
102
+ }
103
+ }
104
+ exports.ResearchManager = ResearchManager;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.checkCommand = checkCommand;
37
+ exports.checkFileEdit = checkFileEdit;
38
+ const path = __importStar(require("path"));
39
+ // Banned command substrings
40
+ const BANNED_COMMAND_PATTERNS = [
41
+ /\brm\b\s+-[rf]{1,2}\s+\//, // rm -rf /
42
+ /\brm\b\s+-[rf]{1,2}\s+\./, // rm -rf .
43
+ /\brm\b\s+-[rf]{1,2}\s+([A-Za-z]:)?\\/, // Windows root deletes
44
+ /\bformat\b/i, // disk formats
45
+ /\bgit\b.*\bpush\b.*\b--force\b/, // force pushes
46
+ /\bgit\b.*\bpush\b/, // any direct push to remote
47
+ /\bchmod\b\s+777/, // unsafe permissions elevation
48
+ /\bchown\b/, // ownership tampering
49
+ /(\bdrop\b|\balter\b)\s+database/i // raw database drops
50
+ ];
51
+ // Secrets patterns (e.g. tp- tokens, standard slack tokens, etc)
52
+ const SECRETS_PATTERNS = [
53
+ /tp-[a-zA-Z0-9]{32,}/, // MiMo tp- Token pattern
54
+ /sk-[a-zA-Z0-9]{20,}/, // standard OpenAI/Anthropic keys
55
+ /API_KEY\s*=\s*['"][a-zA-Z0-9_-]{16,}['"]/i,
56
+ /PASSWORD\s*=\s*['"][a-zA-Z0-9_-]{8,}['"]/i
57
+ ];
58
+ /**
59
+ * Checks if a command string is allowed under RuleZ policies.
60
+ */
61
+ function checkCommand(commandStr) {
62
+ const normalizedCmd = commandStr.trim();
63
+ // 1. Check for banned command patterns
64
+ for (const pattern of BANNED_COMMAND_PATTERNS) {
65
+ if (pattern.test(normalizedCmd)) {
66
+ return {
67
+ allowed: false,
68
+ exitCode: 2,
69
+ message: `Blocked by RuleZ: Command violates security policy (matches pattern: ${pattern.toString()})`
70
+ };
71
+ }
72
+ }
73
+ // 2. Safe commands allowed
74
+ return {
75
+ allowed: true,
76
+ exitCode: 0,
77
+ message: 'Allowed by RuleZ'
78
+ };
79
+ }
80
+ /**
81
+ * Checks if a file edit or write is allowed under RuleZ policies.
82
+ */
83
+ function checkFileEdit(filePath, content) {
84
+ // 1. Protected files lockout (Campbell Safeguard Policy)
85
+ const normalizedPath = filePath.replace(/\\/g, '/');
86
+ const normalizedFile = normalizedPath.toLowerCase();
87
+ const resolvedBaseName = path.basename(filePath).toLowerCase();
88
+ const isProtected = normalizedFile.includes('src/orchestrator/rulez.ts') ||
89
+ normalizedFile.includes('src/orchestrator/sahoo-gateway.ts') ||
90
+ normalizedFile.includes('src/tests/run-tests.ts') ||
91
+ resolvedBaseName === 'package.json' ||
92
+ resolvedBaseName === '.env';
93
+ if (isProtected) {
94
+ return {
95
+ allowed: false,
96
+ exitCode: 2,
97
+ message: `Blocked by RuleZ: Modification of safety harness or environment configurations (${filePath}) is strictly prohibited.`
98
+ };
99
+ }
100
+ // 2. Sandbox isolation check: resolved path must be within the workspace root
101
+ const resolvedTarget = path.resolve(filePath);
102
+ const resolvedRoot = path.resolve(process.cwd());
103
+ const relativePath = path.relative(resolvedRoot, resolvedTarget);
104
+ const isOutside = relativePath.startsWith('..') || path.isAbsolute(relativePath);
105
+ if (isOutside) {
106
+ return {
107
+ allowed: false,
108
+ exitCode: 2,
109
+ message: `Blocked by RuleZ: Path '${filePath}' resolves outside the workspace sandbox.`
110
+ };
111
+ }
112
+ // 2. Prevent dynamic execution (eval / Function)
113
+ if (/\beval\s*\(/i.test(content) || /\bnew\s+Function\s*\(/i.test(content)) {
114
+ return {
115
+ allowed: false,
116
+ exitCode: 2,
117
+ message: `Blocked by RuleZ: Use of dynamic code execution (eval() or new Function()) is banned.`
118
+ };
119
+ }
120
+ // 3. Prevent hardcoding secrets/credentials
121
+ for (const pattern of SECRETS_PATTERNS) {
122
+ if (pattern.test(content)) {
123
+ return {
124
+ allowed: false,
125
+ exitCode: 2,
126
+ message: `Blocked by RuleZ: Potential hardcoded secret or API key pattern detected in changes.`
127
+ };
128
+ }
129
+ }
130
+ return {
131
+ allowed: true,
132
+ exitCode: 0,
133
+ message: 'Allowed by RuleZ'
134
+ };
135
+ }
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateSemanticDrift = calculateSemanticDrift;
4
+ exports.calculateLexicalDrift = calculateLexicalDrift;
5
+ exports.calculateStructuralDrift = calculateStructuralDrift;
6
+ exports.calculateDistributionalDrift = calculateDistributionalDrift;
7
+ exports.checkSafetyConstraints = checkSafetyConstraints;
8
+ exports.evaluateSahoo = evaluateSahoo;
9
+ /**
10
+ * Helper: Computes character trigrams and returns a map of frequencies.
11
+ */
12
+ function getTrigramFreq(str) {
13
+ const map = new Map();
14
+ if (str.length < 3)
15
+ return map;
16
+ for (let i = 0; i <= str.length - 3; i++) {
17
+ const trigram = str.substring(i, i + 3);
18
+ map.set(trigram, (map.get(trigram) || 0) + 1);
19
+ }
20
+ return map;
21
+ }
22
+ /**
23
+ * Calculates Semantic Drift using Trigram Cosine Similarity.
24
+ * Cosine distance = 1 - Cosine Similarity.
25
+ */
26
+ function calculateSemanticDrift(before, after) {
27
+ const tBefore = getTrigramFreq(before);
28
+ const tAfter = getTrigramFreq(after);
29
+ if (tBefore.size === 0 && tAfter.size === 0)
30
+ return 0;
31
+ // Calculate dot product and magnitudes
32
+ let dotProduct = 0;
33
+ tBefore.forEach((val, key) => {
34
+ if (tAfter.has(key)) {
35
+ dotProduct += val * (tAfter.get(key) || 0);
36
+ }
37
+ });
38
+ let magBefore = 0;
39
+ tBefore.forEach(val => magBefore += val * val);
40
+ magBefore = Math.sqrt(magBefore);
41
+ let magAfter = 0;
42
+ tAfter.forEach(val => magAfter += val * val);
43
+ magAfter = Math.sqrt(magAfter);
44
+ if (magBefore === 0 || magAfter === 0)
45
+ return 1.0;
46
+ const similarity = Math.min(Math.max(dotProduct / (magBefore * magAfter), -1.0), 1.0);
47
+ const distance = 1.0 - similarity;
48
+ return Math.abs(distance) < 1e-12 ? 0 : distance; // Cosine distance
49
+ }
50
+ /**
51
+ * Calculates Lexical Drift using normalized Levenshtein edit distance.
52
+ */
53
+ function calculateLexicalDrift(before, after) {
54
+ if (before === after)
55
+ return 0;
56
+ if (before.length === 0)
57
+ return 1.0;
58
+ if (after.length === 0)
59
+ return 1.0;
60
+ const matrix = [];
61
+ const bLen = before.length;
62
+ const aLen = after.length;
63
+ // For memory optimization under large strings, cap calculation length
64
+ const maxLen = 1000;
65
+ const sBefore = before.substring(0, maxLen);
66
+ const sAfter = after.substring(0, maxLen);
67
+ const n = sBefore.length;
68
+ const m = sAfter.length;
69
+ for (let i = 0; i <= n; i++) {
70
+ matrix[i] = [i];
71
+ }
72
+ for (let j = 0; j <= m; j++) {
73
+ matrix[0][j] = j;
74
+ }
75
+ for (let i = 1; i <= n; i++) {
76
+ for (let j = 1; j <= m; j++) {
77
+ if (sBefore[i - 1] === sAfter[j - 1]) {
78
+ matrix[i][j] = matrix[i - 1][j - 1];
79
+ }
80
+ else {
81
+ matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
82
+ matrix[i][j - 1] + 1, // insertion
83
+ matrix[i - 1][j] + 1 // deletion
84
+ );
85
+ }
86
+ }
87
+ }
88
+ return matrix[n][m] / Math.max(n, m);
89
+ }
90
+ /**
91
+ * Calculates Structural Drift: normalized line and size differences.
92
+ */
93
+ function calculateStructuralDrift(before, after) {
94
+ const linesBefore = before.split('\n').length;
95
+ const linesAfter = after.split('\n').length;
96
+ const sizeBefore = before.length;
97
+ const sizeAfter = after.length;
98
+ const lineDiff = Math.abs(linesAfter - linesBefore) / (Math.max(linesBefore, 1));
99
+ const sizeDiff = Math.abs(sizeAfter - sizeBefore) / (Math.max(sizeBefore, 1));
100
+ return Math.min((lineDiff + sizeDiff) / 2, 1.0);
101
+ }
102
+ /**
103
+ * Calculates Distributional Drift by evaluating changes in JavaScript/TypeScript keyword frequencies.
104
+ */
105
+ function calculateDistributionalDrift(before, after) {
106
+ const keywords = ['const', 'let', 'var', 'if', 'else', 'for', 'while', 'function', 'class', 'import', 'export', 'return', 'await', 'async'];
107
+ function getKeywordFreq(str) {
108
+ const map = new Map();
109
+ const tokens = str.split(/\W+/);
110
+ tokens.forEach(tok => {
111
+ if (keywords.includes(tok)) {
112
+ map.set(tok, (map.get(tok) || 0) + 1);
113
+ }
114
+ });
115
+ return map;
116
+ }
117
+ const freqBefore = getKeywordFreq(before);
118
+ const freqAfter = getKeywordFreq(after);
119
+ let totalDiff = 0;
120
+ let totalKeys = 0;
121
+ keywords.forEach(kw => {
122
+ const countBefore = freqBefore.get(kw) || 0;
123
+ const countAfter = freqAfter.get(kw) || 0;
124
+ totalDiff += Math.abs(countAfter - countBefore);
125
+ totalKeys += countBefore + countAfter;
126
+ });
127
+ if (totalKeys === 0)
128
+ return 0;
129
+ return Math.min(totalDiff / totalKeys, 1.0);
130
+ }
131
+ /**
132
+ * Safety Constraints Check for CPS (Constraint Preservation Score).
133
+ */
134
+ function checkSafetyConstraints(filePath, content, compileSuccess, testsSuccess) {
135
+ const failedList = [];
136
+ let satisfied = 0;
137
+ const K = 5; // Number of total constraints
138
+ // Constraint 1: Compiles successfully
139
+ if (compileSuccess) {
140
+ satisfied++;
141
+ }
142
+ else {
143
+ failedList.push('CompilationFailure');
144
+ }
145
+ // Constraint 2: Tests pass
146
+ if (testsSuccess) {
147
+ satisfied++;
148
+ }
149
+ else {
150
+ failedList.push('TestExecutionFailure');
151
+ }
152
+ // Constraint 3: No dynamic eval / Function execution in code
153
+ const hasEval = /\beval\s*\(/i.test(content) || /\bnew\s+Function\s*\(/i.test(content);
154
+ if (!hasEval) {
155
+ satisfied++;
156
+ }
157
+ else {
158
+ failedList.push('DynamicCodeExecutionViolation');
159
+ }
160
+ // Constraint 4: No hardcoded secrets
161
+ const secretPatterns = [
162
+ /tp-[a-zA-Z0-9]{32,}/, // MiMo Token pattern
163
+ /sk-[a-zA-Z0-9]{20,}/ // standard key patterns
164
+ ];
165
+ const hasSecrets = secretPatterns.some(pat => pat.test(content));
166
+ if (!hasSecrets) {
167
+ satisfied++;
168
+ }
169
+ else {
170
+ failedList.push('SecretLeakViolation');
171
+ }
172
+ // Constraint 5: Path safety (inside workspace)
173
+ const normalizedPath = filePath.replace(/\\/g, '/');
174
+ const isSafePath = !normalizedPath.includes('../') && !normalizedPath.includes('..\\');
175
+ if (isSafePath) {
176
+ satisfied++;
177
+ }
178
+ else {
179
+ failedList.push('PathSafetyViolation');
180
+ }
181
+ return {
182
+ score: satisfied / K,
183
+ failedList
184
+ };
185
+ }
186
+ /**
187
+ * Evaluates a codebase mutation against the SAHOO Safeguarding Policy.
188
+ */
189
+ function evaluateSahoo(filePath, beforeContent, afterContent, compileSuccess, testsSuccess, historicalScores = [1.0] // Default history to prevent division by zero
190
+ ) {
191
+ // 1. Calculate individual drifts
192
+ const semantic = calculateSemanticDrift(beforeContent, afterContent);
193
+ const lexical = calculateLexicalDrift(beforeContent, afterContent);
194
+ const structural = calculateStructuralDrift(beforeContent, afterContent);
195
+ const distributional = calculateDistributionalDrift(beforeContent, afterContent);
196
+ // 2. Compute Goal Drift Index (GDI)
197
+ // GDI = 0.38*semantic + 0.12*lexical + 0.21*structural + 0.29*distributional
198
+ const gdi = (0.38 * semantic) + (0.12 * lexical) + (0.21 * structural) + (0.29 * distributional);
199
+ // 3. Compute Constraint Preservation Score (CPS)
200
+ const { score: cps, failedList } = checkSafetyConstraints(filePath, afterContent, compileSuccess, testsSuccess);
201
+ // 4. Compute Regression Risk (R_c)
202
+ // Pr(Q_c < Q_max - delta)
203
+ // We model Q_c as the current CPS score. Q_max is the highest historical score (typically 1.0).
204
+ // If historical performance is low, we quantify risk mathematically.
205
+ const qMax = Math.max(...historicalScores, 1.0);
206
+ const currentQ = cps;
207
+ // Calculate variance of historical scores
208
+ const mean = historicalScores.reduce((a, b) => a + b, 0) / historicalScores.length;
209
+ const variance = historicalScores.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / historicalScores.length;
210
+ const stdDev = Math.max(Math.sqrt(variance), 0.05); // Min standard dev of 5%
211
+ // Regression Risk estimate using Gaussian Cumulative Distribution proxy:
212
+ // Z = (currentQ - qMax) / stdDev
213
+ // R_c = P(Z < 0)
214
+ const z = (currentQ - qMax) / stdDev;
215
+ let regressionRisk = 0.5; // default if z == 0
216
+ if (z < 0) {
217
+ // Standard approximation of normal CDF
218
+ regressionRisk = 1.0 - (1.0 / (1.0 + Math.exp(-1.6 * z)));
219
+ }
220
+ else {
221
+ regressionRisk = 1.0 / (1.0 + Math.exp(1.6 * z));
222
+ }
223
+ const metrics = {
224
+ semanticDrift: semantic,
225
+ lexicalDrift: lexical,
226
+ structuralDrift: structural,
227
+ distributionalDrift: distributional,
228
+ goalDriftIndex: gdi,
229
+ constraintPreservationScore: cps,
230
+ regressionRisk: regressionRisk
231
+ };
232
+ // Halting policies:
233
+ // 1. GDI Threshold: Halts execution if GDI > 0.440
234
+ if (gdi > 0.440) {
235
+ return {
236
+ passed: false,
237
+ metrics,
238
+ reason: `Blocked by SAHOO: Goal Drift Index exceeded threshold (${gdi.toFixed(3)} > 0.440)`
239
+ };
240
+ }
241
+ // 2. CPS Threshold: Halts execution if CPS < 1.0 (Zero-tolerance for safety violations)
242
+ if (cps < 1.0) {
243
+ return {
244
+ passed: false,
245
+ metrics,
246
+ reason: `Blocked by SAHOO: Constraint Preservation Score fell below 1.0 (Violations: ${failedList.join(', ')})`
247
+ };
248
+ }
249
+ // 3. Regression Risk threshold: Halt if risk > 0.8
250
+ if (regressionRisk > 0.80) {
251
+ return {
252
+ passed: false,
253
+ metrics,
254
+ reason: `Blocked by SAHOO: Regression Risk too high (${(regressionRisk * 100).toFixed(1)}% > 80%)`
255
+ };
256
+ }
257
+ return {
258
+ passed: true,
259
+ metrics
260
+ };
261
+ }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getEvolutionState = getEvolutionState;
37
+ exports.updateEvolutionState = updateEvolutionState;
38
+ exports.appendHistory = appendHistory;
39
+ exports.appendArchive = appendArchive;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const statePath = path.join(process.cwd(), 'evolution-state.json');
43
+ const defaultState = {
44
+ status: 'idle',
45
+ currentCycle: 0,
46
+ maxCycles: 0,
47
+ tokenBudget: 500000,
48
+ tokensUsed: { input: 0, output: 0, total: 0 },
49
+ lastUpdated: new Date().toISOString(),
50
+ currentTask: null,
51
+ lastRefactorProposal: null,
52
+ lastRefactorResult: null,
53
+ lastPromptOptimization: null,
54
+ history: [],
55
+ archive: [],
56
+ currentFitness: 0,
57
+ bestFitness: 0,
58
+ dgmPopulationSize: 0,
59
+ dgmBestEntryId: null
60
+ };
61
+ function getEvolutionState() {
62
+ if (!fs.existsSync(statePath)) {
63
+ return defaultState;
64
+ }
65
+ try {
66
+ const raw = fs.readFileSync(statePath, 'utf-8');
67
+ return JSON.parse(raw);
68
+ }
69
+ catch (e) {
70
+ return defaultState;
71
+ }
72
+ }
73
+ const event_stream_1 = require("./event-stream");
74
+ function updateEvolutionState(update) {
75
+ const currentState = getEvolutionState();
76
+ const tokensUsed = update.tokensUsed
77
+ ? { ...currentState.tokensUsed, ...update.tokensUsed }
78
+ : currentState.tokensUsed;
79
+ const merged = {
80
+ ...currentState,
81
+ ...update,
82
+ tokensUsed,
83
+ lastUpdated: new Date().toISOString()
84
+ };
85
+ merged.tokensUsed.total = merged.tokensUsed.input + merged.tokensUsed.output;
86
+ // Log status transitions to EventStream
87
+ if (update.status && update.status !== currentState.status) {
88
+ event_stream_1.EventStream.getInstance().publish('system', 'log', 'StateTransition', `System status changed from '${currentState.status}' to '${update.status}'`);
89
+ }
90
+ try {
91
+ fs.writeFileSync(statePath, JSON.stringify(merged, null, 2), 'utf-8');
92
+ }
93
+ catch (err) {
94
+ console.error('Failed to write evolution state file:', err);
95
+ }
96
+ return merged;
97
+ }
98
+ function appendHistory(item) {
99
+ const state = getEvolutionState();
100
+ const historyItem = {
101
+ ...item,
102
+ time: new Date().toISOString()
103
+ };
104
+ const updatedHistory = [...state.history, historyItem];
105
+ if (updatedHistory.length > 50) {
106
+ updatedHistory.shift();
107
+ }
108
+ updateEvolutionState({ history: updatedHistory });
109
+ }
110
+ function appendArchive(item) {
111
+ const state = getEvolutionState();
112
+ const archiveItem = {
113
+ ...item,
114
+ timestamp: new Date().toISOString()
115
+ };
116
+ const updatedArchive = [...(state.archive || []), archiveItem];
117
+ if (updatedArchive.length > 10) {
118
+ updatedArchive.shift();
119
+ }
120
+ updateEvolutionState({ archive: updatedArchive });
121
+ }