import { describe, expect, it, vi } from 'vitest'; import { RegulatoryFindingRetrievalService } from '../../server/regulatory/regulatory-finding-retrieval'; import type { RegulatoryRetrievalCandidate, RegulatoryRetrievalRequest } from '../../src/domain/regulatory-rag'; import type { UnifiedResultProjection } from '../../src/domain/unified-result'; import { buildRegulatoryFindingQuery } from '../../src/profiles/public-search/regulatory-query'; const privateMarkers = ['Tenant Acme', '10.23.45.67', 'secret.example', 'C:\\Customer\\report.xml', 'analyst@acme.invalid']; function finding(overrides: Partial = {}): UnifiedResultProjection { return { resultProjectionId: 'projection-private', sourceKind: 'scanner-finding', sourceResultId: 'source-private', projectId: 'tenant-private', assessmentId: 'assessment-private', collectionRunId: 'run-private', sourceTool: 'purple-knight', title: `${privateMarkers[0]} has SMB signing disabled on ${privateMarkers[1]}`, description: `Host ${privateMarkers[2]} loaded ${privateMarkers[3]}`, recommendation: `Contact ${privateMarkers[4]}`, affectedAsset: privateMarkers[2], severityOriginal: 'high', severityNormalized: 'high', outcomeOriginal: 'fail', outcomeNormalized: 'fail', technicalExecutionState: 'completed', resultType: 'compliance_check', isIoe: false, isDeviation: true, lifecycleState: 'new', mappingConfidence: 1, reviewStatus: 'open', reviewOwner: privateMarkers[4], importedAt: '2026-09-15T10:00:00.000Z', createdAt: '2026-09-15T10:00:00.000Z', frameworkReferences: [], categories: [], ...overrides }; } const candidate: RegulatoryRetrievalCandidate = { score: 0.8, chunk: { schemaVersion: 1, corpusId: 'synthetic', corpusVersion: '1', documentId: 'control-de', framework: 'Synthetic Framework', frameworkVersion: '1', controlId: 'CTRL-1', chunkId: 'chunk-1', chunkIndex: 0, language: 'de', title: 'Synthetic control', text: 'Synthetic regulatory text.', textSha256: 'a'.repeat(64) } }; describe('regulatory finding retrieval boundary', () => { it('emits only fixed public concepts and never copies private finding data', () => { const query = buildRegulatoryFindingQuery(finding()); expect(query).toMatchObject({ schemaVersion: 1, specificity: 'topic', publicTool: 'Semperis Purple Knight', publicTopics: ['SMB signing requirements'] }); for (const marker of privateMarkers) expect(query?.query).not.toContain(marker); expect(query?.query).not.toContain('disabled'); }); it('allows only exact catalog-owned rule IDs', () => { expect(buildRegulatoryFindingQuery(finding({ sourceTool: 'pingcastle', sourceRuleId: 'a-krbtgt', title: privateMarkers[0], description: undefined, recommendation: undefined }))).toMatchObject({ specificity: 'rule', publicRuleId: 'A-Krbtgt' }); expect(buildRegulatoryFindingQuery(finding({ sourceTool: 'pingcastle', sourceRuleId: 'A-Customer-Private', title: privateMarkers[0], description: undefined, recommendation: undefined }))).toBeUndefined(); }); it('fails closed for non-scanner records or findings without a public signal', () => { expect(buildRegulatoryFindingQuery(finding({ sourceKind: 'environment-observation' }))).toBeUndefined(); expect(buildRegulatoryFindingQuery(finding({ sourceTool: 'customer-private-scanner', title: privateMarkers[0], description: undefined, recommendation: undefined }))).toBeUndefined(); }); it('passes only the prepared public query and explicit filters to the retriever', async () => { const retrieve = vi.fn(async (_request: RegulatoryRetrievalRequest) => [candidate]); const service = new RegulatoryFindingRetrievalService({ retrieve }); const result = await service.retrieve(finding(), 5, { framework: 'Synthetic Framework' }); expect(result).toMatchObject({ sourceResultId: 'source-private', status: 'candidates', candidates: [candidate] }); expect(retrieve).toHaveBeenCalledOnce(); expect(retrieve.mock.calls[0][0]).toEqual({ query: result.preparedQuery?.query, limit: 5, filters: { framework: 'Synthetic Framework' } }); for (const marker of privateMarkers) expect(JSON.stringify(retrieve.mock.calls[0][0])).not.toContain(marker); }); it('does not call retrieval when public context is insufficient', async () => { const retrieve = vi.fn(); const service = new RegulatoryFindingRetrievalService({ retrieve }); await expect(service.retrieve(finding({ title: privateMarkers[0], description: undefined, recommendation: undefined }), 5)) .resolves.toEqual({ sourceResultId: 'source-private', status: 'insufficient-public-context', candidates: [] }); expect(retrieve).not.toHaveBeenCalled(); }); });