rebreak-monorepo/docs/specs/diga/05d-traceability-matrix-v0.md
chahinebrini 577a478c2d docs(diga): Dok 05 (Architektur+SOUP) + 05d (Traceability-Matrix) v0
- 05: Software-Lifecycle/Architektur/SOUP, code-belegt aus package.json-Manifesten
  + graphify-Graph; IEC-62304-Klassifizierungs-Vorschlag (B, ggf. C Krisen-Pfad)
- 05d: Traceability Anforderung<->Risiko<->Code fuer Lyra- + Schutz/Selbstbindungs-
  Strang (27 graph-abgeleitete traceability-Kanten)
- 00: 05 + 05d im Dossier-Plan registriert
- 05b: Gap 'Fehlende Traceability-Matrix' verweist jetzt auf 05d
Alle v0-Entwuerfe; Regulatory-/QM-Validierung ausstehend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 12:49:23 +02:00

174 lines
12 KiB
Markdown
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.

# Dok 05d — Traceability-Matrix: Anforderung ↔ Risiko ↔ Code ↔ Verifikation (v0)
**Bezug:** IEC 62304 §5.1.1 (Software-Entwicklungsplan — Traceability), §5.5.2
(Verifikation je Anforderung), §7.4 (Risikokontrollmaßnahmen ↔ Software)
**Norm-Kontext:** ISO 14971 Risikomanagement, MDR Anh. I (GSPR §17 — Software)
**Status:** Entwurf v0 — **maschinell aus dem Code-/Doc-Knowledge-Graph abgeleitet**
(graphify). Kein formaler, signierter Traceability-Record.
**Drafting:** Claude (aus Code + Dossier). Validierung durch Regulatory-/QM-Profi
ausstehend.
**Einordnung:** Schließt die in **Dok 05b §4.2** als *kritisch / DiGA-blockierend*
markierte Lücke **„Fehlende Traceability-Matrix (Tests ↔ Anforderungen ↔ Risiken)"**
— in dieser v0 für die **zwei sicherheitskritischsten Stränge: (a) Lyra/Krise**
(Dok 04 R-LYRA-01) und **(b) Schutz/Selbstbindung** (R-FALSE-01, R-BYP-03).
Andockpunkte: Dok 03 (Requirements), Dok 04 (Risiko-Akte), Dok 05c (Lyra-Eval),
Spec Protection Coverage & Streak.
---
## 0. Ehrliche Einordnung (bitte zuerst lesen)
Diese Matrix ist **kein** geprüfter Verifikationsnachweis. Sie ist eine aus dem
Knowledge-Graph (`graphify-out/graph.json`) abgeleitete **Erst-Verknüpfung** zwischen
Dossier-Artefakten und tatsächlichen Code-/Test-Symbolen. Jede Zeile trägt ein
Konfidenz-Flag:
- **EXTRACTED (1.0)** — die Quelle benennt das Artefakt **wörtlich** (z. B. nennt die
Risiko-Akte die Datei `crisis-filter.ts`). Belastbar.
- **INFERRED (0.80.95)** — **Modell-Schlussfolgerung** aus funktionaler Übereinstimmung.
Plausibel, aber **durch einen Menschen zu bestätigen**, bevor sie als Nachweis gilt.
Was hier **fehlt** und für einen formalen IEC-62304-Record noch nötig ist
(vgl. Dok 05b §4.2): Soll-Ergebnis-Definition je Testfall, archiviertes Pass/Fail-
Protokoll mit Build-Version + Datum, sowie die Ausweitung auf die noch offenen Stränge
(Mail-Schutz REQ-MAIL, Anonymitäts-Invariante, Onboarding/Streak-Vollabdeckung).
---
## 1. Traceability-Logik (IEC 62304)
```
Anforderung (Dok 03)
└─ Risiko + Risikomaßnahme (Dok 04, ISO 14971)
└─ Code-Artefakt (Implementierung der Maßnahme)
└─ Verifikation (Test + Soll-Metrik, Dok 05b/05c)
```
Für den Lyra-/Krisen-Strang konkret:
```
REQ-LYRA (Dok 03 — Lyra KI-Coach & Krisen-Behandlung, höchste Sicherheitsrelevanz)
└─ R-LYRA-01 (Dok 04 — verpasste Krise/Suizidalität, S4, Top-Risiko)
└─ Maßnahme: Deterministischer Krisen-Keyword-Pre-Filter (crisis-filter.ts)
├─ detectCrisis() backend/server/utils/crisis-filter.ts
├─ getCrisisFallback() backend/server/utils/crisis-filter.ts
└─ SAFETY-REQ-LLM-001 (Dok 05c — Krisenreferenz-Pflicht, Recall 100 %)
└─ Verifikation: crisis-filter.test.ts → Metrik „Crisis-Detection-Recall" (Ziel 100 %)
REQ-LYRA wird realisiert in:
├─ CoachScreen() apps/rebreak-native/app/lyra.tsx (UI)
├─ parseLyraResponse() apps/rebreak-native/lib/lyraResponse.ts (Reply-Parsing)
└─ sos-session.post.ts backend/server/api/coach/ (SOS-Coach-API)
```
---
## 2. Traceability-Matrix — Lyra-/Krisen-Strang (v0)
| DiGA-Artefakt (Anforderung / Risiko / Metrik) | Quelle | → Code-/Test-Artefakt | Datei | Relation | Konfidenz |
|---|---|---|---|---|---|
| REQ-LYRA — Lyra KI-Coach & Krisen-Behandlung | `03-requirements-v0.md` | `detectCrisis()` | `backend/server/utils/crisis-filter.ts` | implementiert durch | INFERRED (0.90) |
| REQ-LYRA — Lyra KI-Coach & Krisen-Behandlung | `03-requirements-v0.md` | `sos-session.post.ts` | `backend/server/api/coach/sos-session.post.ts` | implementiert durch | INFERRED (0.85) |
| REQ-LYRA — Lyra KI-Coach & Krisen-Behandlung | `03-requirements-v0.md` | `CoachScreen()` | `apps/rebreak-native/app/lyra.tsx` | implementiert durch | INFERRED (0.85) |
| REQ-LYRA — Lyra KI-Coach & Krisen-Behandlung | `03-requirements-v0.md` | `parseLyraResponse()` | `apps/rebreak-native/lib/lyraResponse.ts` | implementiert durch | INFERRED (0.85) |
| R-LYRA-01 — verpasste Krise/Suizidalität (S4) | `04-risiko-akte-v0.md` | `detectCrisis()` | `backend/server/utils/crisis-filter.ts` | mitigiert durch | INFERRED (0.95) |
| Maßnahme: Krisen-Keyword-Pre-Filter (`crisis-filter.ts`) | `04-risiko-akte-v0.md` | `crisis-filter.ts` | `backend/server/utils/crisis-filter.ts` | implementiert durch | **EXTRACTED (1.0)** |
| Maßnahme: Krisen-Keyword-Pre-Filter (`crisis-filter.ts`) | `04-risiko-akte-v0.md` | `detectCrisis()` | `backend/server/utils/crisis-filter.ts` | implementiert durch | **EXTRACTED (1.0)** |
| SAFETY-REQ-LLM-001 — Krisenreferenz-Pflicht (Recall 100 %) | `05c-lyra-eval-v0.md` | `detectCrisis()` | `backend/server/utils/crisis-filter.ts` | implementiert durch | INFERRED (0.95) |
| SAFETY-REQ-LLM-001 — Krisenreferenz-Pflicht (Recall 100 %) | `05c-lyra-eval-v0.md` | `getCrisisFallback()` | `backend/server/utils/crisis-filter.ts` | implementiert durch | INFERRED (0.95) |
| Crisis-Detection-Recall — Haupt-Metrik (Ziel 100 %) | `05c-lyra-eval-v0.md` | `crisis-filter.test.ts` | `backend/tests/crisis/crisis-filter.test.ts` | verifiziert durch | INFERRED (0.95) |
| Lyra Persona — Single Source of Truth | `ops/LYRA_PERSONA.md` | `CoachScreen()` | `apps/rebreak-native/app/lyra.tsx` | realisiert in | INFERRED (0.80) |
**Lesart:** „implementiert durch" = das Code-Symbol setzt die Anforderung um;
„mitigiert durch" = das Code-Symbol ist die Risikokontrollmaßnahme (ISO 14971);
„verifiziert durch" = der Test weist die Soll-Metrik nach.
---
## 2b. Traceability-Matrix — Schutz-/Selbstbindungs-Strang (v0)
Zweiter Strang: die geräteweite Zugangserschwerung (REQ-PROT), die Selbstbindung
(REQ-MAGIC), der manipulationssichere Cooldown und die zugehörigen Risiken
R-FALSE-01 (falsche Sicherheit bei inaktivem Schutz) und R-BYP-03 (Selbstbindung
wird zur Falle).
```
REQ-PROT (Dok 03 — geräteweite Zugangserschwerung)
├─ Android: DnsFilter.process() (DNS-NXDOMAIN-Blocking)
├─ iOS: RebreakProtectionModule.applyWebContentLayer() (NEFilter)
├─ Setup: SetupFlows.tsx (Schutz-Aktivierung)
└─ State: protection / isAllLayersOn() (Layer-Status)
└─ R-FALSE-01 (Dok 04 — falsche Sicherheit bei inaktivem Schutz)
├─ isAllLayersOn() (erkennt teil-/inaktiven Schutz)
└─ wasProtectionEverActiveHere() (Bypass-Detection-Flag)
REQ-MAGIC (Dok 03 — Selbstbindung, 24h-Cooldown)
├─ register.post.ts / findActiveDeviceLock() (Bindung)
└─ R-BYP-03 (Dok 04 — legitimer Ausstieg scheitert)
└─ requestDeviceRelease() / request-release.post.ts (Mitigation: Release-Pfad)
Server-time-authoritativer Cooldown (Dok 03 — Uhr-Manipulation-Schutz)
└─ signCooldownToken() / verifyCooldownToken() (backend/server/utils/cooldownToken.ts)
Spec Protection Coverage & Streak (DiGA-Kernmetrik)
├─ streak.ts (Streak-DB-Layer)
└─ addStreakEvent() (append-only protection_state_log)
```
| DiGA-Artefakt (Anforderung / Risiko / Metrik) | Quelle | → Code-Artefakt | Datei | Relation | Konfidenz |
|---|---|---|---|---|---|
| REQ-PROT — Schutz/Blocker (geräteweite Zugangserschwerung) | `03-requirements-v0.md` | `protection` | `apps/rebreak-native/lib/protection.ts` | implementiert durch | INFERRED (0.85) |
| REQ-PROT — Schutz/Blocker (geräteweite Zugangserschwerung) | `03-requirements-v0.md` | `isAllLayersOn()` | `apps/rebreak-native/lib/protection.ts` | implementiert durch | INFERRED (0.85) |
| REQ-PROT — Schutz/Blocker (geräteweite Zugangserschwerung) | `03-requirements-v0.md` | `.applyWebContentLayer()` | `…/ios/RebreakProtectionModule.swift` | implementiert durch | INFERRED (0.80) |
| REQ-PROT — Schutz/Blocker (geräteweite Zugangserschwerung) | `03-requirements-v0.md` | `.process()` | `…/android/…/filter/DnsFilter.kt` | implementiert durch | INFERRED (0.85) |
| REQ-PROT — Schutz/Blocker (geräteweite Zugangserschwerung) | `03-requirements-v0.md` | `SetupFlows.tsx` | `apps/rebreak-native/components/blocker/SetupFlows.tsx` | implementiert durch | INFERRED (0.80) |
| R-FALSE-01 — falsche Sicherheit bei inaktivem Schutz | `04-risiko-akte-v0.md` | `isAllLayersOn()` | `apps/rebreak-native/lib/protection.ts` | mitigiert durch | INFERRED (0.90) |
| R-FALSE-01 — falsche Sicherheit bei inaktivem Schutz | `04-risiko-akte-v0.md` | `wasProtectionEverActiveHere()` | `apps/rebreak-native/lib/protection.ts` | mitigiert durch | INFERRED (0.85) |
| REQ-MAGIC — Selbstbindung (Lock-Modus, 24h-Cooldown) | `03-requirements-v0.md` | `findActiveDeviceLock()` | `backend/server/db/devices.ts` | implementiert durch | INFERRED (0.85) |
| REQ-MAGIC — Selbstbindung (Lock-Modus, 24h-Cooldown) | `03-requirements-v0.md` | `register.post.ts` | `backend/server/api/magic/register.post.ts` | implementiert durch | INFERRED (0.85) |
| R-BYP-03 — Selbstbindung wird zur Falle | `04-risiko-akte-v0.md` | `requestDeviceRelease()` | `backend/server/db/devices.ts` | mitigiert durch | INFERRED (0.90) |
| R-BYP-03 — Selbstbindung wird zur Falle | `04-risiko-akte-v0.md` | `request-release.post.ts` | `backend/server/api/magic/devices/[deviceId]/request-release.post.ts` | mitigiert durch | INFERRED (0.85) |
| Server-time-authoritativer Cooldown (Uhr-Manipulation-Schutz) | `03-requirements-v0.md` | `signCooldownToken()` | `backend/server/utils/cooldownToken.ts` | implementiert durch | INFERRED (0.90) |
| Server-time-authoritativer Cooldown (Uhr-Manipulation-Schutz) | `03-requirements-v0.md` | `verifyCooldownToken()` | `backend/server/utils/cooldownToken.ts` | implementiert durch | INFERRED (0.90) |
| Spec Protection Coverage & Streak (DiGA-Kernmetrik) | `protection-coverage-streak.md` | `streak.ts` | `backend/server/db/streak.ts` | implementiert durch | INFERRED (0.80) |
| protection_state_log (append-only Schutz-Transitions-Log) | `protection-coverage-streak.md` | `addStreakEvent()` | `backend/server/db/streak.ts` | implementiert durch | INFERRED (0.85) |
---
## 3. Herkunft & Reproduzierbarkeit
Diese Matrix ist 1:1 aus den Traceability-Kanten in `graphify-out/graph.json`
abgeleitet (Kanten-Feld `traceability: true`, **27 Kanten** — 12 Lyra-/Krise,
15 Schutz-/Selbstbindung; letztere mit `strand: "protection"`). Erzeugung: graphify-
Knowledge-Graph über `backend/`, `apps/rebreak-native/` und `docs/specs/diga/`.
Vor der Verknüpfung lagen Dossier-Schicht (LLM-extrahiert) und Code-Schicht
(AST-extrahiert) in **getrennten Graph-Komponenten** — exakt die in Dok 05b §3.2
beschriebene implizite, nicht formalisierte Traceability. Nach Einzug dieser Kanten
liegen `REQ-LYRA` und `REQ-PROT` mit der gesamten nativen + Backend-Implementierung
(SOS, DNS-/NEFilter, Device-Lock, Cooldown, Streak) in **einer** Komponente.
> ⚠️ **Automatisch erzeugt ≠ validiert.** Die INFERRED-Zeilen müssen vor jeder
> Verwendung als Nachweis durch einen Regulatory-/QM-Profi bestätigt werden.
---
## 4. Offene Schritte (Richtung formaler IEC-62304-Record)
1. **INFERRED-Zeilen menschlich bestätigen** oder verwerfen (Regulatory-Review).
2. **Soll-Ergebnis je Testfall** als eigenständiges Artefakt definieren
(Dok 05b §4.2 — bislang nur Assertions im Test).
3. **Ergebnis-Protokoll** pro Release: Build-Version, Datum, Pass/Fail je Test-ID
(Vitest-/Maestro-JUnit-XML archivieren).
4. **Restliche Stränge ergänzen:** Mail-Schutz (REQ-MAIL), Anonymitäts-Invariante,
Onboarding/Streak-Vollabdeckung analog verknüpfen. *(Lyra + Schutz/Selbstbindung
sind in dieser v0 abgedeckt.)*
5. **Test-ID-Rückverweise im Code** ergänzen (Vitest-`describe` / Maestro-YAML-
Kommentar referenziert `REQ-XXX` / `R-XXX`), damit die Matrix künftig aus dem
Code selbst regenerierbar ist statt aus Graph-Inferenz.
---
*v0-Erst-Entwurf. Deckt bewusst nur den höchst-sicherheitsrelevanten Lyra-/Krisen-
Strang ab. Die Konfidenz-Flags sind Teil des Dokuments und dürfen beim Übernehmen
in die finale Akte nicht entfernt werden, bevor die jeweilige Zeile validiert ist.*