mindnet/docs/mindnet_v2_implementation_playbook.md
Lars fafa74b0b8
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 3s
docs/mindnet_v2_implementation_playbook.md aktualisiert
2025-11-18 11:19:22 +01:00

366 lines
17 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# mindnet v2 Implementierungs-Playbook & Handover (SidebySide zu v1)
*Stand:* 2025-11-10 08:03
*Autor:* ChatGPT (ProjektHandover)
*Zweck:* Vollständige, ausführbare Anleitung zur Weiterentwicklung von **mindnet** auf eine versionierte, testbare v2Architektur (neben v1), inklusive Prompt für den Folgethread, Akzeptanzkriterien, Dateiliste, Test und RollbackPläne.
---
## 0) Kontext & Zielbild (kurz)
- **Mission:** Persönliches Wissensnetz, das langfristig die eigene Persönlichkeit, Erfahrungen und Entscheidungslogik abbildet; später nachvollziehbare Erklärungen für Familie/Nachwelt.
- **Heutiger Stand (v1):** `mindnet_notes` in Qdrant vorhanden; **Chunks** und **Edges** bisher nur teilweise/nicht konsistent; EdgeDefaults („1 Dot“) vorhanden, aber Ziele teils nicht materialisiert. Importskripte: `import_markdown.py`, `edges.py` (historisch).
- **Ziel (v2):**
- **Collections:** `mindnet_notes_v2`, `mindnet_chunks_v2`, `mindnet_edges_v2` (saubere PayloadSchemata + Indizes).
- **Chunker v2:** Block/Headingaware, Ziel 9001200 Zeichen, Überlappung 120180, deterministische `chunk_id`s.
- **EdgeBuilder v2:** Reihenfolge: **explicit → rule → default_resolved → default**; saubere `provenance`.
- **ImporterPipeline v2:** Parse → Chunk → Edge → Embeddings → BatchUpsert + PayloadIndexpflege + Snapshots.
- **Policies:** Privacy/Recency/TypeGewichte als **Konfiguration** (YAML + JSONSchema), nicht hart im Code.
- **Observability:** FastAPI + OpenTelemetry (Tracing/Metrics); ImportReports (CSV/JSON).
- **SidebySide:** v2 **parallel** zu v1; kein BigBang.
> **Warum so?** QdrantPayloadIndizes/Filter → schnelle, erklärbare Selektionen; Snapshots → betriebssicheres Rollback; OTel → Nachvollziehbarkeit; YAML/JSONSchema → Validierbarkeit & Stabilität.
### 0.1 Aktueller Implementierungsstand (2025-11-18)
- Es existiert eine produktive mindnet-Instanz mit den Collections:
- `${prefix}_notes`
- `${prefix}_chunks`
- `${prefix}_edges`
- Import-Pipeline:
- `scripts/import_markdown.py` erzeugt Notes, Chunks und Edges vollständig.
- `types.yaml` definiert per Note-Typ:
- `retriever_weight`
- `chunk_profile`
- `edge_defaults` (z. B. `depends_on`, `related_to`).
- Edges:
- Strukturkanten: `belongs_to`, `next`, `prev`
- Explizite Kanten aus Wikilinks: `kind="references"`, `rule_id="explicit:wikilink"`
- Typbasierte Default-Kanten aus `edge_defaults`: `rule_id="edge_defaults:<type>:<relation>"`
- Inline-Kanten im Format `[[rel:<relation> <Zielnote>]]` mit `rule_id="inline:rel"`
- alle Edges tragen eine `confidence` im Bereich `[0,1]` als Hinweis für spätere Ranking-Logiken.
- Tests:
- `tests/test_edges_smoke.py`, `tests/test_edges_all.py` und `scripts/edges_full_check.py` validieren Counts, Konsistenz (`belongs_to == chunks`, `next/prev`-Ketten, keine Duplikate) und Provenienz-Zählungen (`explicit`, `defaults`, `inline`, `structure`).
- Offene Punkte:
- Mehrere Ziele in einer Inline-Relation (`rel: similar_to [[A]] [[B]]`) sind noch nicht implementiert.
- Retrieval-Service nutzt die neuen Edges und Weights bisher nur teilweise; ein edge-bewusster Retriever ist als nächster Schritt geplant.
---
## 1) Datenmodelle (Schemata, v2)
Die tatsächlichen JSONSchemata (202012) werden im Repo abgelegt und in CI validiert.
### 1.1 note.schema.json
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.org/mindnet/note.schema.json",
"type": "object",
"required": ["id", "title", "type", "privacy", "created", "hash_body"],
"properties": {
"id": { "type": "string", "pattern": "^[a-zA-Z0-9_-]+$" },
"title": { "type": "string", "minLength": 1 },
"type": { "type": "string" },
"privacy": { "type": "string", "enum": ["public","internal","private"] },
"created": { "type": "string", "format": "date-time" },
"modified": { "type": "string", "format": "date-time" },
"tags": { "type": "array", "items": { "type": "string" } },
"lang": { "type": "string", "default": "de" },
"source_path": { "type": "string" },
"source_collection": { "type": "string" },
"hash_body": { "type": "string" },
"hash_frontmatter": { "type": "string" },
"token_count": { "type": "integer", "minimum": 0 }
}
}
```
### 1.2 chunk.schema.json
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.org/mindnet/chunk.schema.json",
"type": "object",
"required": ["chunk_id","note_id","text","ord"],
"properties": {
"chunk_id": { "type": "string", "pattern": "^[a-zA-Z0-9_-]+#c\d{4}$" },
"note_id": { "type": "string" },
"text": { "type": "string" },
"ord": { "type": "integer", "minimum": 0 },
"span_char_start": { "type": "integer", "minimum": 0 },
"span_char_end": { "type": "integer", "minimum": 0 },
"heading_path": { "type": "array", "items": { "type": "string" } },
"section_title": { "type": "string" },
"tokens_start": { "type": "integer", "minimum": 0 },
"tokens_end": { "type": "integer", "minimum": 0 },
"embeddings_version": { "type": "string" }
}
}
```
### 1.3 edge.schema.json
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.org/mindnet/edge.schema.json",
"type": "object",
"required": ["edge_id","src_note_id","relation","provenance"],
"properties": {
"edge_id": { "type": "string" },
"src_note_id": { "type": "string" },
"src_chunk_id": { "type": "string" },
"dst_note_id": { "type": "string" },
"dst_chunk_id": { "type": "string" },
"relation": { "type": "string" },
"evidence_spans":{ "type": "array", "items": {"type":"object","properties":{"chunk_id":{"type":"string"},"span":[{"type":"integer"},{"type":"integer"}]]} },
"provenance": { "type": "string", "enum": ["explicit","rule","default_resolved","default"] },
"rule_id": { "type": "string" },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 }
}
}
```
### 1.4 default_edge.schema.json
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.org/mindnet/default_edge.schema.json",
"type": "object",
"required": ["src_note_id","relation","target_kind"],
"properties": {
"src_note_id": { "type": "string" },
"relation": { "type": "string" },
"target_kind": { "type": "string" },
"when": { "type": "string" },
"strength_hint":{ "type": "number", "minimum": 0, "maximum": 1 }
}
}
```
---
## 2) Qdrant: Collections & Indizes (v2)
Anlegen **neben** v1:
- `mindnet_notes_v2` (PayloadIndex: `type, privacy, created, modified, tags, source_path`)
- `mindnet_chunks_v2` (PayloadIndex: `note_id, ord, heading_path`)
- `mindnet_edges_v2` (PayloadIndex: `src_note_id, dst_note_id, relation, provenance`)
> Snapshots für Backups/Restore einplanen (Runbook siehe unten).
---
## 3) ImportPipeline v2 Module & Flags
- **Chunker v2** (`chunking/block_chunker.py`): `target_len=1000`, `overlap=150`, `respect_headings=True`, `min_chunk_len=600`, `max_chunk_len=1400`, `chunk_id = f\"{note_id}#c{ordinal:04d}\"`
- **EdgeBuilder v2** (`graph/edge_builder_v2.py`): Reihenfolge **explicit → rule → default_resolved → default**, `provenance` korrekt setzen.
- **Importer** (`scripts/import_markdown.py` erweitern oder `scripts/import_markdown_v2.py`):
Flags: `--schema v2`, `--chunker v2`, `--edges v2`, `--dry-run`, `--apply`, `--prefix "$COLLECTION_PREFIX"`.
**BeispielRun (dryrun):**
```bash
python3 -m scripts.import_markdown_v2 --vault ./vault --schema v2 --chunker v2 --edges v2 --dry-run --prefix "$COLLECTION_PREFIX"
```
**Apply:**
```bash
python3 -m scripts.import_markdown_v2 --vault ./vault --schema v2 --chunker v2 --edges v2 --apply --prefix "$COLLECTION_PREFIX"
```
---
## 4) Policies (konfigurierbar, kein HardCode)
- `policies/retrieval.schema.json` (JSONSchema) und `policies/retrieval.yaml`, z.B.:
```yaml
privacy_order: [private, internal, public]
recency_boost_half_life_days: 90
type_priority:
person: 1.2
event: 1.1
concept: 1.0
max_chunks_per_note: 8
edge_provenance_weights:
explicit: 1.0
rule: 0.8
default_resolved: 0.6
default: 0.2
rule_sets:
- id: "rules:types-v1"
enabled: true
```
---
## 5) Observability & Reports
- **FastAPI + OpenTelemetry**: Traces um Phasen *parse/chunk/edge/upsert*; Metriken (Counter/Histogramme) pro Phase.
- **ImportReport** je Lauf (CSV/JSON): counts für Notes/Chunks/Edges, Fehler, Dauer, EmbeddingVersion.
---
## 6) Teststrategie
- **GoldNotizen** (35 repräsentative .md) mit erwarteten *ChunkCounts* und *EdgeSets*.
- **Regression:** fixer SollCount (z.B. 171 ± 15%) über GesamtVault; keine Duplikate `(src,relation,dst)`.
- **DryRun vs Apply**: identische Counts, nur ohne Upserts.
- **FilterSmokeTests:** QdrantFilter nach `privacy`, `type`, `tags`, `created` funktionieren performant.
---
## 7) Akzeptanzkriterien (KPI)
1. **ChunkQualität:** ≥ 90% der Chunks enden an semantischen Grenzen; ZielLänge 9001200 Zeichen; deterministische IDs.
2. **EdgeKohärenz:** Keine Duplikate gleicher `(src,relation,dst)`; ≥ 95% der expliziten Links materialisiert; `default` nur, wenn kein Ziel existiert.
3. **Filterbarkeit:** Queries nach `privacy/type/tags/created` performant (PayloadIndex vorhanden).
4. **Betriebsfestigkeit:** Telemetrie aktiv; fehlertoleranter Import; QdrantSnapshot nach erfolgreichem Lauf.
---
## 8) Roadmap in kleinen, testbaren Schritten
### Step 0 Safeguards
- QdrantSnapshot v1 erstellen + RestoreProbe.
- ENV: `MINDNET_SCHEMA_VERSION=2` (Importer wird v2 schreiben, v1 bleibt unberührt).
### Step 1 Schemata (nur Dateien)
- Ablage: `/schemas/note.schema.json`, `/schemas/chunk.schema.json`, `/schemas/edge.schema.json`, `/schemas/default_edge.schema.json`
- CIJob: `make schema-validate` (jsonschema).
- **Abnahme:** Validator grün auf 3 GoldNotizen.
### Step 2 Qdrant v2Collections (Optional)
- Anlegen der 3 v2Collections + PayloadIndizes.
- **Abnahme:** FilterQuery liefert erwartbare Ergebnisse.
### Step 2a Edge-Pipeline v1 stabilisieren (ERLEDIGT)
- Ziel: Vollständige Generierung von Struktur-, expliziten, typbasierten und Inline-Kanten in den bestehenden Collections `${prefix}_notes`, `${prefix}_chunks`, `${prefix}_edges`.
- Status: Implementiert und durch `tests/test_edges_smoke.py`, `tests/test_edges_all.py` und `scripts/edges_full_check.py` verifiziert.
### Step 3 Chunker v2
- Implementierung & Flag `--chunker v2`.
- **Abnahme:** ChunkCounts ~ alt (≈171 ± 15%), semantische Schnitte.
### Step 4 EdgeBuilder v2
- Reihenfolge & `provenance` strikt umsetzen, `default_resolved` integrieren.
- **Abnahme:** erwartete Relationensätze auf GoldNotizen, keine Duplikate.
### Step 4a Edge-bewusster Retriever
- Implementiere einen Retrieval-Service, der:
- Chunks über Vektor-Suche aus `${prefix}_chunks` holt,
- dazu passende Nachbar-Chunks (`next/prev`) und typrelevante Notizen (`edge_defaults`, Inline-Relationen, Wikilinks) über `${prefix}_edges` ergänzt,
- `retriever_weight` und `confidence` beim Scoring berücksichtigt.
- Liefere einen API-Endpoint `/mindnet/query` mit einem einfachen JSON-Response (Chunks + Begründung).
- Akzeptanz:
- mindestens ein Testfall mit dem Relations-Showcase-Vault,
- sichtbarer Einfluss von `edge_defaults` und Inline-Relationen auf die Ergebnisliste.
### Step 5 ImporterPipeline v2
- `--schema v2` SidebySide; BatchUpserts; vollständige Payloads; RecencyBoost Konfig **nur** in Policy.
- **Abnahme:** DryRun/ApplyParität, Reports, TelemetrieEreignisse sichtbar.
### Step 6 Observability
- OTelInstrumentierung + `/import/status` + Reports.
- **Abnahme:** Traces & Metriken vorhanden.
### Step 7 Snapshots & Runbook
- Snapshot nach Erfolg; RestoreDokument.
- **Abnahme:** RestoreProbe erfolgreich.
### Step 8 Policies
- `policies/retrieval.yaml` + JSONSchema; A/BTest (Policy ändern → Retrieval ändert sich ohne Reimport).
- **Abnahme:** Sichtbarer Effekt laut Testfall.
### Step 9 Umschalten
- AbnahmeDoku, KPIDelta dokumentiert; Alias/FlagSwitch auf v2.
- **Abnahme:** Funktionale Gleichwertigkeit + Qualitätsgewinn.
---
## 9) Dateien (neu/ändern)
**Neu:**
- `schemas/note.schema.json`
- `schemas/chunk.schema.json`
- `schemas/edge.schema.json`
- `schemas/default_edge.schema.json`
- `policies/retrieval.schema.json`
- `policies/retrieval.yaml`
- `chunking/block_chunker.py`
- `graph/edge_builder_v2.py`
- `docs/OPERATIONS.md` (Snapshots/Restore/Runbook)
- `tests/gold_notes/manifest.yaml` (+ 35 Notizen Kopien)
**Änderungen:**
- `scripts/import_markdown.py` **oder** `scripts/import_markdown_v2.py` neu (Flags `--schema/--chunker/--edges`).
- `edges.py` (falls weiterverwendet): auf **v2EdgeBuilder** migrieren oder auslaufen lassen.
- `types.yaml`: RegelDefinitionen klarisieren (IDs, Bedingungen), **nicht** hart in Code.
---
## 10) BeispielKommandos
```bash
# Step 2: Collections prüfen
curl -s http://127.0.0.1:6333/collections | jq
# Step 3: Chunker v2 (dry-run)
python3 -m scripts.import_markdown_v2 --vault ./vault --schema v2 --chunker v2 --edges v2 --dry-run --prefix "$COLLECTION_PREFIX"
# Step 5: Apply + Report
python3 -m scripts.import_markdown_v2 --vault ./vault --schema v2 --chunker v2 --edges v2 --apply --prefix "$COLLECTION_PREFIX" --report ./reports/import_$(date +%F_%H%M).json
```
---
## 11) Rollback
- v2Collections droppen (wenn SidebySide).
- Aus Snapshot wiederherstellen (v1).
- Flags zurück auf v1.
---
## 12) Referenzen (offizielle Quellen)
- Qdrant Collections, PayloadIndex, Filter: <https://qdrant.tech/documentation/>
- Qdrant Snapshots/Backup: <https://qdrant.tech/documentation/guides/backup/>
- OpenTelemetry (Python/FastAPI): <https://opentelemetry.io/docs/instrumentation/python/>
- JSONSchema 202012: <https://json-schema.org/>
- YAML 1.2: <https://yaml.org/spec/1.2.2/>
- Obsidian Frontmatter: <https://help.obsidian.md/Editing+and+formatting/Properties>
- Ollama CLI/API (lokale Modelle): <https://github.com/ollama/ollama>
---
## 13) **PROMPT für den neuen Chat (bitte exakt so einfügen)**
```
Rolle: Du bist mein SeniorEntwickler & Architekt für mindnet. Arbeite strikt in kleinen, testbaren Schritten (SidebySide v2 neben v1). Liefere komplette Dateien als Downloads. Frage immer zuerst nach den **aktuellsten** Projektdateien, wenn du sie brauchst (z.B. import_markdown.py, edges.py, types.yaml), ändere keine Systemfunktion „workaroundartig“ ohne die Gesamtwirkung zu prüfen.
Kontext (Kurzfassung):
- v1 hat nur mindnet_notes zuverlässig. Chunks/Edges sind inkonsistent/teilweise leer. Ziel: v2 mit drei Collections (notes/chunks/edges), neuem Chunker v2, EdgeBuilder v2 (explicit → rule → default_resolved → default), Policies (YAML), Observability (OTel), Snapshots. Kein BigBang; v2 parallel zu v1.
- Siehe angehängte Datei **mindnet_v2_implementation_playbook.md** (Pfad/Download im Chat). Alles daraus ist verbindlich.
Deine ersten Aufgaben (StepbyStep):
1) **Schemata anlegen (Step 1)**
- Erstelle die Dateien:
- schemas/note.schema.json
- schemas/chunk.schema.json
- schemas/edge.schema.json
- schemas/default_edge.schema.json
- Nutze die in der PlaybookDatei vorgegebenen Strukturen als Basis.
- Liefere zusätzlich ein einfaches `Makefile`Ziel `schema-validate` (jsonschema via Python), plus `requirements.txt`.
- Output: komplette Dateien als Downloads + kurze Testanleitung.
2) **Qdrant v2Collections (Step 2)**
- Erzeuge die Collections + PayloadIndizes.
- Liefere ein kleines PythonSkript `tools/qdrant_bootstrap_v2.py`, das diese Anlage idempotent durchführt (inkl. PrüfOutput).
3) **Chunker v2 (Step 3)**
- Implementiere `chunking/block_chunker.py` mit den im Playbook genannten Parametern.
- Teste gegen 3 GoldNotizen (liefere mini TestHarness in `tests/gold_notes/…`).
Arbeitsweise:
- Jede Aufgabe einzeln, mit klaren Akzeptanzkriterien (aus Playbook) und DownloadArtefakten.
- Keine parallelen Großumbauten.
- Immer deterministische IDs, idempotente Upserts.
Dateien, die ich dir anfänglich bereitstelle:
- **mindnet_v2_implementation_playbook.md** (diese Datei)
- **import_markdown.py** (aktuelle Version aus dem Projekt)
- **edges.py** (aktuelle Version aus dem Projekt)
- **types.yaml** (aktuelle Version)
Sage mir jeweils, welche Datei du als Nächstes brauchst. Beginne jetzt mit Aufgabe 1 (Schemata).
```