Files
memind/memory-v2-shadow-audit.test.mjs
T
john 6f3e53a56a feat(memory-v2): close Phase A with auto-review, product events, and H5 recall UI.
Add candidate auto-review pipeline, shadow audit tooling, admin metrics page,
and user-visible memory recall hints in chat with phase-a readiness checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 17:14:06 +08:00

102 lines
3.0 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
auditMemoryV2Shadow,
detectFalseStoreCandidate,
formatMemoryV2ShadowAuditReport,
parseSinceArg,
} from './memory-v2-shadow-audit.mjs';
test('parseSinceArg supports hour/day/week windows', () => {
const now = Date.parse('2026-07-31T12:00:00.000Z');
assert.equal(parseSinceArg('24h', now).sinceMs, now - 86400000);
assert.equal(parseSinceArg('7d', now).sinceMs, now - 7 * 86400000);
assert.equal(parseSinceArg('2w', now).sinceMs, now - 14 * 86400000);
});
test('detectFalseStoreCandidate flags questions and routing leaks', () => {
assert.equal(detectFalseStoreCandidate('SSE 是什么?').suspicious, true);
assert.equal(detectFalseStoreCandidate('请记住我每周三做代码评审').suspicious, false);
assert.equal(
detectFalseStoreCandidate('[Memory Context] 旧记忆').code,
'routing_leak',
);
});
test('auditMemoryV2Shadow summarizes candidates and pgvector lag', () => {
const nowMs = Date.parse('2026-07-31T12:00:00.000Z');
const sinceMs = nowMs - 7 * 86400000;
const report = auditMemoryV2Shadow({
sinceMs,
nowMs,
candidates: [
{
id: 'c1',
user_id: 'u1',
memory_type: 'episodic',
content: '请记住我每周三下午做代码评审',
status: 'accepted',
policy_reason: 'explicit_memory_request',
confidence: 0.98,
importance: 0.95,
created_at: sinceMs + 1000,
updated_at: sinceMs + 1000,
},
{
id: 'c2',
user_id: 'u1',
memory_type: 'semantic',
content: 'SSE 是什么?',
status: 'candidate',
policy_reason: 'stable_fact_signal',
confidence: 0.82,
importance: 0.75,
created_at: sinceMs + 2000,
updated_at: sinceMs + 2000,
},
],
memoryItems: [
{
id: 'm1',
user_id: 'u1',
label: 'fact',
memory_text: '每周三下午做代码评审',
status: 'active',
created_at: sinceMs + 3000,
updated_at: sinceMs + 3000,
},
{
id: 'm2',
user_id: 'u2',
label: 'fact',
memory_text: '使用 pgvector 做语义检索',
status: 'active',
created_at: sinceMs + 4000,
updated_at: sinceMs + 4000,
},
],
pgvectorMemoryIds: new Set(['m1']),
pgvectorConfigured: true,
agentMemoryEvents: [
{
event_type: 'agent_memory_resolved',
created_at: sinceMs + 5000,
data_json: { count: 2 },
},
{
event_type: 'agent_memory_resolved',
created_at: sinceMs + 6000,
data_json: { count: 0 },
},
],
});
assert.equal(report.window.candidateCount, 2);
assert.equal(report.summary.suspiciousCandidateCount, 1);
assert.equal(report.pgvectorLagUsers.length, 1);
assert.equal(report.pgvectorLagUsers[0].userId, 'u2');
assert.equal(report.summary.resolveHitRate, 0.5);
assert.equal(report.ok, false);
assert.match(formatMemoryV2ShadowAuditReport(report), /pgvector lag users/);
});