feat(ai-act-kompass): internal process documents (reporting policy, approval, audit)

- Internal reporting & escalation policy: internal reporting duty for
  AI incidents with 24h/48h internal deadlines, three escalation
  levels, incident register, whistleblower protection note — feeds the
  statutory Art. 73 report
- AI system approval request form: internal gate against shadow AI
  with risk pre-screening and decision block
- Internal AI compliance audit checklist: periodic self-review
  (inventory/shadow IT, classifications, trainings, logs, incidents,
  provider documents, works agreements, country-module changes) with
  sign-off
- All bilingual (DE/EN), letterhead-printable; 4 new tests (56 total)

Claude-Session: https://claude.ai/code/session_017YjohVNx1ZGNM4MX7tHpfv
This commit is contained in:
Claude 2026-07-04 09:50:23 +00:00
parent 2ec13165c8
commit 45c8c9557d
No known key found for this signature in database
4 changed files with 244 additions and 1 deletions

View File

@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
import { CONTENT_PACK, getContentPack } from '../content/pack';
import { classify } from './classify';
import { aiPolicy, trainingPlan, worksAgreement } from './templatesCompany';
import { approvalRequest, auditChecklist, reportingPolicy } from './templatesInternal';
import { employeeInfo, friaTemplate, incidentReportForm, worksCouncilInfo } from './templatesSystem';
import type { AISystem, AssessmentAnswers, CompanyProfile } from './types';
@ -102,3 +103,35 @@ describe('unternehmensweite Vorlagen', () => {
expect(md).toContain('Betriebsrat: _______________');
});
});
describe('interne Prozess-Dokumente', () => {
it('Melderichtlinie enthält interne Fristen, Eskalationsstufen und HinSchG-Schutz', () => {
const md = reportingPolicy(CONTENT_PACK, TODAY, profile);
expect(md).toContain('interne Meldepflicht');
expect(md).toContain('24 Stunden');
expect(md).toContain('Eskalationsstufen');
expect(md).toContain('HinSchG');
expect(md).toContain('Art. 73');
});
it('Freigabeantrag enthält Prüffelder und Entscheidungsblock', () => {
const md = approvalRequest(CONTENT_PACK, TODAY, profile);
expect(md).toContain('Freigabeantrag');
expect(md).toContain('Risiko-Voreinschätzung');
expect(md).toContain('☐ freigegeben');
expect(md).toContain('KI-Inventar');
});
it('Audit-Checkliste enthält nummerierte Prüfpunkte und Abzeichnung', () => {
const md = auditChecklist(CONTENT_PACK, TODAY, profile);
expect(md).toContain('| 1 |');
expect(md).toContain('Schatten-IT');
expect(md).toContain('Abzeichnung');
});
it('interne Dokumente sind auch auf Englisch verfügbar', () => {
const md = reportingPolicy(getContentPack('en'), TODAY, profile, 'en');
expect(md).toContain('escalation policy');
expect(md).toContain('within 24 hours');
});
});

View File

@ -0,0 +1,179 @@
import type { Locale } from '../i18n/types';
import { docStrings, formatDocDate } from './docStrings';
import type { CompanyProfile, ContentPack } from './types';
/** Gemeinsamer Kopf für interne Prozess-Dokumente. */
function head(
title: string,
pack: ContentPack,
today: string,
locale: Locale,
profile?: CompanyProfile,
): string {
const s = docStrings(locale);
const company = profile && profile.name.trim() !== '' ? profile.name : '_______________';
return [
`# ${title}`,
'',
`**${s.meta.company}:** ${company} · **${s.meta.createdAt}:** ${formatDocDate(today, locale)} · Content-Pack v${pack.version}`,
'',
s.disclaimer,
'',
].join('\n');
}
/**
* Vordruck: Interne Melde- und Eskalationsrichtlinie für KI-Vorfälle
* (interne Meldepflicht Prozess, der die Art.-73-Meldung vorbereitet).
*/
export function reportingPolicy(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const T = locale === 'en'
? {
title: 'Internal reporting and escalation policy for AI incidents (draft)',
sections: [
['1. Purpose', 'This policy defines the internal reporting duty for malfunctions and incidents involving AI systems. It ensures that the company can meet its statutory reporting deadlines (Art. 73 EU AI Act: 15 days, death 10 days, widespread infringement/critical infrastructure 2 days).'],
['2. What must be reported', 'Every employee reports without undue delay: (a) malfunctions or unexpected behaviour of an AI system, (b) suspected harm to health, safety or fundamental rights, (c) suspected discrimination by AI-supported decisions, (d) data protection incidents involving AI, (e) circumvention of human oversight.'],
['3. Reporting channel', 'First report to: AI officer [name, contact] — verbally or via [channel]. If unavailable: [deputy]. Reports may also be made confidentially; whistleblower protection under the applicable whistleblowing rules remains unaffected.'],
['4. Internal deadlines', 'Report by employee: immediately, at the latest within 24 hours of becoming aware. Initial assessment by AI officer: within 48 hours. Decision on external report (Art. 73) with management: without undue delay, so that the statutory deadlines are met.'],
['5. Escalation levels', 'Level 1: AI officer (assessment, containment). Level 2: management + data protection officer + legal. Level 3: external report to the market surveillance authority and, where applicable, information of the provider (Art. 26(5)) and affected persons.'],
['6. Documentation', 'Every report is documented using the serious incident report form and retained for at least [5] years. The AI officer maintains the incident register.'],
['7. No sanctions for good-faith reports', 'Employees who report in good faith must not suffer any disadvantage.'],
['8. Entry into force', 'This policy enters into force on [date].'],
],
}
: {
title: 'Interne Melde- und Eskalationsrichtlinie für KI-Vorfälle (Entwurf)',
sections: [
['1. Zweck', 'Diese Richtlinie regelt die interne Meldepflicht für Störungen und Vorfälle im Zusammenhang mit KI-Systemen. Sie stellt sicher, dass das Unternehmen die gesetzlichen Meldefristen einhalten kann (Art. 73 EU-KI-VO: 15 Tage, Todesfall 10 Tage, weitverbreiteter Verstoß/kritische Infrastruktur 2 Tage).'],
['2. Was zu melden ist', 'Jede/r Beschäftigte meldet unverzüglich: (a) Fehlfunktionen oder unerwartetes Verhalten eines KI-Systems, (b) Verdacht auf Schäden für Gesundheit, Sicherheit oder Grundrechte, (c) Verdacht auf Diskriminierung durch KI-gestützte Entscheidungen, (d) Datenschutzvorfälle mit KI-Bezug, (e) Umgehung der menschlichen Aufsicht.'],
['3. Meldeweg', 'Erstmeldung an: KI-Beauftragte/r [Name, Kontakt] — mündlich oder über [Kanal]. Bei Nichterreichbarkeit: [Vertretung]. Meldungen sind auch vertraulich möglich; der Schutz nach dem Hinweisgeberschutzgesetz (HinSchG) bleibt unberührt.'],
['4. Interne Fristen', 'Meldung durch Beschäftigte: sofort, spätestens 24 Stunden nach Kenntnis. Erstbewertung durch KI-Beauftragte/n: binnen 48 Stunden. Entscheidung über externe Meldung (Art. 73) mit der Geschäftsleitung: unverzüglich, sodass die gesetzlichen Fristen gewahrt bleiben.'],
['5. Eskalationsstufen', 'Stufe 1: KI-Beauftragte/r (Bewertung, Eindämmung). Stufe 2: Geschäftsleitung + Datenschutzbeauftragte/r + Recht. Stufe 3: externe Meldung an die Marktüberwachungsbehörde sowie ggf. Information des Anbieters (Art. 26 Abs. 5) und Betroffener.'],
['6. Dokumentation', 'Jede Meldung wird mit dem Formular „Vorfallmeldung (Art. 73)" dokumentiert und mindestens [5] Jahre aufbewahrt. Der/die KI-Beauftragte führt das Vorfallregister.'],
['7. Keine Sanktionen bei gutgläubiger Meldung', 'Beschäftigten, die in gutem Glauben melden, dürfen keine Nachteile entstehen.'],
['8. Inkrafttreten', 'Diese Richtlinie tritt am [Datum] in Kraft.'],
],
};
const lines = [head(T.title, pack, today, locale, profile)];
for (const [sec, body] of T.sections) {
lines.push(`## ${sec}`, '', body ?? '', '');
}
return lines.join('\n');
}
/** Vordruck: Freigabeantrag für ein neues KI-System (interner Genehmigungsprozess). */
export function approvalRequest(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const s = docStrings(locale);
const T = locale === 'en'
? {
title: 'Approval request for a new AI system (internal form)',
intro: 'To be completed by the requesting department before any productive use of a new AI system or a substantial change to an existing one. Approval is granted by [AI officer / management].',
fields: [
'Requesting department / person / date',
'Name and provider of the AI system (incl. version, deployment form: cloud/on-premises)',
'Intended purpose and expected benefit',
'Categories of data processed (personal data? special categories? trade secrets?)',
'Affected persons (employees, applicants, customers)',
'Preliminary risk view (Annex III area affected? transparency triggers?)',
'Provider documents available (instructions for use, DPA, certifications)',
'Planned human oversight and responsible person',
],
decision: 'Decision',
decisionBody: '☐ approved ☐ approved with conditions: _______________ ☐ rejected\n\nConditions/notes: _______________\n\nDate, signature (AI officer): _______________ Date, signature (management, where required): _______________\n\nAfter approval: enter the system in the AI inventory and run the risk assessment in this tool.',
}
: {
title: 'Freigabeantrag für ein neues KI-System (internes Formular)',
intro: 'Von der anfordernden Fachabteilung auszufüllen, bevor ein neues KI-System produktiv genutzt oder ein bestehendes wesentlich geändert wird. Die Freigabe erteilt [KI-Beauftragte/r / Geschäftsleitung].',
fields: [
'Anfordernde Abteilung / Person / Datum',
'Name und Anbieter des KI-Systems (inkl. Version, Bereitstellungsform: Cloud/On-Premises)',
'Zweckbestimmung und erwarteter Nutzen',
'Verarbeitete Datenarten (personenbezogen? besondere Kategorien? Geschäftsgeheimnisse?)',
'Betroffene Personen (Beschäftigte, Bewerber, Kunden)',
'Risiko-Voreinschätzung (Annex-III-Bereich betroffen? Transparenz-Auslöser?)',
'Vorliegende Anbieterunterlagen (Betriebsanleitung, AVV, Zertifizierungen)',
'Geplante menschliche Aufsicht und verantwortliche Person',
],
decision: 'Entscheidung',
decisionBody: '☐ freigegeben ☐ freigegeben mit Auflagen: _______________ ☐ abgelehnt\n\nAuflagen/Hinweise: _______________\n\nDatum, Unterschrift (KI-Beauftragte/r): _______________ Datum, Unterschrift (Geschäftsleitung, soweit erforderlich): _______________\n\nNach Freigabe: System ins KI-Inventar aufnehmen und die Risikobewertung in diesem Tool durchführen.',
};
const lines = [head(T.title, pack, today, locale, profile)];
lines.push(T.intro, '');
T.fields.forEach((f, i) => {
lines.push(`## ${i + 1}. ${f}`, '', s.todo, '');
});
lines.push(`## ${T.decision}`, '', T.decisionBody);
return lines.join('\n');
}
/** Vordruck: Interne Audit-Checkliste KI-Compliance (periodische Selbstprüfung). */
export function auditChecklist(
pack: ContentPack,
today: string,
profile?: CompanyProfile,
locale: Locale = 'de',
): string {
const T = locale === 'en'
? {
title: 'Internal AI compliance audit checklist (periodic self-review)',
intro: 'Recommended interval: every [6] months and after material changes. Auditor: [AI officer]. Result to management.',
cols: '| # | Check | Result (OK / gap) | Action / owner / due date |',
sep: '|---|---|---|---|',
rows: [
'AI inventory complete? (shadow IT check: new tools in departments, browser extensions, API usage)',
'Risk classifications still accurate? (purpose or scope changed? reassessment run?)',
'All obligations in the task list processed or on schedule?',
'AI literacy trainings (Art. 4) carried out and documented for all relevant staff?',
'Transparency duties (Art. 50) implemented in all customer-facing systems?',
'Logs of high-risk systems retained (min. 6 months) and accessible?',
'Incident register maintained; internal reporting policy known to staff?',
'Provider documents (instructions, DPA, certificates) current and on file?',
'Works council agreements / employee information up to date?',
'National module changes checked (new decrees, authority guidance)?',
'Backup of this tools data exported and stored?',
],
result: 'Overall result & sign-off',
resultBody: 'Gaps found: _______________\n\nDate, signature (auditor): _______________ Date, signature (management): _______________',
}
: {
title: 'Interne Audit-Checkliste KI-Compliance (periodische Selbstprüfung)',
intro: 'Empfohlener Turnus: alle [6] Monate sowie nach wesentlichen Änderungen. Prüfer: [KI-Beauftragte/r]. Ergebnis an die Geschäftsleitung.',
cols: '| # | Prüfpunkt | Ergebnis (OK / Lücke) | Maßnahme / Verantwortlich / Frist |',
sep: '|---|---|---|---|',
rows: [
'KI-Inventar vollständig? (Schatten-IT-Check: neue Tools in Fachabteilungen, Browser-Erweiterungen, API-Nutzung)',
'Risikoklassifizierungen noch zutreffend? (Zweck oder Umfang geändert? Neubewertung durchgeführt?)',
'Alle Pflichten der Aufgabenliste abgearbeitet oder im Plan?',
'KI-Kompetenz-Schulungen (Art. 4) für alle relevanten Beschäftigten durchgeführt und dokumentiert?',
'Transparenzpflichten (Art. 50) in allen kundenseitigen Systemen umgesetzt?',
'Protokolle der Hochrisiko-Systeme aufbewahrt (mind. 6 Monate) und zugänglich?',
'Vorfallregister geführt; interne Melderichtlinie den Beschäftigten bekannt?',
'Anbieterunterlagen (Betriebsanleitung, AVV, Zertifikate) aktuell und abgelegt?',
'Betriebsvereinbarungen / Mitarbeiterinformationen auf aktuellem Stand?',
'Änderungen der Länder-Module geprüft (neue Dekrete, Behördenleitlinien)?',
'Backup der Daten dieses Tools exportiert und abgelegt?',
],
result: 'Gesamtergebnis & Abzeichnung',
resultBody: 'Festgestellte Lücken: _______________\n\nDatum, Unterschrift (Prüfer): _______________ Datum, Unterschrift (Geschäftsleitung): _______________',
};
const lines = [head(T.title, pack, today, locale, profile)];
lines.push(T.intro, '', T.cols, T.sep);
T.rows.forEach((row, i) => {
lines.push(`| ${i + 1} | ${row} | | |`);
});
lines.push('', `## ${T.result}`, '', T.resultBody);
return lines.join('\n');
}

View File

@ -165,6 +165,12 @@ const DE = {
docEmployeeInfo: 'Mitarbeiterinformation KI-Einsatz',
docFria: 'FRIA-Vorlage (Art. 27)',
docIncident: 'Vorfallmeldung (Art. 73)',
tplReporting: 'Interne Melde- & Eskalationsrichtlinie',
tplReportingDesc: 'Interne Meldepflicht für KI-Vorfälle: Meldewege, 24h-/48h-Fristen, Eskalationsstufen, Vorfallregister — bereitet die Art.-73-Meldung vor.',
tplApproval: 'Freigabeantrag KI-System',
tplApprovalDesc: 'Internes Formular für den Genehmigungsprozess neuer KI-Tools — gegen Schatten-KI, mit Entscheidungsfeld.',
tplAudit: 'Interne Audit-Checkliste KI-Compliance',
tplAuditDesc: 'Periodische Selbstprüfung (Inventar, Schulungen, Logs, Vorfälle, Anbieterunterlagen) mit Abzeichnung.',
};
export type UIStrings = typeof DE;
@ -332,6 +338,12 @@ const EN: UIStrings = {
docEmployeeInfo: 'Employee information on AI use',
docFria: 'FRIA template (Art. 27)',
docIncident: 'Incident report (Art. 73)',
tplReporting: 'Internal reporting & escalation policy',
tplReportingDesc: 'Internal reporting duty for AI incidents: channels, 24h/48h deadlines, escalation levels, incident register — prepares the Art. 73 report.',
tplApproval: 'AI system approval request',
tplApprovalDesc: 'Internal form for approving new AI tools — against shadow AI, with decision section.',
tplAudit: 'Internal AI compliance audit checklist',
tplAuditDesc: 'Periodic self-review (inventory, trainings, logs, incidents, provider documents) with sign-off.',
};
const DICTS: Readonly<Record<Locale, UIStrings>> = { de: DE, en: EN };

View File

@ -1,5 +1,6 @@
import { useState } from 'react';
import { aiPolicy, trainingPlan, worksAgreement } from '../engine/templatesCompany';
import { approvalRequest, auditChecklist, reportingPolicy } from '../engine/templatesInternal';
import type { AISystem, CompanyProfile } from '../engine/types';
import { useI18n } from '../i18n/context';
import { printDocument } from '../print/print';
@ -10,7 +11,7 @@ interface TemplatesViewProps {
readonly profile: CompanyProfile;
}
type TplKind = 'policy' | 'training' | 'worksAgreement';
type TplKind = 'policy' | 'reporting' | 'approval' | 'audit' | 'training' | 'worksAgreement';
/** Unternehmensweite Vorlagen: KI-Richtlinie, Schulungsplan, Betriebsvereinbarung. */
export function TemplatesView({ systems, profile }: TemplatesViewProps): JSX.Element {
@ -28,6 +29,24 @@ export function TemplatesView({ systems, profile }: TemplatesViewProps): JSX.Ele
file: `ki-richtlinie-${today}.md`,
render: () => aiPolicy(pack, today, profile, locale),
},
reporting: {
label: t.tplReporting,
desc: t.tplReportingDesc,
file: `melde-richtlinie-${today}.md`,
render: () => reportingPolicy(pack, today, profile, locale),
},
approval: {
label: t.tplApproval,
desc: t.tplApprovalDesc,
file: `freigabeantrag-ki-${today}.md`,
render: () => approvalRequest(pack, today, profile, locale),
},
audit: {
label: t.tplAudit,
desc: t.tplAuditDesc,
file: `audit-checkliste-ki-${today}.md`,
render: () => auditChecklist(pack, today, profile, locale),
},
training: {
label: t.tplTraining,
desc: t.tplTrainingDesc,