Skip to content

Commit 93e44a3

Browse files
author
evolver-publish
committed
Release v1.79.1
1 parent 991b39b commit 93e44a3

36 files changed

Lines changed: 469 additions & 57 deletions

assets/gep/capsules.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"version": 1,
3+
"capsules": []
4+
}

assets/gep/events.jsonl

Whitespace-only changes.

assets/gep/genes.json

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

index.js

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,43 @@ class CycleTimeoutError extends Error {
124124
}
125125
}
126126

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+
127164
// Atomic write of the cycle_progress.json file. Wrapper polls this file every
128165
// 60s; if updated_at goes stale beyond EVOLVE_INNER_STUCK_TIMEOUT_SEC the
129166
// wrapper treats the inner core as zombie and SIGKILLs it. See Issue #19 (the
@@ -498,19 +535,11 @@ async function main() {
498535
started_at: t0,
499536
phase: 'cycle_timeout_respawn',
500537
});
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+
});
514543
releaseLock();
515544
process.exit(1);
516545
}
@@ -565,25 +594,32 @@ async function main() {
565594
if (isVerbose) console.warn('[OMLS] Scheduler error: ' + (e.message || e));
566595
}
567596

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.
569601
if (suicideEnabled) {
570602
const memMb = process.memoryUsage().rss / 1024 / 1024;
571603
if (cycleCount >= maxCyclesPerProcess || memMb > maxRssMb) {
572604
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) {
583611
releaseLock();
584612
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.');
587623
}
588624
}
589625
}
@@ -1705,4 +1741,5 @@ module.exports = {
17051741
parseBoolEnv,
17061742
CycleTimeoutError,
17071743
writeCycleProgressAtomic,
1744+
spawnReplacementProcess,
17081745
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@evomap/evolver",
3-
"version": "1.79.0",
3+
"version": "1.79.1",
44
"description": "A GEP-powered self-evolution engine for AI agents. Features automated log analysis and Genome Evolution Protocol (GEP) for auditable, reusable evolution assets.",
55
"main": "index.js",
66
"bin": {

src/evolve.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gep/.integrity

0 Bytes
Binary file not shown.

src/gep/a2aProtocol.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gep/candidateEval.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gep/candidates.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)