@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.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/scripts/recall-verify-report.js +225 -0
  3. package/src/evolve/guards.js +1 -1
  4. package/src/evolve/pipeline/collect.js +1 -1
  5. package/src/evolve/pipeline/dispatch.js +1 -1
  6. package/src/evolve/pipeline/enrich.js +1 -1
  7. package/src/evolve/pipeline/hub.js +1 -1
  8. package/src/evolve/pipeline/select.js +1 -1
  9. package/src/evolve/pipeline/signals.js +1 -1
  10. package/src/evolve/utils.js +1 -1
  11. package/src/evolve.js +1 -1
  12. package/src/forceUpdate.js +50 -16
  13. package/src/gep/.integrity +0 -0
  14. package/src/gep/a2aProtocol.js +1 -1
  15. package/src/gep/candidateEval.js +1 -1
  16. package/src/gep/candidates.js +1 -1
  17. package/src/gep/contentHash.js +1 -1
  18. package/src/gep/crypto.js +1 -1
  19. package/src/gep/curriculum.js +1 -1
  20. package/src/gep/deviceId.js +1 -1
  21. package/src/gep/envFingerprint.js +1 -1
  22. package/src/gep/epigenetics.js +1 -1
  23. package/src/gep/explore.js +1 -1
  24. package/src/gep/hash.js +1 -1
  25. package/src/gep/hubReview.js +1 -1
  26. package/src/gep/hubSearch.js +1 -1
  27. package/src/gep/hubVerify.js +1 -1
  28. package/src/gep/integrityCheck.js +1 -1
  29. package/src/gep/learningSignals.js +1 -1
  30. package/src/gep/memoryGraph.js +1 -1
  31. package/src/gep/memoryGraphAdapter.js +1 -1
  32. package/src/gep/mutation.js +1 -1
  33. package/src/gep/narrativeMemory.js +1 -1
  34. package/src/gep/openPRRegistry.js +1 -1
  35. package/src/gep/paths.js +20 -0
  36. package/src/gep/personality.js +1 -1
  37. package/src/gep/policyCheck.js +1 -1
  38. package/src/gep/prompt.js +1 -1
  39. package/src/gep/recallVerifier.js +306 -0
  40. package/src/gep/reflection.js +1 -1
  41. package/src/gep/selector.js +1 -1
  42. package/src/gep/shield.js +1 -1
  43. package/src/gep/skillDistiller.js +1 -1
  44. package/src/gep/solidify.js +1 -1
  45. 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.0",
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 };