# QAF → Wertstrom: Offene Punkte & Eskalationen (QVS-P6)

Stand: 2026-07-18 · Programm QVS · P6 (KAR-975). Konsolidierte, ehrliche Liste aller in dieser Phase gefundenen oder bestätigten Grenzen — sowohl neu (P6) als auch aus früheren Phasen referenziert. Kein Punkt hier wurde „nebenbei" gefixt (Auftrag: P6 ist Mess-/Report-Phase, echte Fixes sind eine eigene Folge-Runde nach Review).

## 1. Eskalation an Kais — Entscheidung nötig

### 1.1 Kein Ground-Truth-Datensatz für „erwarteten" Prozess-Count

**Befund:** Der KAR-975-Scope verlangt „Prozess-Count (erkannt vs. erwartet wo Ground-Truth existiert)". Es existiert **kein** Ground-Truth-Datensatz im gesamten Korpus-Repo (`~/work/qaf-corpus`) oder in kadi-v2, der erwartete Prozessschritt-Zahlen je Datei enthält:
- `manifests/corpus-manifest.{json,csv}` — nur Format-/Ladestatus, keine Prozesszahlen.
- `profiles/*.json` (376 Dateien) — heuristische Kandidaten-Regionen mit **expliziter Konfidenz und selbst-deklariertem** „never as a fact"-Vorbehalt (Moduldoc `profile-workbooks.mjs`), keine bestätigte Ground Truth.
- Kein `golden/`-Verzeichnis mit erwarteten Werten (das existierende `golden`-Konzept in kadi-v2 sind kleine handgeschriebene Unit-Test-Fixtures für Kapazitäts-/G60-Logik, **nicht** ein Korpus-weites Prozess-Count-Set).
- Kein Treffer für `groundTruth`/`expectedProcessCount`/„manuell verifiziert" in kadi-v2 ODER qaf-corpus (Volltextsuche, 2026-07-18).
- Auch die drei Vorphasen-Reports (`gap-analysis.md`, `architecture.md`, `corpus-evidence.md`) erwähnen kein solches Set — `architecture.md` §33 plant nur „Real-Korpus (dev-Split-Stichprobe je Template-Familie)" als Testmethode, nie ein Ground-Truth-Label-Set.

**Konsequenz:** `qaf-value-stream-validation-results.md` berichtet Prozess-Count ausschließlich als **„erkannt"** (deskriptive Verteilung: min/median/mean/max je Split). Der im Scope geforderte „erkannt vs. erwartet"-Vergleich ist mit dem heutigen Korpus-Repo-Stand **strukturell unbeantwortbar** — nicht, weil P6 ihn nicht gemessen hätte, sondern weil die zweite Vergleichsgröße nirgends existiert.

**Entscheidung nötig:** Soll ein manuelles Ground-Truth-Set (z. B. 20-30 Dateien je Split, von Hand gegen die Quell-Excel geprüfte Prozesszahlen) für eine künftige Phase erstellt werden? Das wäre ein eigenständiger, nicht-trivialer Aufwand (manuelle Sichtung realer Kundendaten) und damit bewusst außerhalb des P6-Scopes („Mess-/Report-Phase", kein neuer Datensatz-Aufbau ohne expliziten Auftrag).

### 1.2 KAR-977 / KAR-941 — im Repo nicht auffindbar

Der Programm-Kontext nennt diese beiden Ticket-IDs als „bekannte Altlasten", die referenziert (nicht neu hergeleitet) werden sollen. **Volltextsuche über kadi-v2 (`reports/`, `CHANGELOG.md`, `TODO.md`, `docs/`) und die komplette Git-Historie (`git log --all`) findet keinen einzigen Treffer für beide IDs.** Da Linear laut Auftrag nicht angefasst werden soll, konnte ihr Inhalt in dieser Session nicht verifiziert oder eingeordnet werden. Zitiert in `qaf-value-stream-validation-results.md` §10 nur als Platzhalter — **inhaltlich offen**. Falls diese beiden Punkte für die Freigabe-Entscheidung (P7-Flag-Flip) relevant sind, bitte kurz Kontext nachreichen.

### 1.3 `rls-user-scoped.test.ts` — 2 von 9 Kerntabellen real getestet, 2 weitere nur analog abgedeckt, 5 ohne jede Testdatei (Review-Fix, PR #340 Finding 2; präzisiert PR #341)

**Befund:** Von den 9 in der Voll-Suite komplett übersprungenen Testdateien (`qaf-value-stream-test-results.md` §2) sind nur 8 tatsächlich durch `RLS_TEST_DATABASE_URL`/`DB_URL`-`skipIf` gesteuert (bisher fälschlich „alle 9" berichtet — s. `qaf-value-stream-test-results.md` §2 und `qaf-value-stream-regression-results.md` §3, beide jetzt korrigiert). Die 9. Datei, `__tests__/security/rls-user-scoped.test.ts`, hat **kein** Env-Var-Gate — sie besteht ausschließlich aus 36 unbedingten `it.todo()`-Platzhaltern (9 Kerntabellen × 4 Fälle: `projects`, `process_steps`, `cycle_measurements`, `workshop_actions`, `qaf_uploads`, `user_profiles`, `assessments`, `oee_records`, `documents`) und bleibt laut eigenem Datei-Kopfkommentar so, bis separate Fixture-Arbeit erledigt ist (Docker-/embedded-Postgres + 2 provisionierte Nutzer + Erweiterung von `scripts/rls-test/setup.sql`).

**Präzisierung (Review-Fix, PR #341):** Die 36 `it.todo()`-Platzhalter in dieser einen Datei sind NICHT gleichbedeutend mit „für keine der 9 Tabellen existiert ein echter Test". Real getestet, jeweils Teil der oben zitierten 67/67-grün-Runde:
- **`projects`** — `__tests__/security/rls-projects-isolation.test.ts` („RLS projects user-scoped isolation (R61)"), REAL gegen Postgres.
- **`process_steps`** — `__tests__/security/rls-project-children-isolation.test.ts` („RLS project-child isolation — process_steps (R61/KAR-788)"), REAL gegen Postgres. KAR-788 ist das Ticket, das genau diese Abdeckung geliefert hat — nicht das Ticket für die Rest-Lücke.
- **`qaf_uploads`, `workshop_actions`** — kein eigener Test, aber `scripts/rls-test/setup.sql` (Kommentar Zeile 35-37) erklärt `process_steps` explizit als „representative" für dieselbe `*_own`-Prädikat-Klasse inkl. dieser beiden Tabellen (sowie `shift_outputs`, `lsc_*`, `kapa_*`). Das ist ein dokumentierter Analogie-Anspruch, **kein eigener Testlauf** — bleibt hier als solcher benannt, nicht als „getestet" gezählt.
- **Echte Rest-Lücke, ohne jede reale Testdatei:** `cycle_measurements`, `user_profiles`, `assessments`, `oee_records`, `documents` (5 der 9 Tabellen) — für diese existiert weder ein eigener Test noch ein dokumentierter Analogie-Anspruch. Die 36 `it.todo()`-Stubs bleiben die einzige Struktur, die künftige Tests für alle 9 Tabellen vorzeichnet (inkl. der bereits real abgedeckten `projects`/`process_steps` — die Stubs wurden nicht entfernt, nachdem die echten Testdateien entstanden).

Bestätigt auch durch P5s eigenen embedded-Postgres-Lauf: MIT `RLS_TEST_DATABASE_URL` gesetzt blieben trotzdem „36 todo, nur noch 1 Datei/0 Einzeltests übersprungen" (CHANGELOG „QVS-P5 Review-Fixes") — exakt diese eine Datei (die `it.todo()`-Stubs zählen unabhängig von der real existierenden Testabdeckung der anderen Dateien). Die an mehreren Stellen zitierte „P5 hat 67/67 real-RLS-Tests bewiesen"-Aussage deckt damit auch `rls-projects-isolation.test.ts` und `rls-project-children-isolation.test.ts` ab — beide sind Teil der 6 real gegateten `rls-*.test.ts`-Dateien.

**Konsequenz:** Nutzerskopierte RLS-Isolation ist für 5 der 9 Kerntabellen (`cycle_measurements`, `user_profiles`, `assessments`, `oee_records`, `documents`) **zu keinem bisherigen Zeitpunkt real getestet worden**. Für 2 weitere (`qaf_uploads`, `workshop_actions`) existiert nur ein dokumentierter Analogie-Anspruch, kein eigener Test. Für `projects` und `process_steps` liegt echte Testabdeckung vor. Keine der 9 Tabellen gehört zum QVS-Datenmodell (`value_stream_maps`/`value_stream_imports` sind nicht darunter) — die Lücke ist damit für die `qafValueStream`-Flag-Flip-Entscheidung selbst nicht blockierend, aber eine reale, nicht-triviale offene Sicherheits-Testlücke für die 5 unabgedeckten Tabellen, die zuvor pauschal als „9 von 9 nie getestet" überzeichnet dargestellt wurde.

**Entscheidung/Kontext nötig:** Soll das Fixture-Work (Docker-/embedded-Postgres-Setup, Erweiterung von `scripts/rls-test/setup.sql` + der Testdatei selbst) für die verbleibenden 5 Tabellen (plus ggf. ein dedizierter Analogie-zu-Real-Test-Wechsel für `qaf_uploads`/`workshop_actions`) als eigenes Ticket eingeplant werden, unabhängig vom QVS-Programm? KAR-788 ist für den `process_steps`-Teil bereits geliefert und für den Rest reopened. Liegt bei Kais.

## 2. Bekannte Grenzen (referenziert aus Vorphasen, hier konsolidiert)

- **Holdout-Split (75 Dateien) verbraucht seit 16.07. (KAR-963), TABU für P6.** Kein Ersatz-Holdout fabriziert, kein erneuter Zugriff. Die berichteten Validierungs-Zahlen stützen sich ausschließlich auf dev (Kalibrierung) + validation (Bericht) — das ist eine bewusste, im Auftrag vorgegebene Einschränkung, keine P6-eigene Lücke.
- **Zeit-Split-Felder (Rüstzeit/Handzeit/Maschinenzeit/Automatikzeit/Wartezeit/Transportzeit je Schritt): 0/227 Quell-Präsenz** (P1-Scan) — VSM-Zeitfelder bleiben leer, keine Fabrikation. Siehe `qaf-value-stream-corpus-evidence.md`.
- **`plannedCapacity` 124/227 (54,6 %) / `lotSize` 195/227 (85,9 %)** — Datei-Ebene, P4-Messung nach labelScan-Guard. Nicht in P6 neu gemessen (kein P6-Scope-Feld).
- **Rename-Grenze (P5):** eine umbenannte Station erscheint bei Reimport als `REMOVED_FROM_SOURCE`+`NEW_IN_SOURCE` statt eines einzelnen `SOURCE_CHANGED` — bewusst keine Positions-Fallback-Heuristik. Siehe CHANGELOG „QVS-P5".
- **`vaClass` konservativ, nie automatisch `va`** — durch P6 aktiv nachgemessen (0/1391 dev, 0/415 validation), kein reiner Verweis. Bestätigt das dokumentierte Design.

## 3. Neu in P6 gefunden — kein Produkt-Bug, aber dokumentiert

- **`ruestkosten` (Rüstkosten → `setupCostPerUnit`): 19,7 % (dev) / 21,4 % (validation) step-weighted Coverage — deutlich unter allen anderen 11 Primärfeldern.** Root-Cause-Check (Aufschlüsselung aller 1117 `missingFieldReasons`-Einträge über den vollen dev-Split): **100 % `cell_empty`**, 0 % `no_column_mapped` — die Spalte wird immer korrekt lokalisiert, die Quellzelle ist in den meisten Fertigungsschritten schlicht leer. **Kein Parser-Bug** (aktiv ausgeschlossen, nicht nur vermutet) — echte Korpus-Eigenschaft (Rüstkosten werden in der Quelle offenbar nur für ausgewählte Schritte je Datei geführt). Keine Aktion nötig, nur zur Kenntnis für die Programm-Bewertung. (Review-Fix, PR #340 Finding 1: diese Aufschlüsselung ist jetzt tool-nativ reproduzierbar über das additive `missingFieldReasonsByField`-Feld — s. `qaf-value-stream-validation-results.md` §1/§4 — statt einer vorher nicht auditierbaren Zusatzanalyse; beim Re-Run mit dem erweiterten Tool exakt bestätigt.)
- **`lohnkosten` (Lohnkosten → `laborHourRate`): 183/1391 `missingFieldReasons`-Fälle sind `no_column_mapped`** (Spalte in diesen Dateien nie lokalisiert) gegenüber nur 30 `cell_empty` + 50 `not_numeric`. Anders als bei `ruestkosten` **nicht abschließend geklärt**, ob das eine Parser-Header-Erkennungslücke (z. B. eine nicht erkannte Label-Variante) oder eine echte Template-Variante (Datei hat strukturell keine eigene Lohnkosten-Spalte) ist — das würde eine manuelle Sichtung der Quell-Header in den betroffenen Dateien erfordern, außerhalb des P6-Scopes. `lohnkosten` liegt mit 81,1 %/79,8 % aber noch innerhalb der normalen Bandbreite aller anderen Felder (78-99 %) und erscheint in keinem der Top-5-Worst-Performer als Hauptursache — **nicht als Ausreißer eskaliert**, nur als kleine, unentschiedene Beobachtung vermerkt. Empfehlung: bei Gelegenheit (nicht dringend) stichprobenartig 5-10 der 183 Dateien sichten.
- **`MultiQAF: 81_custom` in validation (1/3 parseOk, 33 %) weicht deutlich von dev (3/3, 100 %) ab** — bei **n=3** eine Kleinstichproben-Schwankung, keine belastbare Familien-Aussage. Nur 9 Multi-QAF-Dateien insgesamt über beide Splits (dev: `81_custom` n=3 + `mqaf_v1` n=2 + `mqaf_v2` n=1 = 6; validation: `81_custom` n=3; Konsequenz der ursprünglichen Stratifizierung — Review-Fix, PR #340 Finding 5: vorher fälschlich als „8" gezählt) — jede Multi-QAF-Feinfamilie (`mqaf_v1`/`mqaf_v2`/`81_custom`) hat zu wenige Fälle für eine gesicherte Prozent-Aussage. Nicht eskaliert (kein Bug-Verdacht, reines Stichproben-Artefakt), aber bei einer künftigen Korpus-Erweiterung sollte die Multi-QAF-Stichprobe vergrößert werden, um belastbarere Familien-Schnitte zu ermöglichen.
- **RLS-DB-Ebene: 8 Testdateien in dieser P6-Session nicht real gelaufen** — bewusste Entscheidung (P6 hat 0 RLS-relevante Code-Änderungen, P5 hat den Real-Lauf für genau diese 8 Dateien bereits bewiesen — 67/67 grün), keine neue Lücke. Eine 9., separate Datei (`rls-user-scoped.test.ts`, unbedingter `it.todo()`-Stub statt Env-Var-Gate) ist **keine Entscheidung dieser Session**, sondern eine vorbestehende, bislang falsch als „RLS-DB-gated" dargestellte offene Testlücke (Review-Fix, PR #340 Finding 2) — s. §1.3 (Eskalation). Siehe `qaf-value-stream-regression-results.md` §3.

## 4. Kein Fund in dieser Kategorie

Kein echter, neuer Produkt-Bug (Parser-Fehlverhalten, Mapper-Absturz, falsche Feld-Zuordnung) wurde in P6 gefunden. Die 0-Mapper-Fehler/0-Preview-Fehler über 271 erfolgreich geparste Dateien (207 dev + 64 validation) sind eine aktiv erhobene, nicht nur behauptete Bestätigung (`qaf-value-stream-validation-results.md` §7).

## 5. Zusammenfassung für die Flag-Flip-Entscheidung (P7)

P6 liefert keinen Blocker-Befund für einen künftigen Flag-Flip von `qafValueStream` — alle gemessenen Fehlerraten liegen auf der reinen Mapping-/Preview-Ebene bei 0 %, die für dieses Flag direkt relevante offene Frage ist die fehlende Ground-Truth-Vergleichsgröße (§1.1), die eine Aussage über absolute Korrektheit (nicht nur „läuft durch") einschränkt. Zusätzlich eskaliert, aber **nicht** `qafValueStream`-spezifisch (keine der betroffenen Tabellen gehört zum QVS-Datenmodell): §1.3, die RLS-Testlücke für 5 der 9 dort gelisteten Kerntabellen ohne jede reale Testdatei plus 2 weitere nur analog abgedeckte (Review-Fix, PR #340 Finding 2; präzisiert PR #341 — `projects`/`process_steps` sind real getestet) — relevant für Kais' Gesamtbild, aber kein Grund, den Flag-Flip selbst zurückzuhalten. Diese Entscheidungen liegen bei Kais, nicht bei diesem Report.
