Assessor_2.0/src/profiles/public-search/regulatory-query.ts

55 lines
2.4 KiB
TypeScript

import type { RegulatoryFindingQuery } from '../../domain/regulatory-rag';
import { REGULATORY_FINDING_QUERY_SCHEMA_VERSION } from '../../domain/regulatory-rag';
import type { UnifiedResultProjection } from '../../domain/unified-result';
import catalog from './catalog.json';
import { publicSecurityTopics } from './public-security-topics';
const publicTools: Record<string, string> = {
'cis-cat': 'CIS-CAT / CIS Benchmarks',
maester: 'Maester',
pingcastle: 'PingCastle',
'purple-knight': 'Semperis Purple Knight'
};
const publicRuleIds: Record<string, readonly string[]> = {
maester: catalog.maesterIds,
pingcastle: catalog.pingcastleIds
};
/**
* Builds an embedding query only from catalog-owned identifiers and fixed public
* concepts. Raw finding prose is inspected locally for topic recognition and is
* never copied into the returned query.
*/
export function buildRegulatoryFindingQuery(finding: UnifiedResultProjection): RegulatoryFindingQuery | undefined {
if (finding.sourceKind !== 'scanner-finding') return undefined;
const toolId = finding.sourceTool?.trim().toLowerCase() ?? '';
const publicTool = publicTools[toolId];
const publicRuleId = recognizedRuleId(toolId, finding.sourceRuleId);
const evidence = [finding.title, finding.description, finding.recommendation].filter(Boolean).join('\n').slice(0, 20_000);
const topics = publicSecurityTopics(evidence);
if (!publicRuleId && !topics.length) return undefined;
const specificity = publicRuleId ? 'rule' : 'topic';
const query = [
'Retrieve regulatory controls whose normative requirements directly address this security finding.',
publicTool && `Public assessment tool: ${publicTool}.`,
publicRuleId && `Public rule ID: ${publicRuleId}.`,
topics.length && `Public technical topics: ${topics.join('; ')}.`,
'Prefer controls with direct requirement text over merely related guidance. Do not infer customer scope, assets, configuration values, or compliance status.'
].filter(Boolean).join(' ');
return {
schemaVersion: REGULATORY_FINDING_QUERY_SCHEMA_VERSION,
query,
specificity,
...(publicTool ? { publicTool } : {}),
...(publicRuleId ? { publicRuleId } : {}),
publicTopics: topics
};
}
function recognizedRuleId(toolId: string, value: string | undefined): string | undefined {
const candidate = value?.trim();
if (!candidate) return undefined;
return publicRuleIds[toolId]?.find(id => id.toLowerCase() === candidate.toLowerCase());
}