# QAF-Korpus Real-Matrix — Batch-Report (SupplierPulse)

Erzeugt: 2026-07-15 · Batch-Laufzeit gesamt: 243.1s für 374 Dateien (Ø 0.65s/Datei)
Runner: `/home/aria/work/qaf-corpus/tools/batch-runner.ts` (npx tsx, cwd=kadi-v2 für `@/`-Pfad-Alias)
Rohdaten: `/home/aria/work/qaf-corpus/batch-results.json` (374 Einzelergebnisse, keine Zellwerte/Preise — nur Strukturbefunde)
Pipeline-Module: `loadExcelWorkbook`, `detectG60`, `detectMultiQaf`/`multiQafDetectionInputFromExcelJs`, `buildTemplateFingerprint`, `fingerprintMultiQafTemplateFromExcelJs` — 1:1 dieselben Funktionen wie `app/qaf-differences/actions.ts` (echter Ingest-Pfad), nur ohne Supabase-Persistenz.

Vertraulichkeitsdisziplin: keine Zellinhalte, keine Preise geloggt — nur Dateinamen, Sheet-Strukturen, Klassifikationen.

## 1. Klassifikations-Matrix (primäre Einordnung, 374 Dateien)

| Klasse | Anzahl | Anteil |
|---|---|---|
| standard_summary (V9/Legacy-DE SUMMARY erkannt) | 358 | 95.7% |
| confirmed_multi_qaf | 10 | 2.7% |
| g60_detail | 2 | 0.5% |
| ambiguous (Multi-QAF-Verdacht, schwach) | 2 | 0.5% |
| legacy_xls_unsupported (Ladefehler) | 2 | 0.5% |
| probable_multi_qaf | 0 | — |
| timeout / unexpected_crash | 0 | — |

Ladeergebnis: 372/374 (99.5%) laden erfolgreich über ExcelJS. Die 2 Ladefehler sind exakt die beiden echten Legacy-BIFF-`.xls`-Dateien im Korpus ("QAF_FBK_G20-G22 20P_Quote 3_20131002.xls", "...40P LH_Quote 3_20131002.xls") — JSZip: "Can't find end of central directory" (kein ZIP-Container, also strukturell kein OOXML). Eine dritte `.xls`-Datei im Korpus ("20180601_QAF_v3_Product_GES009_v009_offer_v9_Gestamp.xls") ist tatsächlich ein umbenanntes OOXML-File und lädt problemlos (enthält aber 0 Tabellenblätter — separates Problem, siehe unten).

Multi-QAF-Signale im Detail (via `detectMultiQaf`): 362× `standard_qaf` (kein Signal), 10× `confirmed_multi_qaf` (davon 9 `.xlsx`, 1 `.xlsm`), 2× `ambiguous` (beide sind KEINE echten QAFs, siehe Abschnitt 3).

## 2. Template-Fingerprint: Familien-Verteilung + Coverage

### 2a. Standard-QAF-Profile (`buildTemplateFingerprint`, 360 Dateien mit SUMMARY-Sheet)

| Profil | Klassifikation | Anzahl |
|---|---|---|
| QAF_LEGACY_DE_SUMMARY | modified | 275 |
| QAF_V9_SUMMARY | modified | 81 |
| — (kein Profil, unknown) | unknown | 12 |
| — | **known** | **0** |

**Auffälligkeit:** Über den GESAMTEN Realkorpus gibt es **0 Dateien** mit Klassifikation `known`. Grund: das SUMMARY-Facet erreicht bei KEINER der 356 Dateien mit auswertbarem SUMMARY-Facet `coverageRatio = 1.0` (alle 356 liegen im Band 0.8–0.99). `knownCoverageThreshold` ist aktuell auf `1` gesetzt (template-fingerprint.ts) — für reale Dateien praktisch unerreichbar, vermutlich weil mindestens ein erwartetes SUMMARY-Label in der Praxis strukturell nie vorkommt (nicht nur leerer Wert, sondern fehlendes Label). `known` ist damit im Realbetrieb toter Code — jede Datei landet in `modified`, was das Warnsignal "modified" entwertet (kein Unterschied mehr zwischen "leichte Abweichung" und "eigentlich sauber").

### 2b. Multi-QAF-Template-Familien (`fingerprintMultiQafTemplate`, 12 Dateien mit Multi-QAF-Signal)

| Familie | Klassifikation | Anzahl |
|---|---|---|
| qaf_8_1_custom_multi | modified | 7 |
| m_qaf_1_0 | modified | 2 |
| m_qaf_2_0 | modified | 1 |
| unknown_multi_qaf | unknown | 2 |

Die 2 `unknown_multi_qaf` sind "Jit Matrix Vergabe.xlsx" und "aktualisierte JIT Matrix Raskin.xlsx" — beides KEINE QAFs (siehe Abschnitt 3).

### 2c. Facet-Coverage-Histogramm (alle Dateien mit Standard-Fingerprint, Bänder 1.0 / 0.8–0.99 / 0.5–0.79 / <0.5)

| Facet | 1.0 (voll) | 0.8–0.99 | 0.5–0.79 | <0.5 | nicht vorhanden |
|---|---|---|---|---|---|
| summary | 0 | 356 | 0 | 0 | 4 |
| manufacturing | 257 | 71 | 0 | 0 | ~32 |
| material | 218 | 104 | 9 | 22 | ~7 |
| sbm | 0 | 240 | 0 | 112 | ~8 |
| rmr | 0 | 0 | 0 | **345** | ~15 |
| lccn | 0 | 0 | 9 | 2 | ~349 |
| co2e | 0 | 0 | 0 | 4 | ~356 |

**RMR-Facet (Raw Material Risks)**: 345 von ~354 auswertbaren Dateien liegen bei Coverage <0.5 — die RMR-Sheet-Erkennung/-Zuordnung matcht auf dem Realkorpus fast nie. Separate Kalibrierungsfrage vom SUMMARY-Threshold-Problem oben.

## 3. Top-Auffälligkeiten

### 3a. Alle Dateien mit Exceptions/Fehlern (37 von 374, 9.9%)

Fehlerklassen (Präfix): `manufacturing-parse` (35×), `load` (2×, siehe legacy-xls oben).

**Kritischster Befund:** 37 Dateien werfen beim MANUFACTURING/Fertigungskosten-Parse "Keine passenden Spalten gefunden" — die Datei hat also **0 Fertigungskosten-Zeilen** geparst. Aufschlüsselung nach primärer Klasse:
- 3× confirmed_multi_qaf (erwartet — Multi-QAF kann der Single-Value-Parser strukturell nicht lesen)
- 2× ambiguous (die 2 Nicht-QAF-JIT-Matrizen)
- **30× standard_summary** — und davon werden **nur 12 als `unknown` geflaggt** (kein SUMMARY-Match). Die übrigen **~18–25 Dateien laufen als `modified` durch, OHNE dass das komplette Fehlen der Fertigungskosten-Zeilen im known/modified/unknown-Signal sichtbar wird** (das `manufacturing`-Facet wird bei 0 Steps einfach ausgelassen statt als Abweichung gezählt). Das ist exakt die Master-Prompt-§7-Kategorie "parsed but semantically incorrect ohne sichtbaren Fehler" — hier sogar "gar nicht geparst, aber unsichtbar".

Betroffene Dateicluster (Auswahl, volle Liste in `batch-results.json`):
- BMW G70/I20-Projektdateien 2024/2025 (5× `.xlsm`: `20240325_QAF_BMW-G70_ver17...`, `20240325_QAF_I20_DP_wb_OF_2024...`, `240301_QAF_BMW-G70_ver16.xlsm` + Variante, `240301_QAF_BMW-I20.xlsm`) — auch `unknown` im SUMMARY-Fingerprint, kein G60, kein Multi-QAF-Signal. Sieht nach einer NEUEN BMW-Template-Generation aus, die aktuell komplett unter dem Erkennungsradar läuft.
- "QAF 5A208xx"/"QAF 5A25B3x"-Cluster (13 Dateien, gleiche Namenskonvention) — alle ohne Fertigungskosten-Zeilen.
- "2020_12_01_BMW G45_RD#5.2_QAF_#9xx..."-Cluster (7 Dateien) — dito.
- Einzeldateien: Autoliv_Runde_8_LC_QAF_BBA..., NCAR ECM QAF R3.1..., 20221103_QAF HEAT II Skyfall, 20230706_QAF SW_G26_Werksersatz (+Variante), BMW_Multi-QAF_Kaufteile_Analyse_1.xlsx.

### 3b. Alle "unknown"-Fingerprints (14 Dateien: 12 Standard + 2 Multi-QAF-Familie)

Darunter mehrere Dateien, die vermutlich GAR KEIN QAF sind (Korpushygiene, kein Pipeline-Bug): `231201_Checkliste_Auftragsklärung_DE.xlsx`, `LIST_250307_..._Preismatrix_...xlsx`, `PL_260401_Thyssen-CLAR-Trebtau.xlsx`, `QAF Vergleich STW Oberteil.xlsx`, `Streulichtblenden AF25 inkl. CN Boost.xlsx`, `Jit Matrix Vergabe.xlsx`, `aktualisierte JIT Matrix Raskin.xlsx`, `BMW_Multi-QAF_Kaufteile_Analyse_1.xlsx` — 8 von 14 sind wahrscheinlich Fehlplatzierungen im Korpus-Ordner, nicht echte Quotation-Analysis-Forms.

### 3c. Alle "ambiguous"-Detections (2 Dateien)

`Jit Matrix Vergabe.xlsx` und `aktualisierte JIT Matrix Raskin.xlsx` — beide lösen `materialFactorMatrix` (S3, schwach) aus. Beide sind JIT-Liefermatrizen, keine QAFs — korrektes konservatives Verhalten (nicht `standard_qaf`, aber auch nicht fälschlich `confirmed`).

### 3d. Performance-Ausreißer (>10s)

Nur 1 von 374 Dateien: `171103_Multi-QAF_CLARWE_EU_sz2_SZ_ABD__NEU.xlsx` (Multi-QAF, 1.21 MB) — 11.17s. Die Schwester-Datei ohne `_NEU` liegt bei 9.15s (knapp unter der Schwelle). Nächstschnellste Gruppe: die neuen BMW-G70/I20-`.xlsm`-Dateien (3.9–5.6s) und die beiden echten G60-Dateien (3.9–4.3s) — alle deutlich unter dem 60s-Timeout, kein Datei-Hang, 0 Timeouts.

## 4. Empfehlungs-Kandidaten (KAR-würdige Befund-Klassen)

| # | Befund-Klasse | Betroffene Dateien | Empfehlung |
|---|---|---|---|
| 1 | SUMMARY-`knownCoverageThreshold=1` im Realbetrieb unerreichbar → `known` ist toter Code | 356 (100% der SUMMARY-Dateien) | KAR: Threshold/erwartete-Canonical-IDs für SUMMARY neu kalibrieren gegen Realkorpus, oder Schwelle senken |
| 2 | Fehlende Fertigungskosten-Zeilen (0 Steps) bleibt im Fingerprint-Signal unsichtbar (`modified` statt `unknown`/Warnung) | ~18–25 (von 37 mit Parse-Fehler) | KAR: MANUFACTURING-Facet soll bei 0 Steps + vorhandenem Sheet explizit als Abweichung/Issue zählen, nicht stillschweigend auslassen |
| 3 | Neue/unbekannte BMW-Template-Generation G70/I20 (2024/2025) | 5 (`.xlsm`) | KAR: neue Template-Familie analysieren + Profil/G60-Variante onboarden |
| 4 | RMR-Sheet-Erkennung matcht auf Realkorpus fast nie (Coverage <0.5 bei 345/354) | 345 | KAR: RMR-Parser-Sheet-Alias/Feld-Mapping gegen Realdateien nachkalibrieren |
| 5 | Legacy-BIFF-`.xls` nicht ladbar (ExcelJS ist zip-only) | 2 | KAR: Legacy-xls-Support niedrige Priorität (nur 2/374), ggf. Konvertierungshinweis in Fehlermeldung statt stillem Reject |

Nachrichtlich (kein neuer KAR, Bestätigung bestehender Kalibrierung): Multi-QAF-Erkennung (KAR-925/926/934) hält auf dem Realkorpus — 10 confirmed + 2 korrekt-konservativ ambiguous, 0 False Positives unter den 362 `standard_qaf`-klassifizierten Dateien. G60-Erkennung 2/2 korrekt (`known`, `G60_DETAIL`).
