Files
nexa/docs/05-command-system.md
Claude e8f0d9a2c2 Memory retention design + open-question re-asker + UNAS Pro specifics
Two design questions answered:

1. Web/news/Karakeep INTO long-term memory? Yes, but with per-source TTL.
   docs/08 gains a "Memory sources & retention" section that pins TTLs:
   memo/obsidian/karakeep = permanent, mail = 365d, mail_digest = 90d,
   rss = 30d, web_search = 90d, system = 30d. Every Qdrant point carries
   payload.expires_at; a daily prune workflow honours it. New commands
   in docs/05: #nexa:learn --permanent, #nexa:forget, #nexa:retain,
   #nexa:ask --web (SearXNG → crawl4ai-mcp → markitdown-mcp → embed).
   Phase 2.4 added to roadmap.

2. Re-ask unanswered open questions. Backoff schedule (3d → 7d → 21d →
   60d) tracked in GraphDB per question. Surface ONE question per day
   in the morning digest, but only when the digest is otherwise short
   (capacity guard < 800 chars). User reply parsed → question auto-
   resolved → docs/11 diff proposed (Phase 6.4 hook). New commands in
   docs/05: #nexa:digest, #nexa:remind, #nexa:answered. Phase 5.3 added.

UNAS Pro details from the UniFi Drive dashboard:
- It's a Ubiquiti UNAS Pro (UniFi Drive 4.1.16 on UniFi OS 5.0.17),
  SFP+, RAID 6, 19.96 TiB raw, 2.05 TiB used. Recorded in CLAUDE.md.
- SMB native paths: smb://192.168.1.31/<share> (mac) / \\192.168.1.31\
  <share> (win). UniFi recommends SMB as the modern path — matches our
  decision to default Nexa volumes to SMB.
- ⚠️ Storage-pool snapshots NOT configured ("Click to Setup"). Added as
  optimization #38: highest-leverage data-protection change in the
  homelab right now. Daily + weekly UniFi Drive snapshot, native, no
  agent. RAID 6 doesn't protect against rm -rf or accidental mass-
  delete; snapshots do.
- #39: Nexa workflows that mutate large state can use the same native
  snapshots for fast rollback (pre-snapshot → operate → verify).
2026-05-05 04:45:29 +00:00

6.0 KiB

05 — Command System (#nexa:*)

Nexa "hört" auf folgende Kommandos in Memos-Kommentaren oder als Memo-Inhalt mit Hashtag:

🔧 Konfigurations-Kommandos

#nexa:config

  • Beschreibung: Triggert Autodiscovery aller Services (Nextcloud Listen/Kalender, Qdrant Collections, LiteLLM-Modelle, Mail-Konto).
  • Läuft auch automatisch:
    • Täglich (cron in n8n) — neue Listen / Kalender werden ohne manuelles Eingreifen aufgenommen.
    • Bei Cache-Miss — wenn ein Workflow eine Liste/ID nicht mehr findet, läuft Discovery einmal, dann Retry.
  • Antwort: Postet Report mit den aktuellen Konfigurationen als Memos-Kommentar.
  • Speichert: Konfiguration in der Qdrant _config Namespace (nicht in .env).
#nexa:config

Beispiel-Response:

✅ Autodiscovery abgeschlossen (2026-05-04T23:59):
- Nextcloud Listen: Persönlich (id=14), DLR (id=dlr-1), Einkaufsliste (id=…), Wunschliste (id=…)
- Nextcloud Kalender: Persönlich, DLR, Einkaufsliste, Wunschliste
- Mail-Konto: fkrebs@nucli.de (Posteingang, Archiv, Junk, Waiting)
- Qdrant Collection: nexa_knowledge_text (1024 dims, Cosine, 0 Punkte)
- LiteLLM-Modelle: nexa-chat, nexa-embed

#nexa:status

  • Beschreibung: Zeigt den aktuellen System-Status
  • Antwort: Uptime, verbundene Systeme, Memory-Stats
#nexa:status

#nexa:sync-obsidian

  • Beschreibung: Triggert sofortige Synchronisierung mit Obsidian Vault
  • Optional Parameter: --vault=/path/to/vault oder --force für Neuindexierung
#nexa:sync-obsidian --force

📊 Memory & RAG Kommandos

#nexa:ask [question]

  • Beschreibung: Semantische Suche in Qdrant (RAG) basierend auf Obsidian + Memos
  • Antwort: Top-3 Treffer mit Quellen
#nexa:ask Wie implementierten wir das JWT-Middleware-Pattern?

#nexa:learn [topic]

  • Beschreibung: Explizit neue Information in Qdrant speichern (mit Tags)
  • Optional: --tag=architecture --source=obsidian/notes/arch.md --permanent (überschreibt Default-TTL)
#nexa:learn Das Routing-Schema unterscheidet Work vs. Personal via SAIA-Kontext-Analyse --tag=architecture

#nexa:forget [query-or-iri]

  • Beschreibung: Löscht passende Einträge aus Qdrant + GraphDB sofort.
  • Beispiel: #nexa:forget --source=rss --older-than=14d

#nexa:retain [source_type] [days]

#nexa:ask [question] [--web]

  • Beschreibung: Semantische Suche in Qdrant. Mit --web erweitert Nexa die Suche um eine SearXNG-Abfrage (redis-searxng), holt die Top-3 Treffer via crawl4ai-mcp + markitdown-mcp, embedded sie und nutzt das gemeinsame Material für die Antwort. Geholte Seiten bleiben 90 Tage im Speicher (TTL siehe oben).

🎯 Workflow-Kommandos

#nexa:route-test [text]

  • Beschreibung: Testet die Klassifizierung (Work/Personal) ohne Task zu erstellen
#nexa:route-test Muss morgen die Präsentation für den Client fertigstellen

Response:

💬 Klassifizierung (Test-Mode):
- Kontext: WORK
- Vertrauen: 0.95
- Begründung: "Client-Präsentation → professioneller Kontext"

#nexa:email-digest

  • Beschreibung: Triggert sofortige Email-Zusammenfassung (sonst tägl. 7 Uhr)
#nexa:email-digest

#nexa:digest

  • Beschreibung: Tägliches Morgen-Digest. Läuft automatisch (07:00). Inhalt:
    1. Kurze Mail-Zusammenfassung (siehe #nexa:email-digest).
    2. Anstehende Tasks heute (DLR + Persönlich, nach Urgency).
    3. Drift-Report aus Phase 6 (sobald aktiv).
    4. Re-ask Block — siehe unten. Maximal 1 offene Frage pro Digest, nur wenn der Digest sonst kurz genug ist.

Re-ask der offenen Fragen (docs/11-open-questions.md)

Nexa führt im GraphDB pro offener Frage nexa:askedCount, nexa:lastAskedAt, nexa:nextAskAt. Backoff-Schema:

Mal Wartezeit bis zur nächsten Frage
1 → 2 3 Tage
2 → 3 7 Tage
3 → 4 21 Tage
≥ 5 60 Tage

Im Morgen-Digest wird eine offene Frage angehängt — und zwar nur wenn:

  • Der Digest sonst < 800 Zeichen lang wäre (Capacity-Guard, damit es nicht nervt).
  • nextAskAt <= today.
  • Bevorzugt die Frage mit dem kleinsten askedCount (zuerst neue Fragen, alte selten).

Antwortet der User direkt unter dem Digest-Memo, parst Nexa die Antwort, markiert die Frage in docs/11 als resolved (Phase 6.4 — Self-update of docs) und committet einen Diff zur Review.

#nexa:remind

  • Manuelles Triggern einer Re-Ask, ignoriert Backoff. Nützlich für Rückfragen mitten im Tag.

#nexa:answered

  • Beantwortet eine offene Frage explizit. Setzt resolved im GraphDB und schlägt einen docs/11-Diff vor.

🔐 Admin-Kommandos

#nexa:reset-config

  • Beschreibung: Löscht gespeicherte Konfiguration, triggert neuen Autodiscovery
  • Warnung: Alle benutzerdefinierten Settings werden vergessen
#nexa:reset-config

#nexa:export-state

  • Beschreibung: Exportiert aktuellen State als JSON (für Backups)
#nexa:export-state

📝 Implementierung in n8n

Ein Command Parser läuft immer mit:

  1. Memos Webhook empfängt alle Memos
  2. Regex Check: Sucht nach #nexa:command
  3. Router: Versendet an entsprechenden n8n-Workflow
  4. Antwort: Postet Reply als Kommentar/Edit

Command Parser Regex:

^#nexa:(\w+)(?:\s+([^\n]*?))?(?:$|\s*--)

Extrahiert: [command, parameters]


🎛️ Dynamische Konfigurationsspeicherung

Statt .env zu editieren:

  1. First Run: #nexa:config speichert zu lokalen Metadata

  2. Speich-Ziel:

    • Primary: Qdrant Metadata (als _config Namespace)
    • Fallback: nexa-core/config/runtime_config.json (gitignored)
    • Notfall: .env (nur initial)
  3. Reload-Logik: Bei jedem Workflow-Start werden Settings aus Qdrant geladen

Das macht Nexa vollständig selbstständig nach dem initialem Setup!