feat(completeness): Regulatory Completeness Engine — auditable coverage, not confidence

Phase A½. The move from feature to product development: for every assessment, answer "how sure are
we that this answer is COMPLETE?" — different from confidence. The product never claims full coverage;
it makes its own knowledge state transparent and auditable. Shows what we do NOT know and why.

- compliance/completeness/: assess_completeness(identified, corpus_status, uncertain, assumptions,
  assessed_obligations) -> CompletenessReport. Separates IDENTIFIED from ASSESSED (validated corpus
  AND determined applicability) and justifies every gap. Two kinds of open: corpus gap (future_corpus)
  and applicability uncertainty (query_required + deciding question, e.g. Data Act / generates_usage_data).
- The metric is COUNTS, never a single percentage: "Identifiziert N · bewertet M · offen K ·
  Unsicherheiten U · Begründung ja" + an honest audit statement.
- ADR-007: auditable honesty; phase order A factory -> A½ Completeness -> B new domains; the
  transparency selling point. Deterministic, no LLM; corpus status + obligation count injected.
- reference suite: "Regulatory Completeness" section runs an industrial-dishwasher assessment
  (assessed CRA/MaschinenVO; open EMV/Environmental=future_corpus, Data Act=query_required) and notes
  Environmental flips open->validated automatically once the corpus lands.

11 completeness tests (54 with adjacent modules), mypy --strict clean (15 files), check-loc 0.
Product code with no app caller + ADR/reference = non-runtime -> no deploy (ADR-001). Freeze-safe.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-27 14:16:12 +02:00
parent 0b0d262462
commit aa99111a87
8 changed files with 389 additions and 3 deletions
@@ -104,3 +104,38 @@ def knowledge_intake_section(base_dir) -> None:
("Impact-Triage (HIGH/LOW/NONE/new_domain)", "PASS", "3 Beispiel-Dokumente korrekt eingeordnet"),
("Regelwerk-ID-Normalisierung", "TODO", "CRA vs Cyber Resilience Act vereinheitlichen"),
])
def completeness_section() -> None:
"""Render the Regulatory Completeness section (kept here so generate.py stays under the LOC budget)."""
from compliance.completeness import assess_completeness
rep = assess_completeness(
identified_regulations=["CRA", "MaschinenVO", "EMV", "Environmental", "DataAct"],
corpus_status={"CRA": "validated", "MaschinenVO": "validated", "EMV": "unsupported",
"Environmental": "unsupported", "DataAct": "validated"},
uncertain=[{"regulation": "DataAct", "deciding_question": "generates_usage_data", "reason": "generates_usage_data = unbekannt"}],
assumptions=[{"key": "Funkmodul", "value": "nein"}, {"key": "personenbezogene Nutzungsdaten", "value": "nein"}],
assessed_obligations=128)
w("## Regulatory Completeness — was wir bewerten konnten, und was bewusst nicht")
w("")
w('_Interne Qualitätsmaschine (KEIN Confidence-Score): trennt IDENTIFIZIERT von BEWERTET und begründet jede Lücke. Keine Prozentzahl — auditierbar und ehrlich: „Wir zeigen auch, was wir noch nicht wissen und warum."_')
w("")
w("**%s**" % rep.completeness_summary)
w("")
w("> %s" % rep.audit_statement)
w("")
w("- **Bewertet:** %s (%d Pflichten)" % (", ".join(rep.assessed_regulations), rep.assessed_obligations))
w("- **Offen (jeweils begründet):**")
for e in rep.exclusions:
dq = (" → Rückfrage: `%s`" % e.deciding_question) if e.deciding_question else ""
w(" - `%s` — %s `[%s]`%s" % (e.subject, e.reason, e.resolution, dq))
w("- **Annahmen:** %s" % ", ".join("%s=%s" % (a.key, a.value) for a in rep.assumptions))
w("")
w("_Sobald der Umwelt-Korpus (ISO 14001 etc.) landet, kippt `Environmental` automatisch von offen auf bewertet — die Completeness Engine dokumentiert den Fortschritt je Domäne._")
w("")
coverage_table([
("Regulatory Completeness (auditierbar)", "PASS", rep.completeness_summary),
("Begründete Ausschlüsse (Korpus/Anwendbarkeit)", "PASS", "%d Ausschlüsse, alle mit Grund" % len(rep.exclusions)),
("Fortschritts-Doku je Domäne", "PASS", "Environmental offen→validated bei Korpus-Landung"),
])