mindnet/docs/05_Development/05_WP26_Requirements_Checklist.md

345 lines
8.0 KiB
Markdown
Raw Normal View History

# WP-26 Anforderungen-Checkliste
**Version:** 1.3
**Datum:** 25. Januar 2026
**Status:** Implementierung abgeschlossen
---
## Phase 1: Section-Types & Parsing
### ✅ FA-01: Neues Callout-Format `[!section]`
**Status:** ✅ Implementiert
**Implementierung:**
- `chunking_parser.py`: Regex für `[!section]` Callout-Erkennung
- State-Machine für `current_section_type` und `section_introduced_at_level`
- Retroaktive Propagation via `_propagate_section_type_backwards()`
**Dateien:**
- `app/core/chunking/chunking_parser.py`
- `app/core/chunking/chunking_models.py` (RawBlock, Chunk)
**Tests:**
- `tests/test_wp26_section_types.py::TestSectionTypeRecognition`
---
### ✅ FA-01b: Verschachtelte Edge-Callouts
**Status:** ✅ Implementiert
**Implementierung:**
- `graph_derive_edges.py`: `extract_callout_relations()` unterstützt verschachtelte Callouts
- Einrückungsebene (`>>`) wird korrekt erkannt
**Dateien:**
- `app/core/graph/graph_derive_edges.py`
**Tests:**
- `tests/test_wp26_section_types.py::TestNestedEdgeCallouts`
---
### ✅ FA-02: Scope-Beendigung
**Status:** ✅ Implementiert
**Implementierung:**
- Scope endet bei Überschrift gleicher oder höherer Ebene
- `section_introduced_at_level` Tracking
**Dateien:**
- `app/core/chunking/chunking_parser.py`
**Tests:**
- `tests/test_wp26_section_types.py::TestSectionTypeScope`
---
### ✅ FA-02b: Automatische Section-Erkennung
**Status:** ✅ Implementiert
**Implementierung:**
- Neue Überschrift auf `section_introduced_at_level` erzeugt automatisch neue Section
- Fallback auf `note_type` wenn kein `[!section]` Callout vorhanden
**Dateien:**
- `app/core/chunking/chunking_parser.py`
**Tests:**
- `tests/test_wp26_section_types.py::TestAutomaticSectionRecognition`
---
### ✅ FA-03: `type`-Feld-Befüllung
**Status:** ✅ Implementiert
**Implementierung:**
- `effective_type = section_type if section_type else note_type`
- Wird in `ingestion_chunk_payload.py` berechnet
- `type`-Feld enthält immer den effektiven Typ
**Dateien:**
- `app/core/ingestion/ingestion_chunk_payload.py`
**Tests:**
- `tests/test_wp26_section_types.py` (implizit)
---
### ✅ FA-03b: Body-Section Handling
**Status:** ✅ Implementiert
**Implementierung:**
- Textblöcke vor erstem `[!section]` erhalten `section: "body"`
- `section_type: None` (Fallback auf `note_type`)
**Dateien:**
- `app/core/chunking/chunking_parser.py`
---
### ✅ FA-04: Optionales Feld `note_type`
**Status:** ✅ Implementiert
**Implementierung:**
- Neues Feld `note_type` im Chunk-Payload
- Keyword-Index in Qdrant erstellt
**Dateien:**
- `app/core/ingestion/ingestion_chunk_payload.py`
- `scripts/setup_mindnet_collections.py`
**Tests:**
- `tests/test_wp26_section_types.py` (implizit)
---
### ✅ FA-05: Block-Reference als Link-Format
**Status:** ✅ Implementiert
**Implementierung:**
- `parse_link_target()` extrahiert Block-ID aus `[[#^block-id]]`
- Unterstützt auch `[[#Section Name ^block-id]]` Format
**Dateien:**
- `app/core/graph/graph_utils.py`
**Tests:**
- `tests/test_wp26_section_types.py::TestBlockIdParsing`
---
### ✅ FA-06: Section-zu-Chunk-Mapping
**Status:** ✅ Implementiert
**Implementierung:**
- Mapping erfolgt implizit über Block-IDs und Heading-Matches
- `parse_link_target()` löst Section-Referenzen auf
**Dateien:**
- `app/core/graph/graph_derive_edges.py`
- `app/core/graph/graph_utils.py`
---
### ✅ FA-07: Edge-Erstellung für Intra-Note-Links
**Status:** ✅ Implementiert
**Implementierung:**
- Intra-Note-Links werden zu Chunk-Scope Edges
- `scope: "chunk"` für Intra-Note-Edges
**Dateien:**
- `app/core/graph/graph_derive_edges.py`
---
### ✅ FA-07b: Metadaten-Erweiterung (`is_internal` Flag)
**Status:** ✅ Implementiert
**Implementierung:**
- `is_internal: True` für Edges innerhalb derselben Note
- Automatische Berechnung in `graph_utils._edge()`
- Boolean-Index in Qdrant
**Dateien:**
- `app/core/graph/graph_utils.py`
- `scripts/setup_mindnet_collections.py`
**Tests:**
- `tests/test_wp26_section_types.py::TestIsInternalFlag`
---
### ✅ FA-08: Default-Edges aus graph_schema.md
**Status:** ✅ Implementiert
**Implementierung:**
- `get_typical_edge_for()` ermittelt Default-Edge aus Schema
- Automatische Edge-Erstellung bei Section-Transitions
- `provenance: "rule"`, `rule_id: "inferred:section_transition"`
**Dateien:**
- `app/core/graph/graph_derive_edges.py`
- `app/core/graph/graph_utils.py`
**Tests:**
- `tests/test_wp26_section_types.py::TestAutomaticIntraNoteEdges`
- `tests/test_wp26_section_types.py::TestGraphSchemaParser`
---
## Phase 2: Retriever-Anpassungen
### ✅ FA-09: Edge-Gewichtung für Intra-Note-Edges
**Status:** ✅ Implementiert
**Implementierung:**
- `internal_edge_boost` und `external_edge_boost` in `retriever.yaml`
- Boost wird in `Subgraph.add_edge()` angewendet
**Dateien:**
- `app/core/graph/graph_subgraph.py`
- `config/retriever.yaml`
**Tests:**
- `tests/test_wp26_phase2_retriever.py::TestIsInternalBoost`
---
### ✅ FA-09b: Retrieval-Priorisierung (Section-Type vor Note-Type)
**Status:** ✅ Implementiert
**Implementierung:**
- `effective_type` wird für `retriever_weight` Lookup verwendet
- `type`-Feld enthält bereits den effektiven Typ
**Dateien:**
- `app/core/ingestion/ingestion_chunk_payload.py`
---
### ✅ FA-10: Optionale Chunk-Level-Deduplizierung
**Status:** ✅ Implementiert
**Implementierung:**
- `aggregation.level` in `retriever.yaml` (`"note"` oder `"chunk"`)
- `max_chunks_per_note` für Note-Level-Limitierung
- Implementiert in `retriever._score_and_pool_hits()`
**Dateien:**
- `app/core/retrieval/retriever.py`
- `config/retriever.yaml`
**Tests:**
- `tests/test_wp26_phase2_retriever.py::TestNoteLevelAggregation`
- `tests/test_wp26_phase2_retriever.py::TestChunkLevelAggregation`
---
## Phase 3: Schema-Validierung
### ✅ FA-12: Schema-Validierung gegen effektiven Chunk-Typ
**Status:** ✅ Implementiert
**Implementierung:**
- `validate_intra_note_edge()` prüft gegen `graph_schema.md`
- Verwendet `effective_type` (type-Feld) beider Chunks
- `get_topology_info()` liefert `typical` und `prohibited` Listen
- Integration in Ingestion-Pipeline (nach LLM-Validierung)
**Dateien:**
- `app/core/ingestion/ingestion_validation.py`
- `app/core/graph/graph_utils.py`
- `app/core/ingestion/ingestion_processor.py`
**Tests:**
- `tests/test_wp26_phase3_validation.py`
**Verhalten:**
- Edge in `prohibited` → ❌ Abgelehnt (confidence: 0.0)
- Edge in `typical` → ✅ Erlaubt (confidence: 1.0)
- Edge atypisch → ✅ Erlaubt (confidence: 0.7)
---
## Abwärtskompatibilität
### ✅ FA-11: Fallback-Verhalten
**Status:** ✅ Implementiert
**Garantien:**
- Notes ohne `[!section]` Callouts funktionieren unverändert
- `Chunk.type = note_type` (wie bisher)
- Keine Breaking Changes für bestehende Notes
---
## Zusammenfassung
| Phase | Requirements | Status |
|-------|--------------|--------|
| **Phase 1** | FA-01 bis FA-08 | ✅ 8/8 |
| **Phase 2** | FA-09, FA-09b, FA-10 | ✅ 3/3 |
| **Phase 3** | FA-12 | ✅ 1/1 |
| **Kompatibilität** | FA-11 | ✅ 1/1 |
| **GESAMT** | | ✅ **13/13** |
---
## Manuelle Tests
### 1. Umfassendes Test-Script ausführen
```bash
cd c:\Dev\cursor\mindnet
python scripts/test_wp26_comprehensive.py
```
### 2. Unit-Tests ausführen
```bash
# Alle WP-26 Tests
python -m pytest tests/test_wp26_section_types.py tests/test_wp26_phase2_retriever.py tests/test_wp26_phase3_validation.py -v
# Einzelne Phasen
python -m pytest tests/test_wp26_section_types.py -v
python -m pytest tests/test_wp26_phase2_retriever.py -v
python -m pytest tests/test_wp26_phase3_validation.py -v
```
### 3. Integrationstest mit echter Note
1. Erstelle Test-Note im Vault (siehe `05_WP26_Manual_Testing.md`)
2. Importiere via `scripts/import_markdown.py`
3. Prüfe Chunks und Edges in Qdrant
---
## Bekannte Einschränkungen
1. **Block-ID-Stability:** Obsidian aktualisiert Block-IDs nicht automatisch bei Umbenennung
2. **Heading-Links:** `[[#Section Name]]` funktioniert, aber `[[#^block-id]]` wird bevorzugt
3. **Strict-Mode:** Schema-Validierung im Strict-Mode lehnt atypische Edges ab (Standard: `False`)
---
**Ende der Checkliste**