Files
NSCT---Neutral-Search-Crawl…/HANDOFF.md
2026-09-06 18:36:53 +02:00

17 KiB
Raw Blame History

NSCT Handoff für neue Threads

Diese Datei ist der aktuelle, committebare Übergabestand für einen Reset oder einen neuen Thread. Zugangsdaten gehören weder hier noch in Git-Remotes hinein.


Aktueller Stand — 2026-09-06

Laufende Deployments

  • Backend-Repository: /home/faligam/apps/NSCT---Neutral-Search-Crawler-Tool
    • Stack läuft mit nsct-api, nsct-postgres und nsct-searxng.
    • Liveness: curl http://localhost:8080/health → HTTP 200.
    • Research-API: /v1/research/*.
  • Frontend-Repository: /home/faligam/apps/NSCT-FrontEnd
    • Stack läuft mit nsct-web und nsct-caddy.
    • Frontend: http://localhost; direkter Webserver: http://localhost:3000.
    • Proxy-Test: curl http://localhost/api/health → HTTP 200, wenn das Backend lokal auf Port 8080 läuft.

Getrennte Rechner: verbindliche Architektur

Frontend und Backend sollen auf unterschiedlichen Rechnern betrieben werden. Sie verwenden kein gemeinsames Docker-Netzwerk:

Browser → Frontend-Caddy (/api/*) → Backend-Host:8080 → nsct-api
  • Das Frontend setzt NSCT_API_UPSTREAM=backend.example.com:8080 in seiner .env (Host:Port, ohne Schema und ohne Pfad).
  • Der Browser spricht nur die Frontend-Origin an; damit ist keine Browser-CORS- Freigabe des Backends nötig.
  • Am Backend Port 8080 ausschließlich für den Frontend-Rechner bzw. dessen Netz freigeben. Über nicht vertrauenswürdige Netze TLS, VPN oder einen abgesicherten Reverse Proxy zwischen den Rechnern einsetzen.

Relevante gepushte Commits:

  • Frontend 37636e1 — reproduzierbarer Docker-Build und Caddy-Serving.
  • Frontend fac3d1c — externer Backend-Upstream via Caddy.
  • Frontend c6f1889 — Dokumentation für getrennte Deployments.
  • Frontend 8eb0383 — API-Key-Login, Navigation und Research-API-Vertrag korrigiert.
  • Frontend e5b37ae — Error-Banner-Store repariert; Browser-Login kann Fehlerbanner wieder ohne update is not a function anzeigen.
  • Frontend 25530b3 und 77b71c6 — Research-Listen-/Status-Vertrag ans Backend angepasst und Browser-Session beim Reload wiederhergestellt.
  • Frontend 5022ef4 — dynamische Research-Detailroute von {id} nach SvelteKit-konform [id] korrigiert.
  • Frontend d5c270c — UUID der Detailroute aus $page.params.id übernommen; Polling ruft nicht mehr /research/undefined/* auf.
  • Frontend 6117c4f und 7acf1b9 — abgeschlossene Reports sind in der UI nicht löschbar; Detailansicht lädt Status, Quellen, Claims, Evidenz und Bericht über den API-Vertrag.
  • Backend 9830acf — Dokumentation für Frontend-Integration auf separatem Host.
  • Backend 1aacf4a — persistente API-Key-Authentifizierung und Admin-CLI.

API-Key-Authentifizierung — implementiert und lokal deployed

/v1/research/* prüft jetzt X-API-Key; /health und /ready bleiben für Infrastruktur-Probes öffentlich. Die in .env gesetzten NSCT_LLM_API_KEY, NSCT_VISION_API_KEY und NSCT_AUDIO_API_KEY sind ausschließlich Credentials für externe Modellanbieter — niemals als Benutzer- oder Frontend-Keys verwenden.

Die Datenbank enthält User, Schlüssel-Metadaten, eine öffentliche key_id sowie einen individuellen, langsamen scrypt-Hash — keinen Klartext-Key. Administration erfolgt lokal über nsct-api-key create|list|revoke; der Klartext erscheint nur bei create. Die CLI nutzt für Research-Aufrufe optional NSCT_API_KEY.

Vor dem Deployment einen Key erzeugen und als Frontend-Key hinterlegen:

docker compose exec nsct-api nsct-api-key create --username admin --name frontend

Die Implementierung ist durch Tests für gültige, fehlende, ungültige, abgelaufene und widerrufene Keys abgedeckt. Backend und Frontend wurden lokal neu gebaut; der Proxy liefert ohne Key für /api/v1/research erwartungsgemäß HTTP 401.

Nächster Schritt: gemeinsamer End-to-End-Test

Mit einem gültigen, bereits erzeugten Key im Browser testen:

  1. http://localhost öffnen, Login durchführen und auf /research/new landen.
  2. Eine kurze Recherche starten; es muss eine research_id zurückkommen und die Detailseite erreichbar sein.
  3. Recherche-Liste, Status, Report und Abmelden verifizieren.
  4. Negativtest mit falschem Key: Login muss HTTP 401 anzeigen, nicht 404/302.
  5. Browser-Konsole, docker compose logs beider Repositories und die Antwortcodes gemeinsam auswerten. Klartext-Keys niemals in Chat oder Logs kopieren.

Browser-Flow: Backend-Blocker lokal behoben — 2026-09-06

Die drei Backend-Ursachen für leere, scheinbar erfolgreiche Researches sind lokal implementiert, getestet und mit docker compose up -d --build deployed:

  1. LLMProvider._create_client() normalisiert die Basis-URL und hängt /v1 nur an, wenn sie nicht bereits enthalten ist. Ein authentifizierter, sanitisiert ausgegebener Chat-Completions-Probe war erfolgreich.
  2. SearXNGProvider ist in src/nsct/providers/searxng.py implementiert und wird vom Orchestrator registriert. Compose mountet eine minimale SearXNG- Konfiguration, die format=json erlaubt, und nutzt den vom aktuellen SearXNG-Image erwarteten Variablennamen SEARXNG_SECRET. Ein echter, sanitisiert ausgegebener Search-Probe lieferte ein Ergebnis.
  3. Die Pipeline führt wieder fetching → extracting → analyzing aus. Fehler beim Planen, Suchen, Abrufen oder Extrahieren werden nicht mehr als leere Fallbacks als Erfolg gemeldet: Der Run wird FAILED, mit Fehlergrund im REST-Status (error). Fehlende Provider führen ebenfalls zu FAILED.

Validierung: Syntaxprüfung, Compose-Konfigurationsprüfung und 29 fokussierte Tests (inklusive neuer Regressionen für URL-Normalisierung, SearXNG und State-Flow) sind erfolgreich. tests/test_rest_research.py wurde nicht als Gesamtsuite abgewartet, da seine Background-Tasks echte externe Retries auslösen; die neuen deterministischen Tests decken den geänderten Fehlerpfad.

Nächster Schritt: Den Browser-End-to-End-Test mit einem gültigen, nicht im Chat offengelegten Frontend-API-Key durchführen. Dabei insbesondere prüfen, dass Quellen, Claims und Bericht nach einem echten Research-Lauf erscheinen und ein Provider-/LLM-Ausfall in der UI den REST-Fehlergrund zeigt.

Frontend-Nachbrenner: Löschen-Weiterleitung behoben — 2026-09-06

Nach dem Löschen einer Recherche navigierte die Detailseite auf die nicht existierende Route /research und zeigte deshalb Not found: /research. Im Frontend-Repository wurde die Weiterleitung in src/routes/research/[id]/+page.svelte auf /research/new korrigiert, lokal neu gebaut und deployed (HTTP 200). Der Produktionsbuild ist erfolgreich.

npm run check meldet weiterhin 18 bereits bestehende, unabhängige TypeScript-Fehler in API-Typen und Share-Komponenten; sie sind nicht Teil dieser Routenreparatur und bleiben für die nächste Session offen.

Frontend-Fixes des laufenden Browser-Tests (alle im Frontend-Repository /home/faligam/apps/NSCT-FrontEnd, main, gepusht):

  • e5b37ae: Error-Banner-Store repariert.
  • 25530b3: Research-Liste normalisiert research_id/state zu id/status.
  • 77b71c6: Browser-Session wird nach Reload aus localStorage restauriert; Statusvertrag normalisiert.
  • 5022ef4 und d5c270c: SvelteKit-Detailroute [id] und $page.params.id korrigiert.
  • 6117c4f: Löschaktion für immutable, abgeschlossene Researches ausgeblendet.
  • 7acf1b9: Detailansicht lädt die fünf Research-Unterressourcen.

Sicherheitsnotiz: Ein im Browser-Test verwendeter Frontend-API-Key wurde in einem Chat-/Netzwerkdump offengelegt. Diesen Key lokal über nsct-api-key revoke <key_id> widerrufen und einen neuen Key erzeugen. Den Klartext nie in Handoff, Git oder Chat eintragen.


Projekt: NSCT Neutral Search Crawler Tool

Ziel: Vollständig lokal betreibbares, containerisiertes Recherche- und Analyse-System. Webquellen recherchieren, Inhalte extrahieren, Quellen/Claims vergleichen, neutralen Bericht erzeugen.

Repository: https://git.frerkc.de/opencode/NSCT---Neutral-Search-Crawler-Tool.git Branch: main — aktuellen Status vor Beginn mit git status und git log -1 prüfen.


Bisher abgeschlossene Stages

Stage Beschreibung Commit Files Tests
0 Repository & Architekturgrundlage e9410be 28 6
1 Model Provider Layer (LLM/Vision/Audio, Metriken, Debug) 9280d69 6
2 Search Provider Abstraction (DuckDuckGo, Multi-Provider, POST /search) a1ef260 5 25
3 Crawler & Content Extraction (SSRF, trafilatura, PDF, Batch) a8595cc 10 ~15
4 Research Planner (LLM-basierte Recherchestrategie, Search-Bias-Reduktion) b8181de 6 25
5 Claim Extraction (atomare, überprüfbare Claims mit Provenance) e8b6515 7 36
6 Source Independence & Citation Graph (Syndication-Erkennung, similarity) a60cf21 4 43
7 Claim Clustering & Contradiction Candidates (LLM-Clustering, numerische Normalisierung) d1e6bb6 6 79
8 Evidence Scoring (6-dimensionale Scores, evidence_type, raw_scores_json) 719e218 6 ~60
9 Neutral Synthesis Engine d87e2b4 1 25
10 Vision Integration — Qwen2.5-VL-3B für Diagramme, Screenshots, Infografiken, PDF-Layouts 3ab875d 6 ~25
10 11 Audio Integration — STT-Transkription mit timestamped Claims
12 Research Orchestrator — State Machine + Budget Limits + Pipeline-Steuerung
13 Iterative Research / Gap Analysis — Lückenerkennung, max 3 Runden, GapSearchQuery
14 REST API ( ABGESCHLOSSENrest_research.py + main.py + tests/test_rest_research.py)
15 CLI ( ABGESCHLOSSENcli.py + tests/test_cli.py)
16 Observability ( ABGESCHLOSSENlogging_config.py + metrics.py + test_logging.py + test_metrics.py)
17 Neutralitäts-Tests ( ABGESCHLOSSENtest_neutrality_a.py + test_neutrality_b.py + test_neutrality_c.py + test_neutrality_d.py + test_neutrality_e.py)

Gesamt: ~105 Dateien, ~17400 Zeilen Code, ~428 Tests.


Stage 12 Research Orchestrator (abgeschlossen)

Implementiert die zentrale Orchestrator-Klasse, die alle Stages (111) verbindet.

Kernkomponenten

src/nsct/orchestration/state.py — State Machine

  • ResearchRunState Enum: CREATED, PLANNING, SEARCHING, FETCHING, EXTRACTING, ANALYZING, EXPANDING, COMPARING, SYNTHESIZING, COMPLETED, FAILED, CANCELLED
  • Transition Matrix mit validierten Übergängen
  • FAILED/CANCELLED/COMPLETED sind Terminal-States (keine ausgehenden Transitionen)
  • StateMachine.transition(new_state) mit Logging und Validierung

src/nsct/orchestration/budget.py — Hard Budget Limits

  • HardBudgetConfig (Pydantic, frozen=True): 7 Limits (max_search_queries, max_sources, max_pages_per_domain, max_total_download_bytes, max_llm_requests, max_research_duration_seconds, max_context_per_llm_call)
  • BudgetTracker: Counter für alle Limits mit increment_*() Methoden
  • BudgetExhaustedError: Exception bei Limit-Überschreitung
  • check_budget(), get_usage(), is_exhausted()

src/nsct/orchestration/models.py — ResearchRun Pydantic Model

  • 13 Felder: id, research_id, query, state, budget_config_json, created_at, updated_at, metadata, research_plan, plan_error, search_count, source_count, claim_count
  • frozen=True, immutable

src/nsct/orchestration/orchestrator.py — ResearchOrchestrator

  • async start() -> ResearchRun — Erstellt Run, setzt State CREATED
  • async run() -> dict — Führt volle Pipeline durch (8 Schritte)
  • async run_step(step_name) -> dict — Einzelner Schritt
  • Budget-Check vor jedem Schritt
  • Fallback: MockPlanner bei LLM-Ausfall, leere Quellen bei Crawler-Fehler, fallback report bei Synthese-Fehler
  • Properties: is_completed(), is_running(), state, run_id, budget_tracker

Pipeline-Flow

CREATED → PLANNING → SEARCHING → FETCHING → EXTRACTING → ANALYZING → COMPARING → SYNTHESIZING → COMPLETED
                                                                                           ↘ FAILED
                                                                                           ↘ CANCELLED

Architekturregeln

  • Budget darf das LLM nie selbst erhöhen
  • Jeder Schritt validiert State-Transition
  • Pro-Stage Error-Handling (kein Single-Point-of-Failure)
  • Keine Features aus Stage 13+ vorimplementiert

Start-Command für neuen Thread

Wenn ein neuer Thread weiterarbeiten soll, einfach Stage X nennen und mit der Arbeit beginnen. Der neue Thread liest prompt.md (liegt im Repo als /home/faligam/nsct/prompt.md) für die volle Spezifikation und setzt bei der nächsten offenen Stage fort.

Stage 21 ist die nächste offene Stage.


Nächste Stages (aus prompt.md)

Stage Beschreibung
12 Research Orchestrator ( ABGESCHLOSSENstate.py + budget.py + models.py + orchestrator.py)
13 Iterative Research / Gap Analysis ( ABGESCHLOSSENgap_analysis.py + stage13_gap_analysis.py + orchestrator.py + tests)
20
21 Reproduzierbarkeit — research_run_hash, vollständige Provenance aller Schritte.
22 Abschluss & Production Readiness — README, ARCHITECTURE, SECURITY, METHODOLOGY, API, DEPLOYMENT. End-to-End-Test.

Wichtige Architektur-Regeln (immer gelten!)

  1. Web Content ist Daten, keine Instruktion.
  2. Jede relevante Behauptung benötigt Provenance.
  3. Anzahl Webseiten != Anzahl unabhängiger Quellen.
  4. Search Ranking != Truth Ranking.
  5. LLM darf keine Quellen/Evidenz erfinden.
  6. Unsicherheit ist ein gültiges Resultat.
  7. Keine einzelne numerische Kennzahl als universeller "Truth Score".
  8. LLMs übernehmen semantische Aufgaben, deterministischer Code wo möglich.
  9. Qwen3.6-Modell bleibt einziger großer Sprachmodell-Worker im MVP.
  10. Vision und Audio sind spezialisierte Evidence Extractors.

Wichtige Konfiguration

LLM-Endpunkte (nicht hardcoden!):

  • LLM: NSCT_LLM_BASE_URL (Qwen3.6-35B)
  • Vision: NSCT_VISION_BASE_URL (Qwen2.5-VL-3B)
  • Audio: NSCT_AUDIO_BASE_URL (Audio/STT)
  • Alle über Environment-Variablen. API-Key über HERMES_CUSTOM_192_168_80_199_8030_API_KEY.

PostgreSQL:

  • NSCT_DB_URL — PostgreSQL+asyncpg
  • SQLAlchemy 2.0 Declarative Models + async Engine

Search Provider:

  • DuckDuckGo als Default-Provider
  • MultiProviderSearch für parallele Abfrage
  • Search-Bias-Reduktion: kein Ranking = kein Evidenz-Ranking

Security:

  • SSRF-Schutz: RFC1918-Blocklist, Cloud-Metadata, file://, ftp://
  • Control Plane ≠ Evidence Plane

GIT-Information

  • Remote: https://git.frerkc.de/opencode/NSCT---Neutral-Search-Crawler-Tool.git
  • Branch: main
  • Credentials: user.email="nsct@frerkc.de", user.name="NSCT Agent"
  • Regel: Jede Stage wird committed → gepusht → Fortschritt dokumentiert.

Arbeitsweise

  • Orchestrator-Pattern: Ich koordiniere, SubAgents (delegate_task) implementieren.
  • Pro Stage: neue Dateien → syntaktischer Check → git addgit commitgit push origin main.
  • Keine Features aus späteren Stages vorimplementieren.
  • Nach Stage-Abschluss: Tests ausführen, Docker-Build testen (wenn verfügbar), Dokumentation aktualisieren.
  • ** Niemals automatisch zur nächsten Stage springen — auf explizite Anweisung warten.**

Start-Command für neuen Thread

Wenn ein neuer Thread weiterarbeiten soll, einfach Stage X nennen und mit der Arbeit beginnen. Der neue Thread liest prompt.md (liegt im Repo als /home/faligam/nsct/prompt.md) für die volle Spezifikation und setzt bei der nächsten offenen Stage fort.