2026-08-10 16:20:59 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 16:20:59 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 16:20:59 +02:00
2026-08-10 16:20:59 +02:00
2026-08-10 16:20:59 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 16:20:59 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 05:48:55 +02:00
2026-08-10 16:20:59 +02:00

V3.5 Random Guess Lottery: Optional kann die Zahl der tatsächlich ausgewerteten Tipps pro Zeitfenster begrenzt werden. Im Admin-Tab RUNTIME steuern Lotterie-Zeitfenster (s) und Max. gezogene Tipps je Task/Fenster die Funktion; 0 deaktiviert sie vollständig. Die Lotterie läuft getrennt pro aktivem Task. Alle gültigen, signierten Tipps werden bis zum Ende des Zeitfensters gesammelt und anschließend mit crypto/rand gleichberechtigt zufällig gezogen. Nur gezogene Tipps werden gegen das geheime Ziel ausgewertet und können Score/Winner/NFT auslösen. Nicht gezogene Tipps verbrauchen ihre Sequenz, damit beim nächsten Fenster ein neuer deterministischer Tipp entsteht, zählen aber nicht als akzeptierter guess_count. Abgebrochene HTTP-Requests verbrauchen keinen Lotterie-Slot. Dadurch wird die mögliche Task-Abschluss-/NFT-Rate gedrosselt, ohne Gewinner oder Styles direkt zu manipulieren.

Neural Hunt — V3.1 RIFT Task-Style Collection + Profile Cleanup

V3.1 Admin Profile Cleanup: Im Admin-Tab RUNTIME gibt es ein manuelles Bereinigungstool für alte Identitäten. Die Inaktivitätsdauer ist in Stunden/Tagen/Wochen einstellbar. Vor dem Löschen zeigt PRÜFEN die Anzahl löschbarer Profile. Gelöscht werden ausschließlich Profile, deren letzte Aktivität älter als die gewählte Grenze ist, die aktuell nicht verbunden sind und die niemals Gewinner eines Tasks waren. Gewinner werden immer geschützt; aktuell verbundene Clients ebenfalls. Beim Löschen werden die per Foreign Key abhängigen task_points, client_unlocks und client_task_selection mit entfernt. WebSocket-Verbindungsaufbau und -ende aktualisieren clients.last_seen, damit die Inaktivitätsgrenze tatsächliche Nutzung besser abbildet.

V2.8 RIFT Task-Styles: RIFT-Identität und Rendering-Stil sind jetzt sauber getrennt. /data/artifacts/_collection/character_anchor.png ist ein globaler, neutraler Identity-Lock für den Waschbären RIFT und kann im Admin-Tab ARTIFACT einmalig manuell erzeugt und geprüft werden. Jeder Task kann im Admin-Tab TASK ACTIONS ein eigenes JPEG-/PNG-Style-Referenzbild erhalten; Nutzer sehen dieses Stylebild bereits in der Task-Auswahl und wählen damit indirekt die gewünschte NFT-Art. Bei jeder RIFT-Karte sendet Neural Hunt Image 1 = Character Anchor und Image 2 = Task Style Reference an die Images Edit API. Ohne eigenen Task-Style bleibt internal/artifact/assets/style_reference.jpg nur noch der Default-Fallback. Folge-Tasks erben ihren Style. medium bleibt Standard und die OpenAI-Usage-/Kosten-KPIs aus V2.7 bleiben erhalten.

V2.5.2 Hotfix: Der 3-Sekunden-Telemetrie-Poll hat in V2.5.1 den kompletten Control-Plane-DOM neu aufgebaut. Dadurch wurden native <select>-Dropdowns geschlossen und Cursor-/Scrollzustände in Eingabefeldern zerstört, obwohl die Werte über Drafts erhalten blieben. V2.5.2 trennt Telemetrie-Refresh und Formular-Rendering: Overview, Performance, Taskliste und Map aktualisieren sich weiterhin live, die Formular-Controls werden aber nur noch bei explizitem Tab-/Taskwechsel oder nach einer Admin-Aktion neu aufgebaut. Offene Dropdowns und laufende Eingaben bleiben damit stabil.

V2.5.1 Hotfix: Ein WebSocket-Heartbeat-Fehler in V2.5 konnte Browser-Verbindungen sehr regelmäßig nach ungefähr 90 Sekunden beenden. Der Server hatte zwar eine Pong-Deadline gesetzt, aber nur ein JSON-ping statt eines echten WebSocket-Control-Pings gesendet. Danach fehlte die Presence-Lease und der nächste Tipp erhielt HTTP 409, bis F5 eine neue Verbindung öffnete. V2.5.1 sendet echte Ping-Frames, schützt Reconnects mit generationsgebundenen Presence-Leases und verbindet Browser/Shell automatisch neu. HTTP-409-Antworten besitzen zusätzlich maschinenlesbare Fehlercodes und werden clientseitig selbstständig resynchronisiert.

V2.5: Nutzer wählen ihren Task auf einer eigenen Landing-Page und können jederzeit wechseln. Jeder Task besitzt eigene NFT-Prompt-Anweisungen, Anzeigename und Beschreibung; sein Folge-Task erbt diese Konfiguration. Admin-Formulare behalten ungespeicherte Eingaben auch bei Auto-Refresh und Browser-Reload. Zusätzlich gibt es mit cmd/client einen vollwertigen signierten Shell-Client für unbeaufsichtigten Betrieb.

Die V2.4-SCALE-Architektur bleibt erhalten: Verlierende Tipps bleiben im RAM, Map-Updates werden gebatcht, WebSockets schreiben asynchron und Map-Snapshots sind serverseitig begrenzt. Bitte weiterhin in ein neues/leeres Verzeichnis entpacken.

Neural Hunt ist eine eigenständige Go-Webanwendung für das beschriebene soziale Wahrscheinlichkeitsexperiment. Sie benötigt für den Normalbetrieb nur das Go-Binary und SQLite über modernc.org/sqlite. Es gibt kein PostgreSQL, Redis, S3/MinIO und keinen separaten Frontend-Build.

Die Weboberfläche liegt unter internal/webui/dist/ und wird mit //go:embed in das Binary eingebettet. Der Server lädt beim lokalen Start automatisch eine vorhandene .env (bereits gesetzte Prozess-Umgebungsvariablen haben Vorrang), daher reicht go run ./cmd/server für Backend, Client-UI, Admin-UI und öffentliches Echtzeit-Leaderboard.

HTTPS / Browser-WebCrypto

Die Weboberfläche erzeugt ihre ECDSA-P-256-Identität direkt im Browser über die Web Crypto API. Browser stellen crypto.subtle für normale Remote-Hosts nur in einem sicheren Kontext bereit. Verwende die Weboberfläche deshalb produktiv über HTTPS. http://localhost bzw. Loopback-Adressen werden von Browsern für lokale Entwicklung üblicherweise als vertrauenswürdiger Kontext behandelt. Bei einem Aufruf über http://<IP-or-domain> zeigt Neural Hunt eine verständliche HTTPS-Fehlermeldung statt eines JavaScript-Fehlers.

Schnellstart

cp .env.example .env
# JWT_SECRET, ADMIN_PASSWORD und OPENAI_API_KEY setzen.
# ARTIFACT_MODEL nur ändern, wenn du bewusst ein anderes GPT-Image-Modell nutzen willst.

go run ./cmd/server

oder:

docker compose up --build

Danach:

  • Client: http://localhost:8080/
  • Echtzeit-Leaderboard: http://localhost:8080/leaderboard
  • Admin: http://localhost:8080/admin

V2.5: Task-Landing-Page und Task-Serien

Der Browser startet nach der Anmeldung nicht mehr stillschweigend in einem zufällig zugewiesenen Task. Stattdessen erscheint eine responsive Task-Landing-Page mit allen aktiven Tasks. Jede Karte zeigt Anzeigename, Beschreibung, Zahlenraum, Teilnehmerzahl, eigenen Score/Rank und Pause-Status. Ein Klick wählt den Task aus; über TASKS kann der Client die laufende Session sauber verlassen und später auf einen anderen aktiven Task wechseln.

Die Auswahl wird serverseitig in SQLite an die kryptografische Client-ID gebunden. Wird dieselbe Identität exportiert und auf einem anderen Gerät importiert, bleibt damit auch die zuletzt gewählte Task-Serie erhalten. Die Regel eine Identity = eine aktive WebSocket-Verbindung gilt weiterhin.

Wenn ein Task gewonnen oder administrativ geschlossen wird, erzeugt Neural Hunt genau einen Folge-Task. Dieser erbt vom Vorgänger:

  • Zahlenraum (range_bits),
  • task-spezifisches Server- und Client-Tippintervall,
  • Anzeigename,
  • Landing-Page-Beschreibung,
  • NFT-Prompt-Anweisungen,
  • task-spezifischen Negative Prompt,
  • NFT-Style-Referenz.

paused wird absichtlich nicht vererbt: Ein neuer Folge-Task startet aktiv. Bestehende Client-Auswahlen des Vorgängers werden atomar auf den Folge-Task verschoben.

Task-spezifische NFT-Prompts

Im Admin-Tab TASK besitzt jeder Task jetzt einen eigenen Bereich TASK-KONFIGURATION & NFT-PROMPT. Der globale Artifact-Prompt bleibt die stilistische Basis; die Task-Anweisungen werden anschließend angefügt. Damit kann beispielsweise eine Serie ihren eigenen visuellen Stil oder ihr eigenes Motiv erhalten, ohne die globale Provider-Konfiguration zu verändern.

Beispiel für einen Task:

Anzeigename: Aurora Vault
Beschreibung: 48-Bit-Raum, Gewinner erhält die Aurora-Serie.

NFT-Prompt-Anweisungen:
Create a crystalline aurora data-vault, radial neural filaments,
no readable words, emphasize the winner as a singular luminous core.

Negative Prompt:
text, watermark, logo, duplicated core, low detail

Der Folge-Task übernimmt diese Werte automatisch. OpenAI verwendet die positiven Task-Anweisungen zusammen mit dem globalen Prompt; ComfyUI und A1111 erhalten zusätzlich den kombinierten globalen + task-spezifischen Negative Prompt.

Admin-Entwürfe überleben Refresh

Die dynamischen Admin-Formulare speichern ungespeicherte Eingaben lokal als Draft. Das betrifft Runtime-/Artifact-Settings, Task-Konfiguration und die Felder für geplante Aktionen. Der 3-Sekunden-Auto-Refresh und ein normaler Browser-Reload überschreiben diese Eingaben nicht mehr. Nach erfolgreichem Speichern wird nur der zugehörige Draft-Bereich gelöscht.

Shell-Client

cmd/client ist ein eigenständiger Neural-Hunt-Client ohne Browser. Er verwendet dieselbe P-256-Identität, dieselbe Challenge/Login-Signatur, denselben deterministischen Guess und denselben WebSocket-Presence-Mechanismus wie die Weboberfläche.

Interaktiv starten:

go run ./cmd/client -url http://127.0.0.1:8080

Beim ersten Start wird standardmäßig ~/.neuralhunt/identity.json mit Dateirechten 0600 erzeugt. Danach zeigt die Shell eine Task-Auswahl ähnlich der Browser-Landing-Page.

Wichtige Befehle:

tasks                         aktive Tasks + eigener Score/Rank
use <nr|id|name>              Task wechseln
status                        aktueller Task, Score, Rank, Sequence, Wins
map [n]                       textuelles TARGET FIELD nach Nähe-Zonen
leaderboard [n]               Echtzeit-Leaderboard abrufen
leaderboard watch             Leaderboard alle 5 Sekunden anzeigen
leaderboard stop              Watch beenden
nfts [n]                      Winner-Artefakte mit Wasserzeichen-URLs
nft get <task-id> <datei>     öffentliche Wasserzeichen-Preview speichern
identity                      Client-ID + lokale Identity-Datei
identity export <datei>       browser-kompatibler verschlüsselter Export
quit

Für tmux, screen, systemd oder einen Server ohne Vordergrund-Browser:

go run ./cmd/client \
  -url https://hunt.example.org \
  -non-interactive \
  -task "Aurora Vault" \
  -max-nodes 250

Im Non-Interactive-Modus bleibt der WebSocket offen, sendet automatisch im vom Task vorgegebenen Intervall signierte Tipps und folgt einem abgeschlossenen Task automatisch auf dessen Nachfolger. SIGINT/SIGTERM beendet sauber.

Für eine feste Binary:

go build -trimpath -o neuralhunt-client ./cmd/client
./neuralhunt-client -url https://hunt.example.org -non-interactive -task "Aurora Vault"

Ein minimales systemd-Beispiel:

[Unit]
Description=Neural Hunt Shell Client
After=network-online.target

[Service]
ExecStart=/opt/neuralhunt/neuralhunt-client -url https://hunt.example.org -non-interactive -task "Aurora Vault"
Environment=NEURALHUNT_IDENTITY=/var/lib/neuralhunt-client/identity.json
Restart=on-failure
RestartSec=5
User=neuralhunt

[Install]
WantedBy=multi-user.target

Browser-Identität im Terminal verwenden

Die Browseroberfläche exportiert die Identität verschlüsselt mit PBKDF2-HMAC-SHA256 (250.000 Iterationen) + AES-256-GCM. Der Shell-Client versteht exakt dieses Format:

export NEURALHUNT_IDENTITY_PASSPHRASE='ein-langes-passwort'
go run ./cmd/client \
  -import ./neuralhunt-identity-abc123.json \
  -identity ~/.neuralhunt/identity.json

Um die Terminal-Identity wieder browser-kompatibel zu exportieren:

export NEURALHUNT_IDENTITY_PASSPHRASE='ein-langes-passwort'
go run ./cmd/client \
  -identity ~/.neuralhunt/identity.json \
  -export ./neuralhunt-browser-import.json

Nicht dieselbe Identity gleichzeitig im Browser und im Shell-Client verbinden. Das ist absichtlich durch die Single-Connection-Regel gesperrt. Unterschiedliche Identities dürfen natürlich vom selben Rechner bzw. derselben IP verbunden sein.

Unterstützte Shell-Parameter:

-url                 Server-URL (oder NEURALHUNT_URL)
-identity            persistente Raw-Identity (oder NEURALHUNT_IDENTITY)
-task                Start-Task per Nummer, ID-Präfix oder Anzeigename
-max-nodes           Größe des lokalen Target-Field-Working-Sets
-non-interactive     unbeaufsichtigter Betrieb
-quiet               weniger Konsolenausgabe
-import              Browser-/Terminal-Identity importieren
-export              verschlüsselten Browser-Export schreiben und beenden
-passphrase          Import/Export-Passphrase; bevorzugt ENV verwenden

Faire signierte Tipps

Der Browser darf den Tipp nicht frei wählen. Die Zahl ist deterministisch:

SHA-256(task_id | public_seed | client_id | sequence) mod 2^range_bits

Danach signiert der Browser:

guess|task_id|sequence|guess

mit seinem persistenten P-256-Schlüssel. Der Server berechnet den erwarteten Guess erneut und prüft die Signatur. Standardmäßig akzeptiert der Server höchstens einen Tipp alle 10 Sekunden; der Browser sendet alle 11 Sekunden.

Falsche Roh-Tipps und deren Signaturen werden nicht gespeichert. In V2.4 erzeugt ein akzeptierter Tipp, der den persönlichen Best-Score nicht verbessert, sogar gar keinen SQLite-Write und gar kein WebSocket-Map-Event. next_seq, Rate-Limit, Guess-Zähler und Bestwert liegen auf dem Hotpath im RAM. Erst eine Score-Verbesserung checkpointet den aggregierten Zustand in SQLite; beim Gewinner bleiben zusätzlich der korrekte Guess und dessen Signatur erhalten.

TARGET FIELD — lesbare 3D-Nähe

Die vorherige Visualisierung hatte ein grundsätzliches Wahrnehmungsproblem: Eine echte 3D-Kugel um den Task kann in der 2D-Projektion einen weit entfernten Punkt scheinbar direkt neben dem Task zeigen, wenn er entlang der Kameratiefe liegt. Damit war „wer ist wirklich näher?“ trotz korrekter Daten nicht zuverlässig ablesbar.

V2.3 verwendet deshalb standardmäßig ein 3D-TARGET-FIELD mit unverzerrter Score-Ebene. Der Score bestimmt ausschließlich den sichtbaren Orbitalradius; die Client-ID bestimmt nur den Winkel. Die dritte Dimension wird über Tiefensortierung, Perspektivgröße, Helligkeit und Vorder-/Rückseiten-Cues codiert, verschiebt den Node aber nicht radial. Dadurch kann Kameratiefe die Nähe nicht mehr optisch umkehren. Die Ringe und Nodes benutzen exakt dieselbe Radiusfunktion:

kleinerer Ringradius = höherer Score = näher am Task

Die Wahrnehmungsfunktion ist bewusst im Bereich 90100 gedehnt:

field radius = 0.045 + 0.955 * (1 - score/100)^0.38

Damit sind z. B. 90, 95, 99 und 99.9 noch klar getrennt. Zusätzlich:

  • Score-Ringe bei 0 / 25 / 50 / 75 / 90 / 95 / 99+,
  • Vorder-/Rückseite der Ringe mit unterschiedlicher Intensität als 3D-Tiefencue,
  • Top-10 und eigene ID mit Score-Label,
  • eigene ID mit weißem Doppelring,
  • Kandidaten ab 95 mit zusätzlichem Nähe-Ring,
  • Hover zeigt Score, Rank und eine verständliche Distanzzone,
  • TARGET RADAR zeigt die besten Kandidaten zusätzlich numerisch,
  • TARGET FIELD kann weiterhin auf RAW 3D umgeschaltet werden, um die serverseitigen Rohkoordinaten zu inspizieren.

Keine erfundenen Synapsen mehr

Die alte Option SYNAPSEN verband Clients pseudozufällig miteinander. Dafür gibt es im Experiment keine fachliche Beziehung und die Linien erzeugten nur visuelles Rauschen. Diese Darstellung wurde entfernt.

SIGNALWEGE zeichnen jetzt nur noch Client → Task:

  • nur Top-Kandidaten und der eigene Client erhalten einen Pfad,
  • höhere Scores machen den Pfad deutlicher,
  • unter 90 werden Pfade gestrichelt,
  • wenn ein Client seinen Best-Score verbessert, laufen drei kurze Signalimpulse entlang genau dieses Pfades zum Task,
  • es gibt keine zufälligen Ambient-Partikel und keine Client-zu-Client-Kanten mehr.

Der gleiche Renderer wird im Admin-Bereich verwendet.

Mobile-Modus

Neural Hunt aktiviert auf kleinen Displays bzw. Geräten mit grobem Pointer automatisch einen Mobile-Modus. Er kann über den Button MOBILE auch manuell an- und ausgeschaltet werden; die Auswahl wird im Browser gespeichert.

Im Client reduziert Mobile Mode die Renderlast automatisch (ECO, weniger Nodes, keine optionalen Signalwege/Labels), zeigt Rank/Score/Countdown kompakt im Header und bietet eine einklappbare Detailkarte. Die 3D-Steuerung wird auf die wichtigsten Touch-Aktionen reduziert.

Im Admin-Bereich gibt es auf Mobile drei klare Ansichten MAP / TASKS / CONTROL, damit Task-Liste und Control Plane nicht mehr durch Responsive-CSS verschwinden. Das Leaderboard wechselt auf Karten statt horizontaler Tabellen.

Öffentliches Echtzeit-Leaderboard

/leaderboard ist eine eigene, nicht authentifizierungspflichtige Ansicht. Sie bietet:

  • Live-Ranking nach aktuellem Score,
  • All-Time-Ranking nach Wins / Best Score,
  • Online/Offline-Indikator,
  • Best Score, Wins, Tippanzahl und Unlocks,
  • Client-ID-Suche,
  • WebSocket-getriggerte Aktualisierung bei neuen Punkten, Task-Änderungen und Task-Abschlüssen.

Zusätzlich zeigt das Leaderboard eine Gewinner-Galerie. Die öffentliche API liefert keine Original-Artifact-URI, sondern nur eine Wasserzeichen-Vorschau. Für PNG/JPEG/GIF wird das Wasserzeichen serverseitig in eine neue PNG-Vorschau gerastert; lokale SVG-Artefakte erhalten eine sichtbare, wiederholte SVG-Wasserzeichenebene.

Die Originaldatei und das Manifest sind nur noch über authentifizierte Admin-Endpunkte erreichbar. Der frühere öffentliche /artifacts/*-File-Server wurde entfernt.

API:

GET /api/public/leaderboard?mode=live&limit=500
GET /api/public/leaderboard?mode=alltime&limit=500
GET /api/public/artifacts?limit=96
GET /api/public/artifacts/{task_id}/preview
WS  /api/leaderboard/ws

# nur Admin-JWT
GET /api/admin/tasks/{task_id}/artifact
GET /api/admin/tasks/{task_id}/manifest

Admin: planbare Task-Aktionen

Jeder Task besitzt jetzt einen persistierten Aktionsplan/Audit-Log. Aktionen können sofort oder für einen Zeitpunkt in der Zukunft geplant werden. Ein 1-Sekunden-Scheduler führt fällige Aktionen aus.

Unterstützt sind:

  • set_range_bits — Zahlenraum eines laufenden Tasks ändern,
  • set_intervals — Tippintervalle pro Task überschreiben,
  • clear_intervals — wieder globale Defaults verwenden,
  • pause — Tippabgaben pausieren,
  • resume — fortsetzen,
  • reroll — neues Secret + neuer Public Seed, Scores/Sequenzen zurücksetzen,
  • close — Task beenden und Ersatz-Task sicherstellen,
  • regenerate_artifact — Gewinnerbild erneut in die Queue legen.

Damit lassen sich z. B. Difficulty-Ramps planen:

20:00  24 Bit
20:15  28 Bit
20:30  32 Bit
20:45  pause
20:50  resume

Zahlenraum live ändern

Es gibt zwei Modi:

preserve

  • das geheime Ziel und der Public Seed bleiben bestehen,
  • Sequenzen bleiben bestehen,
  • Scores werden auf den neuen Bit-Denominator re-skaliert,
  • die räumlichen Positionen werden neu berechnet,
  • Verkleinern ist nur möglich, wenn das bestehende Secret in den neuen Zahlenraum passt.

reroll

  • neues Secret,
  • neuer Public Seed,
  • Score/Position/Sequenz werden zurückgesetzt,
  • kumulative Tippanzahl bleibt erhalten.

Die Clients empfangen task_changed via WebSocket und laden range_bits, Seed, Revision und Intervalle neu. Ein Browser verwendet deshalb nach einer Live-Änderung nicht versehentlich die alte Bitzahl.

KI-/NFT-artige Gewinnerbilder

Ein abgeschlossenes Gewinnerbild ist ein NFT-artiges digitales Artefakt, aber noch kein Blockchain-NFT. Neural Hunt mintet nichts on-chain. Es erzeugt Bild + Manifest mit eindeutiger ID und kryptografischen Bindungen.

Das Manifest enthält u. a.:

artifact_id
artifact_preset
task_id
task_range_bits
winner_client_id
winner_public_jwk
winning_guess
winner_guess_signature
raw_art_sha256
image_sha256
prompt_sha256
collection_character
collection_traits
layout
provider
provider_meta

Wichtig: Die Gewinner-Signatur authentifiziert den erfolgreichen Guess. Sie ist keine nachträgliche Signatur der vom Bildprovider erzeugten Pixel. Das erzeugte Bild wird stattdessen per image_sha256 an das Server-Manifest gebunden.

Provider

Das Standard-Preset raccoon_full_art_v1 ist im Admin-Tab ARTIFACT bewusst auf OpenAI + Character-Anchor-Workflow vorkonfiguriert; dort muss normalerweise nur das Bildmodell geändert werden. Die älteren Provider local, comfyui, a1111 und auto bleiben für artifact_preset=legacy kompatibel.

Provider-Secrets und Provider-URLs bleiben absichtlich ENV-only und werden nicht an den Browser ausgeliefert. Das Dashboard zeigt für OpenAI nur, ob der API-Key vorhanden ist, und ob der kanonische Character Anchor bereits erzeugt wurde.

1. Local

Kein externer Dienst. Erzeugt ein deterministisches SVG wie bisher.

ARTIFACT_PROVIDER=local

2. OpenAI Images API — RIFT Collection (Standard)

Für das neue Full-Art-Preset reichen im Normalfall genau zwei Werte:

ARTIFACT_MODEL=gpt-image-2
OPENAI_API_KEY=...

OPENAI_BASE_URL kann optional überschrieben werden; standardmäßig wird https://api.openai.com verwendet. Provider, Portrait-Größe (1024x1536), Quality (medium) und das Collection-Preset sind bereits als Defaults hinterlegt. Eine mit älteren Projektversionen ausgelieferte lokale 1024×1024-Artifact-Konfiguration wird beim ersten Start einmalig auf das neue Preset migriert.

Die RIFT-Quality wird außerdem einmalig von einem früheren high-Default auf medium migriert. Eine später bewusst gesetzte high-Einstellung wird durch diese Migration nicht erneut überschrieben.

Ablauf:

  1. Im Admin-Tab ARTIFACT kann /data/artifacts/_collection/character_anchor.png einmalig manuell erzeugt werden. Der Anchor entsteht nur aus dem neutralen RIFT-Masterprompt und enthält bewusst keinen Task-Style. Ist beim ersten Gewinner noch kein Anchor vorhanden, erzeugt der Worker ihn weiterhin automatisch als Sicherheits-Fallback.
  2. Im Admin-Tab TASK ACTIONS kann jeder Task ein eigenes JPEG-/PNG-Stylebild erhalten. Es wird content-addressed unter data/artifacts/_styles/<sha256>.<ext> gespeichert und über tasks.nft_style_reference dem Task zugeordnet. Ein Folge-Task erbt dieselbe Style-Referenz. Ohne Custom-Style wird das eingebettete internal/artifact/assets/style_reference.jpg als Default verwendet.
  3. Für jede RIFT-Karte sendet Neural Hunt zwei Bildinputs an /v1/images/edits: Image 1 = globaler Character Anchor (Identität) und Image 2 = Task Style Reference (Rendering-Look). Der Prompt weist das Modell explizit an, Gesicht/Fell/Proportionen aus Image 1 und Rendering-Technik/Material/Licht/Farbverhalten aus Image 2 zu übernehmen. Der Kartenprompt erzwingt dabei bewusst keinen festen 3D-Look mehr: ein Task-Style darf z. B. 3D-Cartoon, Cel-Shading, Comic, malerisch, Watercolor-artig, Clay/Toy, Low-Poly oder Retro-Game sein, solange RIFT als Charakter erkennbar und die Ausgabe nicht fotorealistisch bleibt.
  4. internal/artifact/collection.go wählt deterministisch Theme, Outfit, Accessoires, Szene, Mood, Pose, Atmosphäre, Rarity und Akzentfarben. Task-spezifische kreative Vorgaben und Ausschlüsse bleiben optionale Overrides.
  5. Das generierte PNG wird als art.png gespeichert. internal/artifact/card.go baut daraus anschließend das finale image.svg im Format 1024×1536. Die KI muss daher keine Karten-Typografie oder UI exakt rendern.
  6. Das Manifest bindet sowohl Roh-Art als auch fertige Karte per SHA-256 und speichert Collection-Traits sowie die verwendete Task-Style-Referenz/Provider-Metadaten.

Der Character Anchor ist absichtlich global und wird im Admin nach Erstellung als LOCKED behandelt. Ein Wechsel des NFT-Stils erfolgt deshalb nicht mehr durch Austausch des Anchors, sondern durch ein anderes Style-Referenzbild am jeweiligen Task. Das eingebettete style_reference.jpg muss dafür nicht neu kompiliert oder ausgetauscht werden.

OpenAI-Nutzung und Kosten

Jeder erfolgreiche OpenAI-Bildaufruf (Character-Anchor und Gewinnerkarte) wird lokal in artifact_api_usage protokolliert. Wenn OpenAI im Images-Response die Usage-Felder liefert, speichert Neural Hunt die gemeldeten Text-/Bild-Input-Tokens sowie Output-/Total-Tokens und berechnet daraus eine lokale USD-Kostenschätzung. Die Preisbasis ist im Datensatz fixiert, damit historische Werte reproduzierbar bleiben; unbekannte Modelle werden weiter protokolliert, aber ohne erfundene Kostenschätzung.

Im Adminbereich zeigt OPENAI NUTZUNG & KOSTEN die Kosten des heutigen lokalen Kalendertags, den durchschnittlichen Preis pro fertiger Gewinnerkarte und die hochgerechneten Kosten pro 1.000 Karten sowie die letzten API-Aufrufe. Character-Anchor-Aufrufe zählen zu den heutigen API-Kosten, werden aber bewusst nicht in den Karten-Durchschnitt eingerechnet. Die USD-Werte sind eine aus den Provider-Tokens berechnete Standardpreis-Schätzung (ohne separat ausgewiesenen Cached-Input-Rabatt) und keine Rechnungs-/Billing-Abstimmung; dafür ist kein zusätzlicher OpenAI-Admin-Key nötig. Die Rohdaten sind zusätzlich über GET /api/admin/artifact/usage verfügbar.

3. ComfyUI

ARTIFACT_PROVIDER=comfyui
COMFYUI_URL=http://127.0.0.1:8188
COMFYUI_WORKFLOW_PATH=/absolute/path/workflow-api.json
ARTIFACT_MODEL=your-checkpoint.safetensors

Der Workflow muss im API-Format vorliegen. Neural Hunt ersetzt rekursiv folgende String-Platzhalter:

{{PROMPT}}
{{NEGATIVE_PROMPT}}
{{SEED}}
{{WIDTH}}
{{HEIGHT}}
{{STEPS}}
{{MODEL}}

Beispiel in einem KSampler-/Text-Encode-Input:

{
  "text": "{{PROMPT}}",
  "seed": "{{SEED}}",
  "steps": "{{STEPS}}"
}

Der Worker sendet den Workflow an /prompt, pollt /history/{prompt_id} und lädt das erste gefundene Ergebnis über /view.

4. AUTOMATIC1111

A1111 muss mit API gestartet werden, z. B. --api. Optional ist --api-auth user:pass möglich.

ARTIFACT_PROVIDER=a1111
A1111_URL=http://127.0.0.1:7860
A1111_USER=
A1111_PASSWORD=
ARTIFACT_MODEL=my-checkpoint.safetensors
ARTIFACT_STEPS=28
A1111_CFG_SCALE=7

Neural Hunt verwendet /sdapi/v1/txt2img, übernimmt das Base64-Ergebnis und speichert es lokal. Ist ARTIFACT_MODEL kein gpt-image-*-Name, wird es für A1111 als sd_model_checkpoint pro Request gesetzt.

5. Auto

ARTIFACT_PROVIDER=auto

Reihenfolge:

OpenAI (wenn Key gesetzt)
→ ComfyUI (wenn URL + Workflow gesetzt)
→ A1111 (wenn URL gesetzt)
→ lokales SVG

Fehler der fehlgeschlagenen Provider werden im Manifest des lokalen Fallbacks vermerkt.

Docker + lokale ComfyUI/A1111-Instanz

docker-compose.yml enthält host.docker.internal:host-gateway. Dadurch kann der App-Container unter Linux/Windows/macOS typischerweise einen Bildserver auf dem Docker-Host erreichen:

COMFYUI_URL=http://host.docker.internal:8188
A1111_URL=http://host.docker.internal:7860

Ein ComfyUI-Workflow, den der Container lesen soll, muss zusätzlich in den Container gemountet bzw. unter /data abgelegt werden.

Architektur

Browser
  ├─ Client UI + P-256 Identity
  ├─ /leaderboard
  └─ Admin Control Plane
             │ HTTP / WS
             ▼
+------------------------------------------+
| Go Binary                                |
| auth | tasks | scheduler | WS | artifact |
+--------------------+---------------------+
                     │
             modernc.org/sqlite
             /data/neuralhunt.db
                     │
                     └─ /data/artifacts/
                          └─ artifact_<id>/
                              ├─ image.png|svg
                              └─ manifest.json

Optional nur für Bildgenerierung:
OpenAI API ODER ComfyUI ODER A1111

V2.4 Scale-Architektur

Die Standalone-Edition bleibt bewusst ein Go-Prozess auf einem Host. Dafür ist der heiße Pfad jetzt konsequent aus SQLite herausgezogen:

normaler falscher Guess
  -> JWT / Signatur / deterministischen Guess prüfen
  -> Sequence + Rate Limit + GuessCount im RAM
  -> Score berechnen
  -> schlechter als Bestwert
  -> Antwort false

SQLite writes: 0
Map events:    0

Nur Registrierung, erstmaliger Task-Punkt, Score-Verbesserungen, Gewinner, Unlocks, Admin-/Task-Änderungen und Artefakte werden dauerhaft geschrieben. Presence (eine ID = eine aktive Verbindung) liegt ebenfalls im Prozess und verursacht keine regelmäßigen SQLite-Lease-Writes mehr. Die alte Tabelle presence_leases kann aus Kompatibilitätsgründen in bestehenden Datenbanken vorhanden bleiben, wird aber vom V2.4-Hotpath nicht genutzt.

Gebatchte WebSockets

Verbesserungen werden pro Task und Client koalesziert und alle 250 ms als ein points-Frame gesendet. Jeder Socket hat eine bounded Outbound-Queue; ein langsamer Browser blockiert daher niemals einen Guess-Request. Ist seine Queue voll, darf ein transienter Map-Frame verworfen werden. Der persistierte Zustand bleibt maßgeblich.

Server-seitig begrenzte Map-Snapshots

Der Browser lädt nicht mehr pauschal 50.000 Nodes. max_nodes wird an den WebSocket übergeben; der Server liefert höchstens 3 × max_nodes Overscan (hart gedeckelt auf 10.000) und garantiert, dass die eigene Node enthalten ist. Nachfolgende Events werden clientseitig ebenfalls auf dieses Overscan-Budget gekürzt. Das vorhandene LOD arbeitet nur noch auf diesem begrenzten Working Set.

Performance-Telemetrie

GET /api/admin/performance liefert live u. a. Guess/s, Improvements/s, SQLite Writes/s, verworfene Requests, WebSocket Frames/s, WebSocket Bytes/s, Queue-Drops, Goroutines und Heap. Diese Werte erscheinen zusätzlich im Admin-Dashboard.

Lastgenerator

Der integrierte Lastgenerator erzeugt echte P-256-Identitäten, führt Challenge/Login aus, öffnet WebSockets und sendet deterministische signierte Tipps:

go run ./cmd/loadtest \
  -url http://127.0.0.1:8080 \
  -clients 10000 \
  -ramp 60s \
  -duration 5m \
  -max-nodes 250

Für einen realen 10k-Test sollten Server und Lastgenerator nach Möglichkeit auf getrennten Hosts laufen. Die erreichbare Obergrenze hängt von CPU, RAM, TLS, Dateideskriptoren und Netzwerk ab; V2.4 setzt 10.000 gleichzeitige Clients als Lasttest-Ziel, nicht als hardwareunabhängige Garantie.

SQLite und Skalierungsgrenze

SQLite läuft mit Foreign Keys, WAL, busy_timeout und kurzen Transaktionen. Weil normale falsche Tipps SQLite nicht mehr berühren, ist die Single-Writer-Eigenschaft deutlich weniger dominant. Für echtes Multi-Host-Horizontal-Scaling wäre trotzdem wieder eine gemeinsame Koordinations-/Datenbankschicht nötig.

Mehrere lokale Test-Clients

Die IP-Adresse ist nicht Teil der Identität. Mehrere Clients auf 127.0.0.1 funktionieren. Sie brauchen lediglich unterschiedliche Browser-Identitäten, z. B. normales Fenster + Inkognito oder getrennte Browserprofile.

Zwei Tabs desselben Profils teilen localStorage und damit dieselbe ID. Pro ID ist weiterhin nur eine aktive Client-WebSocket-Verbindung erlaubt.

Persistenz / Backup

Relevant sind:

/data/neuralhunt.db
/data/artifacts/

In SQLite liegen u. a.:

clients
tasks
task_points
settings
presence_leases
task_actions

API-Überblick

User:

POST /api/auth/challenge
POST /api/auth/login
GET  /api/tasks/current
POST /api/tasks/{id}/guess
GET  /api/tasks/{id}/points
GET  /api/me
GET  /api/leaderboard
GET  /api/ws

Public:

GET /api/public/leaderboard
WS  /api/leaderboard/ws

Admin:

POST /api/admin/login
GET  /api/admin/overview
GET  /api/admin/performance
GET  /api/admin/settings
PUT  /api/admin/settings
GET  /api/admin/tasks
GET  /api/admin/tasks/{id}/points
GET  /api/admin/tasks/{id}/actions
POST /api/admin/tasks/{id}/actions
POST /api/admin/actions/{id}/cancel
GET  /api/admin/artifact/providers
POST /api/admin/tasks/{id}/close
POST /api/admin/tasks/ensure

Produktions-Hinweise

  • TLS erzwingen.
  • JWT_SECRET und Admin-Passwort ändern.
  • CheckOrigin für WebSockets auf eine Origin-Allowlist begrenzen.
  • /data sichern und freien Speicher überwachen.
  • API-Keys nur als ENV/Secret injizieren, niemals in Runtime-Settings speichern.
  • Bei ComfyUI/A1111 nur vertrauenswürdige lokale/netzinterne Instanzen konfigurieren.
  • Datenschutz-/Einwilligungstexte für das soziale Experiment ergänzen.

V2.9: lokaler RIFT-Pipeline-Test

Im Adminbereich unter TASK ACTIONS kann für den ausgewählten Task eine komplette lokale Testkarte erzeugt werden. Der Test verwendet den vorhandenen character_anchor.png als Mock-Character-Artwork und die Style-Referenz des Tasks als Hintergrund, führt die deterministische Trait-Auswahl, das programmatische Kartenlayout und das Schreiben der Testdateien aus, ruft aber keine externe Bild-API auf. Die Dateien landen unter data/artifacts/_test/<task-id>/; der echte Task- und Artifact-Status bleibt unverändert.

Description
No description provided
Readme 2.3 MiB
Languages
Go 99.1%
PowerShell 0.4%
Makefile 0.2%
HCL 0.1%
Dockerfile 0.1%
Other 0.1%