Files
breakpilot-compliance/admin-compliance/lib/sdk/advisor/regulation-display.ts
T
Benjamin Admin 5a513181cc feat(advisor): Clarity-Gate orchestration in route.ts (consumes /retrieve)
Completes the advisor stack (FE + orchestration; /retrieve is SDK/RAG-owned). The route
now returns the FE contract instead of a text stream:
- retrieveFull() calls /retrieve with {query, context}; consumes clarity/evidence/
  visual_evidence/footnotes (exact shape per board 2026-07-01 12:25).
- mode-routing (resolveMode): clarify unless a context was chosen and /retrieve's
  clarity.mode says so. clarify -> L1 general answer (completeAdvisorAnswer, ungrounded,
  no sources). answer -> L2 answer over numbered evidence with [n] markers.
- citations generated here ([n] -> nth evidence unit); footnotes remapped; evidence /
  visual_evidence passed through.
- advisor-llm: non-streaming completeAdvisorAnswer(). Pure mappings in retrieve-mapping.ts
  (+ tests). Removed the dead v2 evidence.ts/evidence-adapter (RegulationRef moved to
  regulation-display). controls-augmentation kept (tested; re-integrable later).

NOT deployed: joint deploy with the SDK /retrieve endpoint (deploy-coupling). tsc clean,
25 vitest (mapping/clarify/answer/markdown/registry/rag), check-loc 0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-01 12:39:47 +02:00

58 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Human-readable display for regulations. Maps messy codes/short-names to a stable FAMILY key +
// friendly label (+ chapter for multi-part works like the DSK SDM). Presentation layer only:
// it bridges G2 (clean RAG metadata) and keeps working once codes are clean. Extend the table freely.
export interface RegulationRef {
code?: string
name?: string
short?: string
}
export interface RegulationDisplay {
familyKey: string // stable key used to GROUP evidence
familyLabel: string // human-readable regulation name
chapter?: string // e.g. "B51" for a DSK SDM building block
}
interface Rule {
test: RegExp
key: string
label: string
chapter?: RegExp
}
// Order matters: more specific patterns first.
const RULES: Rule[] = [
{
test: /dsk.?sdm|standard.?datenschutzmodell|(^|[^a-z])sdm([^a-z]|$)/i,
key: 'dsk_sdm',
label: 'DSK Standard-Datenschutzmodell (SDM)',
chapter: /\b([A-Z]\d{1,3})\b/,
},
{ test: /cyber.?resilience|(^|[^a-z])cra([^a-z]|$)/i, key: 'cra', label: 'Cyber Resilience Act (CRA)' },
{ test: /(^|[^a-z])nis.?2([^a-z]|$)/i, key: 'nis2', label: 'NIS2-Richtlinie' },
{ test: /data.?privacy.?framework|(^|[^a-z])dpf([^a-z]|$)/i, key: 'dpf', label: 'EU-US Data Privacy Framework' },
{ test: /maschinen|2023.?1230/i, key: 'maschinenvo', label: 'Maschinenverordnung (EU) 2023/1230' },
{ test: /ds.?gvo|gdpr/i, key: 'dsgvo', label: 'DSGVO Datenschutz-Grundverordnung' },
{ test: /(^|[^a-z])bdsg([^a-z]|$)/i, key: 'bdsg', label: 'BDSG Bundesdatenschutzgesetz' },
{ test: /tdddg|ttdsg/i, key: 'tddg', label: 'TDDDG (Digitale-Dienste-Datenschutz)' },
{ test: /edpb|edsa|(^|[^a-z])wp\s?\d+/i, key: 'edpb', label: 'EDPB / DSK Leitlinien' },
{ test: /(^|[^a-z])bsi([^a-z]|$)/i, key: 'bsi', label: 'BSI' },
]
export function resolveRegulation(reg: RegulationRef): RegulationDisplay {
const hay = `${reg.code || ''} ${reg.short || ''} ${reg.name || ''}`
for (const r of RULES) {
if (r.test.test(hay)) {
const chapter = r.chapter
? r.chapter.exec(reg.short || reg.code || '')?.[1] || undefined
: undefined
return { familyKey: r.key, familyLabel: r.label, chapter }
}
}
return {
familyKey: reg.code || reg.short || 'unknown',
familyLabel: reg.short || reg.name || reg.code || 'Regelwerk',
}
}