import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { loadScenarioCatalog } from './catalog.mjs'; import { loadActiveRegressionCorpus, validateRegressionFixture, } from './regression-corpus.mjs'; function fixture(overrides = {}) { return { id: 'PRC-AGENT-001', scenario_ids: ['AGENT-11'], failure_signature: 'worker heartbeat expired', synthetic_intent: '生成一个合成测试页面', source_batch_id: 'audit-2026-07-26', evidence_digest: 'a'.repeat(64), contains_personal_data: false, privacy_review: { reviewed_by: 'release-reviewer', reviewed_at: '2026-07-26T10:00:00.000Z', }, automation: { command: ['node', '--test', 'fixture.test.mjs'], }, ...overrides, }; } test('regression fixture requires scenario mapping, privacy review, and executable replay', async () => { const catalog = await loadScenarioCatalog(); assert.deepEqual( validateRegressionFixture(fixture(), { catalogIds: new Set(catalog.map((scenario) => scenario.id)), }), { valid: true, errors: [] }, ); }); test('regression fixture rejects raw production identity and content fields', () => { const validation = validateRegressionFixture(fixture({ raw_chat: 'private', openid: 'should-not-exist', contains_personal_data: true, })); assert.equal(validation.valid, false); assert.match(validation.errors.join('\n'), /contains_personal_data/); assert.match(validation.errors.join('\n'), /raw_chat/); assert.match(validation.errors.join('\n'), /openid/); }); test('missing active production regression manifest fails closed', async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), 'memind-regression-corpus-')); try { const catalog = await loadScenarioCatalog(); const result = await loadActiveRegressionCorpus({ root, catalog }); assert.equal(result.status, 'missing'); assert.equal(result.fixtures.length, 0); } finally { await fs.rm(root, { recursive: true, force: true }); } });