- 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>
174 lines
12 KiB
Markdown
174 lines
12 KiB
Markdown
# 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.8–0.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.*
|