Files
NSCT---Neutral-Search-Crawl…/HANDOFF.md
2026-09-07 12:46:06 +02:00

430 lines
23 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.
# 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-07
### Browser-E2E: Leeren Abschluss auf Suchausfall zurückgeführt und repariert — 2026-09-07
Der abgeschlossene Browser-Run `33328b0b-18df-48df-9f2d-8af077987ccc` hatte
einen validen Plan mit sechs Suchanfragen, aber keine Treffer: Quellen,
Claims, Evidenz und Bericht waren deshalb leer. SearXNG war erreichbar, seine
Default-Engine-Mischung lieferte im aktuellen Netz jedoch wegen CAPTCHA, 429
und Timeouts keine nutzbaren Ergebnisse. Der Orchestrator behandelte diesen
Fall fehlerhaft als erfolgreichen Run und erzeugte einen leeren Fallback-
Bericht.
- Ein providerweiter Trefferstand von null beendet den Run nun mit einem
eindeutigen Suchfehler, statt `completed` mit leerem Bericht zu speichern.
- Die SearXNG-Engine-Liste ist über `NSCT_SEARXNG_ENGINES` konfigurierbar.
Der lokale Compose-Default ist `bing,yahoo`; diese beiden Engines lieferten
im API-Container erfolgreich Ergebnisse. Betreiber können die Auswahl in
ihrer Umgebung überschreiben.
Validierung: 70 gezielte Tests (`test_backend_pipeline_repairs.py`,
`test_crawler.py`, `test_search.py`), Compose-Konfigurationsprüfung,
Docker-Rebuild und `/health` HTTP 200. Der direkte Provider-Probe aus dem
API-Container lieferte fünf Resultate. Für den nächsten Browser-E2E-Test eine
neue Recherche starten; ein API-Rebuild verwirft weiterhin alte In-Memory-
Run-IDs.
### Planungsinformationen in Research-Details umgesetzt — 2026-09-07
Issue [Frontend #1](https://git.frerkc.de/opencode/NSCT-FrontEnd/issues/1)
ist lokal umgesetzt und in beide Container deployed:
- Das Backend speichert den strukturierten, bereits validierten Research-Plan
unmittelbar nach der Planungsphase. `GET /v1/research/{id}/plan` liefert ihn
authentifiziert als `plan` mit `available`; weder System-Prompt noch rohe
Modellantwort werden offengelegt. Der Plan bleibt auch bei Fehlern in einer
späteren Pipeline-Phase abrufbar.
- Die Research-Detailseite enthält den Tab **Planung**. Er zeigt Thema,
Zeitraum, Suchanfragen samt Zweck/Kategorie, Perspektiven, Entitäten,
vorgesehene Quelltypen, Gegenhypothesen und Maßnahmen gegen Search-Bias.
Vor Ende der Planungsphase erscheint ein eindeutiger Wartehinweis.
Validierung: zwei neue Endpoint-Tests erfolgreich, Backend-Syntaxprüfung,
Frontend-Produktionsbuild, beide Docker-Rebuilds sowie `/health` und
`/api/health` HTTP 200. `npm run check` hat weiterhin die 18 bereits bekannten,
unabhängigen TypeScript-Fehler; die Planansicht fügt keinen hinzu.
### Browser-E2E: Fehlerpfade und Quick-Budgets weiter repariert — 2026-09-07
Die nachfolgenden echten Browser-/Proxy-Tests erreichten erstmals die Crawler-
und Analysephasen. Drei weitere Fehler sind lokal repariert, durch gezielte
Regressionstests abgedeckt und mit `docker compose up -d --build nsct-api`
deployed:
1. Der Crawler erzeugte für einzelne Fetch-Fehler ein `NormalizedDocument` mit
leerem `content_hash`. Der Fehlerpfad verwendet nun `from_text()`, das auch
für leeren Inhalt einen gültigen SHA-256-Hash erzeugt. Einzelne kaputte
Quellen brechen damit nicht mehr die gesamte Recherche ab.
2. Quick-Runs buchten beim Start einen nicht existierenden Planner-Request und
anschließend eine Claim-LLM-Anfrage für jede Quelle, einschließlich
Fehlerquellen. Bei 15 Quellen standen so vor der Analyse 17 statt maximal
15 Requests im Budget. Der Phantom-Eintrag entfällt; nur erfolgreiche
Quellen werden für Claims verarbeitet und ein Request bleibt für die
Synthese reserviert. Ein voll ausgelasteter Quick-Run nutzt damit höchstens
`1 Planung + 13 Claims + 1 Synthese = 15` LLM-Requests.
3. `BudgetTracker.record_time_elapsed()` addierte bei jedem Aufruf erneut die
gesamte Zeit seit Run-Start. Der Tracker verbucht nun ausschließlich das
Intervall seit der letzten Messung. Für das lokale 35B-Modell mit ca.
8 Tokens/s gelten jetzt Zeitlimits von 30 Minuten (Quick), 60 Minuten
(Normal) und 120 Minuten (Deep).
Validierung: 68 gezielte Tests (`test_backend_pipeline_repairs.py`,
`test_crawler.py`, `test_search.py`) erfolgreich; Backend-Container neu
gebaut und `/health` liefert HTTP 200. Der vollständige neue Research-Run
wurde nicht abgewartet, weil die lokale 35B-Inferenz absichtlich mehrere
Minuten dauern kann. Beim nächsten Test eine frische Recherche starten und
insbesondere Quellen, Claims und Bericht nach Abschluss prüfen.
Für die laufende Testphase ist es akzeptiert, dass Research-Runs nur im
Arbeitsspeicher liegen und ein API-Neubau vorhandene Run-IDs verwirft.
### Browser-E2E: Such- und Crawler-Pipeline repariert — 2026-09-07
Während des Browser-E2E-Tests traten drei aufeinanderfolgende Backend-Fehler
auf. Alle sind lokal repariert, durch gezielte Tests abgedeckt und mit
`docker compose up -d --build nsct-api` deployed:
1. SearXNG liefert `NormalizedResult`-Pydantic-Objekte. Der Orchestrator
behandelte optionale leere Felder fälschlich als Dictionary und rief `.get()`
auf. Die Ergebnisnormalisierung unterscheidet nun sauber Modelle, Mappings
und ungültige Werte.
2. `AsyncFetcher` konfigurierte bei `httpx.Timeout` connect/read/write, aber
keinen `pool`-Timeout. Der Crawler konnte deshalb nicht initialisiert
werden. `pool` ist nun konfigurierbar über `NSCT_CRAWLER_POOL_TIMEOUT`
(Default 10 Sekunden).
3. Die Budgetierung buchte für jede Ergebnis-URL vor dem Abruf pauschal 500 KB.
Ein Quick-Run mit 22 URLs überschritt so fälschlich das 500-KB-Budget, obwohl
die tatsächlichen Downloads deutlich kleiner waren. Abrufe werden jetzt auf
verbleibende Quellen- und Bytebudgets begrenzt; die Buchung erfolgt nach
tatsächlich abgerufenen Response-Bytes. Budgetobergrenzen sind inklusiv.
Das Quick-Zeitlimit betrug in diesem Zwischenstand 300 Sekunden und wurde
im späteren Budget-Fix für die lokale 35B-Inferenz auf 30 Minuten erhöht.
Validierung: 63 gezielte Tests (`test_backend_pipeline_repairs.py`,
`test_crawler.py`, `test_search.py`) erfolgreich; Docker-Container und
`/health` erfolgreich. Die komplette REST-Suite startet echte externe
Background-Retries und wurde deshalb nicht abgewartet. Pytest ist lokal in der
ignorierten `.nsct-test-venv` installiert.
Wichtig für den nächsten Browser-Test: Research-Runs werden derzeit nur in
`_research_store` im Arbeitsspeicher gehalten. Jeder API-Neubau/-neustart
entfernt bisherige Run-IDs; die alten Runs liefern danach erwartungsgemäß 404.
Persistente Research-Runs sind ein offener Production-Readiness-Punkt. Vor dem
erneuten Test zuerst eine neue Recherche starten, nicht eine alte Detail-URL
wiederverwenden.
### 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**:
```text
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:
```bash
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 | `10a083a` | 8 | ~20 ||
|||| 12 | **Research Orchestrator** — State Machine + Budget Limits + Pipeline-Steuerung | `2ef7b67` | 4 | 0 ||
|||| 13 | **Iterative Research / Gap Analysis** — Lückenerkennung, max 3 Runden, GapSearchQuery | `0b7a624` | 5 | 17 ||
||| **14** | ~~REST API~~ (✅ **ABGESCHLOSSEN**`rest_research.py` + `main.py` + `tests/test_rest_research.py`) |
||| **15** | ~~CLI~~ (✅ **ABGESCHLOSSEN**`cli.py` + `tests/test_cli.py`) |
|||| **16** | ~~Observability~~ (✅ **ABGESCHLOSSEN**`logging_config.py` + `metrics.py` + `test_logging.py` + `test_metrics.py`) |
||| **17** | ~~Neutralitäts-Tests~~ (✅ **ABGESCHLOSSEN**`test_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~~ (✅ **ABGESCHLOSSEN**`state.py` + `budget.py` + `models.py` + `orchestrator.py`) |
| **13** | ~~Iterative Research / Gap Analysis~~ (✅ **ABGESCHLOSSEN**`gap_analysis.py` + `stage13_gap_analysis.py` + `orchestrator.py` + tests) |
||| **14** | ~~REST API — POST/GET/DELETE für research, status, sources, claims, evidence, report.~~ (✅ **ABGESCHLOSSEN**`rest_research.py` + `main.py` + `tests/test_rest_research.py`) |
||| **15** | ~~CLI~~ (✅ **ABGESCHLOSSEN**`cli.py` + `tests/test_cli.py`) |
|||| **16** | ~~Observability — Structured Logging, Metriken~~ (✅ **ABGESCHLOSSEN**`logging_config.py` + `metrics.py` + `test_logging.py` + `test_metrics.py`) |
||| **17** | ~~Tests für Neutralitätsmethodik~~ (✅ **ABGESCHLOSSEN**`test_neutrality_a_syndication.py` + `test_neutrality_b_political_statements.py` + `test_neutrality_c_scientific_disagreement.py` + `test_neutrality_d_prompt_injection.py` + `test_neutrality_e_missing_evidence.py`) |
|||| **18** | ~~Docker Hardening~~ (`6067908`) | 1 | ||
||| **19** | ~~Performanceoptimierung — LLM Concurrency Semaphore(3), Priorisierung (HIGH/NORMAL/LOW)~~ (`4335a40`) | 5 | 14 ||
|| 20 | ~~Context Budgeting — Pro Stage Kontext-Limits (Planner 12k, Claim 16k, Contradiction 24k, Synthesis 48k)~~ (✅ `context_budget.py` + `orchestrator.py` context_budget + `_track_context_tokens()` + `__init__.py` + `test_context_budget.py` + `test_context_budget_integration.py` + `priority_queue.py` async_fix — 34 Tests) |
| 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 add``git commit``git 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.