@evomap/evolver 1.82.0 → 1.82.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.
- package/package.json +1 -1
- package/scripts/recall-verify-report.js +225 -0
- 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 +50 -16
- package/src/gep/.integrity +0 -0
- 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/hubReview.js +1 -1
- package/src/gep/hubSearch.js +1 -1
- package/src/gep/hubVerify.js +1 -1
- package/src/gep/integrityCheck.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/paths.js +20 -0
- 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 +306 -0
- package/src/gep/reflection.js +1 -1
- package/src/gep/selector.js +1 -1
- package/src/gep/shield.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evomap/evolver",
|
|
3
|
-
"version": "1.82.
|
|
3
|
+
"version": "1.82.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": {
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// recall-verify-report — aggregate kind=recall_verify events from the
|
|
5
|
+
// memory graph jsonl into a Markdown table. Exit 0 = ship gate green
|
|
6
|
+
// (every asset_type has success_rate >= 0.95 and 0 mismatches), exit 2
|
|
7
|
+
// otherwise. Designed to be scripted into deploy.sh as a pre-publish gate.
|
|
8
|
+
//
|
|
9
|
+
// Usage:
|
|
10
|
+
// node scripts/recall-verify-report.js # all events
|
|
11
|
+
// node scripts/recall-verify-report.js --since 1h # last hour
|
|
12
|
+
// node scripts/recall-verify-report.js --since 30m
|
|
13
|
+
// node scripts/recall-verify-report.js --since 2026-05-16T10:00:00Z
|
|
14
|
+
// node scripts/recall-verify-report.js --json # raw JSON for piping
|
|
15
|
+
|
|
16
|
+
const { tryReadMemoryGraphEvents } = require('../src/gep/memoryGraph');
|
|
17
|
+
|
|
18
|
+
const SUCCESS_THRESHOLD = 0.95;
|
|
19
|
+
|
|
20
|
+
function parseSince(value) {
|
|
21
|
+
if (!value) return null;
|
|
22
|
+
// Try relative duration first (1h / 30m / 2d / 45s) — unambiguous.
|
|
23
|
+
const m = String(value).match(/^(\d+)\s*(s|m|h|d)$/i);
|
|
24
|
+
if (m) {
|
|
25
|
+
const n = Number(m[1]);
|
|
26
|
+
const unit = m[2].toLowerCase();
|
|
27
|
+
const factor = unit === 's' ? 1000 : unit === 'm' ? 60000 : unit === 'h' ? 3600000 : 86400000;
|
|
28
|
+
return Date.now() - (n * factor);
|
|
29
|
+
}
|
|
30
|
+
// Then ISO-8601. Require '-' or 'T' so we don't accept loose numeric
|
|
31
|
+
// strings like "5" → year 2001.
|
|
32
|
+
if (/[-T]/.test(String(value))) {
|
|
33
|
+
const iso = Date.parse(value);
|
|
34
|
+
if (!Number.isNaN(iso)) return iso;
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parseArgs(argv) {
|
|
40
|
+
const args = { since: null, json: false };
|
|
41
|
+
for (let i = 2; i < argv.length; i++) {
|
|
42
|
+
const a = argv[i];
|
|
43
|
+
if (a === '--json') args.json = true;
|
|
44
|
+
else if (a === '--since') {
|
|
45
|
+
args.since = argv[++i];
|
|
46
|
+
} else if (a.startsWith('--since=')) {
|
|
47
|
+
args.since = a.slice('--since='.length);
|
|
48
|
+
} else if (a === '--help' || a === '-h') {
|
|
49
|
+
args.help = true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return args;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function percentile(sorted, p) {
|
|
56
|
+
if (!sorted.length) return 0;
|
|
57
|
+
const idx = Math.min(sorted.length - 1, Math.floor(sorted.length * p));
|
|
58
|
+
return sorted[idx];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function aggregate(events) {
|
|
62
|
+
const byType = new Map();
|
|
63
|
+
for (const ev of events) {
|
|
64
|
+
if (!ev || ev.kind !== 'recall_verify') continue;
|
|
65
|
+
const type = (ev.asset && ev.asset.type) || 'Unknown';
|
|
66
|
+
if (!byType.has(type)) {
|
|
67
|
+
byType.set(type, {
|
|
68
|
+
type,
|
|
69
|
+
total: 0,
|
|
70
|
+
ok: 0,
|
|
71
|
+
missing: 0,
|
|
72
|
+
mismatch: 0,
|
|
73
|
+
skipped: 0,
|
|
74
|
+
latencies: [],
|
|
75
|
+
ages: [],
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const bucket = byType.get(type);
|
|
79
|
+
bucket.total += 1;
|
|
80
|
+
const v = ev.verification || {};
|
|
81
|
+
if (v.outcome === 'roundtrip_ok') bucket.ok += 1;
|
|
82
|
+
else if (v.outcome === 'roundtrip_missing') bucket.missing += 1;
|
|
83
|
+
else if (v.outcome === 'roundtrip_mismatch') bucket.mismatch += 1;
|
|
84
|
+
else bucket.skipped += 1;
|
|
85
|
+
if (Number.isFinite(v.latency_ms)) bucket.latencies.push(v.latency_ms);
|
|
86
|
+
if (Number.isFinite(v.age_at_verify_ms)) bucket.ages.push(v.age_at_verify_ms);
|
|
87
|
+
}
|
|
88
|
+
const rows = [];
|
|
89
|
+
for (const bucket of byType.values()) {
|
|
90
|
+
const denom = bucket.ok + bucket.missing + bucket.mismatch;
|
|
91
|
+
bucket.success_rate = denom > 0 ? bucket.ok / denom : 0;
|
|
92
|
+
bucket.latencies.sort(function (a, b) { return a - b; });
|
|
93
|
+
bucket.ages.sort(function (a, b) { return a - b; });
|
|
94
|
+
bucket.p50_latency_ms = percentile(bucket.latencies, 0.5);
|
|
95
|
+
bucket.p95_latency_ms = percentile(bucket.latencies, 0.95);
|
|
96
|
+
bucket.p99_latency_ms = percentile(bucket.latencies, 0.99);
|
|
97
|
+
bucket.p50_age_ms = percentile(bucket.ages, 0.5);
|
|
98
|
+
bucket.p95_age_ms = percentile(bucket.ages, 0.95);
|
|
99
|
+
bucket.p99_age_ms = percentile(bucket.ages, 0.99);
|
|
100
|
+
delete bucket.latencies;
|
|
101
|
+
delete bucket.ages;
|
|
102
|
+
rows.push(bucket);
|
|
103
|
+
}
|
|
104
|
+
rows.sort(function (a, b) { return a.type.localeCompare(b.type); });
|
|
105
|
+
|
|
106
|
+
const totals = { type: 'TOTAL', total: 0, ok: 0, missing: 0, mismatch: 0, skipped: 0 };
|
|
107
|
+
for (const r of rows) {
|
|
108
|
+
totals.total += r.total;
|
|
109
|
+
totals.ok += r.ok;
|
|
110
|
+
totals.missing += r.missing;
|
|
111
|
+
totals.mismatch += r.mismatch;
|
|
112
|
+
totals.skipped += r.skipped;
|
|
113
|
+
}
|
|
114
|
+
const totalsDenom = totals.ok + totals.missing + totals.mismatch;
|
|
115
|
+
totals.success_rate = totalsDenom > 0 ? totals.ok / totalsDenom : 0;
|
|
116
|
+
|
|
117
|
+
let gate = 'GREEN';
|
|
118
|
+
if (rows.length === 0) gate = 'RED';
|
|
119
|
+
else {
|
|
120
|
+
for (const r of rows) {
|
|
121
|
+
if (r.mismatch > 0) { gate = 'RED'; break; }
|
|
122
|
+
if (r.success_rate < SUCCESS_THRESHOLD) {
|
|
123
|
+
gate = r.success_rate >= 0.85 ? 'YELLOW' : 'RED';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return { rows, totals, gate };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function fmtPct(rate) {
|
|
131
|
+
return (rate * 100).toFixed(1) + '%';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function fmtMs(n) {
|
|
135
|
+
if (!Number.isFinite(n) || n === 0) return '—';
|
|
136
|
+
if (n < 1000) return Math.round(n) + 'ms';
|
|
137
|
+
return (n / 1000).toFixed(1) + 's';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function printMarkdown(result, since) {
|
|
141
|
+
const sinceStr = since ? new Date(since).toISOString() : 'all time';
|
|
142
|
+
console.log('# RecallVerify Report (since ' + sinceStr + ')');
|
|
143
|
+
console.log('');
|
|
144
|
+
if (result.rows.length === 0) {
|
|
145
|
+
console.log('_No `recall_verify` events found in memory graph._');
|
|
146
|
+
console.log('');
|
|
147
|
+
console.log('Ship gate: **RED** (no data — feature may be disabled or daemon has not run a publish cycle yet)');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
console.log('| asset_type | total | ok | missing | mismatch | skipped | success_rate | p50_latency | p99_latency | p50_age | p99_age |');
|
|
151
|
+
console.log('|--------------|------:|----:|--------:|---------:|--------:|-------------:|------------:|------------:|--------:|--------:|');
|
|
152
|
+
for (const r of result.rows) {
|
|
153
|
+
console.log('| ' + r.type.padEnd(12) +
|
|
154
|
+
' | ' + String(r.total).padStart(5) +
|
|
155
|
+
' | ' + String(r.ok).padStart(3) +
|
|
156
|
+
' | ' + String(r.missing).padStart(7) +
|
|
157
|
+
' | ' + String(r.mismatch).padStart(8) +
|
|
158
|
+
' | ' + String(r.skipped).padStart(7) +
|
|
159
|
+
' | ' + fmtPct(r.success_rate).padStart(12) +
|
|
160
|
+
' | ' + fmtMs(r.p50_latency_ms).padStart(11) +
|
|
161
|
+
' | ' + fmtMs(r.p99_latency_ms).padStart(11) +
|
|
162
|
+
' | ' + fmtMs(r.p50_age_ms).padStart(7) +
|
|
163
|
+
' | ' + fmtMs(r.p99_age_ms).padStart(7) +
|
|
164
|
+
' |');
|
|
165
|
+
}
|
|
166
|
+
const t = result.totals;
|
|
167
|
+
console.log('| ' + 'TOTAL'.padEnd(12) +
|
|
168
|
+
' | ' + String(t.total).padStart(5) +
|
|
169
|
+
' | ' + String(t.ok).padStart(3) +
|
|
170
|
+
' | ' + String(t.missing).padStart(7) +
|
|
171
|
+
' | ' + String(t.mismatch).padStart(8) +
|
|
172
|
+
' | ' + String(t.skipped).padStart(7) +
|
|
173
|
+
' | ' + fmtPct(t.success_rate).padStart(12) +
|
|
174
|
+
' | ' + '—'.padStart(11) +
|
|
175
|
+
' | ' + '—'.padStart(11) +
|
|
176
|
+
' | ' + '—'.padStart(7) +
|
|
177
|
+
' | ' + '—'.padStart(7) +
|
|
178
|
+
' |');
|
|
179
|
+
console.log('');
|
|
180
|
+
console.log('Ship gate: **' + result.gate + '**' + (result.gate === 'GREEN' ? ' (exit 0)' : ' (exit 2)'));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function main() {
|
|
184
|
+
const args = parseArgs(process.argv);
|
|
185
|
+
if (args.help) {
|
|
186
|
+
console.log('Usage: node scripts/recall-verify-report.js [--since <Nh|Nm|Nd|ISO>] [--json]');
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let sinceMs = null;
|
|
191
|
+
if (args.since) {
|
|
192
|
+
const parsed = parseSince(args.since);
|
|
193
|
+
if (parsed === undefined) {
|
|
194
|
+
console.error('Error: --since must be ISO-8601 or a duration like 1h / 30m / 2d (got: ' + args.since + ')');
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
sinceMs = parsed;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const allEvents = tryReadMemoryGraphEvents(20000);
|
|
201
|
+
const filtered = allEvents.filter(function (ev) {
|
|
202
|
+
if (!ev || ev.kind !== 'recall_verify') return false;
|
|
203
|
+
if (sinceMs != null && Number.isFinite(ev.ts) && ev.ts < sinceMs) return false;
|
|
204
|
+
return true;
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const result = aggregate(filtered);
|
|
208
|
+
|
|
209
|
+
if (args.json) {
|
|
210
|
+
console.log(JSON.stringify({
|
|
211
|
+
since: sinceMs ? new Date(sinceMs).toISOString() : null,
|
|
212
|
+
...result,
|
|
213
|
+
}, null, 2));
|
|
214
|
+
} else {
|
|
215
|
+
printMarkdown(result, sinceMs);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
process.exit(result.gate === 'GREEN' ? 0 : 2);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (require.main === module) {
|
|
222
|
+
main();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
module.exports = { aggregate, parseSince, parseArgs };
|