mindnet/docs/mindnet_v2_implementation_playbook.md
Lars 8bd8f7c0bb
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 3s
Dateien nach "docs" hochladen
2025-11-10 10:26:40 +01:00

14 KiB
Raw Blame History

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_ids.
    • 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.


1) Datenmodelle (Schemata, v2)

Die tatsächlichen JSONSchemata (202012) werden im Repo abgelegt und in CI validiert.

1.1 note.schema.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

{
  "$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

{
  "$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

{
  "$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):

python3 -m scripts.import_markdown_v2 --vault ./vault --schema v2 --chunker v2 --edges v2 --dry-run --prefix "$COLLECTION_PREFIX"

Apply:

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.:
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

  • Anlegen der 3 v2Collections + PayloadIndizes.
  • Abnahme: FilterQuery liefert erwartbare Ergebnisse.

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 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

# 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)


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).