Basis: Certvia dev@a48c5fb als Fundament für Craftvia
CI / build-and-check (push) Canceled after 0s
CI / audit (push) Canceled after 0s
CI / sbom (push) Canceled after 0s

Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation
und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 11:05:39 +02:00
co-authored by Claude Opus 5
commit c8e6f30a27
720 changed files with 140143 additions and 0 deletions
+98
View File
@@ -0,0 +1,98 @@
// Unit-Tests (Story A7-2) für die Reifegrad-Engine gegen die C5-Regelbeispiele.
// Lauf: npx tsx scripts/test-maturity.ts
import {
suggestMaturity,
targetMaturity,
openPoints,
specForControl,
type ControlEvidence,
} from "../src/lib/maturity";
let failed = 0;
function check(name: string, cond: boolean, detail = "") {
if (cond) console.log(` ok ${name}`);
else {
failed++;
console.error(`FAIL ${name}${detail ? ` — ${detail}` : ""}`);
}
}
const base: ControlEvidence = {
policy: "fehlt",
verfahren: "fehlt",
assetLinked: false,
riskLinked: false,
operationalProof: false,
};
// Control mit Richtlinie + Verfahren + Asset (1.3.1: R02 / VA-08 / (A)).
const s131 = specForControl("1.3.1");
check("1.3.1 hat Verfahren + needsAsset", s131.verfahren.length === 1 && s131.needsAsset);
console.log("§2 Belegkonstellationen (Control 1.3.1):");
check("R0 — keine Belege → 0", suggestMaturity(s131, base).value === 0);
check("R1a — Richtlinie verknüpft, unvalidiert → 1", suggestMaturity(s131, { ...base, policy: "verknuepft" }).rule === "R1a");
check(
"R1b — Richtlinie validiert, Verfahren fehlt → 1",
suggestMaturity(s131, { ...base, policy: "validiert" }).rule === "R1b",
);
check(
"R1c — nur operativer Nachweis, keine validierte Richtlinie → 1",
suggestMaturity(s131, { ...base, operationalProof: true }).rule === "R1c",
);
check(
"R2 — Richtlinie+Verfahren validiert + Asset, kein Nachweis → 2",
suggestMaturity(s131, { ...base, policy: "validiert", verfahren: "validiert", assetLinked: true }).value === 2,
);
check(
"R2 verweigert bei fehlender Asset-Verknüpfung → 1",
suggestMaturity(s131, { ...base, policy: "validiert", verfahren: "validiert", assetLinked: false }).value === 1,
);
check(
"R3 — R2 + aktueller Wirksamkeitsnachweis → 3",
suggestMaturity(s131, { ...base, policy: "validiert", verfahren: "validiert", assetLinked: true, operationalProof: true }).value === 3,
);
check(
"Deckelung — Widerspruch/Findings → max. 1 (CAP)",
suggestMaturity(s131, { ...base, policy: "validiert", verfahren: "validiert", assetLinked: true, operationalProof: true, contradiction: true }).value === 1,
);
// Control ohne Verfahren (1.1.1: L00 / — / …): Grad 2 über validierte Umsetzungsregelung (N-basisch).
console.log("§2 Sonderfall ohne Verfahren (Control 1.1.1):");
const s111 = specForControl("1.1.1");
check("1.1.1 ohne Verfahren", s111.verfahren.length === 0);
check(
"R2 ohne V — Richtlinie validiert + validierte Umsetzungsregelung → 2",
suggestMaturity(s111, { ...base, policy: "validiert", implementationRule: true }).value === 2,
);
check(
"R1b ohne V — Richtlinie validiert, keine Umsetzungsregelung → 1",
suggestMaturity(s111, { ...base, policy: "validiert" }).value === 1,
);
check(
"R3 ohne V — Umsetzungsregelung + aktueller Wirksamkeitsnachweis → 3",
suggestMaturity(s111, { ...base, policy: "validiert", implementationRule: true, operationalProof: true }).value === 3,
);
// Zielreifegrad (§3).
console.log("§3 Zielreifegrad:");
check("AL3 → 3", targetMaturity({ level: "AL3", flags: {} }) === 3);
check("AL2 reiner MUSS-Scope → 2", targetMaturity({ level: "AL2", flags: {} }) === 2);
check("AL2 + SOLL → 3", targetMaturity({ level: "AL2", flags: { FLAG_INCLUDE_SHOULD: true } }) === 3);
check("AL2 + HOCH → 3", targetMaturity({ level: "AL2", flags: { FLAG_HIGH_PROTECTION: true } }) === 3);
// Offene Punkte (§4).
console.log("§4 Offene Punkte:");
const evGap: ControlEvidence = { ...base, policy: "validiert", verfahren: "fehlt", assetLinked: false };
const sugGap = suggestMaturity(s131, evGap);
const ops = openPoints(s131, evGap, sugGap, 3);
check("Verfahren-Gap erzeugt Punkt", ops.some((o) => o.kind === "verfahren"));
check("Asset-Verknüpfungs-Gap erzeugt Punkt", ops.some((o) => o.kind === "verknuepfung"));
check("Nachweis-Gap bei Ziel 3 erzeugt Punkt", ops.some((o) => o.kind === "nachweis"));
check(
"kein Gap bei erfülltem Ziel",
openPoints(s131, { ...base, policy: "validiert", verfahren: "validiert", assetLinked: true, operationalProof: true }, suggestMaturity(s131, { ...base, policy: "validiert", verfahren: "validiert", assetLinked: true, operationalProof: true }), 3).length === 0,
);
console.log(failed === 0 ? "\nAlle Reifegrad-Tests grün." : `\n${failed} Test(s) fehlgeschlagen.`);
process.exit(failed === 0 ? 0 : 1);