@evomap/evolver 1.79.0 → 1.79.1

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.
@@ -0,0 +1,2 @@
1
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-06T01:46:54.543Z","signals":["memory_missing","user_missing","session_logs_missing"],"tags":["memory_missing","user_missing","session_logs_missing","area:memory"],"shape":{"title":"Harden session log detection and fallback behavior","input":"Recent session transcript + memory snippets + user instructions","output":"A safe, auditable evolution patch guided by GEP assets","invariants":"Protocol order, small reversible patches, validation, append-only events","params":"Signals: memory_missing, user_missing, session_logs_missing","failure_points":"Missing signals, over-broad changes, skipped validation, missing knowledge solidification","evidence":"Signal present: session_logs_missing"}}
2
+ {"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-06T01:47:23.332Z","signals":["memory_missing","user_missing","session_logs_missing"],"tags":["memory_missing","user_missing","session_logs_missing","area:memory"],"shape":{"title":"Harden session log detection and fallback behavior","input":"Recent session transcript + memory snippets + user instructions","output":"A safe, auditable evolution patch guided by GEP assets","invariants":"Protocol order, small reversible patches, validation, append-only events","params":"Signals: memory_missing, user_missing, session_logs_missing","failure_points":"Missing signals, over-broad changes, skipped validation, missing knowledge solidification","evidence":"Signal present: session_logs_missing"}}
@@ -0,0 +1,4 @@
1
+ {
2
+ "version": 1,
3
+ "capsules": []
4
+ }
File without changes
@@ -0,0 +1,4 @@
1
+ {
2
+ "version": 1,
3
+ "failed_capsules": []
4
+ }
@@ -0,0 +1,201 @@
1
+ {
2
+ "version": 2,
3
+ "genes": [
4
+ {
5
+ "type": "Gene",
6
+ "id": "gene_gep_repair_from_errors",
7
+ "category": "repair",
8
+ "signals_match": [
9
+ "error",
10
+ "exception",
11
+ "failed",
12
+ "unstable"
13
+ ],
14
+ "preconditions": [
15
+ "signals contains error-related indicators"
16
+ ],
17
+ "strategy": [
18
+ "Extract structured signals from logs and user instructions",
19
+ "Select an existing Gene by signals match (no improvisation)",
20
+ "Estimate blast radius (files, lines) before editing",
21
+ "Apply smallest reversible patch",
22
+ "Validate using declared validation steps; rollback on failure",
23
+ "Solidify knowledge: append EvolutionEvent, update Gene/Capsule store"
24
+ ],
25
+ "constraints": {
26
+ "max_files": 20,
27
+ "forbidden_paths": [
28
+ ".git",
29
+ "node_modules"
30
+ ]
31
+ },
32
+ "validation": [
33
+ "node scripts/validate-modules.js ./src/evolve ./src/gep/solidify ./src/gep/policyCheck ./src/gep/selector ./src/gep/memoryGraph ./src/gep/assetStore",
34
+ "node scripts/validate-suite.js"
35
+ ]
36
+ },
37
+ {
38
+ "type": "Gene",
39
+ "id": "gene_gep_optimize_prompt_and_assets",
40
+ "category": "optimize",
41
+ "signals_match": [
42
+ "protocol",
43
+ "gep",
44
+ "prompt",
45
+ "audit",
46
+ "reusable"
47
+ ],
48
+ "preconditions": [
49
+ "need stricter, auditable evolution protocol outputs"
50
+ ],
51
+ "strategy": [
52
+ "Extract signals and determine selection rationale via Selector JSON",
53
+ "Prefer reusing existing Gene/Capsule; only create if no match exists",
54
+ "Refactor prompt assembly to embed assets (genes, capsules, parent event)",
55
+ "Reduce noise and ambiguity; enforce strict output schema",
56
+ "Validate by running node index.js run and ensuring no runtime errors",
57
+ "Solidify: record EvolutionEvent, update Gene definitions, create Capsule on success"
58
+ ],
59
+ "constraints": {
60
+ "max_files": 20,
61
+ "forbidden_paths": [
62
+ ".git",
63
+ "node_modules"
64
+ ]
65
+ },
66
+ "validation": [
67
+ "node scripts/validate-modules.js ./src/evolve ./src/gep/prompt ./src/gep/contentHash ./src/gep/skillDistiller",
68
+ "node scripts/validate-suite.js"
69
+ ]
70
+ },
71
+ {
72
+ "type": "Gene",
73
+ "id": "gene_gep_innovate_from_opportunity",
74
+ "category": "innovate",
75
+ "signals_match": [
76
+ "user_feature_request",
77
+ "user_improvement_suggestion",
78
+ "perf_bottleneck",
79
+ "capability_gap",
80
+ "stable_success_plateau",
81
+ "external_opportunity",
82
+ "bounty_task"
83
+ ],
84
+ "preconditions": [
85
+ "at least one opportunity signal is present",
86
+ "no active log_error signals (stability first)"
87
+ ],
88
+ "strategy": [
89
+ "Extract opportunity signals and identify the specific user need or system gap",
90
+ "Search existing Genes and Capsules for partial matches (avoid reinventing)",
91
+ "Design a minimal, testable implementation plan (prefer small increments)",
92
+ "Estimate blast radius; innovate changes may touch more files but must stay within constraints",
93
+ "Implement the change with clear validation criteria",
94
+ "Validate using declared validation steps; rollback on failure",
95
+ "Solidify: record EvolutionEvent with intent=innovate, create new Gene if pattern is novel, create Capsule on success"
96
+ ],
97
+ "constraints": {
98
+ "max_files": 25,
99
+ "forbidden_paths": [
100
+ ".git",
101
+ "node_modules"
102
+ ]
103
+ },
104
+ "validation": [
105
+ "node scripts/validate-modules.js ./src/evolve ./src/gep/solidify ./src/gep/policyCheck ./src/gep/mutation ./src/gep/personality",
106
+ "node scripts/validate-suite.js"
107
+ ]
108
+ },
109
+ {
110
+ "type": "Gene",
111
+ "id": "gene_gep_optimize_tool_usage",
112
+ "summary": "Optimize tool execution patterns by reducing redundant exec calls, improving tool selection strategy, and enforcing tool-use constraints to prevent bypass.",
113
+ "category": "optimize",
114
+ "signals_match": [
115
+ "high_tool_usage:exec",
116
+ "repeated_tool_usage:exec",
117
+ "tool_bypass",
118
+ "tool_loop",
119
+ "high_tool_usage"
120
+ ],
121
+ "preconditions": [
122
+ "agent repeatedly invokes the same tool (especially exec) without progress",
123
+ "tool execution bypass patterns detected",
124
+ "no active error signals (errors would take repair priority)"
125
+ ],
126
+ "strategy": [
127
+ "Analyze tool usage patterns to identify the root cause of repetition (wrong tool, missing context, or lack of guardrails)",
128
+ "Introduce strategy-level guardrails: prefer single-shot commands, batch related operations, add explicit retry limits",
129
+ "If tool_bypass detected, strengthen constraint enforcement in prompt assembly or tool routing",
130
+ "Estimate blast radius; changes should target tool routing, prompt constraints, or signal deduplication logic",
131
+ "Validate by confirming no regressions in existing tool tests and signal extraction accuracy",
132
+ "Solidify: record EvolutionEvent with intent=optimize, update Capsule on success"
133
+ ],
134
+ "constraints": {
135
+ "max_files": 15,
136
+ "forbidden_paths": [
137
+ ".git",
138
+ "node_modules"
139
+ ]
140
+ },
141
+ "validation": [
142
+ "node scripts/validate-modules.js ./src/gep/signals ./src/evolve",
143
+ "node scripts/validate-suite.js"
144
+ ]
145
+ },
146
+ {
147
+ "type": "Gene",
148
+ "id": "gene_distilled_s2g-env-vars",
149
+ "summary": "Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, OIDC tokens, or managing environment-specific configuration.",
150
+ "category": "optimize",
151
+ "signals_match": [
152
+ "use_when_working_with",
153
+ "env_files",
154
+ "vercel_env_commands",
155
+ "oidc_tokens",
156
+ "vercel_env_pull",
157
+ "env_local_overwrite",
158
+ "oidc_token_expiry",
159
+ "dotenv_cli"
160
+ ],
161
+ "preconditions": [
162
+ "Skill env-vars has just been executed locally"
163
+ ],
164
+ "strategy": [
165
+ "Identify the dominant trigger signals from the Skill description.",
166
+ "Apply the smallest targeted change that satisfies the Skill workflow.",
167
+ "Run the Skill validation commands and abort if any fails."
168
+ ],
169
+ "constraints": {
170
+ "max_files": 12,
171
+ "forbidden_paths": [
172
+ ".git",
173
+ "node_modules"
174
+ ]
175
+ },
176
+ "validation": [
177
+ "node --version"
178
+ ],
179
+ "schema_version": "1.6.0",
180
+ "_source": {
181
+ "kind": "skill2gep",
182
+ "skill_name": "env-vars",
183
+ "skill_platform": "vercel",
184
+ "skill_hash": "ba0bdb4db2",
185
+ "rationale_paper": "Wang, Ren, Zhang. From Procedural Skills to Strategy Genes. arXiv:2604.15097",
186
+ "paper_scope": "code-science (arXiv:2604.15097, 45 tasks, Gemini 3.1 Pro/Flash Lite)",
187
+ "claims_outside_scope": "assumption",
188
+ "quality_heuristics": {
189
+ "strategy_steps": 0,
190
+ "avoid_count": 0,
191
+ "validation_declared_count": 0,
192
+ "validation_runnable_count": 0,
193
+ "validation_fallback_used": true,
194
+ "signals_extracted": 4,
195
+ "preconditions_extracted": 0
196
+ }
197
+ },
198
+ "asset_id": "sha256:4fa74fe34d19564416dfd8e63f3012a1672e86f39c4bff85d1c70524e06b5a2e"
199
+ }
200
+ ]
201
+ }
File without changes
package/index.js CHANGED
@@ -124,6 +124,43 @@ class CycleTimeoutError extends Error {
124
124
  }
125
125
  }
126
126
 
127
+ // Issue #528: on Windows, child_process.spawn(detached: true, windowsHide: true)
128
+ // allocates a new conhost window every time -- windowsHide is silently ignored
129
+ // in detached mode. So suicide-respawn (cycles >= max, RSS over budget, or the
130
+ // new cycle hard-timeout) opens a new cmd popup on every restart. We now skip
131
+ // the in-process detached spawn on Windows by default and rely on an external
132
+ // supervisor (feishu-evolver-wrapper >= 1.10.0, NSSM, pm2-windows, etc.) to
133
+ // respawn the daemon on non-zero exit. Users who insist can opt back in with
134
+ // EVOLVER_SUICIDE_WINDOWS=true (and accept the popups).
135
+ function spawnReplacementProcess({ reason, args, logPath }) {
136
+ const isWindows = process.platform === 'win32';
137
+ const allowOnWindows = parseBoolEnv(process.env.EVOLVER_SUICIDE_WINDOWS, false);
138
+ if (isWindows && !allowOnWindows) {
139
+ console.log(
140
+ '[Daemon] Skipping in-process respawn on Windows (' + reason + '). ' +
141
+ 'Native Node spawn(detached, windowsHide) opens a cmd popup on every restart (Issue #528). ' +
142
+ 'Set EVOLVER_SUICIDE_WINDOWS=true to opt back in. ' +
143
+ 'Recommended: run evolver under feishu-evolver-wrapper >= 1.10.0, NSSM, or pm2-windows so the supervisor restarts on exit.'
144
+ );
145
+ return { spawned: false, reason: 'windows_default_skip' };
146
+ }
147
+ try {
148
+ const logFd = fs.openSync(logPath, 'a');
149
+ const spawnOpts = {
150
+ detached: true,
151
+ stdio: ['ignore', logFd, logFd],
152
+ env: process.env,
153
+ windowsHide: true,
154
+ };
155
+ const child = spawn(process.execPath, [__filename, ...args], spawnOpts);
156
+ child.unref();
157
+ return { spawned: true };
158
+ } catch (e) {
159
+ console.error('[Daemon] Spawn-replacement failed (' + reason + '): ' + (e && e.message || e));
160
+ return { spawned: false, reason: 'spawn_error', error: e };
161
+ }
162
+ }
163
+
127
164
  // Atomic write of the cycle_progress.json file. Wrapper polls this file every
128
165
  // 60s; if updated_at goes stale beyond EVOLVE_INNER_STUCK_TIMEOUT_SEC the
129
166
  // wrapper treats the inner core as zombie and SIGKILLs it. See Issue #19 (the
@@ -498,19 +535,11 @@ async function main() {
498
535
  started_at: t0,
499
536
  phase: 'cycle_timeout_respawn',
500
537
  });
501
- try {
502
- const logFd = fs.openSync(getEvolverLogPath(), 'a');
503
- const spawnOpts = {
504
- detached: true,
505
- stdio: ['ignore', logFd, logFd],
506
- env: process.env,
507
- windowsHide: true,
508
- };
509
- const child = spawn(process.execPath, [__filename, ...args], spawnOpts);
510
- child.unref();
511
- } catch (spawnErr) {
512
- console.error('[Daemon] Force-restart spawn after cycle timeout failed: ' + (spawnErr && spawnErr.message || spawnErr));
513
- }
538
+ spawnReplacementProcess({
539
+ reason: 'cycle_hard_timeout',
540
+ args: args,
541
+ logPath: getEvolverLogPath(),
542
+ });
514
543
  releaseLock();
515
544
  process.exit(1);
516
545
  }
@@ -565,25 +594,32 @@ async function main() {
565
594
  if (isVerbose) console.warn('[OMLS] Scheduler error: ' + (e.message || e));
566
595
  }
567
596
 
568
- // Suicide check (memory leak protection)
597
+ // Suicide check (memory leak protection). On Windows the
598
+ // in-process respawn opens a cmd popup (Issue #528), so by default
599
+ // we delegate to an external supervisor by exiting with a non-zero
600
+ // code instead. See spawnReplacementProcess() for the policy.
569
601
  if (suicideEnabled) {
570
602
  const memMb = process.memoryUsage().rss / 1024 / 1024;
571
603
  if (cycleCount >= maxCyclesPerProcess || memMb > maxRssMb) {
572
604
  console.log(`[Daemon] Restarting self (cycles=${cycleCount}, rssMb=${memMb.toFixed(0)})`);
573
- try {
574
- const logFd = fs.openSync(getEvolverLogPath(), 'a');
575
- const spawnOpts = {
576
- detached: true,
577
- stdio: ['ignore', logFd, logFd],
578
- env: process.env,
579
- windowsHide: true,
580
- };
581
- const child = spawn(process.execPath, [__filename, ...args], spawnOpts);
582
- child.unref();
605
+ const result = spawnReplacementProcess({
606
+ reason: 'max_cycles_or_rss',
607
+ args: args,
608
+ logPath: getEvolverLogPath(),
609
+ });
610
+ if (result.spawned) {
583
611
  releaseLock();
584
612
  process.exit(0);
585
- } catch (spawnErr) {
586
- console.error('[Daemon] Spawn failed, continuing current process:', spawnErr.message);
613
+ } else if (result.reason === 'windows_default_skip') {
614
+ console.log('[Daemon] Exiting with code 1 to let external supervisor respawn.');
615
+ releaseLock();
616
+ process.exit(1);
617
+ } else {
618
+ // Non-Windows spawn error: keep the lock and fall through to
619
+ // the next iteration of the loop instead of leaving the daemon
620
+ // dead. This matches the pre-1.79.1 behavior where a failed
621
+ // spawn was logged and the process continued running.
622
+ console.error('[Daemon] Spawn failed, continuing current process.');
587
623
  }
588
624
  }
589
625
  }
@@ -1705,4 +1741,5 @@ module.exports = {
1705
1741
  parseBoolEnv,
1706
1742
  CycleTimeoutError,
1707
1743
  writeCycleProgressAtomic,
1744
+ spawnReplacementProcess,
1708
1745
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evomap/evolver",
3
- "version": "1.79.0",
3
+ "version": "1.79.1",
4
4
  "description": "A GEP-powered self-evolution engine for AI agents. Features automated log analysis and Genome Evolution Protocol (GEP) for auditable, reusable evolution assets.",
5
5
  "main": "index.js",
6
6
  "bin": {