Explorer
/opt/struktur/AA-043-P34-R1.md
← Zurück ↓ Download
# AA-043-P34-R1 – Abschlussbericht

## A. Prüfzeitpunkt und Schutzgrenze

**Prüfzeitpunkt:** `2026-08-27T23:01:33.877297+00:00` UTC.

Autoritative Quelle:

```text
/opt/struktur/youtube-research/knowledge.db
```

Die Datenbank wurde ausschließlich mit SQLite `mode=ro` geöffnet. Es wurden keine `INSERT`, `UPDATE`, `DELETE`, `ALTER TABLE`, `DROP`, `VACUUM`, `REINDEX`, Migrationen, Requeues, Provideraufrufe, Graphiti-POSTs oder Neo4j-Writes ausgeführt.

## B. Baseline

Read-only-Ergebnis:

```text
PRAGMA integrity_check: ok
PRAGMA foreign_key_check: 485 rows
```

Verteilung:

```text
chapters:    279
video_links: 206
sonstige:      0
```

Die vollständige strukturierte Liste aller 485 Verstöße liegt zusätzlich als JSON-Artefakt vor und enthält je Zeile `table`, `rowid`, `parent`, `fkid`, Child-Datensatz und FK-Metadaten.

## C. Betroffene Foreign Keys

Alle betroffenen Constraints sind:

| Child-Tabelle | Child-Spalte | Parent-Tabelle | Parent-Spalte | ON UPDATE | ON DELETE | Verstöße |
|---|---|---|---|---|---|---:|
| `chapters` | `video_id` | `videos` | `id` | `NO ACTION` | `NO ACTION` | 279 |
| `video_links` | `video_id` | `videos` | `id` | `NO ACTION` | `NO ACTION` | 206 |

Weitere deklarierte Foreign Keys auf `videos` wurden ebenfalls ermittelt:

- `transcript_segments.video_id → videos.id`: `NO ACTION` / `NO ACTION`;
- `video_tags.video_id → videos.id`: `NO ACTION` / `NO ACTION`;
- `notes.video_id → videos.id`: `NO ACTION` / `NO ACTION`;
- `processing_runs.video_id → videos.id`: `NO ACTION` / `NO ACTION`;
- `processing_queue.video_id → videos.id`: `NO ACTION` / `NO ACTION`;
- `fundus_items.video_id → videos.id`: `NO ACTION` / `CASCADE`;
- `e2e_extractions.video_id → videos.id`: `NO ACTION` / `CASCADE`.

Für diese zusätzlichen Child-Tabellen wurde im aktuellen `foreign_key_check` kein weiterer Verstoß gefunden.

## D. Quantifizierung der Parent-Probleme

```text
FK-Verstöße gesamt:             485
unterschiedliche fehlende IDs:  27
vorhandene videos-Zeilen:       1098
```

Die 485 Zeilen sind daher **27 fehlende Parent-IDs mit insgesamt 485 referenzierenden Child-Zeilen**, nicht 485 unabhängige fehlende Videos.

### Betroffene IDs und Child-Mengen

| fehlende `videos.id` | `chapters` | `video_links` | gesamt |
|---:|---:|---:|---:|
| 54 | 26 | 14 | 40 |
| 65 | 27 | 12 | 39 |
| 68 | 6 | 7 | 13 |
| 71 | 0 | 6 | 6 |
| 78 | 7 | 6 | 13 |
| 80 | 9 | 1 | 10 |
| 90 | 0 | 6 | 6 |
| 97 | 0 | 11 | 11 |
| 100 | 7 | 1 | 8 |
| 102 | 10 | 10 | 20 |
| 117 | 11 | 9 | 20 |
| 119 | 15 | 8 | 23 |
| 128 | 14 | 11 | 25 |
| 134 | 9 | 5 | 14 |
| 140 | 8 | 11 | 19 |
| 195 | 16 | 13 | 29 |
| 196 | 23 | 12 | 35 |
| 251 | 16 | 14 | 30 |
| 256 | 0 | 7 | 7 |
| 258 | 0 | 3 | 3 |
| 293 | 0 | 4 | 4 |
| 299 | 10 | 12 | 22 |
| 300 | 0 | 4 | 4 |
| 301 | 9 | 1 | 10 |
| 307 | 15 | 5 | 20 |
| 311 | 0 | 3 | 3 |
| 319 | 41 | 10 | 51 |
| **Summe** | **279** | **206** | **485** |

`chapters` betrifft 19 der 27 IDs, `video_links` 26 der 27 IDs, davon 18 IDs beide Childtypen.

Top fehlende Parent-IDs nach referenzierenden Child-Zeilen:

```text
319=51, 54=40, 65=39, 196=35, 251=30, 195=29,
68=13, 78=13, 128=25, 299=22, 102=20, 117=20,
307=20, 140=19, 134=14, 119=23, 100=8, 256=7,
71=6, 80=10, 90=6, 97=11, 258=3, 293=4,
300=4, 301=10, 311=3
```

## E. Fachliche Bewertung der Child-Daten

`chapters` enthält weiterhin fachliche Strukturinformationen:

```text
video_id
chapter index über die Zeilen-/ID-Reihenfolge
start_seconds
title
```

Die Chapter-Titel und Zeitmarken sind nicht als wertloser technischer Müll nachgewiesen. Sie könnten für Inhaltsnavigation oder Rekonstruktion relevant sein.

`video_links` enthält weiterhin:

```text
video_id
label
url
```

Die URLs sind externe Quellen-/Referenzlinks. Auch sie sind nicht als wertlos nachgewiesen.

**Informationsverlust-Risiko:** Eine Löschung der 485 Child-Zeilen wäre derzeit nicht vertretbar. Es wurde nichts gelöscht.

## F. Rekonstruktion der Parent-Videos

Für alle 27 fehlenden `videos.id` wurde read-only geprüft:

- aktuelle `videos`-Tabelle;
- `e2e_jobs`;
- `e2e_extractions`;
- `transcript_segments`;
- `processing_runs`;
- `graphiti_import_queue`;
- `source_processing_registry`;
- `content_extraction.db`, insbesondere `ce_sources.source_video_id`;
- relevante Report-/Backup-Snapshots;
- Obsidian- und vorhandene Pipelinepfade.

Ergebnis:

```text
vollständig rekonstruierbare Parent-Videos: 0
sicher remappbare Parent-Videos:            0
eindeutig obsolet nachgewiesene Child-Sätze: 0
unklare Fälle:                             27
```

Die `source_processing_registry` enthält für einige numerisch gleichnamige `source_id`-Werte Obsidian-Quellen. Das ist kein Nachweis, dass diese Werte frühere `videos.id` darstellen; die Identitäten dürfen nicht gleichgesetzt werden.

Für die 27 fehlenden IDs existiert keine belastbare aktuelle YouTube-ID-/Titel-/URL-Zuordnung aus einer autoritativen Parent-Zeile. `ce_sources.source_video_id` liefert für diese IDs keine Zuordnung.

## G. Backup-Vergleich und Zeitpunkt

Verglichene Snapshots:

```text
/opt/struktur/reports/backfill-backups-20260717T181315Z/knowledge.db
/opt/struktur/reports/obsidian-transcript-backup-20260717T193928Z/knowledge.db
/opt/struktur/reports/aa043-p34/20260827T223847Z/knowledge.db.pre-migration.bak
```

Alle drei Snapshots zeigen:

```text
foreign_key_check: 485
integrity_check: ok
fehlende untersuchte Parent-IDs: alle weiterhin fehlend
```

Der FK-Zustand ist damit spätestens im Snapshot vom **14.07.2026** vorhanden. Ein älterer konsistenter Snapshot mit den 27 Parent-Zeilen wurde in den relevanten verfügbaren Snapshots nicht gefunden.

Das belegt den historischen Bestand, aber nicht den exakten Löschzeitpunkt.

## H. Root-Cause-Bewertung

### Bewiesen

1. Die 27 `videos.id` existieren aktuell nicht.
2. `chapters` und `video_links` referenzieren diese IDs weiterhin.
3. Die Constraints stehen auf `ON DELETE NO ACTION`.
4. Die Verstöße bestanden bereits im ältesten gefundenen Snapshot vom 14.07.2026.
5. Der aktuelle produktive `db.py`-Pfad setzt `PRAGMA foreign_keys=ON`.
6. Der aktuelle `e2e_worker.py`-Verbindungsaufbau setzt ebenfalls `PRAGMA foreign_keys=ON`.

### Konkreter historischer plausibler Mechanismus

Im archivierten E2E-Worker unter:

```text
/opt/struktur/youtube-research/e2e-test/backups/20260718-103749/e2e_worker.py
```

existiert ein Reject-Pfad mit `DELETE FROM videos WHERE id=?`. Der dort sichtbare Verbindungsaufbau setzt `busy_timeout`, aber kein nachgewiesenes `PRAGMA foreign_keys=ON`. Im Reject-Pfad werden `chapters` und `video_links` nicht vorher gelöscht.

Das passt technisch zum beobachteten Orphan-Muster: Ein Parent-Delete bei deaktivierter SQLite-FK-Prüfung kann Child-Zeilen zurücklassen.

Dieser Pfad ist als **PLAUSIBEL** zu bewerten. Dass genau alle 27 betroffenen IDs durch diesen konkreten Lauf gelöscht wurden, ist nicht durch Run-/Job-Historie oder Parent-Metadaten nachgewiesen.

### Nicht nachgewiesen

- exakter Erzeuger jedes einzelnen Orphans;
- konkreter Löschzeitpunkt je Parent-ID;
- ob IDs durch Reject, Cleanup, Restore oder eine andere historische Operation verschwanden;
- `INSERT OR REPLACE INTO videos` als Ursache: im geprüften produktiven Writer-Code nicht nachgewiesen;
- ein vollständiger historischer Run-/Attempt-Nachweis für alle 27 IDs.

**Ursache noch nicht nachgewiesen.**

## I. Foreign-Key-Enforcement und aktuelles Risiko

Aktuelle relevante Pfade:

```text
/opt/struktur/youtube-research/db.py
  get_connection(): PRAGMA foreign_keys=ON
  delete_video(): löscht bekannte Child-Tabellen vor videos

/opt/struktur/youtube-research/e2e_worker.py
  DB-Verbindung: PRAGMA foreign_keys=ON
```

Historische bzw. sonstige direkte SQLite-Verbindungen sind nicht durchgehend einheitlich instrumentiert. In den aktuellen produktiven Pfaden wurde jedoch kein weiterer sicherer `DELETE FROM videos`-Pfad mit fehlendem FK-Schutz gefunden.

```text
AKTUELLES RISIKO: UNKLAR
```

Begründung: Der zentrale aktuelle Delete-/E2E-Code setzt FK-Prüfung, aber die gesamte Menge direkt öffnender Writer-Verbindungen und ihre Laufzeitaktivierung ist nicht als lückenloser Single-Writer-Nachweis bewiesen. Neue Orphans sind daher nicht sicher ausgeschlossen.

## J. Orphan-Klassifikation

| Klasse | Anzahl Parent-IDs | Entscheidung |
|---|---:|---|
| `RECOVER_PARENT` | 0 | Parent nicht vollständig autoritativ rekonstruierbar |
| `REMAP_CHILDREN` | 0 | kein anderer Parent eindeutig nachgewiesen |
| `DELETE_ORPHAN_CHILDREN` | 0 | fachliche Obsoleszenz nicht bewiesen |
| `UNCLEAR` | 27 | manuelle/weitere historische Prüfung erforderlich |

Es werden keine Dummy-Videos angelegt und keine Child-Zeilen gelöscht oder umgehängt.

## K. Reparaturplan, nicht ausgeführt

### Für `UNCLEAR`

1. Child-Zeilen unverändert erhalten.
2. Historische Import-/Reject-/Cleanup-Logs gezielt nach den 27 IDs oder den zugehörigen damaligen YouTube-IDs suchen.
3. Falls eine vollständige Parent-Zeile aus einem autoritativen Snapshot gefunden wird: `RECOVER_PARENT` auf einer Kopie simulieren.
4. Falls nur eine zweifelsfreie andere Parent-ID nachgewiesen wird: `REMAP_CHILDREN` ausschließlich auf einer Kopie simulieren.
5. Keine Löschung ohne fachliche Entscheidung und Informationsverlustnachweis.

### Zulässige spätere Reparaturvarianten

- **Parent restaurieren:** nur mit vollständiger, eindeutiger Parent-Provenienz;
- **Children remappen:** nur bei zweifelsfreier Identität;
- **Child-Löschung:** derzeit nicht freigegeben;
- **Unverändert/manual review:** aktueller sicherer Zustand.

Eine Reparatursimulation wurde nicht durchgeführt, weil für keinen der 27 Fälle eine eindeutige verlustfreie Operation vorliegt.

## L. P34-Auswirkung

Bewertung:

```text
GLOBALER ALTBESTAND
```

Begründung:

- Die FK-Verstöße betreffen `chapters` und `video_links` → `videos`.
- Die geplante KU-Schemaerweiterung betrifft `knowledge_units` und eine neue Provenienz-/Review-Struktur.
- Zwischen den 485 Orphans und den geplanten KU-Feldern besteht kein direkter Foreign-Key-Zusammenhang.
- Der frühere P34-Test wurde blockiert, weil der globale Abnahmetest `foreign_key_check=0` verlangte, nicht weil die KU-Migration technisch auf `videos` angewiesen ist.

Für eine globale Qualitätsfreigabe der gemeinsamen KnowledgeDB bleibt der Befund trotzdem ein Abnahmeblocker, bis eine dokumentierte Reparatur- oder Ausnahmeentscheidung vorliegt.

## M. Dashboard

Keine Dashboard-Änderung in diesem Auftrag.

Eine spätere technische Überwachung sollte getrennt ausweisen:

```text
FK-Verstöße gesamt
betroffene Child-Tabellen
fehlende Parent-IDs
ältester bekannter Snapshot
RECOVER_PARENT / REMAP_CHILDREN / DELETE_ORPHAN_CHILDREN / UNCLEAR
```

## N. Empfehlung

**Primäre Empfehlung: D – Ursache weiterhin unklar, keine produktive Änderung zulässig.**

Eine Teilreparatur ist derzeit nicht sicher genug, weil für keinen der 27 fehlenden Parent-Datensätze eine vollständige, eindeutige Rekonstruktion oder ein zweifelsfreies Remapping nachgewiesen wurde.

P34 darf erst nach einer separaten Entscheidung über `foreign_key_check=485` fortgesetzt werden. Ein kontrollierter KU-Pilot sollte nicht als Reparatur der Video-Altlast missbraucht werden.

## O. Schutzstatus

```text
Produktive DB verändert = 0
KU-Migration = 0
KUs neu = 0
Backfill = 0
graphiti_release = 0
Graphiti-POSTs = 0
Neo4j-Writes = 0
Gold-Promotion = 0
FK-Reparatur = 0
```

## P. Artefakte

Audit-JSON mit vollständiger `foreign_key_check`-Liste:

```text
/opt/struktur/reports/aa043-p34-r1/20260827T230113Z/AA-043-P34-R1-audit.json
```

Der Abschlussbericht wird zusammen mit dem vollständigen Audit-JSON und den geprüften Skript-Hashes unter einem timestamped P34-R1-Verzeichnis abgelegt.

## Abschluss

Arbeitsauftrag AA-043-P34-R1 erledigt – 485 historische Foreign-Key-Verstöße vollständig klassifiziert und sichere Reparatur-/Ausnahmeentscheidung für die Fortsetzung von P34 vorbereitet.