MCPcopy Create free account
hub / github.com/EvoMap/evolver / aggregate

Function aggregate

scripts/recall-verify-report.js:61–137  ·  view source on GitHub ↗
(events)

Source from the content-addressed store, hash-verified

59}
60
61function 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 // Gate severity is monotonic: once a row triggers a worse state, later
118 // rows cannot downgrade it. Without this, AntiPattern@0% (RED) followed

Callers 2

mainFunction · 0.85

Calls 2

percentileFunction · 0.85
escalateFunction · 0.85

Tested by

no test coverage detected