@evomap/evolver 1.87.0 → 1.87.2
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/assets/gep/candidates.jsonl +1 -0
- package/assets/gep/capsules.json +4 -0
- package/assets/gep/events.jsonl +0 -0
- package/assets/gep/failed_capsules.json +4 -0
- package/assets/gep/genes.json +245 -0
- package/assets/gep/genes.jsonl +0 -0
- package/index.js +33 -14
- package/package.json +1 -1
- package/src/adapters/hookAdapter.js +19 -4
- package/src/atp/autoBuyer.js +90 -11
- package/src/atp/cli.js +98 -0
- package/src/atp/cliAutobuyPrompt.js +59 -52
- package/src/evolve/guards.js +1 -1
- package/src/evolve/pipeline/collect.js +1 -1
- package/src/evolve/pipeline/dispatch.js +1 -1
- package/src/evolve/pipeline/enrich.js +1 -1
- package/src/evolve/pipeline/hub.js +1 -1
- package/src/evolve/pipeline/select.js +1 -1
- package/src/evolve/pipeline/signals.js +1 -1
- package/src/evolve/utils.js +1 -1
- package/src/evolve.js +1 -1
- package/src/forceUpdate.js +2 -1
- package/src/gep/a2aProtocol.js +1 -1
- package/src/gep/candidateEval.js +1 -1
- package/src/gep/candidates.js +1 -1
- package/src/gep/contentHash.js +1 -1
- package/src/gep/crypto.js +1 -1
- package/src/gep/curriculum.js +1 -1
- package/src/gep/deviceId.js +1 -1
- package/src/gep/envFingerprint.js +1 -1
- package/src/gep/epigenetics.js +1 -1
- package/src/gep/explore.js +1 -1
- package/src/gep/hash.js +1 -1
- package/src/gep/hubFetch.js +1 -1
- package/src/gep/hubReview.js +1 -1
- package/src/gep/hubSearch.js +1 -1
- package/src/gep/hubVerify.js +1 -1
- package/src/gep/learningSignals.js +1 -1
- package/src/gep/memoryGraph.js +1 -1
- package/src/gep/memoryGraphAdapter.js +1 -1
- package/src/gep/mutation.js +1 -1
- package/src/gep/narrativeMemory.js +1 -1
- package/src/gep/openPRRegistry.js +1 -1
- package/src/gep/personality.js +1 -1
- package/src/gep/policyCheck.js +1 -1
- package/src/gep/prompt.js +1 -1
- package/src/gep/recallVerifier.js +1 -1
- package/src/gep/reflection.js +1 -1
- package/src/gep/selector.js +1 -1
- package/src/gep/skillDistiller.js +1 -1
- package/src/gep/solidify.js +1 -1
- package/src/gep/strategy.js +1 -1
- package/src/gep/workspaceKeychain.js +1 -1
- package/src/proxy/index.js +29 -9
- package/src/proxy/router/messages_route.js +80 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"CapabilityCandidate","id":"cand_b9a66a5c","title":"Harden session log detection and fallback behavior","source":"signals","created_at":"2026-05-27T12:51:59.052Z","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"}}
|
|
File without changes
|
|
@@ -0,0 +1,245 @@
|
|
|
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|失败|失敗|실패|fail",
|
|
12
|
+
"unstable|不稳定|不安定|불안정",
|
|
13
|
+
"log_error",
|
|
14
|
+
"test_failure"
|
|
15
|
+
],
|
|
16
|
+
"preconditions": [
|
|
17
|
+
"signals contains error-related indicators"
|
|
18
|
+
],
|
|
19
|
+
"strategy": [
|
|
20
|
+
"Extract structured signals from logs and user instructions",
|
|
21
|
+
"Select an existing Gene by signals match (no improvisation)",
|
|
22
|
+
"Estimate blast radius (files, lines) before editing",
|
|
23
|
+
"Apply smallest reversible patch",
|
|
24
|
+
"Validate using declared validation steps; rollback on failure",
|
|
25
|
+
"Solidify knowledge: append EvolutionEvent, update Gene/Capsule store"
|
|
26
|
+
],
|
|
27
|
+
"constraints": {
|
|
28
|
+
"max_files": 20,
|
|
29
|
+
"forbidden_paths": [
|
|
30
|
+
".git",
|
|
31
|
+
"node_modules"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"validation": [
|
|
35
|
+
"node scripts/validate-modules.js ./src/evolve ./src/gep/solidify ./src/gep/policyCheck ./src/gep/selector ./src/gep/memoryGraph ./src/gep/assetStore",
|
|
36
|
+
"node scripts/validate-suite.js"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"type": "Gene",
|
|
41
|
+
"id": "gene_gep_optimize_prompt_and_assets",
|
|
42
|
+
"category": "optimize",
|
|
43
|
+
"signals_match": [
|
|
44
|
+
"protocol|协议|プロトコル|프로토콜",
|
|
45
|
+
"gep",
|
|
46
|
+
"prompt|提示词|提示|プロンプト|프롬프트",
|
|
47
|
+
"audit|审计|監査|감사",
|
|
48
|
+
"reusable|可复用|再利用|재사용"
|
|
49
|
+
],
|
|
50
|
+
"preconditions": [
|
|
51
|
+
"need stricter, auditable evolution protocol outputs"
|
|
52
|
+
],
|
|
53
|
+
"strategy": [
|
|
54
|
+
"Extract signals and determine selection rationale via Selector JSON",
|
|
55
|
+
"Prefer reusing existing Gene/Capsule; only create if no match exists",
|
|
56
|
+
"Refactor prompt assembly to embed assets (genes, capsules, parent event)",
|
|
57
|
+
"Reduce noise and ambiguity; enforce strict output schema",
|
|
58
|
+
"Validate by running node index.js run and ensuring no runtime errors",
|
|
59
|
+
"Solidify: record EvolutionEvent, update Gene definitions, create Capsule on success"
|
|
60
|
+
],
|
|
61
|
+
"constraints": {
|
|
62
|
+
"max_files": 20,
|
|
63
|
+
"forbidden_paths": [
|
|
64
|
+
".git",
|
|
65
|
+
"node_modules"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"validation": [
|
|
69
|
+
"node scripts/validate-modules.js ./src/evolve ./src/gep/prompt ./src/gep/contentHash ./src/gep/skillDistiller",
|
|
70
|
+
"node scripts/validate-suite.js"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"type": "Gene",
|
|
75
|
+
"id": "gene_gep_innovate_from_opportunity",
|
|
76
|
+
"category": "innovate",
|
|
77
|
+
"signals_match": [
|
|
78
|
+
"user_feature_request|功能请求|機能リクエスト|기능요청",
|
|
79
|
+
"user_improvement_suggestion|改进建议|改善提案|개선제안",
|
|
80
|
+
"perf_bottleneck|性能瓶颈|パフォーマンス|성능병목",
|
|
81
|
+
"capability_gap|能力缺口|機能ギャップ|역량공백",
|
|
82
|
+
"stable_success_plateau",
|
|
83
|
+
"external_opportunity|外部机会|外部機会|외부기회",
|
|
84
|
+
"bounty_task"
|
|
85
|
+
],
|
|
86
|
+
"preconditions": [
|
|
87
|
+
"at least one opportunity signal is present",
|
|
88
|
+
"no active log_error signals (stability first)"
|
|
89
|
+
],
|
|
90
|
+
"strategy": [
|
|
91
|
+
"Extract opportunity signals and identify the specific user need or system gap",
|
|
92
|
+
"Search existing Genes and Capsules for partial matches (avoid reinventing)",
|
|
93
|
+
"Design a minimal, testable implementation plan (prefer small increments)",
|
|
94
|
+
"Estimate blast radius; innovate changes may touch more files but must stay within constraints",
|
|
95
|
+
"Implement the change with clear validation criteria",
|
|
96
|
+
"Validate using declared validation steps; rollback on failure",
|
|
97
|
+
"Solidify: record EvolutionEvent with intent=innovate, create new Gene if pattern is novel, create Capsule on success"
|
|
98
|
+
],
|
|
99
|
+
"constraints": {
|
|
100
|
+
"max_files": 25,
|
|
101
|
+
"forbidden_paths": [
|
|
102
|
+
".git",
|
|
103
|
+
"node_modules"
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
"validation": [
|
|
107
|
+
"node scripts/validate-modules.js ./src/evolve ./src/gep/solidify ./src/gep/policyCheck ./src/gep/mutation ./src/gep/personality",
|
|
108
|
+
"node scripts/validate-suite.js"
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"type": "Gene",
|
|
113
|
+
"id": "gene_gep_optimize_tool_usage",
|
|
114
|
+
"summary": "Optimize tool execution patterns by reducing redundant exec calls, improving tool selection strategy, and enforcing tool-use constraints to prevent bypass.",
|
|
115
|
+
"category": "optimize",
|
|
116
|
+
"signals_match": [
|
|
117
|
+
"high_tool_usage:exec",
|
|
118
|
+
"repeated_tool_usage:exec",
|
|
119
|
+
"tool_bypass|工具绕过|ツール迂回|도구우회",
|
|
120
|
+
"tool_loop|工具循环|ツールループ|도구반복",
|
|
121
|
+
"high_tool_usage"
|
|
122
|
+
],
|
|
123
|
+
"preconditions": [
|
|
124
|
+
"agent repeatedly invokes the same tool (especially exec) without progress",
|
|
125
|
+
"tool execution bypass patterns detected",
|
|
126
|
+
"no active error signals (errors would take repair priority)"
|
|
127
|
+
],
|
|
128
|
+
"strategy": [
|
|
129
|
+
"Analyze tool usage patterns to identify the root cause of repetition (wrong tool, missing context, or lack of guardrails)",
|
|
130
|
+
"Introduce strategy-level guardrails: prefer single-shot commands, batch related operations, add explicit retry limits",
|
|
131
|
+
"If tool_bypass detected, strengthen constraint enforcement in prompt assembly or tool routing",
|
|
132
|
+
"Estimate blast radius; changes should target tool routing, prompt constraints, or signal deduplication logic",
|
|
133
|
+
"Validate by confirming no regressions in existing tool tests and signal extraction accuracy",
|
|
134
|
+
"Solidify: record EvolutionEvent with intent=optimize, update Capsule on success"
|
|
135
|
+
],
|
|
136
|
+
"constraints": {
|
|
137
|
+
"max_files": 15,
|
|
138
|
+
"forbidden_paths": [
|
|
139
|
+
".git",
|
|
140
|
+
"node_modules"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
"validation": [
|
|
144
|
+
"node scripts/validate-modules.js ./src/gep/signals ./src/evolve",
|
|
145
|
+
"node scripts/validate-suite.js"
|
|
146
|
+
],
|
|
147
|
+
"routing_hint": {
|
|
148
|
+
"tier": "mid",
|
|
149
|
+
"reasoning_level": "medium"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"type": "Gene",
|
|
154
|
+
"id": "gene_distilled_s2g-env-vars",
|
|
155
|
+
"summary": "Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, OIDC tokens, or managing environment-specific configuration.",
|
|
156
|
+
"category": "optimize",
|
|
157
|
+
"signals_match": [
|
|
158
|
+
"use_when_working_with",
|
|
159
|
+
"env_files",
|
|
160
|
+
"vercel_env_commands",
|
|
161
|
+
"oidc_tokens",
|
|
162
|
+
"vercel_env_pull",
|
|
163
|
+
"env_local_overwrite",
|
|
164
|
+
"oidc_token_expiry",
|
|
165
|
+
"dotenv_cli"
|
|
166
|
+
],
|
|
167
|
+
"preconditions": [
|
|
168
|
+
"Skill env-vars has just been executed locally"
|
|
169
|
+
],
|
|
170
|
+
"strategy": [
|
|
171
|
+
"Identify the dominant trigger signals from the Skill description.",
|
|
172
|
+
"Apply the smallest targeted change that satisfies the Skill workflow.",
|
|
173
|
+
"Run the Skill validation commands and abort if any fails."
|
|
174
|
+
],
|
|
175
|
+
"constraints": {
|
|
176
|
+
"max_files": 12,
|
|
177
|
+
"forbidden_paths": [
|
|
178
|
+
".git",
|
|
179
|
+
"node_modules"
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
"validation": [
|
|
183
|
+
"node --version"
|
|
184
|
+
],
|
|
185
|
+
"routing_hint": {
|
|
186
|
+
"tier": "cheap",
|
|
187
|
+
"reasoning_level": "low"
|
|
188
|
+
},
|
|
189
|
+
"schema_version": "1.6.0",
|
|
190
|
+
"_source": {
|
|
191
|
+
"kind": "skill2gep",
|
|
192
|
+
"skill_name": "env-vars",
|
|
193
|
+
"skill_platform": "vercel",
|
|
194
|
+
"skill_hash": "ba0bdb4db2",
|
|
195
|
+
"rationale_paper": "Wang, Ren, Zhang. From Procedural Skills to Strategy Genes. arXiv:2604.15097",
|
|
196
|
+
"paper_scope": "code-science (arXiv:2604.15097, 45 tasks, Gemini 3.1 Pro/Flash Lite)",
|
|
197
|
+
"claims_outside_scope": "assumption",
|
|
198
|
+
"quality_heuristics": {
|
|
199
|
+
"strategy_steps": 0,
|
|
200
|
+
"avoid_count": 0,
|
|
201
|
+
"validation_declared_count": 0,
|
|
202
|
+
"validation_runnable_count": 0,
|
|
203
|
+
"validation_fallback_used": true,
|
|
204
|
+
"signals_extracted": 4,
|
|
205
|
+
"preconditions_extracted": 0
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"asset_id": "sha256:1501bc37fbefb18630c4dc8a95d8cdc1ed32bec4a465dc3223280ae907e07297"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"type": "Gene",
|
|
212
|
+
"id": "gene_tool_integrity",
|
|
213
|
+
"category": "repair",
|
|
214
|
+
"signals_match": [
|
|
215
|
+
"tool_bypass|工具绕过|ツール迂回|도구우회"
|
|
216
|
+
],
|
|
217
|
+
"preconditions": [
|
|
218
|
+
"agent used shell/exec to perform an action that a registered tool can handle"
|
|
219
|
+
],
|
|
220
|
+
"strategy": [
|
|
221
|
+
"Always prefer registered tools over ad-hoc scripts or shell workarounds",
|
|
222
|
+
"If a registered tool fails, report the actual error honestly and attempt to fix the root cause",
|
|
223
|
+
"Never fabricate explanations -- describe actual actions transparently",
|
|
224
|
+
"Do not create temporary scripts in extension or project directories"
|
|
225
|
+
],
|
|
226
|
+
"constraints": {
|
|
227
|
+
"max_files": 4,
|
|
228
|
+
"forbidden_paths": [
|
|
229
|
+
".git",
|
|
230
|
+
"node_modules"
|
|
231
|
+
]
|
|
232
|
+
},
|
|
233
|
+
"validation": [
|
|
234
|
+
"node scripts/validate-suite.js"
|
|
235
|
+
],
|
|
236
|
+
"anti_patterns": [
|
|
237
|
+
"tool_bypass"
|
|
238
|
+
],
|
|
239
|
+
"routing_hint": {
|
|
240
|
+
"tier": "cheap",
|
|
241
|
+
"reasoning_level": "low"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
}
|
|
File without changes
|
package/index.js
CHANGED
|
@@ -390,11 +390,11 @@ async function main() {
|
|
|
390
390
|
// own env, since verification can run with HubMirror off (verifier
|
|
391
391
|
// events are local-only on first ship).
|
|
392
392
|
try {
|
|
393
|
-
const enabled = String(process.env.EVOLVE_RECALL_VERIFY || '
|
|
393
|
+
const enabled = String(process.env.EVOLVE_RECALL_VERIFY || '0') === '1';
|
|
394
394
|
const sampleRateRaw = Number(process.env.EVOLVE_RECALL_VERIFY_SAMPLE_RATE);
|
|
395
395
|
const sampleRate = Number.isFinite(sampleRateRaw) && sampleRateRaw >= 0 && sampleRateRaw <= 1 ? sampleRateRaw : 1.0;
|
|
396
396
|
if (!enabled) {
|
|
397
|
-
console.log('[RecallVerify] DISABLED —
|
|
397
|
+
console.log('[RecallVerify] DISABLED (default) — opt-in observability only. Set EVOLVE_RECALL_VERIFY=1 to verify published assets round-trip via Hub Phase 2 lookup.');
|
|
398
398
|
} else {
|
|
399
399
|
console.log(`[RecallVerify] ENABLED — verifying published assets via Hub Phase 2 lookup, sample_rate=${sampleRate}. Set EVOLVE_RECALL_VERIFY=0 to disable.`);
|
|
400
400
|
}
|
|
@@ -451,7 +451,7 @@ async function main() {
|
|
|
451
451
|
// RecallVerify worker: starts once per process; drains the publish-
|
|
452
452
|
// verification queue with backoff. unref'd so it never blocks exit.
|
|
453
453
|
try {
|
|
454
|
-
if (String(process.env.EVOLVE_RECALL_VERIFY || '
|
|
454
|
+
if (String(process.env.EVOLVE_RECALL_VERIFY || '0') === '1') {
|
|
455
455
|
require('./src/gep/recallVerifier').startWorker();
|
|
456
456
|
}
|
|
457
457
|
} catch (rvStartErr) {
|
|
@@ -491,10 +491,11 @@ async function main() {
|
|
|
491
491
|
console.warn('[ATP] Auto-init failed: ' + (atpInitErr && atpInitErr.message || atpInitErr));
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
-
// ATP: capability-gap auto-buyer.
|
|
495
|
-
//
|
|
496
|
-
//
|
|
497
|
-
//
|
|
494
|
+
// ATP: capability-gap auto-buyer. OPT-IN as of consent-required
|
|
495
|
+
// change — new installs do not auto-spend until the user explicitly
|
|
496
|
+
// runs `evolver atp enable` or answers `y` at the first-run prompt.
|
|
497
|
+
// Also starts the merchant-side auto-deliver daemon so claimed ATP
|
|
498
|
+
// tasks actually call submitDelivery and settle instead of expiring.
|
|
498
499
|
try {
|
|
499
500
|
try {
|
|
500
501
|
const { runPrompt } = require('./src/atp/cliAutobuyPrompt');
|
|
@@ -502,16 +503,31 @@ async function main() {
|
|
|
502
503
|
} catch (promptErr) {
|
|
503
504
|
console.warn('[ATP-AutoBuyer] first-run prompt failed: ' + (promptErr && promptErr.message || promptErr));
|
|
504
505
|
}
|
|
505
|
-
const
|
|
506
|
-
const
|
|
507
|
-
if (
|
|
506
|
+
const { autoBuyer } = require('./src/atp');
|
|
507
|
+
const consent = autoBuyer.getConsent();
|
|
508
|
+
if (consent.enabled) {
|
|
508
509
|
const hubUrl = process.env.A2A_HUB_URL || process.env.EVOMAP_HUB_URL || '';
|
|
509
510
|
if (hubUrl) {
|
|
510
|
-
const { autoBuyer } = require('./src/atp');
|
|
511
511
|
autoBuyer.start({
|
|
512
512
|
dailyCap: Number(process.env.ATP_AUTOBUY_DAILY_CAP_CREDITS) || undefined,
|
|
513
513
|
perOrderCap: Number(process.env.ATP_AUTOBUY_PER_ORDER_CAP_CREDITS) || undefined,
|
|
514
514
|
});
|
|
515
|
+
if (consent.source === 'default') {
|
|
516
|
+
// First-run on a non-TTY (daemon, hook, CI) where the prompt
|
|
517
|
+
// could not fire AND no env override + no ack file. autoBuyer
|
|
518
|
+
// is starting with the default-on policy — surface a single
|
|
519
|
+
// WARN per process so users see what is happening and how to
|
|
520
|
+
// opt out, instead of discovering it via a credit balance dip.
|
|
521
|
+
let safeHubUrl;
|
|
522
|
+
try { safeHubUrl = new URL(hubUrl).origin; }
|
|
523
|
+
catch { safeHubUrl = '(configured)'; }
|
|
524
|
+
console.warn('[ATP-AutoBuyer] ATP auto-spend is ON (default for new installs).');
|
|
525
|
+
console.warn(' Hub: ' + safeHubUrl + ' Caps: ' +
|
|
526
|
+
(process.env.ATP_AUTOBUY_DAILY_CAP_CREDITS || '50') + ' credits/day, ' +
|
|
527
|
+
(process.env.ATP_AUTOBUY_PER_ORDER_CAP_CREDITS || '10') + '/order' +
|
|
528
|
+
' (cold-start half-cap for the first 5 min).');
|
|
529
|
+
console.warn(' To opt out: evolver atp disable (or EVOLVER_ATP_AUTOBUY=off)');
|
|
530
|
+
}
|
|
515
531
|
} else {
|
|
516
532
|
console.warn('[ATP-AutoBuyer] autobuy enabled but no hub URL configured, skipping.');
|
|
517
533
|
}
|
|
@@ -1815,7 +1831,7 @@ async function main() {
|
|
|
1815
1831
|
process.exit(1);
|
|
1816
1832
|
}
|
|
1817
1833
|
|
|
1818
|
-
} else if (command === 'buy' || command === 'orders' || command === 'verify') {
|
|
1834
|
+
} else if (command === 'buy' || command === 'orders' || command === 'verify' || command === 'atp') {
|
|
1819
1835
|
try {
|
|
1820
1836
|
const atpCli = require('./src/atp/cli');
|
|
1821
1837
|
const subArgs = args.slice(1); // drop the command token (e.g. "buy") itself
|
|
@@ -1827,9 +1843,12 @@ async function main() {
|
|
|
1827
1843
|
} else if (command === 'orders') {
|
|
1828
1844
|
parsed = atpCli.parseOrdersArgs(subArgs);
|
|
1829
1845
|
runner = atpCli.runOrders;
|
|
1830
|
-
} else {
|
|
1846
|
+
} else if (command === 'verify') {
|
|
1831
1847
|
parsed = atpCli.parseVerifyArgs(subArgs);
|
|
1832
1848
|
runner = atpCli.runVerify;
|
|
1849
|
+
} else {
|
|
1850
|
+
parsed = atpCli.parseAtpArgs(subArgs);
|
|
1851
|
+
runner = atpCli.runAtp;
|
|
1833
1852
|
}
|
|
1834
1853
|
if (!parsed.ok) {
|
|
1835
1854
|
console.error('[ATP] ' + parsed.error);
|
|
@@ -1844,7 +1863,7 @@ async function main() {
|
|
|
1844
1863
|
}
|
|
1845
1864
|
|
|
1846
1865
|
} else {
|
|
1847
|
-
console.log(`Usage: node index.js [run|/evolve|solidify|review|distill|fetch|sync|asset-log|webui|setup-hooks|buy|orders|verify|atp-complete] [--loop]
|
|
1866
|
+
console.log(`Usage: node index.js [run|/evolve|solidify|review|distill|fetch|sync|asset-log|webui|setup-hooks|buy|orders|verify|atp|atp-complete] [--loop]
|
|
1848
1867
|
- fetch flags:
|
|
1849
1868
|
- --skill=<id> | -s <id> (skill ID to download)
|
|
1850
1869
|
- --out=<dir> (output directory, default: ./skills/<skill_id>)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evomap/evolver",
|
|
3
|
-
"version": "1.87.
|
|
3
|
+
"version": "1.87.2",
|
|
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": {
|
|
@@ -153,12 +153,21 @@ function assertNotSymlink(p, label) {
|
|
|
153
153
|
|
|
154
154
|
function copyHookScripts(destDir, evolverRoot) {
|
|
155
155
|
const scriptsDir = path.join(evolverRoot || __dirname, 'scripts');
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
156
|
+
// Every helper required by the entry-point hooks via `require('./_xxx')`
|
|
157
|
+
// resolves relative to the *destination* (`__dirname` after copy), so
|
|
158
|
+
// every such helper MUST appear here or the hook crashes with
|
|
159
|
+
// MODULE_NOT_FOUND at runtime. Two regressions of this shape have shipped
|
|
160
|
+
// already:
|
|
161
|
+
// - PR #94 review caught `_runtimePaths.js` missing from this list.
|
|
162
|
+
// - Issue #547 (rendigua, v1.87.0): `_memoryFiltering.js` was added to
|
|
163
|
+
// evolver-session-start.js but not here, so fresh installs failed
|
|
164
|
+
// immediately on `node .codex/hooks/evolver-session-start.js`.
|
|
165
|
+
// To keep future helpers from re-living this, the regression test in
|
|
166
|
+
// test/adapters.test.js scans every `require('./_*')` in the source
|
|
167
|
+
// adapter scripts and asserts the target file is in this list.
|
|
160
168
|
const scripts = [
|
|
161
169
|
'_runtimePaths.js',
|
|
170
|
+
'_memoryFiltering.js',
|
|
162
171
|
'evolver-session-start.js',
|
|
163
172
|
'evolver-signal-detect.js',
|
|
164
173
|
'evolver-session-end.js',
|
|
@@ -235,8 +244,14 @@ function removeEvolverHooks(filePath, { markerKey = '_evolver_managed' } = {}) {
|
|
|
235
244
|
}
|
|
236
245
|
|
|
237
246
|
function removeHookScripts(hooksDir) {
|
|
247
|
+
// Must mirror the install list above. If install copies a helper but
|
|
248
|
+
// uninstall doesn't remove it, `setup-hooks --uninstall` leaves orphan
|
|
249
|
+
// files behind that the user then has to clean up by hand (#547 fix
|
|
250
|
+
// would have introduced exactly this gap if only the install side
|
|
251
|
+
// had been updated).
|
|
238
252
|
const scripts = [
|
|
239
253
|
'_runtimePaths.js',
|
|
254
|
+
'_memoryFiltering.js',
|
|
240
255
|
'evolver-session-start.js',
|
|
241
256
|
'evolver-signal-detect.js',
|
|
242
257
|
'evolver-session-end.js',
|
package/src/atp/autoBuyer.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
// ATP Auto-Buyer (opt-
|
|
1
|
+
// ATP Auto-Buyer (opt-in: requires explicit consent before auto-spending)
|
|
2
2
|
// Converts capability gaps into ATP orders with strict budget caps and
|
|
3
|
-
// 24h question-level deduplication.
|
|
4
|
-
// EVOLVER_ATP_AUTOBUY=off. Budget caps:
|
|
3
|
+
// 24h question-level deduplication. Budget caps:
|
|
5
4
|
// ATP_AUTOBUY_DAILY_CAP_CREDITS (default 50)
|
|
6
5
|
// ATP_AUTOBUY_PER_ORDER_CAP_CREDITS (default 10)
|
|
7
6
|
// Cold-start safety: the first 5 minutes after process start use a half-cap
|
|
8
7
|
// to protect against misconfiguration loops on restart storms.
|
|
9
8
|
//
|
|
9
|
+
// Consent resolution (in order):
|
|
10
|
+
// 1. EVOLVER_ATP_AUTOBUY=on|off env — explicit operator override wins.
|
|
11
|
+
// 2. ack file at <memory>/atp-autobuy-ack.json with `{enabled: bool}` —
|
|
12
|
+
// written by first-run prompt (cliAutobuyPrompt) or `evolver atp
|
|
13
|
+
// enable|disable`.
|
|
14
|
+
// 3. No signal → OFF. New installs never auto-spend before the user has
|
|
15
|
+
// explicitly opted in (consumer protection: ATP spends real credits).
|
|
16
|
+
//
|
|
10
17
|
// Integration contract:
|
|
11
18
|
// 1) Call start({ dailyCap, perOrderCap }) once at Evolver boot. The
|
|
12
19
|
// evolve loop does this at the top of every cycle; start() is
|
|
@@ -31,6 +38,7 @@ const DEFAULT_ORDER_TIMEOUT_MS = 3000;
|
|
|
31
38
|
const COLD_START_WINDOW_MS = 5 * 60 * 1000;
|
|
32
39
|
const DEDUP_TTL_MS = 24 * 60 * 60 * 1000;
|
|
33
40
|
const LEDGER_FILENAME = 'atp-autobuyer-ledger.json';
|
|
41
|
+
const ACK_FILENAME = 'atp-autobuy-ack.json';
|
|
34
42
|
|
|
35
43
|
let _started = false;
|
|
36
44
|
let _startedAt = 0;
|
|
@@ -44,18 +52,57 @@ function _ledgerPath() {
|
|
|
44
52
|
return path.join(getMemoryDir(), LEDGER_FILENAME);
|
|
45
53
|
}
|
|
46
54
|
|
|
55
|
+
function _ackPath() {
|
|
56
|
+
return path.join(getMemoryDir(), ACK_FILENAME);
|
|
57
|
+
}
|
|
58
|
+
|
|
47
59
|
function _todayKey(now) {
|
|
48
60
|
const d = new Date(typeof now === 'number' ? now : Date.now());
|
|
49
61
|
return d.toISOString().slice(0, 10); // UTC YYYY-MM-DD
|
|
50
62
|
}
|
|
51
63
|
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
function _readAck() {
|
|
65
|
+
try {
|
|
66
|
+
const p = _ackPath();
|
|
67
|
+
if (!fs.existsSync(p)) return null;
|
|
68
|
+
const parsed = JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
69
|
+
if (!parsed || typeof parsed !== 'object') return null;
|
|
70
|
+
if (typeof parsed.enabled !== 'boolean') return null;
|
|
71
|
+
return parsed;
|
|
72
|
+
} catch (_) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Resolve consent. Returns:
|
|
78
|
+
// { enabled: true, source: 'env'|'ack'|'default' }
|
|
79
|
+
// { enabled: false, source: 'env'|'ack' }
|
|
80
|
+
// The `default` case is the new-install path (no env override, no ack file):
|
|
81
|
+
// auto-spend defaults ON, gated by the daily/per-order caps and the cold-start
|
|
82
|
+
// half-cap window. The first-run prompt and `evolver atp disable` remain the
|
|
83
|
+
// opt-out paths for users who do not want auto-spend; once an explicit ack is
|
|
84
|
+
// recorded the source flips to 'ack' and the user's choice (either way) wins
|
|
85
|
+
// over this default.
|
|
86
|
+
function getConsent() {
|
|
87
|
+
const envRaw = process.env.EVOLVER_ATP_AUTOBUY;
|
|
88
|
+
if (typeof envRaw === 'string') {
|
|
89
|
+
// Trim BEFORE the length check so whitespace-only values
|
|
90
|
+
// (e.g. EVOLVER_ATP_AUTOBUY=" ") count as unset, matching the
|
|
91
|
+
// classify() helper in cliAutobuyPrompt.js. Without this alignment a
|
|
92
|
+
// whitespace value would skip the prompt in classify (treats as unset
|
|
93
|
+
// → 'eligible') but still enter this env branch, trim to "", fail to
|
|
94
|
+
// match 'off'/'0'/'false', and silently return enabled=true.
|
|
95
|
+
const s = envRaw.trim().toLowerCase();
|
|
96
|
+
if (s.length > 0) {
|
|
97
|
+
const enabled = s !== 'off' && s !== '0' && s !== 'false';
|
|
98
|
+
return { enabled, source: 'env' };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const ack = _readAck();
|
|
102
|
+
if (ack) {
|
|
103
|
+
return { enabled: ack.enabled === true, source: 'ack' };
|
|
104
|
+
}
|
|
105
|
+
return { enabled: true, source: 'default' };
|
|
59
106
|
}
|
|
60
107
|
|
|
61
108
|
function _emptyLedger() {
|
|
@@ -125,7 +172,8 @@ function _effectiveCap(value, now) {
|
|
|
125
172
|
|
|
126
173
|
function start(opts) {
|
|
127
174
|
if (_started) return;
|
|
128
|
-
|
|
175
|
+
const consent = getConsent();
|
|
176
|
+
if (!consent.enabled) return;
|
|
129
177
|
_started = true;
|
|
130
178
|
_startedAt = Date.now();
|
|
131
179
|
const dailyCap = Math.max(0, Math.floor(Number((opts && opts.dailyCap) || process.env.ATP_AUTOBUY_DAILY_CAP_CREDITS) || DEFAULT_DAILY_CAP));
|
|
@@ -213,6 +261,24 @@ async function considerOrder(opts) {
|
|
|
213
261
|
return { ok: false, error: (result && result.error) || 'unknown_error' };
|
|
214
262
|
}
|
|
215
263
|
|
|
264
|
+
// Write the consent ack file. Used by `evolver atp enable|disable` and the
|
|
265
|
+
// first-run prompt. `enabled=true` persists opt-in; `enabled=false` persists
|
|
266
|
+
// explicit opt-out so the prompt does not re-ask next session. Atomic write
|
|
267
|
+
// via .tmp + rename so a crash mid-write never produces a corrupt ack file.
|
|
268
|
+
function setConsent(enabled) {
|
|
269
|
+
const dir = getMemoryDir();
|
|
270
|
+
try { if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); } catch (_) {}
|
|
271
|
+
const body = {
|
|
272
|
+
enabled: !!enabled,
|
|
273
|
+
acknowledged_at: new Date().toISOString(),
|
|
274
|
+
version: 1,
|
|
275
|
+
};
|
|
276
|
+
const tmp = _ackPath() + '.tmp';
|
|
277
|
+
fs.writeFileSync(tmp, JSON.stringify(body, null, 2) + '\n', 'utf8');
|
|
278
|
+
fs.renameSync(tmp, _ackPath());
|
|
279
|
+
return body;
|
|
280
|
+
}
|
|
281
|
+
|
|
216
282
|
// Test-only reset, not exported by default.
|
|
217
283
|
function _resetForTests() {
|
|
218
284
|
_started = false;
|
|
@@ -225,10 +291,20 @@ function _resetForTests() {
|
|
|
225
291
|
}
|
|
226
292
|
|
|
227
293
|
module.exports = {
|
|
294
|
+
// Lifecycle.
|
|
228
295
|
start,
|
|
229
296
|
stop,
|
|
230
297
|
isStarted,
|
|
231
298
|
considerOrder,
|
|
299
|
+
// Consent surface — public API. Production callers (CLI runAtp,
|
|
300
|
+
// cliAutobuyPrompt, the daemon run loop) MUST use these, not the
|
|
301
|
+
// __internals duplicates below, so the "test-only" contract on
|
|
302
|
+
// __internals stays honest (Bugbot PR #141 R6).
|
|
303
|
+
getConsent,
|
|
304
|
+
setConsent,
|
|
305
|
+
getAckPath: _ackPath,
|
|
306
|
+
readAck: _readAck,
|
|
307
|
+
ACK_FILENAME,
|
|
232
308
|
// Exposed for tests and diagnostics only; callers should not depend on
|
|
233
309
|
// these internals in production code paths.
|
|
234
310
|
__internals: {
|
|
@@ -237,12 +313,15 @@ module.exports = {
|
|
|
237
313
|
questionHash: _questionHash,
|
|
238
314
|
effectiveCap: _effectiveCap,
|
|
239
315
|
resetForTests: _resetForTests,
|
|
316
|
+
ackPath: _ackPath,
|
|
317
|
+
readAck: _readAck,
|
|
240
318
|
constants: {
|
|
241
319
|
DEFAULT_DAILY_CAP,
|
|
242
320
|
DEFAULT_PER_ORDER_CAP,
|
|
243
321
|
COLD_START_WINDOW_MS,
|
|
244
322
|
DEDUP_TTL_MS,
|
|
245
323
|
LEDGER_FILENAME,
|
|
324
|
+
ACK_FILENAME,
|
|
246
325
|
},
|
|
247
326
|
},
|
|
248
327
|
};
|