Files
claude-marketplace/nexus-dev/skills/nexus-invariants/SKILL.md
T

38 lines
3.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
---
name: nexus-invariants
description: Security- und Privacy-Invarianten von nexus (Family Knowledge Hub) korrekt implementieren. Verwenden bei JEDER Karte, die Daten liest, LLMs aufruft, Sichtbarkeit beruehrt oder loescht. Deckt ab - ACL-vor-Retrieval (SICHT-1/2), fail-closed LLM-Routing (PRIV-3), Privacy-Klassen, Log-Redaction, Loesch-Kaskade, Pflicht-Testmuster (SICHT-4).
---
# nexus Invarianten — Implementierungsleitfaden
Quelle der Wahrheit: PRD Phase 1 (SICHT-*, PRIV-*, QUEUE-4, DEL-*) und ADR-0004. Dieser Skill übersetzt sie in Code-Muster.
## ACL-vor-Retrieval (SICHT-1/2)
- Sichtbarkeit wird **in der Query** durchgesetzt, nie als Python-Nachfilter: jede Repository-/Query-Funktion nimmt den `viewer` als Pflichtparameter und joint/filtert auf dessen sichtbaren Korpus (eigene + an ihn geteilte + familie).
- Es gibt EINEN zentralen Visibility-Baustein (z. B. `visible_to(viewer)`-Query-Helper); Fach-Code baut Sichtbarkeit nie ad hoc nach.
- Nicht-sichtbar verhält sich identisch zu nicht-existent: gleiche 404, gleiche Fehlertexte, keine abweichenden Trefferzahlen oder IDs in Fehlern.
- Auch Suchindex-Queries (FTS) laufen über den Visibility-Helper — niemals erst suchen, dann filtern.
## Fail-closed LLM-Routing (PRIV-1…4)
- Fach-Code ruft NIE direkt einen Modell-Endpoint auf — ausschließlich `router.run(task_profile, privacy_class, payload)`.
- Router-Auflösung: exakter Matrix-Eintrag (Task-Profil × Privacy-Klasse) erforderlich. Fehlt er, ist er mehrdeutig oder ist der lokale Endpoint unhealthy ⇒ Job-Status `blocked` + Audit-Event. **Es gibt keinen Codepfad, der auf extern ausweicht** — auch nicht bei Timeouts.
- `privat`/`familie` an externe Endpoints ist auch bei expliziter Policy-Fehlkonfiguration zu verweigern (Hard Guard im Router, zweite Verteidigungslinie vor der Policy).
- Vor jedem Call: Sensitivitäts-Pre-Check (PRIV-6, Regex: Keys/IBAN/Passwörter) → bei Treffer kein LLM-Call, Flag `sensitive-content`, direkt in die Queue.
## Logging (PRIV-5)
- structlog mit Redaction-Processor: niemals Bodies, OCR-Text, Titel oder Dateinamen mit Inhaltssemantik in Logs/Fehlermeldungen/Exceptions. IDs + Metadaten ja, Inhalte nein. Gilt auch für Audit-Events (AUDIT-3).
## Löschung (DEL-*, ADR-0004)
- Löschen = Referenz entfernen + Kaskade (Entry-Versionen, Suchindex, später Embeddings/Graph) in EINER Transaktion + Audit-Event; Blob-GC bei refcount=0.
- Pflichttest: geteilter Blob — Löschen durch A entfernt nur As Referenz/Derivate, Bs Exemplar bleibt.
## Pflicht-Testmuster (SICHT-4 — Teil jeder Lese-API)
Für jede neue Lese-Route/Query parametrisierte Tests mit zwei Nutzern A, B (B besitzt einen privaten Eintrag):
1. A listet → Bs privater Eintrag fehlt; 2. A holt Bs ID direkt → 404 identisch zu nicht-existent; 3. A sucht passende Keywords → kein Treffer; 4. Geteilt-Fall: B teilt mit A → jetzt sichtbar; Familie-Fall analog.
Routing-Test je Karte mit LLM-Beteiligung: Policy-Eintrag entfernen → Job `blocked`, kein Outbound-Call (Mock-Assert).