Compare commits

..
53 Commits
Author SHA1 Message Date
Nico 72e1ade0a9 Archive BUG-000022 evaluation and deferred final-review findings 2026-10-25 00:37:42 +02:00
Nico aec2bcdb21 Record completed BUG-000021 field result and usage snapshot 2026-10-24 23:03:02 +02:00
Nico 61889740e6 Add audited operator approval for one entity repair attempt 2026-10-24 22:22:16 +02:00
Nico 4cbba4c1e4 Repair only invalid entity assessments with precise scoped feedback 2026-10-24 21:18:51 +02:00
Nico 33603db9bd Add guarded Linux deployment updater 2026-10-24 18:37:13 +02:00
Nico c4225ebf04 Report independent interpretation citation errors in one repair 2026-10-24 18:20:21 +02:00
Nico a9b49bbb13 Fix multi-database entity resolution capture validation 2026-10-24 17:59:01 +02:00
Nico 9c9d9d70d6 Support multiple allowlisted databases in project research tools 2026-10-24 12:33:41 +02:00
Nico 9408af5356 Document VPS installation and first setup on repository homepage 2026-10-23 15:36:11 +02:00
Nico 085a5c4026 Add packaged user manual and configuration guides to web console 2026-10-23 15:18:02 +02:00
Nico b42bafb711 Unify processed case listing with blocked states and package downloads 2026-10-23 13:59:15 +02:00
Nico b8c0d7ec40 Add capture worker v0.4 with durable BugAnalysis API handoff 2026-10-23 13:33:28 +02:00
Nico cbf112b0f8 Add recoverable encrypted integration keys and web management 2026-10-23 08:46:24 +02:00
Nico ca4ab48fdc Add Linux deployment installer, supervised services and readiness checks 2026-10-22 22:56:33 +02:00
Nico 203e765992 Add SQLite web users, privileged account CLI and session editing claims 2026-10-22 18:56:59 +02:00
Nico 9fc5c1805c Add human test request inbox and authenticated feedback resume 2026-10-22 13:14:01 +02:00
Nico ac179883c6 Add scoped operator controls and durable worker release queue 2026-10-22 09:46:56 +02:00
Nico c478518425 Add readable case details and completed results browser 2026-10-21 23:05:13 +02:00
Nico cbb69a2115 Show all analysis phases in token chart legend and preview 2026-10-21 21:39:26 +02:00
Nico 58fc00601e Add web overview with worker progress and separate correction token charts 2026-10-21 21:25:23 +02:00
Nico 012a8d8e91 Add persistent profile-routed analysis worker and shared workflow 2026-10-21 16:46:28 +02:00
Nico 27feda6d7f Add authenticated case intake and completed-case return API 2026-10-21 14:36:26 +02:00
Nico 830dabe870 Record Bug20 qualified-review regression metrics and assessment 2026-10-21 10:39:48 +02:00
Nico 78acf84f27 Prepare Bug20 qualified-review regression instead of Bug17 2026-10-21 08:31:09 +02:00
Nico a33cee0cf8 Prepare fresh Bug17 qualified-review regression trial 2026-10-21 08:28:57 +02:00
Nico 4e8ed1adce Record final confirmed billing for Bug17 bounded trial 2026-10-20 23:35:27 +02:00
Nico 85b4fa83eb Qualify final causal review and preserve diagnostic caveats in handoffs 2026-10-20 23:33:21 +02:00
Nico bb5d128079 Record completed Bug17 trial costs and false-positive diagnosis 2026-10-20 22:57:56 +02:00
Nico f2b13ae7cd Clarify investigation source contracts and recover nested recall 2026-10-20 22:42:48 +02:00
Nico 84c4f7f96c Record Bug17 source search failures and investigation progress 2026-10-20 22:27:22 +02:00
Nico cb61ac8cd6 Scope budget assessments and recover valid research after recall 2026-10-20 21:59:59 +02:00
Nico 3eb0972395 Record Bug17 assessment rejection after evidence recall 2026-10-20 21:40:27 +02:00
Nico 7b7779b769 Align checkpoint recall validation and resume lean investigation 2026-10-20 21:36:32 +02:00
Nico e92476517c Record Bug17 consolidation recall contract failure 2026-10-20 21:27:37 +02:00
Nico 167d8d5f5e Allow explicit operator resume after technical response repairs 2026-10-20 21:20:46 +02:00
Nico ecec96ce14 Return bounded source excerpts instead of rejecting oversized reads 2026-10-20 21:12:03 +02:00
Nico ab31924b79 Record Bug17 source range rejection and trial metrics 2026-10-20 21:02:55 +02:00
Nico a3e1ea0429 Prepare full bounded Bug17 evaluation and preserve cost baselines 2026-10-20 20:57:58 +02:00
Nico 86a02cb8c0 Record completed bounded contract v2 regression 2026-10-20 20:37:16 +02:00
Nico 424ad95018 Record contract v2 continuation through generation 97 2026-10-20 20:28:57 +02:00
Nico e2d092f1ce Record bounded contract v2 regression metrics 2026-10-20 20:22:20 +02:00
Nico 3a82a37ee6 Stabilize bounded investigation contracts and targeted recovery 2026-10-20 19:59:00 +02:00
Nico ed148b1a50 Record bounded investigation regression metrics and rejected outputs 2026-10-20 17:46:03 +02:00
Nico 682f275590 Bound investigation prompts and paginate research evidence 2026-10-20 17:04:49 +02:00
Nico 377644ffa0 Record startup batch trial metrics and successful scoped repair example 2026-10-20 13:42:12 +02:00
Nico b33208363c Add lean hypothesis startup round with joint evidence review 2026-10-20 12:53:55 +02:00
Nico 3beac3bd1c Archive standalone token usage reports and retention rules 2026-10-20 10:59:33 +02:00
Nico 3872735c0a Recover misplaced joint blocks and preserve unchanged entity citations 2026-10-20 09:50:56 +02:00
Nico c3a4690a55 Recover joint planning dependencies and preserve valid hypothesis siblings 2026-10-20 08:12:23 +02:00
Nico 83ef9e6d6c Add source-constrained joint planning and scoped dependency-aware recovery 2026-10-20 00:43:27 +02:00
Nico d280f001fc Preserve corpus bytes across Git checkouts 2026-10-19 23:33:57 +02:00
Nico 26cd9d3d04 Preserve curated rejected LLM responses with context and failure analysis 2026-10-19 23:33:17 +02:00
Nico f9792586d1 Add joint case planning with independent interpretation and hypothesis recovery 2026-10-19 22:17:00 +02:00
375 changed files with 43190 additions and 354 deletions

No files matched your search

+10
View File
@@ -7,6 +7,7 @@
- Älteste Testläufe zuerst bereinigen, soweit erforderlich, um die Grenze einzuhalten. Aktuelle Vergleichsläufe nur innerhalb dieses Gesamtbudgets behalten. Vor rekursivem Löschen die aufgelösten Zielpfade prüfen; keine Quelldaten, Projektkonfiguration, Testdatenbank oder Source-Checkouts mitlöschen.
- Langfristig ausschließlich das Ergebnis und eine Beschreibung des Testlaufes archivieren. Die Beschreibung sollte Eingaben/Referenzen, Code- und Konfigurationsstand ohne Geheimnisse, Testziel, Ergebnisbewertung sowie verfügbare Laufzeit-, Token-, Cache- und Kostenmetriken festhalten.
- Vollständige Zwischenstände, Paketgenerationen, Request-/Response-Dumps und temporäre Arbeitskopien sind keine dauerhaften Testarchive. Ein finales Ergebnispaket darf als Ergebnis archiviert werden.
- Ausdrücklich ausgenommen vom Verbot langfristiger Request-/Response-Dumps ist das vom Nutzer beauftragte, kleine und kuratierte Fehlerkorpus unter `tests/fixtures/llm_rejections/`: ausgewählte abgelehnte Antworten mit benötigtem Prüfkontext und Fehleranalyse dürfen dort dauerhaft versioniert bleiben. Es sind keine vollständigen Testlaufarchive. Das Korpus darf bei der automatischen Testlaufbereinigung nicht mitgelöscht werden und zählt weiterhin zum gesamten Speicherbudget für Entwicklungs-/Testdaten.
- Diese Aufbewahrungsregel erlaubt keine Entfernung einzelner Inhalte aus einer erhaltenen Case-Akte. Paketinhalt und lokale Aufbewahrung vollständiger Testläufe bleiben getrennte Anliegen.
## Ausführung
@@ -14,3 +15,12 @@
- Kostenpflichtige LLM-Testläufe führt der Nutzer selbst aus, sofern er nicht ausdrücklich eine andere Ausführung beauftragt.
- Lokale Commits sind erlaubt. Nicht pushen; der Nutzer führt Pushes selbst durch.
- `docs/architecture.md` ist die maßgebliche Designspezifikation und darf ohne ausdrücklichen Auftrag nicht geändert werden.
## Dauerhafte Testmetriken
- Nach jeder ausgewerteten LLM-Testausführung die Tokenbilanz unabhängig vom Case-Paket unter `docs/test-results/token-usage/` sichern. Vor dem Entfernen eines Test-Workspaces das Vorhandensein des Berichts prüfen.
- Gesamtverbrauch einschließlich Korrektur-/Wiederholungsaufrufen und bereinigte Phasenbilanzen getrennt ausweisen; gemeinsame Aufrufe nur einmal zählen. Fehlende Werte bleiben als unbekannt gekennzeichnet. Denktokens nicht erneut zu Ausgabetokens addieren, wenn sie darin bereits enthalten sind.
- Lauf-/Case-Identität, Ergebnis und Messumfang, Prompt-/Modellversionen, Konfigurations-/Quellenhashes, Cachewerte, verfügbare API-/Falllaufzeiten sowie Kostenstände mit Abrechnungsstatus festhalten. Bereits berichtete Snapshots erhalten, spätere Fortschritte als neue Snapshots ergänzen.
- Berichte enthalten keine Prompts, vollständigen Antworten, Secrets oder Konfigurationsinhalte. Die kleinen Metrikberichte und Vergleiche dürfen langfristig versioniert bleiben; sie zählen zum Speicherbudget für Testdaten.
- Zusätzlich Gesamt- und bereinigte Kostenschätzungen pro Phase und LLM-Aufruf ausweisen. Der erste reguläre Aufruf bleibt in der bereinigten Bilanz, auch wenn er korrigiert werden musste; zusätzliche Reparatur- und Wiederholungsaufrufe bilden den Korrekturaufwand.
- Modell und verwendete Preistabelle mit Währung und Erfassungsstand im Bericht sichern. Ungecachte Eingabe, Cacheeingabe und Ausgabe einschließlich Denktokens getrennt berechnen; Cache-Speicherung separat, fehlende Werte als unbekannt. USD-Schätzungen nicht mit den vom Nutzer gemeldeten EUR-Abrechnungskosten gleichsetzen.
+365 -4
View File
@@ -1,5 +1,348 @@
# VianoBugAnalysis
BugAnalysis untersucht gemeldete Softwarefehler anhand von Diagnosepaketen,
Sourcecode und lesenden Datenbankabfragen. Ein dauerhaft laufender Worker erstellt
Diagnosen und Aufträge für Codingagenten beziehungsweise menschliche Entwickler.
Die Weboberfläche bietet Benutzeranmeldung, Betriebsübersicht, Testerantworten,
API-Schlüssel und Paketdownloads. Das aktuelle Projektprofil ist für WoW/Vcore
ausgelegt. BugAnalysis installiert selbst keine Bugfixes auf dem Spielserver.
## Installation auf einem Linux-VPS
Diese Anleitung ist direkt auf der Repository-Startseite lesbar. Sie setzt einen
Linux-Server mit systemd und einen SSH-Zugang mit sudo-Rechten voraus. Die
Paketbefehle unten gelten für Debian/Ubuntu; auf anderen Distributionen die
entsprechenden Pakete installieren. **Python 3.11 oder neuer ist erforderlich.**
### 1. Voraussetzungen installieren
```sh
sudo apt-get update
sudo apt-get install python3 python3-venv python3-pip git nginx ca-certificates curl
python3 --version
```
Ist die Python-Version älter als 3.11, zuerst eine unterstützte Python-Version
bereitstellen und diese für den Installer verwenden. Datenbankserver und
World-Daten werden vom Installer nicht eingerichtet oder importiert. Ein
erreichbarer MariaDB-Datenbestand für die Recherche muss separat vorhanden
sein, beispielsweise eine isolierte Testdatenbank aus einem Backup.
### 2. Repository in das vorgesehene Verzeichnis klonen
**Der Installer und die systemd-Units erwarten derzeit genau
`/opt/viano-bug-analysis`.** Nicht einen beliebigen Ordnernamen verwenden.
Git legt den Zielordner an; er muss dafür noch nicht existieren oder leer sein.
```sh
sudo git clone https://gitea.viano-software.de/Nico/VianoBugAnalysis /opt/viano-bug-analysis
cd /opt/viano-bug-analysis
```
Das Klonen mit sudo erzeugt einen root-eigenen Checkout. Der Installer verlangt,
dass Programmdateien root gehören und weder für Gruppe noch andere Benutzer
schreibbar sind. Bei einem privaten Repository die Git-Anmeldung interaktiv
durchführen; keine Zugangsdaten in die URL schreiben.
### 3. Installationsplan prüfen und installieren
```sh
python3 deploy/install.py --dry-run
sudo python3 deploy/install.py
```
Der erste Befehl zeigt nur den Plan. Der zweite erstellt den Dienstbenutzer
`buganalysis`, die virtuelle Python-Umgebung, Konfigurationsvorlagen und beide
systemd-Units. Er startet oder aktiviert noch keinen Dienst und sendet keine
LLM-Anfrage. Vorhandene Konfigurationsdateien und Units werden nicht überschrieben.
| Verzeichnis | Inhalt |
| --- | --- |
| `/opt/viano-bug-analysis` | Programmcode und `.venv`; root-verwaltet |
| `/etc/viano-bug-analysis` | Konfiguration, geschützte Environment-Dateien und Webnutzerdatei |
| `/var/lib/viano-bug-analysis` | Fallakten, Inbox, Outbox, Review und Laufzeitdaten |
| `/srv/viano-bug-analysis/viano-core` | Separater Source-Checkout des untersuchten Vcore-Projekts |
Der Linux-Dienstbenutzer ist kein Webkonto. Webkonten werden in Schritt 6
gesondert angelegt. Ein Programm zur automatischen Erfassung benötigt später
einen Integrationsschlüssel, ebenfalls kein Webpasswort oder Cloud-API-Key.
### 4. Vcore-Sourcecode und lesenden Datenbankzugang bereitstellen
BugAnalysis benötigt zusätzlich zu seinem eigenen Repository den Sourcecode des
untersuchten Projekts. Für Vcore beispielsweise:
```sh
sudo git clone --branch master --single-branch https://gitea.viano-software.de/Nico/Viano-Core /srv/viano-bug-analysis/viano-core
sudo git -C /srv/viano-bug-analysis/viano-core rev-parse HEAD
```
Die Ausgabe des zweiten Befehls ist der vollständige Commit. Der für die Analyse
gewünschte Stand muss lokal vorhanden sein und wird in `project.toml` festgelegt.
Der aktuelle Branchkopf ist nur dann passend, wenn genau dieser Stand untersucht
werden soll. Der Worker klont oder aktualisiert den Sourcecode nicht automatisch.
Ein DB-Administrator richtet einen Benutzer mit ausschließlich passenden
SELECT-Rechten auf die World-Daten ein. Keine Schreibrechte und keinen
allgemeinen Administrationszugang verwenden. Für entfernte Datenbanken einen
geschützten Netzwerkweg bereitstellen; der aktuelle DB-Provider richtet selbst
kein TLS ein. Die vollständige Tabellenfreigabe steht in der Projektvorlage.
### 5. Konfigurationen und Zugangsdaten eintragen
Die Konfiguration liegt außerhalb des Git-Checkouts. Beispiele öffnen:
```sh
sudoedit /etc/viano-bug-analysis/api.toml
sudoedit /etc/viano-bug-analysis/project.toml
sudoedit /etc/viano-bug-analysis/llm.toml
sudoedit /etc/viano-bug-analysis/worker.env
```
| Datei | Beim ersten Einrichten prüfen |
| --- | --- |
| `api.toml` | Projekt-ID, Profilzuordnung und Konfigurationspfade; HTTP-Bindung auf `127.0.0.1:8080` lassen |
| `project.toml` | Sourcepfad und vollständigen Commit, DB-Host/Port/Name/Benutzer, Snapshotkennung und Tabellenfreigaben |
| `llm.toml` | Anbieter, tatsächlich verfügbares Modell, Cache- und Timeout-Einstellungen; verwendete Schlüssel-Umgebungsvariable |
| `worker.env` | Cloud-API-Key und DB-Passwort |
| `worker.toml` | Verweis auf `api.toml`, Polling und Speicherreserve; Vorgaben zunächst übernehmen |
| `investigation.bounded.toml`, `budget.human-tests.toml` | Untersuchungs- und Budgetregeln; Vorgaben zunächst übernehmen |
| `telemetry.toml` | Betriebsbeobachtung; Vorgaben zunächst übernehmen |
In `project.toml` die Null-Commit- und `CONFIGURE_ME`-Platzhalter ersetzen. Die
vollständige Vorlage mit Relations-, Enrichment- und Werkzeugregeln beibehalten;
die Projektdatei nicht auf DB-Adresse und Sourcepfad zusammenkürzen.
Für mehrere Datenbanken derselben MariaDB-Instanz kann in `project.toml` ein
zusätzlicher Abschnitt ergänzt werden:
```toml
[database.additional_databases]
cata_hotfixes = ["*"]
cata_locale = ["*"]
```
`[database].database` bleibt beispielsweise `cata_world`, `user` kann
`buganalysis` sein. Für den DB-Benutzer müssen entsprechende SELECT-Grants
vorliegen. `["*"]` erlaubt ausdrücklich alle sichtbaren Tabellen der jeweiligen
DB. Alternativ konkrete Tabellennamen auflisten. Nicht konfigurierte Datenbanken
bleiben gesperrt. Einzeldatenbank-Konfigurationen bleiben gültig.
Vollständige Mehrdatenbank-Vorlage:
[project.vcore-multidb.example.toml](config/project.vcore-multidb.example.toml).
Bei Verwendung der gelieferten Gemini-/DB-Vorlagen enthält `worker.env`:
```text
GEMINI_API_KEY="HIER_DEN_CLOUD_API_KEY_EINTRAGEN"
VIANO_DB_PASSWORD="HIER_DAS_DB_PASSWORT_EINTRAGEN"
```
Das sind Platzhalter, keine gültigen Zugangsdaten. Keine `export`-Anweisungen
verwenden. Die Datei wird durch systemd geladen und bleibt root-geschützt mit
Modus 0600. Secrets nicht ins Repository oder in Shell-Befehlsargumente schreiben.
**Wenn Integrationsschlüssel über die Weboberfläche verwaltet werden sollen:**
Den ausgelieferten `[[clients]]`-Beispielblock für `wow-capture-worker` vollständig
aus `api.toml` entfernen. Dazu gehören seine `id`-, `token_env`- und `projects`-
Zeilen. Die `[[projects]]`-Projektdefinition bleibt bestehen. `api.env` darf dann
zunächst nur Kommentare enthalten; ein `VBA_INTAKE_TOKEN` ist auf der
BugAnalysis-Seite nicht erforderlich. Andernfalls erwartet die Startprüfung für
den vorhandenen Beispielclient einen manuell konfigurierten Token in `api.env`.
Details: [Projektkonfiguration](docs/project-configuration.md),
[Modell-/Cachekonfiguration](docs/llm-context-caching.md) und
[Linux-Betrieb](docs/linux-deployment.md).
### 6. Persönliches Webkonto anlegen
`meinname` durch den gewünschten Benutzernamen ersetzen. Das Passwort wird
verdeckt abgefragt; es gehört nicht in die Befehlszeile.
```sh
sudo /opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.api create_user meinname --config /etc/viano-bug-analysis/api.toml --service-group buganalysis
```
Alle Webnutzer besitzen dieselben Bedienrechte. Nutzer werden ausschließlich per
privilegierter Konsole angelegt, geändert oder gelöscht; es gibt keine öffentliche
Registrierung. Weitere Befehle: [Benutzerkonten](docs/user-accounts.md).
### 7. Bereitschaft ohne Modellanfrage prüfen
Die Prüfungen laufen mit den Rechten und Environment-Dateien der späteren Dienste:
```sh
sudo systemd-run --wait --pipe --collect \
--property=User=buganalysis --property=Group=buganalysis \
--property=EnvironmentFile=/etc/viano-bug-analysis/api.env \
/opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.deployment check \
--role api --config /etc/viano-bug-analysis/api.toml
sudo systemd-run --wait --pipe --collect \
--property=User=buganalysis --property=Group=buganalysis \
--property=EnvironmentFile=/etc/viano-bug-analysis/worker.env \
--setenv=GIT_CONFIG_GLOBAL=/etc/viano-bug-analysis/gitconfig \
/opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.deployment check \
--role worker --config /etc/viano-bug-analysis/worker.toml
```
Erwartet wird jeweils `READY` mit `model_requests: 0`. Geprüft werden unter
anderem Speicher, Schreib-/Leserechte, Webnutzer, Konfiguration, Git-Stand und
DB-Schemata. Die Prüfung sendet keine kostenpflichtige Modellanfrage; sie bestätigt
deshalb nicht die Gültigkeit des Cloud-Keys oder die Modellverfügbarkeit.
Bei `NOT_READY` zunächst den gemeldeten Fehler beheben.
### 8. API starten und HTTPS einrichten
```sh
sudo systemd-analyze verify /etc/systemd/system/viano-bug-analysis-api.service /etc/systemd/system/viano-bug-analysis-worker.service
sudo systemctl enable --now viano-bug-analysis-api.service
curl --fail http://127.0.0.1:8080/healthz
```
Der Health-Aufruf auf dem VPS sollte `{"status":"OK"}` liefern. Die API bleibt
an Loopback gebunden. Für die öffentliche Webadresse eine Domain mit passendem
DNS-Eintrag und gültigem TLS-Zertifikat bereitstellen. Zertifikatsbeschaffung
und Firewallfreigaben an die vorhandene VPS-/Nginx-Einrichtung anpassen.
Auf Debian/Ubuntu kann eine eigene Nginx-Site aus der Vorlage angelegt werden:
```sh
sudo cp /etc/viano-bug-analysis/nginx.conf.example /etc/nginx/sites-available/viano-bug-analysis
sudoedit /etc/nginx/sites-available/viano-bug-analysis
sudo ln -s /etc/nginx/sites-available/viano-bug-analysis /etc/nginx/sites-enabled/viano-bug-analysis
sudo nginx -t
sudo systemctl enable --now nginx
sudo systemctl reload nginx
```
**Vor `nginx -t` alle Beispieldomains und Zertifikatpfade ersetzen; die Zertifikate
müssen bereits vorhanden sein.** Bei bereits vorhandener Site keinen zweiten
Symlink anlegen, sondern die bestehende Einrichtung prüfen. Andere VPS-Sites
nicht entfernen. Erst über die fertige HTTPS-Adresse öffentlich anmelden.
Für einen ersten lokalen Zugriff ohne fertige Domain ist ein SSH-Tunnel möglich.
Auf deinem eigenen Rechner ausführen, mit deinem SSH-Benutzer und VPS-Host:
```sh
ssh -L 8080:127.0.0.1:8080 benutzer@vps-host
```
Danach lokal `http://127.0.0.1:8080/` öffnen, während der Tunnel läuft. Der Port auf
dem eigenen Rechner muss frei sein. Für den regulären externen Erfassungsworker
weiterhin die öffentliche HTTPS-Adresse einrichten.
### 9. Erfassungsworker verbinden und Analysebetrieb einschalten
Auf der Weboberfläche mit deinem Konto anmelden. Unter **API-Schlüssel** einen
Schlüssel für den Erfassungsworker und das Projekt `viano-core` erstellen.
Den Schlüssel im Environment des **wowdiag-Workers** als `VBA_INTAKE_TOKEN`
hinterlegen. Dessen `[buganalysis]`-Abschnitt mit URL, Projekt und Profil einrichten
und bewusst aktivieren. Anleitung und Vorlagen:
[Erfassungsworker v0.4](deploy/capture-worker/README.md).
Der Erfassungsworker ist ein eigener Dienst auf dem Erfassungssystem. Er wird
nicht durch den BugAnalysis-Installer installiert oder gestartet. Die Datenbank-
Zugänge dieser beiden Programme sind ebenfalls voneinander unabhängig.
Anschließend den Analyseworker aktivieren:
```sh
sudo systemctl enable --now viano-bug-analysis-worker.service
sudo systemctl status viano-bug-analysis-api.service viano-bug-analysis-worker.service
```
**Ab diesem Zeitpunkt können vorhandene und neue Inbox-Aufträge kostenpflichtige
Modellaufrufe auslösen.** Mit einem kontrollierten echten Auftrag beginnen. In der
Weboberfläche Annahme und Fortschritt verfolgen, gegebenenfalls Testanfragen
beantworten und unter **Bearbeitete Fälle** das Ergebnis herunterladen.
Ergebnisse gehen in die Outbox, gescheiterte Analysen ins Review; blockierte Fälle
bleiben zur Fortsetzung erhalten. Ein Download bestätigt keine fachliche Übergabe.
### 10. Betrieb, Sicherung und Updates
```sh
sudo journalctl -u viano-bug-analysis-api -u viano-bug-analysis-worker -f
sudo systemctl stop viano-bug-analysis-worker.service
```
Der Worker beendet beim Stoppen den aktuellen Dispatch kontrolliert. Das kann
während einer laufenden Anfrage dauern. Vor Code-/Profiländerungen anhalten;
Konfigurationsbindungen laufender Fälle nicht beiläufig ändern.
Mindestens `/etc/viano-bug-analysis` und `/var/lib/viano-bug-analysis` gesichert
aufbewahren. Dazu zählen die Nutzer-SQLite sowie Integrationsschlüssel-SQLite und
deren separate Serverschlüsseldatei unter `runtime/integration-secrets`. Dieses
Verzeichnis ist kein beliebig löschbarer Cache. Für eine einfache konsistente
Dateisicherung beide Dienste anhalten. Zugriffe auf Backups mit Secrets schützen.
Für reguläre Codeupdates steht ein Update-Skript bereit:
```sh
sudo python3 /opt/viano-bug-analysis/deploy/update.py
```
Eine Vorschau ohne Netzwerkzugriff oder Änderungen ist mit `--dry-run` möglich.
Das Skript benötigt root und einen sauberen, root-eigenen Checkout mit Tracking-Branch.
Es holt den Remote-Stand, prüft Fast-forward, stoppt zuerst den Worker kontrolliert
und danach die API, installiert das aktualisierte Paket in die vorhandene venv
und startet nur die zuvor aktiven Dienste. Deren Startprüfungen testen die
Bereitschaft ohne LLM-Aufruf. Vorher inaktive Dienste werden nicht aktiviert.
Auch bei identischem Commit wird das Paket erneut installiert, etwa nach einem
vorherigen manuellen Pull. Parallele Updates sind gesperrt.
Konfigurationen, Zugangsdaten, Fallakten, Apache, Source-Checkout und Capture-Worker
werden nicht verändert. Das Skript erstellt keine Datensicherung und führt keine
projektspezifischen Migrationen aus.
Scheitert Installation oder Dienststart, bleiben beide Dienste gestoppt. Es gibt
keinen automatischen Rollback von Code oder Daten. Nach Behebung der Ursache das
Paket erneut installieren (auch mit diesem Skript möglich) und die gewünschten
Dienste ausdrücklich starten. Falls das Skript im bisherigen Checkout noch fehlt,
einmal vorab den folgenden Befehl ausführen und danach das Skript starten:
```sh
sudo git -C /opt/viano-bug-analysis pull --ff-only
```
Releasehinweise und geänderte Konfigurations-/Unit-Vorlagen vorher prüfen.
Das Updatebeispiel ersetzt keine gezielte Übernahme geänderter systemd-Units
mit anschließendem `systemctl daemon-reload`. Vorlagen werden vom Installer
absichtlich nicht über bestehende Konfigurationen kopiert.
Die Einrichtung ist abgeschlossen, wenn Anmeldung, automatischer Auftragseingang,
Analyse, Ergebnisdownload, menschliche Rückfrage und Wiederanlauf nach einem
Dienst-/Serverneustart geprüft wurden. Die native Linux-/HTTPS-Prüfung erfolgt auf
deinem Zielserver; lokale Windows-Entwicklungstests ersetzen sie nicht.
### Häufige Probleme bei der Ersteinrichtung
| Meldung / Verhalten | Zuerst prüfen |
| --- | --- |
| Installer verlangt root-eigenen Checkout | Pfad `/opt/viano-bug-analysis`, Eigentümer und Schreibrechte des Codes |
| `DEPLOY_MACHINE_CREDENTIALS` | Unbenutzten `[[clients]]`-Beispielblock entfernen oder dessen env-Token korrekt einrichten |
| `LLM_CREDENTIALS` | `worker.env`, Name der Schlüsselvariable in `llm.toml` und Laden der Datei durch systemd |
| `PROJECT_DATABASE_UNAVAILABLE` | DB-Adresse/Port, Netzwerkweg, Passwort und DB-Benutzer |
| Sourceprüfung schlägt fehl | Lokaler Checkout, tatsächlicher Commit, Leserechte und `/etc/viano-bug-analysis/gitconfig` |
| `nginx -t` meldet fehlendes Zertifikat | Zertifikat bereitstellen und die Beispielpfade im Site-Block ersetzen |
| Anmeldung funktioniert, aber kein Fall wird analysiert | Analyseworker läuft, Projektbindung stimmt, Auftrag ist tatsächlich angenommen |
Dienstfehler über `journalctl` prüfen. Ein fehlgeschlagener Start wird durch
systemd erneut versucht; nach einer Korrektur lässt sich der betreffende Dienst
mit `sudo systemctl restart DIENSTNAME` gezielt neu starten. Dabei den echten
Namen `viano-bug-analysis-api.service` beziehungsweise
`viano-bug-analysis-worker.service` einsetzen.
## Weiterführende Anleitungen
- [Verwendung und Funktionsweise](docs/user-guide.md) – auch im Webreiter Benutzeranleitung.
- [Projekt-, Source-, DB- und Modellkonfiguration](docs/project-configuration.md).
- [Übergabe-API und Rückgaben](docs/intake-api.md).
- [Analyseworker](docs/analysis-worker.md).
- [Benutzerkonten](docs/user-accounts.md).
- [Integrationsschlüssel](docs/integration-keys.md).
- [Linux-Betrieb im Detail](docs/linux-deployment.md).
## Entwicklung und technische Dokumentation
Project-independent foundations for reading, validating and extending ZIP case
packages. The authoritative design is [docs/architecture.md](docs/architecture.md).
The implemented v1 contract is documented in
@@ -10,6 +353,20 @@ Generic case construction and its input contracts are documented in
[docs/case-builder-v1.md](docs/case-builder-v1.md).
Vcore imports for wowdiag/wowsrc are documented in
[docs/vcore-adapters-v1.md](docs/vcore-adapters-v1.md).
Authenticated submission of new cases and completed-case feedback is documented in
[docs/intake-api.md](docs/intake-api.md). The HTTP API creates and queues packages;
external callers do not need to implement the internal package format.
The [continuous analysis worker](docs/analysis-worker.md) consumes that inbox,
routes cases to configured projects and resumes checkpointed analysis after restart.
The [web console](docs/web-console.md) shows active workers, case progress and token
charts, with corrections accounted for separately, and accepts new/return submissions.
The [Linux deployment guide](docs/linux-deployment.md) covers systemd services,
protected credentials, HTTPS and non-billable readiness checks.
The [integration key manager](docs/integration-keys.md) lets signed-in users
create, reveal and revoke project-scoped machine credentials.
The web tab **Benutzeranleitung** includes the [user guide](docs/user-guide.md)
and operator documentation, including project/source/database configuration.
After editing bundled documentation, run `python scripts/build_user_manual.py`.
Requires Python 3.11 or newer.
@@ -26,13 +383,15 @@ per-hypothesis budget accounting. An LLM-driven investigation controller connect
read-only queries, durable evidence and asynchronous test handoffs. Final evaluation
produces traceable diagnoses or human review. Confirmed diagnoses can produce
policy-bound Change Requests, with final output validation and atomic local
outbox/review publication. Opt-in operational telemetry observes the existing APIs. A continuous worker
remains a future milestone.
outbox/review publication. Operational telemetry observes the APIs and continuous worker.
A bounded single-case command-line trial now connects import, analysis and local
delivery with telemetry: [first real LLM trial](docs/first-llm-trial.md).
Use `python -m viano_bug_analysis.trial --help`. Only its `run` command makes LLM
requests; `prepare` and `check` do not contact model services.
For a new revision, `run --planning-mode joint` opts into a single interpretation/
hypothesis call with independent block validation: [joint case planning](docs/joint-case-planning.md).
New joint revisions use [v2 source constraints and dependency-aware corrections](docs/joint-case-planning-v2.md); frozen v1 cases remain replayable.
The trial enables bounded, durable early model-output corrections with explicit
validation feedback: [early correction](docs/early-correction-v1.md), configured
@@ -59,8 +418,8 @@ Durable investigation budget accounting, configurable costs/rewards and stopping
rules: [budget-manager-v1.md](docs/budget-manager-v1.md), with [budget configuration](config/budget.example.toml).
Case-local asynchronous test requests, confirmed feedback and budget-preserving
event-driven resume: [async-tests-v1.md](docs/async-tests-v1.md). Web UI and external
bot/client adapters are future integrations.
event-driven resume: [async-tests-v1.md](docs/async-tests-v1.md). Human test requests
can be answered through the web console; external bot adapters are separate integrations.
Read-only packaged source/database queries and the strict tool allowlist:
[investigation-tools-v1.md](docs/investigation-tools-v1.md).
@@ -88,3 +447,5 @@ Policy-bound coding requests and validated, resumable local output delivery:
Opt-in operational logs, safe error chains, metrics, heartbeat/progress and passive
queue diagnostics: [telemetry-v1.md](docs/telemetry-v1.md), with
[telemetry configuration](config/telemetry.example.toml).
Schlanke Untersuchungsstarts mit gemeinsamer Erstbewertung: [Ablauf und Konfiguration](docs/investigation-startup-batch-v1.md).
+35
View File
@@ -0,0 +1,35 @@
[api]
workspace = "../service-data/service"
host = "127.0.0.1"
port = 8080
[auth]
session_seconds = 3600
# Production Linux: root-owned file, read-only for the service group.
# users_database = "/etc/viano-bug-analysis/users.sqlite3"
[[projects]]
id = "viano-core"
type = "wow"
profile = "vcore"
adapter = "vcore"
planning_mode = "joint"
# Trusted server-side analysis settings; never accepted from upload metadata.
# [projects.settings]
# project_config = "project.local.toml"
# llm_config = "llm.early-review.local.toml"
# investigation_config = "investigation.bounded.toml"
# budget_config = "budget.human-tests.toml"
[[clients]]
id = "wow-capture-worker"
token_env = "VBA_INTAKE_TOKEN"
projects = ["viano-core"]
# Optional privileged machine integration, not a human login.
# [[clients]]
# id = "automation-operator"
# token_env = "VBA_OPERATOR_TOKEN"
# projects = ["viano-core"]
# operator = true
# Human accounts are created only by the privileged create_user console command.
+5
View File
@@ -0,0 +1,5 @@
# Human requests are available when an authenticated web feedback adapter exists.
# Frozen per new analysis revision; existing revisions retain their policy.
[budget]
[budget.action_costs]
"testing.request_human" = 40
+19
View File
@@ -0,0 +1,19 @@
[investigation]
lean_loop = true
lean_protocol = 2
# Temporary experiment: no periodic consolidation.
lean_checkpoint_steps = 0
bootstrap_json_framing = true
# Versioned native object shapes for nonempty bootstrap findings.
bootstrap_framing_version = 3
# Deterministic normalization and bounded format-only repair.
response_recovery_version = 1
# New revisions only: lean initial queries, followed by one joint review.
startup_batch_review = true
# Bounded model view; full evidence remains in the case package.
prompt_window_version = 2
prompt_target_characters = 10000
+15
View File
@@ -0,0 +1,15 @@
[investigation]
lean_loop = true
lean_protocol = 2
# Temporary experiment: no periodic consolidation.
lean_checkpoint_steps = 0
bootstrap_json_framing = true
# Versioned native object shapes for nonempty bootstrap findings.
bootstrap_framing_version = 3
# Deterministic normalization and bounded format-only repair.
response_recovery_version = 1
# New revisions only: lean initial queries, followed by one joint review.
startup_batch_review = true
+6
View File
@@ -19,6 +19,12 @@ snapshot_id = "backup-sha256:4964f277ef5cf7f7f98bf4378971dcb55180bac813d49bcda6d
# Explicit allowlist: no account or character tables.
tables = ["creature_template", "creature_template_locale", "creature", "quest_template", "quest_template_addon", "smart_scripts", "conditions", "game_event", "game_event_creature", "spell_script_names", "gameobject_template", "gameobject", "creature_equip_template", "item_script_names", "creature_queststarter", "spell_dbc"]
# Optional additional databases on this same connection; enable explicitly:
# [database.additional_databases]
# cata_hotfixes = ["*"]
# cata_locale = ["*"]
# Use individual table names instead of "*" for narrower access.
[limits]
max_rows = 50
max_result_bytes = 65536
+265
View File
@@ -0,0 +1,265 @@
# Operator-controlled bindings. The model cannot override these settings.
relations_file = "project-relations.vcore.toml"
[project]
type = "wow"
profile = "vcore"
[source]
path = "/srv/viano-bug-analysis/viano-core"
url = "https://gitea.viano-software.de/Nico/Viano-Core"
commit = "0000000000000000000000000000000000000000"
[database]
host = "127.0.0.1"
port = 3306
database = "cata_world"
user = "buganalysis"
password_env = "VIANO_DB_PASSWORD"
snapshot_id = "CONFIGURE_ME"
# Explicit allowlist: no account or character tables.
tables = ["*"]
# Explicit database scope: no auth, character or locale-reference access.
[database.additional_databases]
cata_hotfixes = ["*"]
cata_locale = ["*"]
[limits]
max_rows = 50
max_result_bytes = 65536
max_files = 20000
max_file_bytes = 2097152
max_search_bytes = 134217728
max_lines = 80
timeout_seconds = 15
max_cached_queries = 256
[enrichment]
max_queries = 24
max_depth = 3
max_relationships = 128
[[enrichment.texts]]
table = "quest_template"
id_column = "ID"
context_role = "quest_definition"
columns = ["LogTitle", "LogDescription", "QuestDescription"]
[[enrichment.queries]]
kind = "source.schema"
text = "CREATE TABLE `creature`"
path_prefix = "sql/base/"
case_sensitive = true
offset = 0
limit = 1
[[enrichment.queries]]
kind = "source.schema"
text = "CREATE TABLE `quest_template`"
path_prefix = "sql/base/"
case_sensitive = true
offset = 0
limit = 1
# Deterministic entity resolution before the first LLM call; no diagnosis.
[[enrichment.entities]]
entity_type = "creature"
table = "creature_template"
column = "entry"
name_column = "name"
columns = ["entry", "name", "subname", "ScriptName", "AIName"]
limit = 1
[[enrichment.entities]]
entity_type = "quest"
table = "quest_template"
column = "ID"
name_column = "LogTitle"
columns = ["ID", "LogTitle", "LogDescription", "QuestDescription", "StartItem", "RequiredNpcOrGo1", "RequiredNpcOrGo2", "RequiredNpcOrGo3", "RequiredNpcOrGo4", "RequiredItemId1", "RequiredItemId2", "RequiredItemId3", "RequiredItemId4", "RequiredItemId5", "RequiredItemId6", "RequiredSpell"]
limit = 1
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "StartItem"
relation = "quest_start_item"
entity_type = "item"
table = "item_script_names"
column = "Id"
columns = ["Id", "ScriptName"]
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "RequiredItemId1"
relation = "quest_required_item"
entity_type = "item"
table = "item_script_names"
column = "Id"
columns = ["Id", "ScriptName"]
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "RequiredItemId2"
relation = "quest_required_item"
entity_type = "item"
table = "item_script_names"
column = "Id"
columns = ["Id", "ScriptName"]
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "ID"
relation = "quest_starter_records"
table = "creature_queststarter"
column = "quest"
columns = ["id", "quest"]
[[enrichment.relationships]]
from_table = "creature_queststarter"
from_id_column = "quest"
from_column = "id"
relation = "quest_giver"
entity_type = "creature"
table = "creature_template"
column = "entry"
columns = ["entry", "name", "AIName", "ScriptName"]
[[enrichment.relationships]]
from_table = "creature_template"
from_id_column = "entry"
from_column = "entry"
when_column = "AIName"
when_value = "SmartAI"
relation = "creature_smartai_records"
table = "smart_scripts"
column = "entryorguid"
columns = ["entryorguid", "source_type", "id", "link", "event_type", "event_param1", "event_param2", "event_param3", "event_param4", "action_type", "action_param1", "action_param2", "action_param3", "action_param4", "action_param5", "action_param6", "target_type", "target_param1", "target_param2", "target_param3", "comment"]
filters = [{column = "source_type", operator = "eq", value = 0}]
limit = 10
[[enrichment.relationships]]
from_table = "creature_template"
from_id_column = "entry"
from_column = "ScriptName"
relation = "creature_script_binding"
kind = "source.symbol"
path_prefix = "src/server/scripts/"
limit = 5
[[enrichment.relationships]]
from_table = "item_script_names"
from_id_column = "Id"
from_column = "ScriptName"
relation = "item_script_binding"
kind = "source.symbol"
path_prefix = "src/server/scripts/"
limit = 5
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "RequiredSpell"
relation = "quest_required_spell"
entity_type = "spell"
table = "spell_script_names"
column = "spell_id"
columns = ["spell_id", "ScriptName"]
[[enrichment.relationships]]
from_table = "spell_script_names"
from_id_column = "spell_id"
from_column = "ScriptName"
relation = "spell_script_binding"
kind = "source.symbol"
path_prefix = "src/server/scripts/"
limit = 5
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "RequiredItemId3"
relation = "quest_required_item"
entity_type = "item"
table = "item_script_names"
column = "Id"
columns = ["Id", "ScriptName"]
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "RequiredItemId4"
relation = "quest_required_item"
entity_type = "item"
table = "item_script_names"
column = "Id"
columns = ["Id", "ScriptName"]
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "RequiredItemId5"
relation = "quest_required_item"
entity_type = "item"
table = "item_script_names"
column = "Id"
columns = ["Id", "ScriptName"]
[[enrichment.relationships]]
from_table = "quest_template"
from_id_column = "ID"
from_column = "RequiredItemId6"
relation = "quest_required_item"
entity_type = "item"
table = "item_script_names"
column = "Id"
columns = ["Id", "ScriptName"]
# Semantic name lookup runs in Case Interpretation, never in the deterministic CaseBuilder.
[entity_resolution]
enabled = true
max_searches = 4
max_candidates = 8
max_invalid_responses = 3
[[entity_resolution.catalogs]]
id = "creatures"
entity_type = "creature"
table = "creature_template"
id_column = "entry"
name_column = "name"
columns = ["entry", "name", "subname", "AIName", "ScriptName", "minlevel", "maxlevel", "faction", "unit_flags"]
[[entity_resolution.catalogs]]
id = "localized_creatures"
entity_type = "creature"
table = "creature_template_locale"
id_column = "entry"
name_column = "Name"
columns = ["entry", "locale", "Name", "Title"]
# Larger read-only source tool; registration naming is project-specific.
[source_analysis]
enabled = true
context_lines = 8
max_searches = 4
max_matches = 12
max_files = 8
max_blocks = 12
max_total_lines = 160
registration_prefixes = ["AddSC_"]
# Context-aware source selection. Domain markers belong to this adapter.
protocol = 2
max_seed_terms = 8
max_candidate_matches = 50
max_weak_hits = 8
code_prefixes = ["src/"]
schema_prefixes = ["sql/base/"]
historical_prefixes = ["sql/old/", "sql/archive/"]
context_fact_names = ["zone_name", "area_name", "world_event_name"]
type_markers = {creature = ["NPC", "CREATURE"], quest = ["QUEST"], spell = ["SPELL"], item = ["ITEM"], gameobject = ["GO", "GAMEOBJECT"]}
entity_tables = [{table = "creature_template", entity_type = "creature", id_column = "entry", script_columns = ["ScriptName"]}]
focus_roles = ["diagnostic_focus", "explicit_quest"]
+8
View File
@@ -0,0 +1,8 @@
[worker]
# Same intake configuration/workspace/project catalogue as the HTTP API.
intake_config = "api.local.toml"
poll_seconds = 5
error_retry_seconds = 60
max_inbox_per_pass = 20
min_free_bytes = 536870912
# telemetry_config = "telemetry.local.toml"
+73
View File
@@ -0,0 +1,73 @@
# wowdiag-worker v0.4 – BugAnalysis-Übergabe
Erweiterung des vorgelegten v0.3-Workers. Die ursprüngliche Queue-Claim-Logik und
DB-Struktur bleiben erhalten. Keine Änderung der aktiven `config.toml`, kein
Dienststart und keine Datenbankmigration durch diese Dateien.
Nach erfolgreicher wowdiag-/wowsrc-Erzeugung wird ein Versandauftrag dauerhaft
in einer separaten lokalen SQLite-Outbox gespeichert. `diagnostic_runs.completed`
bedeutet weiterhin **Erfassung abgeschlossen**, nicht Analyse abgeschlossen oder
API-Zustellung bestätigt. Die Versandquittung ist über `--handoff-status` sichtbar.
Die API übernimmt den Fall anschließend in ihren eigenen Analyseworker.
## Einrichtung
1. Bestehende `wowdiag_worker.py` sichern und die v0.4-Datei sowie
`buganalysis_handoff.py` nebeneinander installieren. Python 3.11 und PyMySQL
bleiben die Voraussetzungen; der HTTP-Client benötigt keine neue Bibliothek.
2. Den Abschnitt aus `buganalysis.config.example.toml` in die vorhandene
Worker-Konfiguration übernehmen. Tatsächliche URL und Projektzuordnung setzen.
Der URL muss die Serverwurzel sein; HTTPS ist für entfernte Server erforderlich.
3. Einen Integrationsschlüssel in BugAnalysis für das Projekt erzeugen und im
Dienst-Environment als `VBA_INTAKE_TOKEN` hinterlegen. Unter Linux eine geschützte
systemd-EnvironmentFile verwenden; den Schlüssel nicht in Skriptargumente,
Repository oder Worker-Logs schreiben. Bestehende Unit um EnvironmentFile
ergänzen und anschließend kontrolliert neu starten.
4. SQLite-Outbox und Diagnosearchive bis zur bestätigten Zustellung erhalten.
Das Outbox-Verzeichnis muss für den Worker schreibbar sein und einen lokalen
Datenträger mit SQLite-Dateisperren verwenden. Die Datei nicht zwischen
unabhängigen Installationen teilen.
Ohne aktivierten `[buganalysis]`-Abschnitt bleibt der bisherige Ablauf erhalten.
Das Flag bedeutet ausschließlich Erfassung plus Übergabe; der Worker löst keine
Modellanfrage selbst aus. Ein laufender BugAnalysis-Worker kann nach Annahme
allerdings sofort eine kostenpflichtige Analyse beginnen.
## Wiederholungen und Status
```sh
python3 wowdiag_worker.py --config config.toml --handoff-status
python3 wowdiag_worker.py --config config.toml --retry-handoffs
```
Diese beiden Befehle führen keine Erfassung aus. Der normale Dauerdienst sendet
fällige Aufträge vor dem nächsten Capture; `--once` versucht sie auch danach.
Netzwerkfehler, Serverausfälle, temporäre Ablehnungen und fehlende/ungültige
Zugangsdaten bleiben `pending`. Nach Behebung werden dieselben Inhalte mit
demselben Idempotenzschlüssel versandt. Auch eine verlorene Erfolgsantwort legt
dadurch keinen zweiten Fall an. Es werden keine HTTP-Redirects verfolgt.
Unveränderliche Metadaten, Ziel-URL, Archivpfade und Inhaltsprüfwerte stehen in der
Outbox; Zugangsdaten stehen dort nicht. Archivänderung oder endgültiger HTTP-
Konflikt wird `attention` und benötigt Betreiberprüfung. Ein Lease verhindert
gleichzeitigen regulären Versand durch mehrere Worker-Prozesse. Ein Prozessabbruch
lässt den Auftrag nach Ablauf des Lease erneut versuchen. Es gibt keine automatische
Neuerzeugung von Archiven oder ein Zurücksetzen der ursprünglichen Queue-Claims.
Bereits vor dem Update abgeschlossene Erfassungen werden nicht automatisch
nachträglich eingesendet. Ein erneuter neuer Auftrag für dieselbe Bug-ID wird von
BugAnalysis bewusst abgewiesen, wenn der Fall bereits existiert. Rückgaben nach
einem Patch erfolgen über den separaten `case_return`-Vertrag und nicht durch
automatisches Umdeuten neuer Captures.
Der Übergabeumschlag nennt die Bug-ID und den Erfassungs-Commit. Die wirklichen
Testerbeobachtungen, Titel und Beziehungen liest der BugAnalysis-Importer direkt
aus den unveränderten Archiven. Der Worker erfindet keine Beobachtungen und gibt
den Erfassungsstand nicht als Stand der ursprünglichen Fehlermeldung aus.
## Lokale Prüfung im BugAnalysis-Checkout
`python -m pytest tests/profiles/vcore/test_capture_handoff.py` prüft den Versand gegen die echte
lokale Intake-API mit synthetischen Archiven. Kein echter Server, keine Cloud-
Anfrage, keine Änderung der Diagnose-Queue. Ein Server-Feldtest mit einem neuen
Bug und Dienstneustart steht nach der Konfiguration noch aus.
@@ -0,0 +1,12 @@
# Add this section to the EXISTING worker configuration. Do not replace its DB/path settings.
[buganalysis]
enabled = true
url = "https://buganalysis.example.org"
project_id = "viano-core"
profile_id = "vcore"
# Keep this name stable and unique for this capture installation / queue database.
producer_id = "vcore-testserver"
token_env = "VBA_INTAKE_TOKEN"
outbox = "buganalysis-outbox.sqlite3"
timeout_seconds = 120
retry_seconds = 60
@@ -0,0 +1,162 @@
"""Durable, streaming BugAnalysis intake client. Python stdlib only."""
from contextlib import contextmanager
import hashlib
import http.client
import json
import os
from pathlib import Path
import re
import secrets
import sqlite3
import time
from urllib.parse import urlsplit
class HandoffError(Exception):
pass
def settings(raw,base):
if raw and type(raw.get('enabled',False)) is not bool:raise HandoffError('HANDOFF_CONFIG')
if not raw or not raw.get('enabled',False):return None
value=dict(raw)
allowed={'enabled','url','project_id','profile_id','token_env','outbox','timeout_seconds','retry_seconds','producer_id'}
if set(value)-allowed:raise HandoffError('HANDOFF_CONFIG')
value.setdefault('profile_id','vcore');value.setdefault('token_env','VBA_INTAKE_TOKEN')
value.setdefault('timeout_seconds',120);value.setdefault('retry_seconds',60)
for field in ('project_id','profile_id','producer_id'):
if not re.fullmatch(r'[A-Za-z0-9][A-Za-z0-9_.-]{0,63}',str(value.get(field,''))):raise HandoffError('HANDOFF_CONFIG')
if not re.fullmatch(r'[A-Za-z_][A-Za-z0-9_]*',value['token_env']):raise HandoffError('HANDOFF_CONFIG')
parsed=urlsplit(value.get('url',''))
if (parsed.scheme not in {'https','http'} or not parsed.hostname or parsed.username or parsed.password
or parsed.query or parsed.fragment or parsed.path not in {'','/'}
or (parsed.scheme=='http' and parsed.hostname not in {'127.0.0.1','localhost','::1'})):
raise HandoffError('HANDOFF_URL')
if any(type(value[f]) is not int or not 1<=value[f]<=3600 for f in ('timeout_seconds','retry_seconds')):
raise HandoffError('HANDOFF_CONFIG')
value['outbox']=str((base/Path(value.get('outbox','buganalysis-outbox.sqlite3'))).resolve())
return value
def digest(path):
h=hashlib.sha256()
with Path(path).open('rb') as stream:
for chunk in iter(lambda:stream.read(1024*1024),b''):h.update(chunk)
return h.hexdigest()
class Outbox:
def __init__(self,config,*,clock=time.time):
self.config=config;self.clock=clock;self.path=Path(config['outbox'])
self.path.parent.mkdir(parents=True,exist_ok=True)
if not self.path.exists():
try:
fd=os.open(self.path,os.O_CREAT|os.O_EXCL|os.O_WRONLY,0o600);os.close(fd)
except FileExistsError:pass
with self.db() as db:
db.execute('CREATE TABLE IF NOT EXISTS deliveries (job TEXT PRIMARY KEY, idempotency TEXT NOT NULL UNIQUE, payload TEXT NOT NULL,status TEXT NOT NULL, attempts INTEGER NOT NULL DEFAULT 0, next_try REAL NOT NULL DEFAULT 0, code TEXT, receipt TEXT, lease_until REAL NOT NULL DEFAULT 0)')
@contextmanager
def db(self):
conn=sqlite3.connect(self.path,timeout=10);conn.row_factory=sqlite3.Row
try:
with conn:yield conn
finally:conn.close()
def stage(self,run_id,bug_id,diag,src,revision):
files=[]
for role,path in (('wowdiag',diag),('wowsrc',src)):
path=Path(path).resolve()
files.append({'role':role,'path':str(path),'size':path.stat().st_size,'sha256':digest(path)})
# The adapters import actual observations/title from the unchanged archives.
# Do not invent an observation merely to populate envelope metadata.
metadata={'kind':'new_case','project_id':self.config['project_id'],'profile_id':self.config['profile_id'],
'case_id':f'BUG-{bug_id:06d}','report':{'title':f'BUG-{bug_id:06d}'},'versions':{'capture_server':revision}}
payload=json.dumps({'url':self.config['url'],'metadata':metadata,'files':files},sort_keys=True)
job=f"{self.config['producer_id']}:{run_id}"
with self.db() as db:
db.execute('BEGIN IMMEDIATE')
row=db.execute('SELECT payload FROM deliveries WHERE job=?',(job,)).fetchone()
if row:
if row['payload']!=payload:raise HandoffError('HANDOFF_JOB_CONTENT_CHANGED')
return
db.execute('INSERT INTO deliveries(job,idempotency,payload,status) VALUES (?,?,?,?)',
(job,'capture-'+secrets.token_hex(24),payload,'pending'))
def status(self):
with self.db() as db:
return [dict(r) for r in db.execute('SELECT job,status,attempts,next_try,code,receipt FROM deliveries ORDER BY job')]
def flush(self,*,send=None,force=False,maximum=5):
send=send or upload
for _ in range(maximum):
now=self.clock()
with self.db() as db:
db.execute('BEGIN IMMEDIATE')
row=db.execute("SELECT * FROM deliveries WHERE status='pending' AND lease_until<=? AND (next_try<=? OR ?) ORDER BY next_try,job LIMIT 1",(now,now,int(force))).fetchone()
if not row:return
# Lease prevents concurrent --retry-handoffs and worker submissions.
db.execute('UPDATE deliveries SET lease_until=?,attempts=attempts+1 WHERE job=?',
(now+self.config['timeout_seconds']+60,row['job']))
status='pending';receipt=None
try:
payload=json.loads(row['payload'])
for file in payload['files']:
path=Path(file['path'])
if not path.is_file() or path.stat().st_size!=file['size'] or digest(path)!=file['sha256']:
raise HandoffError('HANDOFF_ARCHIVE_CHANGED')
code,receipt=send(self.config,payload,row['idempotency'])
if code=='OK':status='sent'
elif code.startswith('HTTP_') and code not in {'HTTP_401','HTTP_403','HTTP_408','HTTP_425','HTTP_429','HTTP_500','HTTP_502','HTTP_503','HTTP_504','HTTP_507'}:status='attention'
except HandoffError as error:
code=str(error)
if code=='HANDOFF_ARCHIVE_CHANGED':status='attention'
except Exception:
# Never persist arbitrary exception text or HTTP bodies (may contain secrets).
code='HANDOFF_TRANSPORT'
with self.db() as db:
db.execute('UPDATE deliveries SET status=?,next_try=?,code=?,receipt=?,lease_until=0 WHERE job=?',
(status,self.clock()+self.config['retry_seconds'],code,json.dumps(receipt) if receipt else None,row['job']))
print(json.dumps({'handoff':row['job'],'status':status,'code':code}),flush=True)
if status=='pending':return # avoid retrying this request repeatedly in the same pass
def upload(config,payload,idempotency):
token=os.environ.get(config['token_env'],'')
if not re.fullmatch(r'[A-Za-z0-9_-]{32,256}',token):raise HandoffError('HANDOFF_CREDENTIALS')
target=urlsplit(payload['url']);boundary='vba-'+secrets.token_hex(24)
prefix=(f'--{boundary}\r\nContent-Disposition: form-data; name="metadata"\r\n\r\n'+json.dumps(payload['metadata'])+'\r\n').encode()
parts=[]
for file in payload['files']:
role=file['role']
header=f'--{boundary}\r\nContent-Disposition: form-data; name="{role}"; filename="{role}.tar.gz"\r\nContent-Type: application/gzip\r\n\r\n'.encode()
parts.append((header,file))
ending=f'--{boundary}--\r\n'.encode()
length=len(prefix)+len(ending)+sum(len(header)+file['size']+2 for header,file in parts)
connection=(http.client.HTTPSConnection if target.scheme=='https' else http.client.HTTPConnection)(target.hostname,target.port,timeout=config['timeout_seconds'])
started=time.monotonic()
def transmit(chunk):
remaining=config['timeout_seconds']-(time.monotonic()-started)
if remaining<=0:raise HandoffError('HANDOFF_TIMEOUT')
if connection.sock:connection.sock.settimeout(remaining)
connection.send(chunk)
try:
connection.request('POST','/v1/submissions',headers={'Authorization':'Bearer '+token,
'Idempotency-Key':idempotency,'Content-Type':'multipart/form-data; boundary='+boundary,
'Content-Length':str(length)},body=None)
transmit(prefix)
for header,file in parts:
transmit(header)
with Path(file['path']).open('rb') as stream:
for chunk in iter(lambda:stream.read(1024*1024),b''):transmit(chunk)
transmit(b'\r\n')
transmit(ending)
response=connection.getresponse();body=response.read(65537)
if response.status not in {200,201}:return f'HTTP_{response.status}',None
if len(body)>65536:raise HandoffError('HANDOFF_RECEIPT_INVALID')
try:data=json.loads(body)
except ValueError:raise HandoffError('HANDOFF_RECEIPT_INVALID') from None
if (not isinstance(data,dict) or not isinstance(data.get('submission_id'),str)
or data.get('case_id')!=payload['metadata']['case_id']):raise HandoffError('HANDOFF_RECEIPT_INVALID')
return 'OK',{field:data[field] for field in ('submission_id','case_id','status') if field in data}
finally:connection.close()
+29
View File
@@ -0,0 +1,29 @@
[database]
host = "127.0.0.1"
port = 3306
user = "vcore_worker"
password = "CHANGE_ME"
database = "vcore_dev"
[worker]
poll_seconds = 10
job_timeout_seconds = 900
[paths]
python = "/usr/bin/python3"
wowdiag_script = "/home/wow_admin/vcore-tools/wowdiag/wowdiag.py"
wowdiag_config = "/home/wow_admin/vcore-tools/wowdiag/config.toml"
wowsrc_script = "/home/wow_admin/vcore-tools/wowsrc/wowsrc.py"
wowsrc_config = "/home/wow_admin/vcore-tools/wowsrc/config.toml"
log_dir = "/home/wow_admin/vcore-data/diagnostics/worker-logs"
[buganalysis]
enabled = false
url = "https://buganalysis.example.org"
project_id = "viano-core"
profile_id = "vcore"
producer_id = "vcore-testserver"
token_env = "VBA_INTAKE_TOKEN"
outbox = "buganalysis-outbox.sqlite3"
timeout_seconds = 120
retry_seconds = 60
+617
View File
@@ -0,0 +1,617 @@
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import os
import re
import socket
import subprocess
import sys
import time
import tomllib
import uuid
from dataclasses import dataclass
from pathlib import Path
from typing import Optional
import pymysql
from buganalysis_handoff import Outbox, settings as handoff_settings
WORKER_VERSION = "0.4"
ARCHIVE_RE = re.compile(r"^Archive created:\s*(.+?)\s*$", re.MULTILINE)
WOWDIAG_PACKAGE_RE = re.compile(r"^Diagnostic package created:\s*(.+?)\s*$", re.MULTILINE)
WOWSRC_PACKAGE_RE = re.compile(r"^wowsrc package created:\s*(.+?)\s*$", re.MULTILINE)
@dataclass(frozen=True)
class Config:
host: str
port: int
user: str
password: str
database: str
poll_seconds: int
timeout: int
python: str
wowdiag_script: Path
wowdiag_config: Path
wowsrc_script: Path
wowsrc_config: Path
log_dir: Path
buganalysis: Optional[dict] = None
@dataclass(frozen=True)
class ToolContext:
diagnostics_root: Path
source_context_root: Path
core_source: Path
@dataclass(frozen=True)
class Job:
run_id: int
bug_id: int
claim_token: str
def load_config(path: Path) -> Config:
with path.open("rb") as f:
d = tomllib.load(f)
db, w, p = d["database"], d.get("worker", {}), d["paths"]
return Config(
str(db.get("host", "127.0.0.1")),
int(db.get("port", 3306)),
str(db["user"]),
str(db["password"]),
str(db.get("database", "vcore_dev")),
max(1, int(w.get("poll_seconds", 10))),
max(30, int(w.get("job_timeout_seconds", 900))),
str(p.get("python", sys.executable)),
Path(p["wowdiag_script"]).resolve(),
Path(p["wowdiag_config"]).resolve(),
Path(p["wowsrc_script"]).resolve(),
Path(p["wowsrc_config"]).resolve(),
Path(p["log_dir"]).resolve(),
handoff_settings(d.get('buganalysis'),path.parent),
)
def load_tool_context(cfg: Config) -> ToolContext:
with cfg.wowdiag_config.open("rb") as f:
diag = tomllib.load(f)
with cfg.wowsrc_config.open("rb") as f:
src = tomllib.load(f)
diag_paths = diag["paths"]
src_paths = src["paths"]
diag_core = Path(diag_paths["core_source"]).resolve()
src_core = Path(src_paths["core_source"]).resolve()
if diag_core != src_core:
raise RuntimeError(
"wowdiag and wowsrc use different core_source paths: "
f"wowdiag={diag_core}, wowsrc={src_core}"
)
return ToolContext(
diagnostics_root=Path(diag_paths["diagnostics"]).resolve(),
source_context_root=Path(src_paths["output_root"]).resolve(),
core_source=diag_core,
)
def connect(cfg: Config):
return pymysql.connect(
host=cfg.host,
port=cfg.port,
user=cfg.user,
password=cfg.password,
database=cfg.database,
charset="utf8mb4",
autocommit=False,
cursorclass=pymysql.cursors.DictCursor,
)
def identity() -> str:
return f"{socket.gethostname()}:{os.getpid()}"
def claim_one(conn, claimed_by: str) -> Optional[Job]:
token = uuid.uuid4().hex
try:
with conn.cursor() as cur:
cur.execute(
"""
UPDATE diagnostic_runs
SET status='running', claim_token=%s, claimed_by=%s,
claimed_at=NOW(), started_at=NOW(), error_message=NULL
WHERE status='queued'
ORDER BY diagnostic_run_id ASC
LIMIT 1
""",
(token, claimed_by),
)
if cur.rowcount != 1:
conn.rollback()
return None
conn.commit()
with conn.cursor() as cur:
cur.execute(
"""SELECT diagnostic_run_id, bug_id, claim_token
FROM diagnostic_runs
WHERE claim_token=%s AND status='running' LIMIT 1""",
(token,),
)
row = cur.fetchone()
if not row:
raise RuntimeError("Claim succeeded but claimed row could not be resolved")
return Job(
int(row["diagnostic_run_id"]),
int(row["bug_id"]),
str(row["claim_token"]),
)
except Exception:
conn.rollback()
raise
def mark_completed(
conn,
job: Job,
wowdiag_archive: Path,
wowdiag_version: str,
core_revision: str,
):
"""
Keep the existing diagnostic_runs schema contract intact.
output_path remains the wowdiag archive. The paired wowsrc archive is
generated in the configured wowsrc output_root and is recorded in the
worker log. A future DB migration can add dedicated wowsrc columns without
changing the pipeline execution semantics introduced here.
"""
with conn.cursor() as cur:
cur.execute(
"""
UPDATE diagnostic_runs
SET status='completed', finished_at=NOW(), output_path=%s,
error_message=NULL, wowdiag_version=%s, core_revision=%s
WHERE diagnostic_run_id=%s AND claim_token=%s AND status='running'
""",
(
str(wowdiag_archive),
wowdiag_version[:64],
core_revision[:64],
job.run_id,
job.claim_token,
),
)
if cur.rowcount != 1:
conn.rollback()
raise RuntimeError("Could not finalize job: claim ownership/status changed")
conn.commit()
def mark_failed(conn, job: Job, message: str):
with conn.cursor() as cur:
cur.execute(
"""
UPDATE diagnostic_runs
SET status='failed', finished_at=NOW(), error_message=%s
WHERE diagnostic_run_id=%s AND claim_token=%s AND status='running'
""",
(message[:65535], job.run_id, job.claim_token),
)
if cur.rowcount != 1:
conn.rollback()
raise RuntimeError("Could not mark job failed: claim ownership/status changed")
conn.commit()
def validated_path_from_match(
stdout: str,
regex: re.Pattern[str],
root: Path,
description: str,
must_be_dir: bool,
) -> Optional[Path]:
m = regex.search(stdout)
if not m:
return None
p = Path(m.group(1).strip()).resolve()
try:
p.relative_to(root)
except ValueError as exc:
raise RuntimeError(f"{description} outside configured output root: {p}") from exc
if must_be_dir:
if not p.is_dir():
raise RuntimeError(f"{description} directory does not exist: {p}")
elif not p.is_file():
raise RuntimeError(f"{description} file does not exist: {p}")
return p
def package_from_stdout(
stdout: str,
regex: re.Pattern[str],
root: Path,
description: str,
) -> Optional[Path]:
return validated_path_from_match(
stdout, regex, root, description, must_be_dir=True
)
def archive_from_stdout(stdout: str, root: Path, description: str) -> Optional[Path]:
p = validated_path_from_match(
stdout, ARCHIVE_RE, root, description, must_be_dir=False
)
if p and p.suffixes[-2:] != [".tar", ".gz"]:
raise RuntimeError(f"unexpected archive type: {p}")
return p
def fallback_archive(root: Path, pattern: str, started: float) -> Optional[Path]:
found = []
for p in root.glob(pattern):
try:
st = p.stat()
except OSError:
continue
if st.st_mtime >= started - 2:
found.append((st.st_mtime, p.resolve()))
return sorted(found, reverse=True)[0][1] if found else None
def manifest_metadata(package_dir: Path, expected_tool: str) -> tuple[str, str]:
manifest_path = package_dir / "manifest.json"
if not manifest_path.is_file():
raise RuntimeError(f"{expected_tool} manifest not found: {manifest_path}")
try:
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
except Exception as exc:
raise RuntimeError(f"Could not read {expected_tool} manifest: {exc}") from exc
tool = str(manifest.get("tool") or "").strip()
if tool and tool != expected_tool:
raise RuntimeError(
f"Unexpected manifest tool in {manifest_path}: {tool!r}"
)
version = str(manifest.get("tool_version") or "").strip()
revision = str(manifest.get("core_revision") or "").strip()
if not version:
raise RuntimeError(f"{expected_tool} manifest contains no tool_version")
if not revision:
raise RuntimeError(f"{expected_tool} manifest contains no core_revision")
return version, revision
def run_command(cmd: list[str], cwd: Path, timeout: int) -> tuple[int, str, str]:
r = subprocess.run(
cmd,
cwd=str(cwd),
capture_output=True,
text=True,
timeout=timeout,
check=False,
)
return r.returncode, r.stdout or "", r.stderr or ""
def write_log(
cfg: Config,
job: Job,
diag_cmd: list[str],
diag_rc: Optional[int],
diag_out: str,
diag_err: str,
src_cmd: Optional[list[str]] = None,
src_rc: Optional[int] = None,
src_out: str = "",
src_err: str = "",
wowdiag_archive: Optional[Path] = None,
wowsrc_archive: Optional[Path] = None,
failure: Optional[BaseException] = None,
):
cfg.log_dir.mkdir(parents=True, exist_ok=True)
p = cfg.log_dir / f"DIAG-{job.run_id:06d}.log"
parts = [
f"worker_version={WORKER_VERSION}",
f"diagnostic_run_id={job.run_id}",
f"bug_id={job.bug_id}",
f"claim_token={job.claim_token}",
f"wowdiag_archive={wowdiag_archive or ''}",
f"wowsrc_archive={wowsrc_archive or ''}",
"",
"WOWDIAG COMMAND:",
repr(diag_cmd),
f"returncode={diag_rc}",
"",
"WOWDIAG STDOUT:",
diag_out or "",
"",
"WOWDIAG STDERR:",
diag_err or "",
]
if src_cmd is not None:
parts += [
"",
"WOWSRC COMMAND:",
repr(src_cmd),
f"returncode={src_rc}",
"",
"WOWSRC STDOUT:",
src_out or "",
"",
"WOWSRC STDERR:",
src_err or "",
]
if failure:
parts += ["", "ERROR:", str(failure)]
p.write_text("\n".join(parts), encoding="utf-8")
def execute_pipeline(cfg: Config, ctx: ToolContext, job: Job):
if not cfg.wowdiag_script.is_file():
raise RuntimeError(f"wowdiag script not found: {cfg.wowdiag_script}")
if not cfg.wowdiag_config.is_file():
raise RuntimeError(f"wowdiag config not found: {cfg.wowdiag_config}")
if not cfg.wowsrc_script.is_file():
raise RuntimeError(f"wowsrc script not found: {cfg.wowsrc_script}")
if not cfg.wowsrc_config.is_file():
raise RuntimeError(f"wowsrc config not found: {cfg.wowsrc_config}")
ctx.diagnostics_root.mkdir(parents=True, exist_ok=True)
ctx.source_context_root.mkdir(parents=True, exist_ok=True)
diag_cmd = [
cfg.python,
str(cfg.wowdiag_script),
"--config",
str(cfg.wowdiag_config),
"bug",
str(job.bug_id),
]
src_cmd: Optional[list[str]] = None
diag_out = diag_err = src_out = src_err = ""
diag_rc: Optional[int] = None
src_rc: Optional[int] = None
wowdiag_archive: Optional[Path] = None
wowsrc_archive: Optional[Path] = None
try:
diag_started = time.time()
diag_rc, diag_out, diag_err = run_command(
diag_cmd, cfg.wowdiag_script.parent, cfg.timeout
)
if diag_rc != 0:
raise RuntimeError(
f"wowdiag exited with code {diag_rc}; "
f"stderr: {diag_err.strip() or '<empty>'}"
)
diag_package = package_from_stdout(
diag_out,
WOWDIAG_PACKAGE_RE,
ctx.diagnostics_root,
"wowdiag package",
)
if not diag_package:
raise RuntimeError(
"wowdiag exited successfully but no package directory could be identified"
)
wowdiag_archive = (
archive_from_stdout(diag_out, ctx.diagnostics_root, "wowdiag archive")
or fallback_archive(
ctx.diagnostics_root,
f"BUG-{job.bug_id:06d}-*.tar.gz",
diag_started,
)
)
if not wowdiag_archive:
raise RuntimeError(
"wowdiag exited successfully but no archive could be identified"
)
wowdiag_version, diag_revision = manifest_metadata(diag_package, "wowdiag")
# wowsrc deliberately consumes the exact wowdiag archive generated by
# this same queue job. This prevents it from silently picking up an
# older package for the same bug.
src_cmd = [
cfg.python,
str(cfg.wowsrc_script),
"--config",
str(cfg.wowsrc_config),
"bug",
str(job.bug_id),
"--diag",
str(wowdiag_archive),
]
src_started = time.time()
src_rc, src_out, src_err = run_command(
src_cmd, cfg.wowsrc_script.parent, cfg.timeout
)
if src_rc != 0:
raise RuntimeError(
f"wowsrc exited with code {src_rc}; "
f"stderr: {src_err.strip() or '<empty>'}"
)
src_package = package_from_stdout(
src_out,
WOWSRC_PACKAGE_RE,
ctx.source_context_root,
"wowsrc package",
)
if not src_package:
raise RuntimeError(
"wowsrc exited successfully but no package directory could be identified"
)
wowsrc_archive = (
archive_from_stdout(src_out, ctx.source_context_root, "wowsrc archive")
or fallback_archive(
ctx.source_context_root,
f"WOWSRC-BUG-{job.bug_id:06d}-*.tar.gz",
src_started,
)
)
if not wowsrc_archive:
raise RuntimeError(
"wowsrc exited successfully but no archive could be identified"
)
_, src_revision = manifest_metadata(src_package, "wowsrc")
if diag_revision != src_revision:
raise RuntimeError(
"wowdiag and wowsrc were generated from different core revisions: "
f"wowdiag={diag_revision}, wowsrc={src_revision}"
)
write_log(
cfg,
job,
diag_cmd,
diag_rc,
diag_out,
diag_err,
src_cmd,
src_rc,
src_out,
src_err,
wowdiag_archive,
wowsrc_archive,
)
return wowdiag_archive, wowsrc_archive, wowdiag_version, diag_revision
except Exception as exc:
write_log(
cfg,
job,
diag_cmd,
diag_rc,
diag_out,
diag_err,
src_cmd,
src_rc,
src_out,
src_err,
wowdiag_archive,
wowsrc_archive,
exc,
)
raise
def process_one(cfg: Config, ctx: ToolContext) -> bool:
conn = connect(cfg)
try:
job = claim_one(conn, identity())
if not job:
return False
print(
f"Claimed DIAG-{job.run_id} for BUG-{job.bug_id} as {identity()}",
flush=True,
)
try:
diag_archive, src_archive, version, revision = execute_pipeline(
cfg, ctx, job
)
if cfg.buganalysis:
Outbox(cfg.buganalysis).stage(job.run_id,job.bug_id,diag_archive,src_archive,revision)
mark_completed(conn, job, diag_archive, version, revision)
print(
f"Completed DIAG-{job.run_id}: "
f"wowdiag={diag_archive} wowsrc={src_archive}",
flush=True,
)
except Exception as exc:
mark_failed(conn, job, str(exc))
print(
f"FAILED DIAG-{job.run_id}: {exc}",
file=sys.stderr,
flush=True,
)
return True
finally:
conn.close()
def main() -> int:
ap = argparse.ArgumentParser(
prog="wowdiag-worker",
description="Vcore diagnostic_runs -> wowdiag -> wowsrc worker",
)
ap.add_argument(
"--config",
default=str(Path(__file__).with_name("config.toml")),
)
ap.add_argument(
"--once",
action="store_true",
help="Process at most one queued job and exit",
)
ap.add_argument('--retry-handoffs',action='store_true',help='Retry queued API deliveries only; no capture jobs')
ap.add_argument('--handoff-status',action='store_true',help='List API delivery status; no capture jobs')
args = ap.parse_args()
cfg = load_config(Path(args.config).resolve())
outbox=Outbox(cfg.buganalysis) if cfg.buganalysis else None
if args.handoff_status or args.retry_handoffs:
if not outbox:
print('BugAnalysis handoff is disabled.',file=sys.stderr);return 1
if args.retry_handoffs:outbox.flush(force=True,maximum=100)
print(json.dumps(outbox.status()));return 0
ctx = load_tool_context(cfg)
print(f"Vcore diagnostic worker v{WORKER_VERSION} ({identity()})", flush=True)
if args.once:
if outbox:outbox.flush()
if not process_one(cfg, ctx):
print("No queued diagnostic job found.", flush=True)
if outbox:outbox.flush()
return 0
while True:
try:
if outbox:outbox.flush()
if not process_one(cfg, ctx):
time.sleep(cfg.poll_seconds)
except KeyboardInterrupt:
print("Worker stopped.", flush=True)
return 0
except Exception as exc:
print(f"Worker loop error: {exc}", file=sys.stderr, flush=True)
time.sleep(cfg.poll_seconds)
if __name__ == "__main__":
raise SystemExit(main())
+104
View File
@@ -0,0 +1,104 @@
"""Install the fixed Linux service layout. Never enables or starts services."""
import argparse
import json
import os
from pathlib import Path
import shutil
import subprocess
import sys
import tomllib
ROOT = Path(__file__).resolve().parents[1]
CONFIG = Path('/etc/viano-bug-analysis')
STATE = Path('/var/lib/viano-bug-analysis')
SOURCE = Path('/srv/viano-bug-analysis')
def project_template(root=ROOT):
text=(root/'config/project.example.toml').read_text(encoding='utf-8')
replacements={
'path = "../service-data/research/viano-core"':'path = "/srv/viano-bug-analysis/viano-core"',
'port = 33079':'port = 3306',
'password_file = "../service-data/research/world-db/reader.local.txt"':'password_env = "VIANO_DB_PASSWORD"',
}
for old,new in replacements.items():
if text.count(old)!=1:raise ValueError('Deployment template changed; review replacements')
text=text.replace(old,new)
import re
text=re.sub(r'^commit = "[0-9a-f]{40}"$', 'commit = "'+'0'*40+'"',text,flags=re.M)
text=re.sub(r'^snapshot_id = .*$', 'snapshot_id = "CONFIGURE_ME"',text,flags=re.M)
tomllib.loads(text)
return text
def templates(root=ROOT):
files={name:(root/'deploy/linux'/name).read_text(encoding='utf-8')
for name in ('api.toml','worker.toml','gitconfig','nginx.conf.example')}
for target,source in {
'llm.toml':'llm.gemini-cache.example.toml',
'investigation.bounded.toml':'investigation.bounded.toml',
'budget.human-tests.toml':'budget.human-tests.toml',
'project-relations.vcore.toml':'project-relations.vcore.toml',
'telemetry.toml':'telemetry.example.toml',
}.items():files[target]=(root/'config'/source).read_text(encoding='utf-8')
files['project.toml']=project_template(root)
for name in ('api','worker'):
files[name+'.env']=(root/'deploy/linux'/(name+'.env.example')).read_text(encoding='utf-8')
return files
def main(argv=None):
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--dry-run',action='store_true')
args=parser.parse_args(argv)
files=templates()
if args.dry_run:
print(json.dumps({'status':'PLAN','code':'/opt/viano-bug-analysis',
'config':str(CONFIG),'state':str(STATE),'source':str(SOURCE),
'config_files':sorted(files),'existing_files':'preserved','services_started':False}))
return 0
if sys.platform!='linux' or os.geteuid()!=0:
parser.error('Installation requires Linux and root; use --dry-run elsewhere')
if ROOT!=Path('/opt/viano-bug-analysis') or ROOT.is_symlink():
parser.error('Place a root-owned checkout at /opt/viano-bug-analysis first')
# Root executes packaging code: reject an untrusted checkout/venv.
for base in (ROOT,ROOT/'src',ROOT/'deploy',ROOT/'config',ROOT/'pyproject.toml',ROOT/'.venv'):
if not base.exists():continue
paths=[base,*base.rglob('*')] if base.is_dir() and base!=ROOT else [base]
for path in paths:
stat=path.stat()
if path.is_symlink() and base!=ROOT/'.venv':raise RuntimeError('Symlink in installation sources')
if stat.st_uid!=0 or stat.st_mode&0o022:raise RuntimeError('Installation sources must be root-owned and not group/world writable')
def run(*command):subprocess.run(command,check=True)
import grp
import pwd
try:group=grp.getgrnam('buganalysis')
except KeyError:
run('groupadd','--system','buganalysis');group=grp.getgrnam('buganalysis')
try:user=pwd.getpwnam('buganalysis')
except KeyError:
run('useradd','--system','--gid','buganalysis','--home-dir',str(STATE),'--no-create-home','--shell','/usr/sbin/nologin','buganalysis')
user=pwd.getpwnam('buganalysis')
if user.pw_uid==0 or user.pw_gid!=group.gr_gid:raise RuntimeError('Unexpected service account identity')
for path,uid in ((CONFIG,0),(CONFIG/'auth',0),(STATE,user.pw_uid),(SOURCE,0)):
if path.is_symlink():raise RuntimeError('Symlink in deployment directories')
path.mkdir(parents=True,exist_ok=True)
os.chown(path,uid,group.gr_gid);os.chmod(path,0o750)
def install(path,text,mode):
if path.is_symlink():raise RuntimeError('Symlink at deployment target')
if path.exists():return
with path.open('x',encoding='utf-8',newline='\n') as stream:stream.write(text)
os.chown(path,0,group.gr_gid);os.chmod(path,mode)
for name,text in files.items():install(CONFIG/name,text,0o600 if name.endswith('.env') else 0o640)
for role in ('api','worker'):
name=f'viano-bug-analysis-{role}.service'
install(Path('/etc/systemd/system')/name,(ROOT/'deploy'/name).read_text(encoding='utf-8'),0o644)
if not (ROOT/'.venv/bin/python').exists():run(sys.executable,'-m','venv',str(ROOT/'.venv'))
run(str(ROOT/'.venv/bin/python'),'-m','pip','install',str(ROOT)+'[api,research]')
run('systemctl','daemon-reload')
print(json.dumps({'status':'INSTALLED','existing_files':'preserved','services_started':False,
'next':'Configure project, secrets, source checkout, web user and HTTPS; run readiness checks before enabling services'}))
return 0
if __name__=='__main__':raise SystemExit(main())
+3
View File
@@ -0,0 +1,3 @@
# Read by systemd as root, not by the web user. chmod 0600, owner root.
# Configure once; never commit a filled copy.
# VBA_INTAKE_TOKEN="replace-with-a-random-32-to-256-character-base64url-token"
+25
View File
@@ -0,0 +1,25 @@
[api]
workspace = "/var/lib/viano-bug-analysis"
host = "127.0.0.1"
port = 8080
[auth]
users_database = "/etc/viano-bug-analysis/auth/users.sqlite3"
session_seconds = 3600
[[projects]]
id = "viano-core"
type = "wow"
profile = "vcore"
adapter = "vcore"
planning_mode = "joint"
[projects.settings]
project_config = "project.toml"
llm_config = "llm.toml"
investigation_config = "investigation.bounded.toml"
budget_config = "budget.human-tests.toml"
[[clients]]
id = "wow-capture-worker"
token_env = "VBA_INTAKE_TOKEN"
projects = ["viano-core"]
+2
View File
@@ -0,0 +1,2 @@
[safe]
directory = /srv/viano-bug-analysis/viano-core
+29
View File
@@ -0,0 +1,29 @@
# Replace domain and certificate paths. Install manually after nginx -t.
# Root path on its own HTTPS hostname; upstream must remain loopback-only.
server {
listen 80;
server_name buganalysis.example.org;
return 308 https://buganalysis.example.org$request_uri;
}
server {
listen 443 ssl;
server_name buganalysis.example.org;
ssl_certificate /etc/letsencrypt/live/buganalysis.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/buganalysis.example.org/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
client_max_body_size 768m;
client_body_timeout 120s;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_request_buffering off;
proxy_read_timeout 180s;
proxy_send_timeout 180s;
proxy_cache off;
proxy_no_cache 1;
}
}
+3
View File
@@ -0,0 +1,3 @@
# Read by systemd as root. chmod 0600, owner root. No shell export statements.
# GEMINI_API_KEY="your-cloud-key"
# VIANO_DB_PASSWORD="your-read-only-database-password"
+7
View File
@@ -0,0 +1,7 @@
[worker]
intake_config = "api.toml"
poll_seconds = 5
error_retry_seconds = 60
max_inbox_per_pass = 20
min_free_bytes = 536870912
telemetry_config = "telemetry.toml"
+107
View File
@@ -0,0 +1,107 @@
"""Update an existing Linux deployment; preserve configuration and case data."""
import argparse
import json
import os
from pathlib import Path
import subprocess
import sys
ROOT = Path('/opt/viano-bug-analysis')
SERVICES = ('viano-bug-analysis-worker.service', 'viano-bug-analysis-api.service')
def run(*args, check=True):
result = subprocess.run(args, check=False, text=True, stdout=subprocess.PIPE)
if check and result.returncode:
if result.stdout:
print(result.stdout, flush=True)
raise subprocess.CalledProcessError(result.returncode, args)
return result.stdout.strip()
def trusted(root):
for base in (root, root/'.git', root/'src', root/'deploy', root/'pyproject.toml', root/'.venv'):
if not base.exists():
raise RuntimeError('Installation is incomplete')
paths = [base, *base.rglob('*')] if base.is_dir() and base != root else [base]
for path in paths:
stat = path.stat()
if path.is_symlink() and base != root/'.venv':
raise RuntimeError('Symlink in installation sources')
if stat.st_uid != 0 or stat.st_mode & 0o022:
raise RuntimeError('Installation must be root-owned and not group/world writable')
def update(root=ROOT, execute=run):
def git(*args):
return execute('git', '-C', str(root), *args)
if git('status', '--porcelain'):
raise RuntimeError('Checkout has local changes; update refused')
old = git('rev-parse', 'HEAD')
upstream = git('rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}')
# Fetch changes objects/refs only, while services still use the installed code.
git('fetch', '--prune')
target = git('rev-parse', upstream)
git('merge-base', '--is-ancestor', old, target)
active = []
for service in SERVICES:
state = execute('systemctl', 'show', '--property=ActiveState', '--value', service)
if state in {'active', 'activating', 'reloading'}:
active.append(service)
elif state not in {'inactive', 'failed'}:
raise RuntimeError('Service is changing state; retry later')
stopped = False
try:
# Stop the worker first; its unit waits for the current dispatch to finish.
stopped = True
for service in SERVICES:
execute('systemctl', 'stop', service)
git('merge', '--ff-only', target)
trusted(root)
execute(str(root/'.venv/bin/python'), '-m', 'pip', 'install', str(root)+'[api,research]')
# Existing units/configs are intentionally not overwritten. ExecStartPre
# runs readiness checks with the real service restrictions and secrets.
for service in reversed(active):
execute('systemctl', 'start', service)
execute('systemctl', 'is-active', '--quiet', service)
except Exception:
if stopped:
# A partly installed package must never be left serving traffic.
execute('systemctl', 'stop', *SERVICES)
raise
return {'status':'UPDATED', 'previous_commit':old, 'commit':target,
'services_restarted':active, 'configuration':'preserved', 'case_data':'preserved'}
def main(argv=None):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--dry-run', action='store_true', help='Show the procedure without fetching or changing anything')
args = parser.parse_args(argv)
if args.dry_run:
print(json.dumps({'status':'PLAN', 'root':str(ROOT), 'steps':[
'require root-owned clean checkout and tracking branch', 'fetch and require fast-forward',
'stop worker and API', 'fast-forward to fetched commit', 'install into existing venv',
'restart previously active services with readiness checks'],
'configurations_and_units':'preserved', 'case_data':'preserved'}))
return 0
if sys.platform != 'linux' or os.geteuid() != 0:
parser.error('Update requires Linux and root')
if Path(__file__).absolute().parents[1] != ROOT:
parser.error('Run the updater from /opt/viano-bug-analysis/deploy/update.py')
import fcntl
try:
trusted(ROOT)
# One updater at a time; kernel releases the lock on process exit.
with (ROOT/'.git/viano-update.lock').open('a') as lock:
fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
result = update()
print(json.dumps(result))
return 0
except Exception:
print(json.dumps({'status':'ERROR', 'code':'UPDATE_FAILED',
'instruction':'Inspect command output. After an installation/start failure both services remain stopped; fix the cause, reinstall the package and start the required services. No automatic rollback or case changes.'}))
return 1
if __name__ == '__main__':
raise SystemExit(main())
+36
View File
@@ -0,0 +1,36 @@
[Unit]
Description=Viano BugAnalysis web and intake API
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0
[Service]
Type=simple
User=buganalysis
Group=buganalysis
WorkingDirectory=/var/lib/viano-bug-analysis
EnvironmentFile=/etc/viano-bug-analysis/api.env
Environment=PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
ExecStartPre=/opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.deployment check --role api --config /etc/viano-bug-analysis/api.toml
ExecStart=/opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.api serve --config /etc/viano-bug-analysis/api.toml
Restart=always
RestartSec=10
KillSignal=SIGTERM
TimeoutStartSec=60
TimeoutStopSec=180
UMask=0077
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/viano-bug-analysis
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
CapabilityBoundingSet=
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
[Install]
WantedBy=multi-user.target
+37
View File
@@ -0,0 +1,37 @@
[Unit]
Description=Viano BugAnalysis analysis worker
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0
[Service]
Type=simple
User=buganalysis
Group=buganalysis
WorkingDirectory=/var/lib/viano-bug-analysis
EnvironmentFile=/etc/viano-bug-analysis/worker.env
Environment=PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1 GIT_CONFIG_GLOBAL=/etc/viano-bug-analysis/gitconfig GIT_TERMINAL_PROMPT=0
ExecStartPre=/opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.deployment check --role worker --config /etc/viano-bug-analysis/worker.toml
ExecStart=/opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.worker run --config /etc/viano-bug-analysis/worker.toml
Restart=always
RestartSec=10
KillSignal=SIGTERM
# Finish the current checkpointed dispatch; operator can still force-stop.
TimeoutStopSec=infinity
TimeoutStartSec=300
UMask=0077
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/viano-bug-analysis
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
CapabilityBoundingSet=
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
[Install]
WantedBy=multi-user.target
+209
View File
@@ -0,0 +1,209 @@
# Dauerhafter Analyseworker
Der Worker verbindet die Übergabe-API mit dem vorhandenen Analyseablauf. Er nimmt
Pakete aus derselben Inbox auf, wählt die serverseitige Projektkonfiguration und
bearbeitet aktive Fälle bis zu Outbox oder Review. Er erstellt keine Patches,
führt keine Builds aus und verändert keine Projekt-Datenbank.
## Konfiguration
`config/worker.example.toml` verweist auf die Konfiguration der Übergabe-API.
API und Worker müssen denselben Workspace und Projektkatalog verwenden. Der
Worker benötigt die API-Clienttokens nicht, wohl aber die in seiner LLM-Konfiguration
genannten Provider-Zugangsdaten. Beide Prozesse dürfen getrennt laufen.
Für jedes freigegebene Projekt werden die Analysekonfigurationen in der
API-Konfiguration hinterlegt:
```toml
[[projects]]
id = "viano-core"
type = "wow"
profile = "vcore"
adapter = "vcore"
planning_mode = "joint"
[projects.settings]
project_config = "project.local.toml"
llm_config = "llm.early-review.local.toml"
investigation_config = "investigation.bounded.toml"
```
Die Pfade sind relativ zur API-Konfigurationsdatei. `llm_config` ist erforderlich.
Weitere optionale Einstellungen: `analysis_config`, `budget_config`,
`diagnosis_config`, `change_request_config`, `correction_config`. Ohne explizite
Datei gelten deren bestehende Standardwerte. Für den aktuellen Vcore-Betrieb die
erprobte `investigation.bounded.toml` verwenden; ältere ausführliche Promptmodi
können an der unveränderten 20.000-Zeichen-Grenze scheitern.
`planning_mode` ist je Projekt `joint` (Standard) oder `separate`. Die Profilbindung
einer Akte muss vollständig zum Katalog passen: `project.id`, `type`, `profile`.
Alte manuelle Pakete ohne `project.id` werden nicht automatisch zugeordnet.
Andere Projektadapter bleiben ein eigener Ausbauschritt.
## Start und Prüfung
```powershell
.\.venv\Scripts\python.exe -m viano_bug_analysis.worker check --config config/worker.local.toml
.\.venv\Scripts\python.exe -m viano_bug_analysis.worker run --config config/worker.local.toml
```
`check` lädt Konfiguration und prüft die Anwesenheit der LLM-Zugangsdaten. Es sendet
keine Modellanfrage und ist kein Erreichbarkeitstest für API, Datenbank oder
Repository. `run` verarbeitet angenommene Aufträge und kann deshalb kostenpflichtige
LLM-Aufrufe auslösen. Der reine Start ohne anstehende Fälle führt keine Modellaufrufe
aus. `run --once` führt genau einen Scheduler-Durchgang aus, nicht einen vollständigen
Buglauf. Auch dieser Modus kann LLM-Aufrufe auslösen.
API zusätzlich in einem zweiten Prozess starten:
```powershell
.\.venv\Scripts\python.exe -m viano_bug_analysis.api serve --config config/api.local.toml
```
Für diese Entwicklung wurden die zuvor nicht vorhandenen lokalen Dateien
`config/api.local.toml` und `config/worker.local.toml` mit dem Vcore-Profil vorbereitet.
Sie sind nicht versioniert und enthalten keine Zugangsschlüssel. Vorhandene lokale
Konfigurationen werden bei späteren Änderungen nicht automatisch überschrieben.
## Scheduling und Wiederanlauf
- Pro Durchgang erhält jeder berechtigte aktive Fall einen Dispatch. Danach
darf der nächste Fall arbeiten. Gibt es Fortschritt, folgt der nächste Durchgang
unmittelbar; nur im Leerlauf oder bei Wartefällen greift das Pollintervall.
- Der Dienst läuft als einzelner Analyseprozess. Eine OS-Dateisperre verhindert
einen zweiten Worker im selben Workspace. Die Fall-Lease ist mit dem manuellen
Trialbefehl geteilt. API-Veröffentlichungen verwenden weiterhin die kurzen
Checkpoint-/Inbox-Sperren; während einer Modellanfrage bleibt die API benutzbar.
- Paketmanifest und Checkpoints bleiben maßgeblich. Es wird nur die neueste
Generation pro Fall geprüft, nicht jede historische Generation erneut geöffnet.
- Bei Neustart werden verwaltete aktive Fälle und noch nicht übernommene Uploads
wiedergefunden. PREPARED-Veröffentlichungen der API werden vor der Verarbeitung
abgeschlossen. Rückläufer starten die bereits eröffnete neue Analyse-Revision;
alte Interpretation und Hypothesen werden nicht als neue Ergebnisse behandelt.
- Bestehende LLM-Operationskennungen bleiben stabil. Der Dienst ändert keine
Versuchskennungen, Budgets, Iterationsgrenzen oder Korrekturregeln, um einen
blockierten Fall weiterzutreiben.
- `RETRY_PENDING`/`DEFERRED` beachten die gespeicherte Wartezeit. Ein unerwarteter
Konfigurations-/Vorbereitungsfehler erhält einen lokalen Cooldown; andere Fälle
werden weiterbearbeitet. Eine ausdrücklich zurückgegebene `ERROR`-Antwort oder
unerwartete Exception während eines Dispatch erzeugt `ATTENTION`, statt dieselbe
Fehlantwort endlos abzuspielen oder möglicherweise erneut Modellkosten auszulösen.
- BLOCKED bleibt BLOCKED, wenn eine menschliche Testerantwort benötigt wird,
automatische Wiederholung untersagt ist, Modellvalidierung gescheitert ist oder
die LLM-Wiederholungen ausgeschöpft sind. Explizit freigegebene, fällige technische
Wiederholungen dürfen über den vorhandenen Resume-Checkpoint fortgesetzt werden.
- Outbox-/Review-Veröffentlichung wird nach Erfolg nicht ständig wiederholt. Nach
einem Absturz zwischen Paketabschluss und Veröffentlichung kann der bestehende
Outputvalidator die fehlende Veröffentlichung idempotent nachholen.
Ein Prozessabbruch während einer externen Modellanfrage kann deren bereits
berechnete Kosten nicht zurücknehmen. Ist die Antwort vor dem Checkpoint verloren
gegangen, lässt sich eine erneute Anfrage nicht grundsätzlich ausschließen. Der
Worker verspricht keine Exactly-once-Ausführung beim externen Anbieter.
## Betrieb und Fehlerbehandlung
```powershell
.\.venv\Scripts\python.exe -m viano_bug_analysis.worker status --config config/worker.local.toml
```
`runtime/worker/status.json` enthält den letzten Dienstzustand und gegebenenfalls
den bearbeiteten Fall. Es ist ein Snapshot, kein Beweis für einen noch lebenden
Prozess. Die bestehende Telemetrie liefert ergänzend Heartbeat, Phasen, Laufzeiten
und Modellverbrauch. `runtime/worker/cases/` enthält kleine lokale
Schedulingquittungen mit Status, Fehlercode, Wartezeit und Konfigurationshashes.
Keine Prompts, Antworten oder Geheimnisse werden diesen Quittungen hinzugefügt.
Die Statusantwort der Übergabe-API enthält für einen zugeordneten Fall zusätzlich
den letzten Workerstatus.
Die Akte bleibt vollständig transportabel. Die lokalen Quittungen sind keine
fachliche Beweisquelle und keine verteilte Jobdatenbank. Bei ihrer vollständigen
Entfernung müssen reine Scheduler-Cooldowns/Attention-Markierungen gegebenenfalls
neu erkannt werden; fachliche Sperren und LLM-Operationshistorie bleiben im Paket.
Konfigurationsdateien werden über ihre Hashes vor dem ersten Dispatch gebunden.
Eine geänderte Konfiguration wird nicht unbemerkt auf dieselbe aktive Revision
angewendet. Neue Profileinstellungen benötigen einen Worker-Neustart; laufende
Revisionen mit abweichender Bindung gehen auf `ATTENTION/WORKER_CONFIG_CHANGED`.
Auch abhängige Profil-/Relationsdateien nicht während einer Untersuchung ändern.
Eine allgemeine Migration laufender Modelloperationen auf neue Policies ist noch
kein Bestandteil dieses Dienstes.
Nach Behebung eines lokalen Schedulingfehlers kann der Betreiber den **gestoppten**
Worker freigeben:
```powershell
.\.venv\Scripts\python.exe -m viano_bug_analysis.worker retry --config config/worker.local.toml --case-id BUG-000020 --package-id api-PAKETIDENTITAET
```
Dies entfernt die lokale Warte-/Attention-Markierung, aber setzt keine LLM-Operation
oder fachliche Budgets zurück. Für einen fälligen `RESEARCH_UNAVAILABLE`-Fall
bestätigt der Befehl zusätzlich die Reparatur des Research-Dienstes und setzt dessen
Resume-Checkpoint fort. Andere BLOCKED-Gründe, ausstehende menschliche Rückmeldungen
und abweichende Konfigurationsbindungen werden damit nicht umgangen.
Bei zu wenig freiem Speicher pausiert der Worker mit `STORAGE_LOW`, ohne Akten zu
löschen oder Untersuchungsbudgets zu verbrauchen. Die konfigurierbare
`min_free_bytes`-Reserve ersetzt keine Speicherüberwachung oder Retention. Die
20-GB-Vorgabe für Entwicklungs-/Testdaten bleibt davon unabhängig. Der Worker
löscht keine Paketgenerationen und keine Inhalte erhaltener Akten.
Die [Web-Betriebssteuerung](web-console.md#betriebssteuerung) kann neue Fälle je
Projekt pausieren, während begonnene Analysen abschließen. Freigabeaufträge werden
dauerhaft gespeichert und zwischen Dispatches unter derselben Fall-Lease geprüft.
Damit ist für Web-Freigaben kein Worker-Stopp nötig. CLI-Freigaben benötigen
weiterhin den gestoppten Dienst. Alle fachlichen Retry- und Budgetregeln gelten
für beide Wege; ein veralteter Webauftrag entsperrt keinen neueren Paketstand.
Ctrl+C bzw. SIGTERM fordert einen geordneten Stopp an. Der laufende Dispatch darf
noch abschließen; erst danach wird die Prozess-Lease freigegeben. Ein Dispatch
kann mehrere interne Schritte/Modellanfragen enthalten und entsprechend dauern.
Bei hartem Beenden greift beim nächsten Start der Checkpoint-Wiederanlauf.
## Freigabe nach einer technischen Korrektur
Bei `ENTITY_RESOLUTION_INVALID_RESPONSES` bietet die aktuelle Fallansicht die
Aktion **Einen Reparaturversuch freigeben**. Vorher die technische Ursache beheben
und im Pflichtfeld kurz dokumentieren (keine Secrets). Die Freigabe wird über den
authentifizierten Betreiberzugang mit CSRF-Schutz vorgemerkt. Maschinenclients
dürfen sie nicht auslösen. Der Worker prüft Zustand, Projektbindung und aktuelle
Paketgeneration erneut. Doppelte oder veraltete Aufträge gewähren keinen weiteren Versuch.
Jede Freigabe erlaubt genau einen zusätzlichen Antwortversuch in der betroffenen
Namensauflösungsstufe (Suchplan oder Bewertung), ohne die bisherigen Versuche zu
löschen. Eine gültige Reparatur kann anschließend den regulären Ablauf fortsetzen.
Scheitert sie, bleibt der Fall erneut gesperrt. Weitere Versuche benötigen eine neue
ausdrückliche Freigabe. Akteur, Begründung, betroffener Antwort-Hash und Code-Hash
werden dauerhaft als Checkpoint in der Fallakte gespeichert. Revision, gültiger
Suchplan, Recherchebelege und Untersuchungsbudgets werden nicht zurückgesetzt.
Die Freigabe selbst führt keine Modellanfrage aus; die anschließende Bearbeitung
kann reguläre LLM-Kosten verursachen.
Alternativ bei gestopptem Worker als root unter Linux:
```sh
/opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.worker repair --config /etc/viano-bug-analysis/worker.toml --case-id BUG-000021 --package-id api-PAKETIDENTITAET --reason "Technische Korrektur installiert; Namensbewertung gezielt reparieren"
```
Danach den Worker wieder starten. Der CLI-Befehl benötigt keinen Cloud-Schlüssel,
weil er nur eine Freigabe protokolliert. Die vorhandene Projektkonfiguration muss
unverändert gebunden sein. Diese Freigabe ist derzeit bewusst auf ausgeschöpfte
Namensauflösung beschränkt. Sie umgeht weder menschliche Rückfragen noch
fachliche Budgetgrenzen und öffnet keine erfolgreich abgeschlossenen Fälle oder
`FAILED_TO_ANALYZE`-Revisionen. Für andere Fehlergründe bleiben die jeweiligen
Retry- beziehungsweise Review-Verfahren maßgeblich.
Für einen Server ist die Vorlage `deploy/viano-bug-analysis-worker.service`
vorbereitet. Sie wird nicht automatisch installiert oder gestartet. Dienstbenutzer,
Pfade, Zugangsdaten und gemeinsame Workspace-Berechtigungen müssen zum Zielserver
passen. Der Worker startet weder die lokale Testdatenbank noch einen Repository-
Synchronisationsdienst. Diese Abhängigkeiten werden separat betrieben.
## Lokale Tests
Worker-, Übergabe- und Wiederanlauftests verwenden künstliche Daten und lokale
Provideradapter; es werden keine kostenpflichtigen Modellanfragen ausgeführt:
```powershell
.\.venv\Scripts\python.exe -m pytest tests/test_worker.py tests/profiles/vcore/test_worker_intake.py tests/profiles/vcore/test_intake_api.py -q
```
+56
View File
@@ -0,0 +1,56 @@
# Budgetbewertung nach erneutem Belegabruf
Bug17 wurde an Generation 103 blockiert, weil drei Antworten nach Recall eine
Bewertung enthielten, obwohl `previous_result` null war. Die nächste Source-Abfrage
war plausibel und vollständig. `assessment` betrifft ausschließlich die einmalige
Budgetabrechnung eines neuen Rechercheergebnisses, nicht eine erneute Bewertung
alten Inhalts. Recall selbst erzeugt keinen neuen abrechenbaren Auftrag.
## Kontextabhängiger Vertrag
Neue begrenzte Untersuchungskontexte enthalten `assessment_scope_version: 1`.
Damit erlaubt ihr Antwortschema bei null `previous_result` nur null `assessment`,
bei einem offenen Ergebnis dagegen nur ein vollständiges Bewertungsobjekt.
Das optionale Kontextfeld erhält bestehende gespeicherte Anfragen unverändert.
Bereits eingefrorene Kontexte werden nicht nachträglich umgeschrieben; die
Controllerprüfung und neue Rückmeldungen gelten trotzdem auch bei ihnen.
Fehlerhinweise nennen `/assessment` und erklären das erforderliche Verhalten.
## Eng begrenzte Übernahme
Bei aktivierter Antwortreparatur und begrenztem Fenster v2 kann ein normaler
`investigate_one_step` mit ausdrücklich null `previous_result` eine überflüssige
Budgetbewertung neutralisieren. Voraussetzung sind:
- Ausschließlich `assessment`, `observation`, `next` an der Antwortwurzel.
- Vollständige Bewertung mit Integer-Score 0–100 und nicht leerem Grund.
- Keine zusätzlichen Belegfelder und keine unbekannten E-Referenzen im Grund.
- Eindeutige Aktion `tool`/`project.query` mit einem bekannten lesenden Query-Kind.
- Die Antwort besteht nach Setzen von `assessment: null` das Antwortschema.
Beobachtung und Auftrag bleiben unverändert. Original und Regel
`non_applicable_budget_assessment:/assessment` werden im Aufruf gespeichert;
die entfernte Bewertung wird weder als Erkenntnis noch als Gutschrift übernommen.
Anschließend gelten weiterhin sämtliche Controller-, Beleg-, Projekt- und
Budgetprüfungen vor der Ausführung. Unbekannte Aktionen, fehlerhafte Scores,
zusätzliche Findings, unklare Belegangaben und ausstehende neue Ergebnisse fallen
nicht unter diese Reparatur. Fehlende Bewertungen werden nicht erfunden.
## Nachweis
`test-results/token-usage/bug17-assessment-recovery-offline-20261020.json`
protokolliert die Übernahme aller drei Originalantworten gegen die exakten
ursprünglichen Kontexte und die konfigurierte Source-Prüfung. Keine Ausführung,
keine Budgetänderung, keine neuen bezahlten API-Anfragen.
Tests prüfen kontextabhängige Schemas, historische Kontextkompatibilität,
Originalantworten, Idempotenz, Audit, Ausschluss mehrdeutiger Fälle und einen
Controllerdurchlauf nach Recall: Ein gültiger Rechercheauftrag kostet genau seine
regulären Einheiten, ohne zusätzliche Rückerstattung für den bereits bekannten
Beleg und ohne zusätzlichen LLM-Korrekturaufruf.
Prüfergebnis: 212 Tests der breiteren Prüfung bestanden (191,46 Sekunden).
Die gezielten Tests wurden nach der letzten Präzisierung erneut ausgeführt:
24 bestanden (6,48 Sekunden); die Mengen überlappen. `git diff --check` ohne Befund.
Der bestehende Fall ist ohne Budget-/Artefaktänderung von Generation 103 auf 104
manuell wieder freigegeben. Keine kostenpflichtigen API-Aufrufe.
+6 -5
View File
@@ -1,8 +1,9 @@
# Asynchronous test handoff v1
This addition prepares the existing project for externally performed human and
automated tests. No web UI, HTTP feedback endpoint, notifications, bot steering,
client automation, Tool Router or Investigation Loop is implemented here.
This contract supports externally performed human and automated tests. The human
HTTP adapter and dedicated web page are now documented in
[Web console](web-console.md#menschliche-testanfragen). Automated execution,
notifications, bot steering and client automation are not provided by that page.
`docs/architecture.md` remains unchanged and authoritative: VianoBugAnalysis
does not steer labs. It requests observations through a future external adapter.
@@ -10,8 +11,8 @@ does not steer labs. It requests observations through a future external adapter.
`AsyncTestCoordinator` is imported from `viano_bug_analysis.lifecycle.async_tests`.
It is a trusted controller service, not a callable operation exposed directly to
an LLM. The future router must validate requests before calling it. The future
web adapter must authenticate/authorize users and confirm feedback before calling
an LLM. The investigation controller validates requests before calling it. The
web adapter authenticates/authorizes users and confirms feedback before calling
`confirm_feedback`; a payload claiming `confirmed = true` is not authentication.
User-supplied observations are untrusted data, not executable instructions.
+38
View File
@@ -0,0 +1,38 @@
# Konsolidierung mit anschließendem Belegabruf
Der Bug17-Lauf wurde an Generation 84 technisch blockiert. Entgegen der ersten
Auswertung war `recall` im äußeren begrenzten v20-Checkpoint-Vertrag bereits erlaubt.
Die zweite Prüfung der normalisierten kanonischen Antwort verwendete jedoch den
alten Vertrag ohne Recall-Aktion und verwarf alle drei Antworten an `/next`.
Die Erklärung in den bisherigen Testberichten bleibt als historischer Befund
stehen; dieser Nachtrag präzisiert die tatsächliche Ursache.
Beide Prüfschichten verwenden jetzt dieselbe Aktion für begrenzte Checkpoints:
eine bekannte E-Referenz und eine nichtnegative Seitennummer. Unbekannte Belege
und nicht vorhandene Seiten werden weiter vom Controller abgelehnt. Die gesonderte
frühe Diagnosebewertung bleibt auf ihre erlaubten Aktionen beschränkt.
Bei erfolgreicher Konsolidierung mit Recall wird unter Fenster-Version 2 der
aktuelle Arbeitsstand gespeichert, die Session konsolidiert und der Checkpoint
beendet. Die angeforderte Seite bleibt im Zustand erhalten; der nächste Aufruf ist
wieder `investigate_one_step`. Es erfolgt keine automatische Tool-Recherche und
keine Umdeutung der Aktionsabsicht. Bereits gespeicherte Antworten werden nicht
verändert. Budgetabrechnung, Gegenbelege, Hypothesenwahl und Zeichenobergrenze
bleiben erhalten. Fenster-Version 1 behält ihr bisheriges Sessionverhalten.
Bei ungültigen Next-Aktionen nennt das Feedback jetzt `/next/kind` und die aus dem
maßgeblichen Schema abgeleiteten zulässigen Aktionen. Keine ungeprüften Nutzwerte
werden in den Hinweis übernommen.
Der Offline-Bericht `test-results/token-usage/bug17-checkpoint-recall-offline-fix-20261020.json`
belegt, dass sämtliche drei kuratierten Antworten gegen ihre exakten ursprünglichen
Vollkontexte bestehen. Messages, Antwortschema und Prompt-Version der ursprünglichen
Anfragen bleiben identisch. Kein neuer API-Aufruf war dafür notwendig.
Regressionstests prüfen Originalantworten, beide Prüfschichten, gespeicherten
Arbeitsstand, Rückkehr zur schlanken Schleife, portable Wiederaufnahme, unveränderte
Budgets beim reinen Recall sowie Ablehnung unbekannter Belegreferenzen und Seiten.
Prüfergebnis: 89 lokale Tests bestanden (158,35 Sekunden). Der bestehende
Bug17-Fall wurde ohne Budget- oder Artefaktänderung von Generation 84 auf 85
manuell wieder freigegeben. Keine kostenpflichtigen API-Aufrufe.
+172
View File
@@ -0,0 +1,172 @@
# Übergabe-API v1
Die API erstellt interne Case-Pakete und veröffentlicht sie atomar in der Inbox.
Externe Programme liefern Metadaten und Dateien; sie erzeugen und bearbeiten keine
internen Manifeste. Die API führt keine Analyse und keine LLM-Aufrufe aus. Ein
dauerhaft laufender [Analyseworker](analysis-worker.md) übernimmt anschließend die
Aufnahme und Verarbeitung. Die [Weboberfläche](web-console.md) bietet Übersicht,
Auftragsübergabe, Testerantworten und Ergebnisdownloads.
## Lokaler Start
```powershell
.\.venv\Scripts\python.exe -m pip install -e '.[api]'
Copy-Item config/api.example.toml config/api.local.toml
$env:VBA_INTAKE_TOKEN = [Convert]::ToHexString([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(32))
.\.venv\Scripts\python.exe -m viano_bug_analysis.api check --config config/api.local.toml
.\.venv\Scripts\python.exe -m viano_bug_analysis.api serve --config config/api.local.toml
```
Der API-Token ist ein eigener Zugangsschlüssel, kein Gemini-Key. Programme erhalten
vorzugsweise einen Schlüssel aus der [Web-Schlüsselverwaltung](integration-keys.md).
Alternativ bleiben Clients mit Token aus einer serverseitigen Umgebungsvariable
unterstützt; der Beispielstart oben zeigt diese Variante. Der
Token benötigt 32–256 Zeichen aus `A-Z a-z 0-9 _ -`. Auf älterem Windows PowerShell
kann ein solcher Token über einen Passwortmanager erzeugt und als Variable gesetzt
werden. Der Beispielstart bindet nur an `127.0.0.1:8080`. Für entfernte Nutzung sind
HTTPS und ein passend konfigurierter Reverseproxy erforderlich. Tokens nicht in
URLs oder Git-Konfiguration ablegen. Zugriff auf das Workspace-Dateisystem bleibt
auf den Dienst und vertrauenswürdige Betreiber beschränkt.
`projects` ist die serverseitige Freigabeliste. Jeder Auftrag benennt `project_id`
und `profile_id`. Er kann keine Repository-URLs, DB-Zugänge, Budgets oder
Konfigurationspfade überschreiben. Optionale `projects.settings` halten die spätere
Worker-Konfiguration bereit; die Eingangsschicht verwendet diese Dateien nicht für
Analysen. Aktuell ist der Importadapter `vcore` für `wow/vcore` implementiert.
Weitere Projekte benötigen passende Adapter/Profile, keine separat gepflegten Forks.
## Endpunkte
| Methode/Pfad | Bedeutung |
|---|---|
| `GET /healthz` | Minimale öffentliche Erreichbarkeitsprüfung |
| `GET /v1/profiles` | Für diesen Client freigegebene Projekte/Profile |
| `GET /v1/schema` | Öffentliches JSON-Schema der Übergabemetadaten |
| `GET /v1/overview` | Projektbezogene Worker-/Fallübersicht und Tokenstatistik |
| `POST /v1/submissions` | Multipart-Upload, `201` bei neuer Einreihung, `200` bei Wiederholung |
| `GET /v1/submissions/{id}` | Quittung und aktueller verwalteter Zustand |
| `GET /v1/submissions/{id}/package` | Abgeschlossene Akte herunterladen; sonst `409` |
Alle Endpunkte außer Health benötigen `Authorization: Bearer TOKEN`.
POST benötigt zusätzlich `Idempotency-Key: frei-gewaehlte-eindeutige-id` (1–128
Zeichen, Buchstaben/Ziffern sowie Punkt, Unterstrich, Bindestrich; erstes Zeichen
alphanumerisch). Derselbe Client/Schlüssel mit denselben Metadaten und Dateiinhalten
liefert dieselbe Quittung, auch nach einem Neustart. Abweichender Inhalt ergibt
`409 API_IDEMPOTENCY_CONFLICT`. Dateinamen und Multipart-Grenzen zählen nicht als
Inhaltsänderung; Rollen und Reihenfolge der Dateien zählen. Ein zweiter neuer
Auftrag für dasselbe Projekt und dieselbe Case-ID wird zurückgewiesen.
## Neuer Auftrag
`metadata` ist ein UTF-8-JSON-Textfeld, kein Datei-Upload. Dateien: genau einmal
`wowdiag`, optional einmal `wowsrc`, optional mehrfach `attachments`. Für Vcore muss
die Case-ID dem Bug des Erfassungsarchivs entsprechen (`BUG-000020`). Beide
Erfassungsarchive müssen zueinander passen. Beispiel `submission.json`:
```json
{
"kind": "new_case",
"project_id": "viano-core",
"profile_id": "vcore",
"case_id": "BUG-000020",
"report": {
"title": "Wolpertinger fehlen",
"observations": ["Nach Questannahme waren im untersuchten Gebiet keine Tiere sichtbar."],
"expected_behavior": ["Fangbare Tiere sind im Gebiet vorhanden."]
},
"versions": {
"reported_server": "commit-des-gemeldeten-serverstands",
"capture_server": "commit-des-erfassungsstands"
}
}
```
```powershell
curl.exe --fail-with-body -H "Authorization: Bearer $env:VBA_INTAKE_TOKEN" -H "Idempotency-Key: bug20-capture-001" -F "metadata=<submission.json" -F "wowdiag=@wowdiag.tar.gz" -F "wowsrc=@wowsrc.tar.gz" http://127.0.0.1:8080/v1/submissions
```
Versionsangaben werden als unbestätigte Angaben des Einlieferers gespeichert, nicht
als verifizierte technische Fakten. Sie ersetzen keine Prüfung des Deployments.
Zusätzliche Anhänge werden unter generierten internen Namen unverändert erhalten;
sie werden nicht ausgeführt. Originalarchive bleiben ebenfalls erhalten.
## Rückläufer nach Abschluss
Dateien: genau einmal `case_package` (unveränderte abgeschlossene ZIP-Akte), optional
mehrfach `attachments`. Kein erneutes Erzeugen interner JSON-Dateien nötig:
```json
{
"kind": "case_return",
"project_id": "viano-core",
"profile_id": "vcore",
"case_id": "BUG-000020",
"feedback": {
"outcome": "patch_failed",
"summary": "Der Patch wurde getestet, das Verhalten besteht weiter.",
"observations": ["Die Tiere bleiben auch nach Neustart unsichtbar."],
"patch_id": "pr-123",
"tested_build": "commit-des-getesteten-builds"
}
}
```
```powershell
curl.exe --fail-with-body -H "Authorization: Bearer $env:VBA_INTAKE_TOKEN" -H "Idempotency-Key: bug20-patch123-feedback" -F "metadata=<return.json" -F "case_package=@case.zip" http://127.0.0.1:8080/v1/submissions
```
Zulässig sind `OUTPUT_READY`, `HANDED_OFF`, `FAILED_TO_ANALYZE`. Die API übernimmt
bei `OUTPUT_READY` die interne Übergabemarkierung, ergänzt Feedback, Bericht und
Anhänge und wechselt anschließend nach `REOPENED`. Die Paketidentität bleibt,
`analysis_revision` steigt genau einmal. Bisherige Artefakte bleiben erhalten und
der Casebuilder sieht die neuen Beobachtungen. Das neue Paket wird in die Inbox
gelegt; `QUEUED` bedeutet ausschließlich angenommen, nicht erfolgreich analysiert.
Ein verwalteter Fall darf nur mit seiner exakten aktuellen Akte zurückgegeben
werden. Veraltete/divergierende Akten und parallele Rückgaben werden abgewiesen.
Ohne lokale Fallhistorie ist eine gültige abgeschlossene, passend zugeordnete Akte
importierbar. Alte manuelle Testpakete ohne `project.id` benötigen vorerst eine
betreiberseitige Migration; sie werden nicht stillschweigend einem Projekt zugeordnet.
BLOCKED-Fälle, laufende Fälle und asynchrone Testerantworten innerhalb einer
Untersuchung sind keine Abschlussrückläufer und werden hier nicht wiedereröffnet.
## Grenzen und Wiederanlauf
Standard: 768 MiB gesamter HTTP-Body, 512 MiB je Datei, 64 KiB Metadaten, 12 Dateien,
120 Sekunden Uploadzeit und zwei gleichzeitige Uploads pro Prozess. Konfigurierbar
über `[limits]` mit den Feldnamen aus `IntakeLimits`. Die existierenden Import- und
ZIP-Validatoren setzen zusätzlich ihre eigenen Grenzen durch (Vcore-Import ist
enger begrenzt). Dies sind Betriebsschutzwerte, keine fachlichen Analysebudgets.
Uploads werden vor dem Parsen authentifiziert. Auch Requests ohne Content-Length
werden anhand tatsächlich empfangener Bytes begrenzt. Multipart-Spools werden bei
Fehler/Timeout geschlossen, eigene temporäre Arbeitskopien wieder entfernt. Der
Dienst prüft freien Speicher vor Aufnahme und Paketbau. Für den ersten Betrieb
einen einzelnen Uvicorn-Prozess verwenden; die Upload-Parallelitätsgrenze gilt pro
Prozess. Der Workspace verwendet zusätzlich OS-Dateisperren für Veröffentlichung.
Unter `runtime/intake/requests` bleiben kleine Quittungen und Hashes. Vor der
atomaren Inbox-Veröffentlichung wird eine PREPARED-Quittung mit fertigem Paket
gesichert. Beim Neustart werden solche Veröffentlichungen fortgesetzt. Nach
Einreihung wird die zusätzliche Paketkopie entfernt. Bereits vom Worker übernommene
Pakete werden über ihre Checkpoint-Kette erkannt und nicht erneut eingereiht.
Nach hartem Prozessabbruch können verwaiste Arbeitsverzeichnisse unter
`runtime/intake/staging` und Betriebssystem-Temporärdateien verbleiben; deren
betriebliche Bereinigung/Retention gehört zum folgenden Worker-/Dienst-Ausbau.
Fehlerantworten enthalten stabile Codes, keine Dateipfade oder Secrets. Wesentliche
Fälle: `401` Zugriff, `403` Projektfreigabe, `409` Konflikt/Zustand, `413` Größe,
`422` ungültige Metadaten/Archive, `503` beschäftigt/Speicherfehler, `507` freier
Speicher zu gering. Bei `503` mit demselben Idempotenzschlüssel wiederholen.
## Lokale Prüfung
```powershell
.\.venv\Scripts\python.exe -m pip install -e '.[api,api-test]'
.\.venv\Scripts\python.exe -m pytest tests/profiles/vcore/test_intake_api.py -q
```
Die Tests verwenden künstliche Erfassungsarchive und HTTP-Testtransport. Sie prüfen
auch Feedbackübernahme durch den echten Casebuilder, Idempotenz, veraltete
Rückläufer, Uploadgrenzen sowie Abstürze vor und nach Queue-Veröffentlichung. Es
finden keine kostenpflichtigen LLM-Aufrufe statt.
+45
View File
@@ -0,0 +1,45 @@
# Integrationsschlüssel
Angemeldete Webnutzer finden unter **API-Schlüssel** eine eigene Verwaltungsseite.
Programmname und mindestens ein Projekt auswählen, dann den Schlüssel erstellen.
**Anzeigen** ruft ihn bei Bedarf erneut ab; **Verbergen** entfernt ihn aus dem
Eingabefeld. **Kopieren** verwendet die Zwischenablage (HTTPS oder localhost).
**Widerrufen** sperrt ihn sofort für nachfolgende API-Anfragen. Bereits laufende
Anfragen werden dadurch nicht abgebrochen. Ein widerrufener Schlüssel wird nicht
mehr angezeigt; für einen Ersatz einen neuen Schlüssel erstellen.
Alle angemeldeten menschlichen Nutzer haben dieselben Verwaltungsrechte.
Maschinenzugänge können weder Schlüssel verwalten noch andere Schlüssel anzeigen.
Webmutationen einschließlich Anzeigen benötigen die vorhandene CSRF-Absicherung.
Das aufrufende Programm sendet `Authorization: Bearer <Schlüssel>` an die
Übergabe-API. Neue Schlüssel erlauben Auftragsübergabe einschließlich Rückgaben
und lesenden Zugriff auf die ausgewählten Projekte. Sie erlauben keine
Betriebssteuerung oder Beantwortung menschlicher Testanfragen. Zugriff auf weitere
Projekte erfordert einen neuen Schlüssel. Bestehende env-basierte Integrationen
bleiben unverändert nutzbar und erscheinen nicht in der SQLite-Schlüsselliste.
## Speicherung und Sicherung
- SQLite unter `<workspace>/runtime/integrations/keys.sqlite3` speichert Metadaten,
SHA-256-Prüfwerte und mit Fernet authentifiziert verschlüsselte Schlüssel.
- Der separate Serverschlüssel entsteht beim ersten Erstellen automatisch unter
`<workspace>/runtime/integration-secrets/master.key`, Dateimodus 0600.
Nutzerkonten und ihre root-verwaltete SQLite-Datei werden nicht verändert.
- Mit `VIANO_INTEGRATION_KEY_FILE` kann die API stattdessen eine separate
Schlüsseldatei verwenden. Vorhandene Dateien müssen einen gültigen Fernet-Key
enthalten und für den API-Dienst lesbar sein; fehlt die Datei beim ersten
Erstellen, muss der Dienst sie im gewählten Verzeichnis anlegen dürfen.
- SQLite und Serverschlüssel getrennt geschützt sichern. Das Laufzeitverzeichnis
enthält damit dauerhaft notwendige Integrationsdaten und darf bei einer
Bereinigung von Sessions nicht pauschal gelöscht werden. Unter Windows passende
Dateisystem-ACLs verwenden; POSIX-Modusbits ersetzen dort keine ACLs.
- Geht der Serverschlüssel verloren oder wird er unpassend ausgetauscht, können
Schlüssel nicht mehr angezeigt werden. Das System ersetzt ihn bei bestehenden
Einträgen nicht stillschweigend. Vorhandene Schlüssel können anhand ihrer
Prüfwerte weiterhin authentifiziert und über die Weboberfläche widerrufen werden.
Zur Wiederherstellung die richtige Schlüsseldatei aus der Sicherung zurückspielen.
Nach einem Update die API-Abhängigkeiten neu installieren (`.[api]` umfasst jetzt
`cryptography`) und den API-Dienst neu starten. Eine Datenbankmigration per Hand
ist nicht nötig. Keine Änderung oder Neueingabe des Gemini-Schlüssels erforderlich.
+108
View File
@@ -0,0 +1,108 @@
# Begrenzte Untersuchungsdarstellung v2
Die bestehende begrenzte Untersuchung bleibt bei einem Richtwert von 10.000 und
höchstens 20.000 Zeichen für den vollständigen logischen Provider-Input, inklusive
Systemtext, Cache-Präfix und gegebenenfalls transportiertem Antwortschema.
Dies sind Kontextregeln der Untersuchung, keine Paketformatgrenzen.
## Antwortformat und Identitäten
`prompt_window_version = 2` ersetzt verschachtelte Schema-Dokumentation mit
`choices`/`const` durch kompakte textuelle Signaturen und bei Rechercheentscheidungen
ein ausdrücklich als Formbeispiel bezeichnetes, wörtliches JSON-Objekt. Beispielwerte
sind Platzhalter, keine Recherchevorgabe. Das vollständige kanonische JSON-Schema
bleibt der ausführbare Validator. Gemini erhält im Textpräfix kein zusätzliches
Duplikat dieses Schemas; native Schemaübertragung und lokale Prüfung bleiben erhalten.
`input.entities` enthält die unveränderten kanonischen N-Referenzen mit typisierten
IDs, Namen und Rollen aus `case_sources`. Gleiche numerische IDs verschiedener
Entitätstypen werden nicht zusammengeführt. Eine beobachtete oder primäre Entität
ist nicht automatisch der Fehlergegenstand. Frühere Interpretation wird als solche
gekennzeichnet. Unbekannte N-Referenzen dürfen keinen Toolauftrag auslösen.
## Fehlerbehandlung
Schemafehler werden mit Feldpfad, Pflichtfeldern und knapper Handlungsanweisung
zurückgemeldet, auch wenn die äußere Providerprüfung bereits abgelehnt hat.
Fehlerhinweise enthalten keine ungeprüften Nutzdaten.
Bei aktivierter Antwortreparatur wird ausschließlich die eindeutige Hülle
`next.arguments = {"choices": [<ein einzelnes Query-Objekt>]}` entfernt, wenn die
Aktion bereits wörtlich `tool`/`project.query` und der Query-Kind vorhanden ist.
Andere Felder, IDs und Beobachtungen bleiben unverändert; Original und Reparaturregel
werden im LLM-Aufruf protokolliert. Vor Budgetreservierung und Ausführung gelten
weiterhin sämtliche Schema-, Beleg-, Identitäts- und semantischen Prüfungen.
Mehrere Alternativen, zusätzliche Geschwisterfelder, unbekannte Aktionen, fehlende
Pflichtwerte oder rohe IDs anstelle von N-Referenzen werden nicht geraten.
Insbesondere ergänzt die Reparatur keinen fehlenden Offset oder Query-Kind.
## Aktivierung und Nachweis
`config/investigation.bounded.toml` aktiviert Version 2 für neue Untersuchungen.
Eine vorhandene Case-Akte behält ihre eingefrorene Policy; sie wird nicht migriert.
Version 1 bleibt für historische Request-Rekonstruktion unverändert verfügbar.
Ein neuer Test benötigt daher einen frischen Fall beziehungsweise eine neue
Analyse-Revision mit dieser Konfiguration.
Die Offline-Gegenprobe im Bericht
`test-results/token-usage/investigation-contract-v2-offline-20261020.json`
rekonstruiert alle sieben gespeicherten Startup-Anfragen aus dem letzten begrenzten
Test mit identischen Messages, Schema und Prompt-Version. Mit v2 liegen dieselben
Kontexte einschließlich Cache-Präfix bei 8.460 bis 14.817 Zeichen. Zwei ältere
Folgeschritte ergeben 9.331 und 12.064 Zeichen. Der Richtwert wird damit nicht
überall erreicht; die harte Grenze bleibt gewahrt. Es wurden keine API-Aufrufe
getätigt. Dies belegt Darstellung und Grenzen, noch keine bessere LLM-Antwortqualität.
Lokale Tests prüfen die echten kuratierten Ablehnungen, sichere und verweigerte
Reparaturen, unveränderte IDs, fehlende Budgetnebenwirkungen, Wiederaufnahme nach
Unterbrechung, gemeinsame Startbewertung, Checkpoints bis zum Abschluss sowie
Cache-Aufteilung und frühe Diagnose-Routingentscheidung.
Validierung am 20.10.2026: 307 lokale Tests bestanden (171,87 Sekunden),
`git diff --check` ohne Befund. Keine kostenpflichtigen LLM-Tests ausgeführt.
## Quellenraum und gezielte Korrekturen (20.10.2026)
Neue v2-Kontexte speichern `research_guidance_version=1`. Ein kleiner, im stabilen
Fallkontext cachebarer Quellenkatalog unterscheidet konfigurierte Git-Recherche
(`project.query`) von den deklarierten Dateien im Paket (`source.*`). Höchstens
drei Paketpfade mit zusammen höchstens 700 Zeichen werden aufgeführt; weitere
Referenzen werden als ausgelassen gezählt. Historische Kontexte und ihre Requests
bleiben unverändert rekonstruierbar. Die vollständige Eingabe unterliegt weiterhin
der bestehenden 20.000-Zeichen-Grenze und dem 10.000-Zeichen-Richtwert.
Fehlender Query-Kind, unvollständige `source.search`-Argumente und falscher
Quellenraum erhalten kurze, feldbezogene Hinweise. Es werden weder fehlende
Argumente erfunden noch Repository-Pfade automatisch in Paketquellen umgedeutet.
Die Hinweise passen in das bestehende Limit von 160 Zeichen.
Die Antwortreparatur entfernt bei einem bekannten, einzelnen `recall` lediglich
die eindeutige `arguments`-Hülle. Beleg-ID, optionale Seitennummer, Beobachtung und
Bewertung bleiben erhalten. Mehrdeutige Hüllen, unbekannte IDs, mehrere Belege,
negative oder nicht ganzzahlige Seiten und unbekannte Aktionen werden nicht
repariert. Anschließend gelten unverändert Schema-, Provenienz-, Seiten- und
Budgetprüfungen; Originalantwort und Reparaturregel werden protokolliert.
Die neue allgemeine Untersuchungsanweisung verlangt bei vermeintlich fehlenden
Hooks auch Aufrufer, Overrides, indirekte Übergaben und Registrierung zu prüfen.
Vorhandener Implementierungscode allein ist kein Beleg für einen Defekt. Das
ändert keine gespeicherten Confidence-Werte und erzwingt keine Bug17-spezifische
Schlussfolgerung. Ob diese Anleitung die fachliche Qualität verbessert, muss ein
späterer LLM-Lauf zeigen.
Der blockierte Bug17-Lauf wurde ohne API-Aufruf von Generation 204 über einen
protokollierten manuellen technischen Retry auf Generation 206 vorbereitet.
806 vorhandene Archiveinträge bleiben erhalten; Budget, Hypothesenstände und
Versuchsnummer bleiben unverändert. Der neue Kontext ergänzt ausschließlich die
versionierten Quellenhinweise und den fehlenden Korrekturhinweis. Die vollständige
logische Anfrage misst 13.849 Zeichen einschließlich Cache-Kontext. Der portable
Paketvalidator akzeptiert die Ausgabe. Details:
`test-results/token-usage/bug17-source-contract-repair-20261020.json`.
Validierung der Quellenkorrekturen: 269 lokale Regressionstests bestanden in
192,85 Sekunden. Darunter 18 gezielte Tests für die kuratierten Suchfehler,
eindeutige und verweigerte Recall-Reparaturen, vollständige Controller-Prüfung,
Budgetneutralität, Cache-Aufteilung und die Zeichenobergrenze.
`git diff --check` ohne Befund; keine kostenpflichtigen Aufrufe.
+102
View File
@@ -0,0 +1,102 @@
# Begrenztes Arbeitsfenster für die Hypothesenuntersuchung
## Ziel und Geltungsbereich
Normale Untersuchungsschritte sollen ungefähr 10.000 Zeichen umfassen. Kein
Aufruf der Untersuchungsphase darf 20.000 Zeichen überschreiten. Das gilt auch
für Initialabfragen, gemeinsame Startbewertungen, Checkpoints und Reparaturen.
Caseinterpretation, Hypothesenplanung und finale Diagnose werden nicht gekürzt.
Es gibt keine neue finanzielle Abbruchgrenze.
Gezählt werden Unicode-Zeichen der System- und übrigen Nachrichten sowie des
zusätzlich übertragenen Antwortschemas. Gecachte Inhalte zählen vollständig.
Eine identische Schemaangabe, die Gemini lediglich aus der Nachricht in den
Präfix verschiebt, wird bei der Vorprüfung nicht doppelt gezählt. Die Adapter
prüfen anschließend den vollständigen logischen Providerinput, einschließlich
Cachepräfix und gegebenenfalls nativem Antwortschema. JSON-HTTP-Escaping und
Providerparameter wie Timeout oder Modellname sind keine Promptzeichen.
Untersuchungsaufrufe speichern zusätzlich `outcome.prompt_size` mit Nachrichten-
und konservativer Gesamtzeichenzahl, Richtwert und Obergrenze. Die tatsächliche
Providerdarstellung wird nach der Cachepartition nochmals geprüft.
Der Vorprüfung bleiben 1.500 Zeichen Reserve für Transportinstruktionen und
Präfixrahmen. Der 10.000-Zeichen-Richtwert darf für benötigte aktuelle Ergebnisse
überschritten werden, die harte Grenze niemals. Tokens und Denkarbeit lassen
sich daraus nicht exakt ableiten; der kostenpflichtige Qualitätstest steht aus.
## Darstellung und Validierung
`config/investigation.bounded.toml` aktiviert `prompt_window_version = 1` mit
schlanker Schleife v2 und gemeinsamer Startbewertung. Die Policy wird für eine
neue Analyserevision eingefroren. Bereits gespeicherte Kontexte und Requests
werden nicht umgeschrieben. Alte Presets bleiben für reproduzierbare lokale
Vergleiche erhalten; übergroße alte Anfragen werden von der allgemeinen
Sicherheitsprüfung vor dem Provideraufruf abgelehnt.
Das Arbeitsfenster enthält die aktuelle Hypothese, beobachtetes/erwartetes
Verhalten, relevante Entities, den Arbeitsstand und benötigte Ergebnisfenster.
Interne Source-Konfiguration, Provenienzverwaltung und Budgetbuchhaltung werden
nicht ständig mitübertragen. Die Werkzeugprofile bleiben mit Namen und Zweck
sichtbar. Die vollständigen Ausführungsregeln und Bindungen bleiben im Controller.
Der strenge Antwort-/Werkzeugvertrag wird einmal in kompakter struktureller
Notation beschrieben: Pflichtfelder, optionale Felder, Alternativen, Typen,
Enums und Arraygrenzen. Das Provider-Schema prüft die äußere Form; anschließend
gelten weiterhin die vollständigen lokalen Schema-, Referenz-, Parameter- und
Zustandsprüfungen. Die kompakte Darstellung autorisiert keine weiteren Aktionen.
Unklare oder erfundene Aktionen/Belege werden weiterhin abgelehnt.
Der Cache kann den festen Vertrag und den gezielten Fallkontext verlustfrei
auslagern; der vollständige rekonstruierte Input muss dieselbe Grenze einhalten.
Kurze Präfixe können unterhalb anbieterseitiger Cache-Mindestgrößen liegen.
Sie werden nicht künstlich aufgebläht, um einen Cache zu erzwingen. Vorhandene
bevorzugte/verpflichtende Cache-Policies bleiben maßgeblich.
## Rechercheergebnisse und Wachstum
Neue und explizit nachgeladene Ergebnisse haben Vorrang. Zusätzliche ältere
Rohbelege werden nur aufgenommen, solange der Größenrichtwert Platz lässt.
Ein begrenzter Katalog zeigt die letzten IDs und den Umfang des Archivs.
Das Archiv bleibt vollständig im Case; seine fehlende Darstellung behauptet
weder die Abwesenheit von Evidenz noch deren Löschung.
Große Ergebnisse werden als `json_fragment` mit Seitenindex, Seitenanzahl,
Zeichenposition, Gesamtlänge und SHA-256 der vollständigen bisherigen
Modelldarstellung angeboten. Eine Seite enthält höchstens 1.600 Zeichen des
serialisierten Belegs. Die JSON-Fragmente sind ausdrücklich keine vollständigen
Queryantworten. Seiten können mitten in einem JSON-Token enden; erst die
Verkettung aller Fragmente ergibt die vollständige JSON-Darstellung. Strukturierte
Query-/Coverageinformationen und vorhandene relationale Aggregationen bleiben
zusätzlich sichtbar. Deren Aussagekraft bleibt auf den erklärten Scope begrenzt.
Mit `{"kind":"recall","evidence_refs":["E000001"],"page":1}` wird eine
andere nullbasierte Seite lokal nachgeladen, ohne externe Wiederholungsquery.
Pro Aktion wird ein Beleg gelesen. Ungültige IDs oder Seiten werden abgelehnt.
Seitenwahl und Request bleiben nach Wiederaufnahme nachvollziehbar. Das nächste
normale Arbeitsfenster trägt nicht alle früher gelesenen Seiten weiter.
Ein Checkpoint wird unabhängig von der abgeschalteten periodischen Vier-Schritt-
Regel angefordert, wenn die bereits bewerteten Sitzungsergebnisse mehr als 4.000
Bytes oder das Sitzungsprotokoll mehr als 2.000 Bytes umfassen. Das ist ein
Bedarfsauslöser, keine weitere Promptobergrenze. Auch Checkpoints nutzen begrenzte
Ergebnisfenster und dürfen zum Nachlesen `recall` wählen, bevor sie konsolidieren.
In diesem Fall bleibt die provisorische Sitzung erhalten. Erst eine erfolgreiche
Konsolidierung leert sie. Die vorhandene Delta-Verarbeitung bewahrt frühere
Findings; die Darstellung kennzeichnet ausgelassene Findings und Gegenbelege.
Passt selbst der notwendige Grundkontext nicht unter die Sicherheitsgrenze,
wird der Fall kontrolliert mit `INVESTIGATION_PROMPT_LIMIT` zurückgestellt.
Es wird kein kostenpflichtiger übergroßer Request gesendet und kein Text still
abgeschnitten. Das interne JSON-Kontextlimit ist weiterhin eine getrennte,
konfigurierbare Sicherheitsgrenze und wird hierdurch nicht aufgehoben.
## Lokale Verifikation
`tests/test_investigation_window.py` prüft unter anderem harte Grenzen vor dem
Provider, Reparatur-/Reviewversionen, exakte Seitendarstellung, begrenztes Wachstum
bis 138 Ergebnissen, strenge Aktionsvalidierung, Cache-Rekonstruktion,
Startbewertung, Wiederaufnahme und Abschluss.
Die Größenmessung an gespeicherten Bug-20-Kontexten liegt getrennt vom Paket in
`docs/test-results/token-usage/investigation-window-offline-20261020.json`.
Sie enthält keine Prompts und ist kein Nachweis gleicher LLM-Ergebnisqualität.
+57
View File
@@ -0,0 +1,57 @@
# Schlanke Startrunde mit gemeinsamer Bewertung
Neue Fälle können mit `--investigation-config config/investigation.startup-batch.toml`
gestartet werden. Diese Konfiguration aktiviert `startup_batch_review = true` bei
`lean_loop = true` und `lean_protocol = 2`. Bisherige Konfigurationen und eingefrorene
Fallzustände werden nicht migriert. Ein geänderter expliziter Konfigurationsstand
wird bei bestehenden Fällen wie bisher kontrolliert abgelehnt.
## Ablauf und Grenzen
1. Der Controller wählt die vorhandenen Hypothesen in numerischer Reihenfolge.
Jede erhält eine schlanke `investigation_startup_v1`-Anfrage für genau einen
zulässigen Rechercheauftrag. Keine Confidence-Bewertung, kein Arbeitsstand,
keine Abschluss-/Wechselentscheidung. Bereits terminale Konten werden übersprungen.
2. Jeder Auftrag wird vor Ausführung vollständig technisch geprüft. Reservierung,
Kostenbelastung, Resultat und Provenienz werden sofort dauerhaft gespeichert.
Das Ergebnis wartet auf die semantische Bewertung; es gibt noch keinen Reward.
3. Alle erfassten Ergebnisse der Startrunde sind für die folgenden Hypothesen lesbar.
Es erfolgt weder eine zusätzliche LLM-Zusammenfassung noch eine Kürzung der Payloads.
4. Nach der Startrunde bewertet `investigation_startup_review_v1` alle ausstehenden
Hypothesen gemeinsam. Fallkontext und Ergebnisse stehen einmal im Prompt;
identische Bewertungsverträge ebenfalls nur einmal. Findings, Confidence,
Gegenbelege, offene Fragen und Informationswert werden pro Hypothese geprüft.
5. Gültige Einzelbewertungen werden mit echten LLM-Quellenverweisen übernommen;
fehlerhafte Geschwister werden nicht mit übernommen. Nur diese verbleibenden
Blöcke werden erneut angefordert. Sichere bestehende Formnormalisierung greift
auch auf die einzelnen Blöcke. Unbekannte Evidenz oder unzulässige Scores bleiben
ungültig. Eine begrenzte Anzahl fehlerhafter Runden führt zu BLOCKED.
6. Nach der vollständigen Bewertung setzt der bisherige Confidence-Scheduler fort.
Die weitere schlanke Schleife, Frühabschlussprüfung und finale Diagnose bleiben
inhaltlich unverändert. Die Startrunde ist auf die vorhandene Hypothesenmenge
ausgelegt und nicht auf exakt drei Einträge fest verdrahtet.
## Persistenz und Wiederaufnahme
Die versionierte Policy und `startup` im Investigation-State halten Reihenfolge,
Fortschritt, eingefrorene Bewertungskontexte, Anfragen, akzeptierte Einzelbewertungen
und deren Bindung an die tatsächlichen LLM-Antworten fest. Die Bewertungsanfragen
werden vor Aufruf gespeichert und bei Wiederaufnahme rekonstruiert/geprüft.
Budgetsettlements sind idempotent; bei einem Abbruch nach der Abrechnung wird die
bereits gespeicherte Antwort erneut projiziert, statt erneut angefragt/vergütet.
Neue Kontexte, Anfragen und Arbeitsstände werden durch bestätigte Checkpoints als
Analyseartefakte ausgewiesen. Sie verändern nicht nachträglich den Case-Inputhash.
Ein importiertes Paket trägt die benötigten Zustände und Antwortprovenienz mit sich.
Beide Prompttypen unterstützen die bestehende verlustfreie Cache-Aufteilung.
## Erprobung
Die lokalen Tests prüfen automatische Reihenfolge, gemeinsame Evidenzsicht,
ausstehende und abschließende Budgetabrechnung, getrennte Blockvalidierung,
Korrektur nur fehlerhafter Blöcke, Import/Wiederaufnahme, Abbruch nach Settlement,
verbotene Aktionen, Wiederholungsgrenzen, terminale Konten, Cache-Aufteilung,
variable Hypothesenmengen und den anschließenden Confidence-Scheduler.
Kostenpflichtige API-Tests erfolgen durch den Nutzer. Eine wirtschaftliche Einsparung
ist erst durch den Vergleich der gesamten Startrunde inklusive Bewertung und
Korrekturen nachweisbar; kleinere Einzelprompts allein reichen dafür nicht aus.
+154
View File
@@ -0,0 +1,154 @@
# Gemeinsame Planung v2: Quellen, Teilkorrekturen und Abhängigkeiten
Neue Revisionen mit `trial run --planning-mode joint` verwenden `case_plan_v2`.
Der Kontext speichert `joint_generation.version=2`. Bereits eingefrorene v1-Kontexte
und Requests bleiben unverändert und über den bisherigen Pfad wiederaufnehmbar.
Der getrennte Modus, Investigation-Loop, Tools, Budgets und Diagnose bleiben unverändert.
`docs/architecture.md` wurde nicht geändert. Syntaxreparaturen sind ein separater Ausbau.
## Quellenklassen und ausdrückliche Testerannahmen
Die dynamischen Interpretationsverträge beschränken source_ids je Aussagekategorie
auf tatsächlich vorhandene IDs der zulässigen Quellentypen. Dies gilt im Prompt und
in der fachlichen Annahme, nicht nur im Transport. Leere Quellmengen erlauben nur
leere entsprechende Aussagearrays. Testerannahmen sind in v2 ausschließlich aus
explizit typisierten tester_assumption-Quellen zugelassen. Kommentare/Beobachtungen
werden nicht allein durch ihre Verfügbarkeit zu Annahmen. Ohne solche Quellen bleibt
tester_assumptions leer. Die LLM darf eigene Schlussfolgerungen nicht dem Tester zuschreiben.
## Explizite Voraussetzungen
Jeder v2-Wire-Vorschlag enthält premises mit kind=grounded oder unverified, knappem
Text, source_ids und interpretation_paths. Grounded benötigt mindestens einen
Verweis und darf keine ungelesenen Referenzen als gelesenen Beleg ausgeben. Referenzen
müssen im Kontext und in den eigenen deklarierten Vorschlagsreferenzen existieren.
Hypothesen bleiben spekulativ; eine Voraussetzung ist keine Bestätigung des Mechanismus.
Die vollständigen Voraussetzungen und Reviews bleiben im unveränderlichen Originalcall.
Die kanonischen Vorschläge behalten den bisherigen Vertrag und erhalten nach Prüfung
nur deterministisch aufgelöste I-IDs. Übernahme/Replays prüfen den Original-Wire-Vertrag erneut.
## Lokale Beanstandungen und begrenzte Patches
Ablehnungen speichern validation_issues mit Aussage-/Feldpfad, Fehlerkategorien und
Quell-/Schemahinweisen. Korrigierbare Stellen werden aus der tatsächlichen Antwort
ermittelt: Quellenklassen, unbekannte Quellen, Schemafehler, Entity-Provenienz,
fehlende Erwartungs-Vollständigkeit und Lookup-Ungewissheit. Unbekannte/globale
Fehler und zu viele Stellen erhalten keinen frei geratenen Patchbereich.
case_plan_statement_repair_v2 verlangt nur Patches für genau die beanstandeten Stellen.
Ein Patch ersetzt eine ganze Aussage bzw. ein nötiges oberes Feld. Null darf eine
beanstandete Arrayaussage entfernen; Löschungen werden absteigend angewandt, damit
sich Indizes nicht während der Zusammensetzung verschieben. Andere Stellen können
nicht überschrieben werden. Ein fehlender oder zusätzlicher Pfad wird abgelehnt.
Es gibt keine stille Entfernung unzulässiger Quellen oder Testerbehauptungen.
Der Request enthält beanstandete Aussagen, nötige verfügbare Quellen, die vorhandenen
Hypothesen samt Voraussetzungen und deren deklarierten Interpretationsaussagen.
Er enthält keinen weiteren vollständigen Case. Kontextkomprimierung/Konsolidierung
bleiben aktiv. Source-Call und Hash binden die unveränderte Ausgangsantwort außerhalb
der Komprimierung. Danach wird die vollständig zusammengesetzte Interpretation geprüft.
Ist keine sichere Lokalisierung möglich, bleibt der bisherige begrenzte Ersatzpfad verfügbar.
## Individuelle Hypothesenprüfung
Der Korrekturaufruf muss jede Hypothese auf direkte UND implizite Abhängigkeit von
korrigierten Aussagen prüfen, auch ohne direkten Verweis auf diese Stellen. Er meldet:
- retain: begründet unabhängig, keine neue Vorschlagsfassung.
- replace: gezielt ein Ersatzvorschlag im vollständigen v2-Vertrag.
- uncertain: keine ungeprüfte Übernahme.
Der Controller lässt retain nur zu, wenn zusätzlich ALLE deklarierten Inputs exakt
unverändert sind. Bei Löschungen wird der Inhalt am Pointer verglichen, nicht nur
dessen Fortbestehen. Geänderte direkte Grundlagen erfordern Ersatz oder weitere Prüfung.
Der Controller kann versteckte Bedeutungsabhängigkeiten nicht beweisen; die semantische
Review bleibt eine fehlbare LLM-Bewertung. Fehlende Referenzen allein gelten niemals
als Nachweis von Unabhängigkeit. Alle zusammengesetzten Vorschläge durchlaufen erneut
Quellen-, Fokus-, Diversitäts-, Count- und Registry-Prüfungen.
Auch ein fehlender oder falsch geformter Review-Block verwirft einen gültigen Interpretationspatch nicht. Seine Hypothesen werden dann nicht ungeprüft übernommen.
Ist die Interpretation gültig, aber ein Kandidat noch unklar, bleibt die Interpretation
angenommen. Explizit geprüfte unabhängige Vorschläge werden in joint_retained des
kanonischen Hypothesenkontexts festgehalten. Folgeaufrufe dürfen nur die anderen Positionen
neu bearbeiten. Position/Anzahl und erhaltene Objekte sind durch Schema-const/prefixItems
UND phasenseitige Gleichheitsprüfung gesperrt. Die volle Registry wird erst nach gültigem
Gesamtergebnis veröffentlicht. Fehlt eine auswertbare Review, wird keine Unabhängigkeit
unterstellt; dann bleibt der konservative Ersatzpfad nötig.
## Persistenz und Grenzen
Original, Patch und Reviews bleiben getrennte echte Calls mit echten Usage-Werten.
Es gibt keine künstlichen LLM-Runden oder doppelte Kostenbuchung. Die Interpretation
wird deterministisch aus Original und zulässigen Patches rekonstruiert. Beim Wiederlesen
werden Quellenhash, Requesthash, Identität, Phase, Konfiguration, erlaubte Pfade und
Zusammensetzung geprüft. Die Kette ist begrenzt; direkte Selbstreferenzen und zu tiefe
Ketten werden abgelehnt. Gespeicherte Reparaturcalls werden nach einem Abbruch wiederbenutzt.
Der bestehende Korrekturversuchszähler begrenzt weiterhin Modellversuche. Transport-Retries
bleiben getrennt. Ein formaler Validierungserfolg beweist weiterhin nicht die Wahrheit
jedes Freitextsatzes. Die Begrenzung dieser Unsicherheit ist ausdrücklich Teil der Policy.
## Offline-Prüfung
Die Tests decken Quellen-Enums, fehlende Annahmenquellen, Voraussetzungscitations,
gezielte Patches, direkte Abhängigkeiten, explizite Ersatzvorschläge, unklare Reviews,
Sperren erhaltener Vorschläge, falsch geformte Modellfelder, Abbruch/Wiederaufnahme und
Import in einen neuen Workspace ab. Ein Fall des unveränderten kuratierten Fehlerkorpus
prüft die Lokalisierung der tatsächlich beobachteten Fehler. Kein bezahlter API-Test
wurde ausgeführt; Kosten und semantische Qualität sind im nächsten Realtest zu messen.
## Dependency recovery revision 1
New joint contexts freeze `joint_generation.recovery_version = 1`. Contexts without
this marker retain the earlier projection and request behavior for replay.
Valid explicit premise references are unioned into their proposal dependency lists
on a copied projection, never by editing the saved LLM answer. Only existing readable
source IDs and exact existing interpretation statement pointers are eligible. Unknown
references and grounded unread references still fail validation. No premise is promoted
from unverified to grounded, and no claim is deleted or rewritten.
Each candidate is checked independently before freezing `joint_retained` in the
hypothesis context. Initial candidates based on an already accepted interpretation
can be retained directly; after interpretation repair, explicit dependency review is
still required. Invalid candidates remain unlocked. Duplicate candidates are not locked
against a necessary diversity correction. A followup corrects only unlocked positions;
locked proposals are enforced with schema constants and local equality checks. Final
publication still validates the full set for count, grounding, primary focus and diversity.
The joint prompt repeats the required `described_behavior.verification` value. Missing
verification is not silently filled: the scoped statement correction must provide it.
The original 2026-10-20 replies and a bounded validation context are preserved in the
curated rejection corpus. Offline regression checks hashes, reference union, sibling
preservation and rejection of invented references. No paid API request was needed.
## Structural recovery revision 2
New contexts freeze `recovery_version = 2`; revision 1 and unmarked historical
contexts keep their original request/projection behavior. This revision includes
revision 1 dependency completion and sibling preservation.
One exact misplaced wrapper is recoverable: a sole top-level `hypotheses` object
containing exactly an `interpretation` object and a `hypotheses` array. These are
copied to the two intended blocks, without changing or dropping any content.
Competing top-level interpretations (even null), extra sibling keys and malformed
wrappers are never guessed away. Both recovered blocks still undergo all existing
schema, source, dependency and semantic contract checks. The original call stays
unchanged and remains the usage/provenance source during replay and import.
During a scoped entity correction, existing eligible identity/mention citations
are restored only when BOTH entity_id and reason are unchanged. Eligible references
come from the original statement and the frozen entity's matching capture/mention
provenance. New evidence is never invented. Changed claims receive no restoration;
unknown replacement sources remain present and invalid. Requests explicitly explain
which existing citations to preserve. When no reusable hypotheses exist, the request
explicitly requires an empty reviews array instead of asking to reconstruct them.
The curated `joint-nested-envelope` corpus preserves the actual rejected replies,
their hashes and bounded context. Offline tests confirm that the initial reply passes
full interpretation and hypothesis validation after lossless wrapper recovery and
existing dependency normalization. A separate regression confirms the later scoped
patch passes interpretation validation after preserving unchanged identity evidence.
No paid API request was executed to establish these results.
+91
View File
@@ -0,0 +1,91 @@
# Gemeinsame Interpretation und Hypothesengenerierung
Diese Seite dokumentiert das erhaltene v1-Protokoll. Neue gemeinsame Revisionen verwenden
[v2 mit Quellenbeschränkungen und gezielten Abhängigkeitsprüfungen](joint-case-planning-v2.md).
## Modus und Grenze
`trial run --planning-mode joint` aktiviert für eine neue, noch nicht interpretierte
Analysis Revision einen gemeinsamen Aufruf. Standard bleibt `separate` als Vergleich.
Der Modus wird samt Hypothesenpolicy und vorherigen Generationen im unveränderlichen
Interpretationskontext gespeichert. Beim Wiederaufnehmen bleibt dieser Kontext
maßgeblich, auch ohne erneute Angabe des Schalters. Ein bereits eingefrorener
getrennter Kontext wird nicht rückwirkend umgestellt.
`case_plan_v1` ist ein neuer englischer Prompt für einmaliges Fallverständnis:
Beobachtungen, Erwartungs-/Beschreibungsprovenienz, Identitäten und Wissenslücken
werden eingeordnet; daraus werden unterschiedliche ungetestete Mechanismen abgeleitet.
Er verkettet nicht die bisherigen Systemprompts und überträgt den Fall nur einmal.
Die bestehende deterministische Kontextselektion und JSON-Konsolidierung bleiben aktiv.
Die Namensauflösung davor und die Hypothesenuntersuchung danach bleiben eigenständig.
`docs/architecture.md` wird nicht verändert; die fachlichen Phasengrenzen bleiben erhalten.
## Antwort und unabhängige Annahme
Der echte Modellaufruf liefert:
```json
{
"interpretation": {"...": "bestehender Interpretationsvertrag"},
"hypotheses": {"hypotheses": ["Vorschläge mit interpretation_paths"]}
}
```
Die vollständigen Kindverträge stehen einmal im Prompt. Der Transportvertrag erlaubt
unabhängig fehlerhafte/fehlende Kindblöcke. Ein gültiger Interpretationsblock geht deshalb
nicht durch eine ungültige Hypothese verloren. Jeder Block wird separat mit dem bisherigen
Schema und den fachlichen Provenienz-/Identitäts-/Diversitätsregeln geprüft.
Hypothesen verwenden zunächst exakte JSON-Pointer zu ganzen Aussagen der Interpretation,
z.B. `/interpretation/observed_behavior/0`. Erst nach Annahme der Interpretation bildet
der Controller diese auf die deterministischen I-IDs des kanonischen Hypothesenkontexts ab.
Unbekannte Pointer werden abgelehnt. Das Modell erfindet keine internen I-IDs.
Die Interpretation wird mit dem bisherigen Complete-Checkpoint gespeichert. Danach kann
der Hypothesenbuilder ohne weiteren API-Aufruf den zweiten Block übernehmen und die
bestehende Registry mit gleichen Startbudgets erzeugen. Beide fachlichen Artefakte
referenzieren denselben echten Call. Es entstehen keine künstlichen LLM-Runden; Usage
ist aus den `llm/operations/*/round-*.json`-Datensätzen einmalig zu summieren, nicht aus
den wiederholten Metadaten der fachlichen Artefakte.
## Fehler und Wiederaufnahme
- Gemeinsame lokale JSON-Korrektur und begrenztes Capture greifen weiterhin im Gateway.
- Jeder Kindblock kann zusätzlich unabhängig durch dieselben konservativen
Objekt-/Array-Normalisierungsregeln geprüft werden. Der unveränderte Originalcall
bleibt erhalten; die Projektion wird beim Lesen deterministisch erneut berechnet.
- Gültige Interpretation, ungültige Hypothesen: Interpretation bleibt unverändert;
nur der Hypothesenblock wird über den bestehenden, begrenzten Korrekturpfad ersetzt.
Der Folgeprompt enthält die akzeptierte Interpretation als Kontext, verlangt aber
ausschließlich Hypothesen. Er erzeugt keine zweite Interpretation.
- Ungültige Interpretation: `case_plan_interpretation_repair_v1` verlangt ausschließlich
eine korrigierte Interpretation, mit deren Quellenkontext und konkretem Fehlerhinweis.
Die Hypothesen des ursprünglichen Calls werden vorsichtshalber verworfen, weil ihre
Abhängigkeit von der fehlerhaften Interpretation nicht sicher auszuschließen ist.
Nach Annahme erzeugt der normale Hypothesenpfad neue Vorschläge.
- Nicht parsebare oder unvollständige Gesamtausgaben bleiben kontrolliert abgelehnt.
Es werden keine fehlenden Fakten oder Endklammern ergänzt.
- Die bestehenden Retry-, Failover-, Fall-Locks, erwarteten Generationen und
Maximalversuche bleiben verbindlich. Nach Abbruch zwischen den zwei fachlichen
Complete-Checkpoints wird der gespeicherte Call verwendet, nicht neu generiert.
- Replay prüft Originalrequest, Hash, Identität, Phase, akzeptierte Interpretation und
die exakte Pointerprojektion. Eine nachträglich geänderte Interpretation kann keine
alten Hypothesen legitimieren.
`--stop-after interpretation` bleibt ein fachlicher Haltepunkt: Der gemeinsame Call
hat Hypothesen bereits geliefert, veröffentlicht sie aber erst beim späteren Builder-
Dispatch nach eigener Prüfung. Die Dispatchanzahl muss dadurch nicht um eins sinken;
die Zahl tatsächlich kostenpflichtiger Aufrufe sinkt im gültigen Fall um eins.
## Messung und zurückgestellte Arbeit
Offline mit dem gespeicherten BUG-20-Kontext des shared-recovery-Laufs:
37.999 Nachrichtzeichen für den neuen gemeinsamen Prompt gegenüber 41.419 für die
Interpretation plus 42.287 für die erfolgreiche Hypothesengenerierung (83.706 zusammen).
Das ist eine Zeichenmessung ohne neue API-Anfrage, kein Nachweis für eine bestimmte
Token-/Kostenersparnis oder unveränderte semantische Qualität. Der Realtest muss
Gesamteingabe, sichtbare Ausgabe, Denktokens, Korrekturen, Laufzeit und Qualität vergleichen.
Nach Umsetzung und Erprobung dieses Modus bleiben ausdrücklich zurückgestellt:
Untersuchung der gespeicherten beschädigten Originalantworten auf sichere Reparierbarkeit;
Vereinfachung ausführlicher Untersuchungsstarts und deterministische Ableitung unnötiger
Zustandsangaben; weitere gezielte Senkung von Denk- und Korrekturkosten.
+158
View File
@@ -0,0 +1,158 @@
# Linux-Betrieb
API und Analyseworker laufen als getrennte systemd-Dienste. Ein Auftragseingang
weckt keinen neuen Prozess: Der dauerhaft laufende Worker übernimmt Inbox-Aufträge.
Die Weboberfläche ist eine alternative Bedienung desselben Arbeitsablaufs.
Die Installation startet keine Dienste und führt keine Modellanfrage aus.
## Voraussetzungen und Verzeichnisse
Linux mit systemd, Python 3.11 oder neuer inklusive venv/pip, Git und Nginx.
Diese Programme über die Paketverwaltung des Servers installieren. Die aktuelle
Projektvorlage ist für WoW/Vcore eingerichtet; sie ist kein allgemeiner Adapter.
| Pfad | Zweck und Rechte |
| --- | --- |
| `/opt/viano-bug-analysis` | Root-eigener Checkout und virtuelle Python-Umgebung; Dienst darf nur lesen |
| `/etc/viano-bug-analysis` | Root-eigene Konfiguration, Gruppe `buganalysis`, Verzeichnis 0750, Dateien 0640 |
| `/etc/viano-bug-analysis/*.env` | Zugangsdaten, root:buganalysis 0600; systemd liest sie vor dem Benutzerwechsel |
| `/etc/viano-bug-analysis/auth/users.sqlite3` | Root-verwaltete Nutzer, Gruppe `buganalysis` darf lesen |
| `/var/lib/viano-bug-analysis` | Dienst-eigene Fallakten, Laufzeitdaten und Websessions |
| `/srv/viano-bug-analysis/viano-core` | Root-eigener Source-Checkout, Dienst hat Leserechte |
Die env-Dateien sind durch Betriebssystemrechte geschützte Klartextdateien, kein
verschlüsselter Tresor. Sie gehören nicht ins Repository oder in Diagnosepakete.
API und Worker erhalten unterschiedliche Dateien: Nur der Worker erhält Cloud-
und DB-Zugangsdaten. Die Diensthärtung und EnvironmentFile-Nutzung folgen der
[systemd-Dokumentation](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html).
Die [Webverwaltung für Integrationsschlüssel](integration-keys.md) ergänzt die
env-basierte Maschinenanmeldung. Ihre SQLite und separate Schlüsseldatei müssen
ebenfalls gesichert werden; beide liegen standardmäßig unter der Fallablage.
## Installation
Den vertrauenswürdigen BugAnalysis-Checkout als root unter
`/opt/viano-bug-analysis` ablegen. Code und Unterverzeichnisse dürfen nicht für
andere Benutzer schreibbar sein. Dann:
```sh
cd /opt/viano-bug-analysis
python3 deploy/install.py --dry-run
sudo python3 deploy/install.py
```
Der Installer legt den Dienstbenutzer `buganalysis`, Konfigurationen, venv und
Units an. Er installiert die Python-Abhängigkeiten und lädt systemd neu.
Bestehende Zielkonfigurationen und Units werden erhalten. Updates an bereits
installierten Units daher bewusst mit den versionierten Vorlagen abgleichen.
Bei Installationsfehlern bleiben vorhandene Dateien erhalten; erneutes Ausführen
setzt die Einrichtung fort. Der Installer verändert keine bestehende Datenbank.
## Einmalige Konfiguration
Mit `sudoedit` die Dateien unter `/etc/viano-bug-analysis` bearbeiten:
1. `project.toml`: DB-Adresse/Port, Datenbank und nur lesenden Benutzer einstellen,
tatsächliche Snapshotkennung und vollständigen Source-Commit eintragen.
Die ausgelieferten Null-Commit- und `CONFIGURE_ME`-Werte sind Platzhalter.
2. Den Vcore-Checkout als root unter `/srv/viano-bug-analysis/viano-core` anlegen;
der konfigurierte Commit muss lokal vorhanden und für `buganalysis` lesbar sein.
Der Dienst lädt keine Commits nach. `gitconfig` vertraut ausschließlich diesem
konkreten Root-Checkout, nicht beliebigen Repositories.
3. `worker.env`: `GEMINI_API_KEY=...` und `VIANO_DB_PASSWORD=...` eintragen.
Keine `export`-Anweisungen verwenden. Für Sonderzeichen gelten die
EnvironmentFile-Quotingregeln von systemd. Werte nicht als Shellargumente übergeben.
4. `api.env`: `VBA_INTAKE_TOKEN=...` für den Erfassungsworker setzen
(32–256 Zeichen aus Buchstaben, Ziffern, `_` und `-`). Dies ist ein separater
Integrationsschlüssel, kein Gemini-Key. Wird keine externe API-Integration
benötigt, den zugehörigen `[[clients]]`-Block aus `api.toml` entfernen.
5. `llm.toml`: gewünschtes Modell, Anbieter und Cacheeinstellungen kontrollieren.
Investigation-, Budget- und Telemetrie-Dateien sind separat konfigurierbar.
Die DB-Verbindung benötigt einen Benutzer mit ausschließlich passenden
SELECT-Rechten auf die freigegebenen World-Tabellen. Diese Rechte legt der
DB-Administrator an; BugAnalysis vergibt keine Grants. Der Readiness-Test belegt
Lesbarkeit, nicht die Abwesenheit zusätzlicher Schreibrechte. Für entfernte DBs
einen geschützten Netzwerkweg verwenden: Der aktuelle DB-Provider konfiguriert
selbst kein TLS. Zugang zu Produktionsdaten ist für die lokale Entwicklung
weiterhin nicht erforderlich.
Webnutzer anlegen; das Passwort wird verdeckt abgefragt:
```sh
sudo /opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.api create_user NAME --config /etc/viano-bug-analysis/api.toml --service-group buganalysis
```
Nutzerverwaltung bleibt root vorbehalten. Siehe [Nutzerverwaltung](user-accounts.md).
Keine Nutzer werden automatisch angelegt. Nach der Installation besitzen die
env-Dateien Modus 0600; diese Rechte nach manuellen Änderungen erhalten.
## Kostenfreie Bereitschaftsprüfung
Die Prüfung unter der tatsächlichen Dienstidentität samt env-Datei ausführen:
```sh
sudo systemd-run --wait --pipe --collect --property=User=buganalysis --property=Group=buganalysis --property=EnvironmentFile=/etc/viano-bug-analysis/api.env /opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.deployment check --role api --config /etc/viano-bug-analysis/api.toml
sudo systemd-run --wait --pipe --collect --property=User=buganalysis --property=Group=buganalysis --property=EnvironmentFile=/etc/viano-bug-analysis/worker.env --setenv=GIT_CONFIG_GLOBAL=/etc/viano-bug-analysis/gitconfig /opt/viano-bug-analysis/.venv/bin/python -m viano_bug_analysis.deployment check --role worker --config /etc/viano-bug-analysis/worker.toml
```
Erwartet: `READY`, `model_requests: 0`. Geprüft werden Konfiguration,
Zugangsdaten-Präsenz, Speicherreserve, Schreibbarkeit der Laufzeitablage,
Webnutzer/Sessions beziehungsweise Git-Objekte und die freigegebenen DB-Schemata.
Cloud-Key-Gültigkeit und Modellverfügbarkeit sind damit noch nicht getestet.
`--offline` überspringt Git-/DB-Zugriffe und meldet nur `CONFIG_READY`.
Fehlerausgaben enthalten kontrollierte Fehlercodes statt Zugangsdaten.
## HTTPS und Start
Die API bleibt auf `127.0.0.1:8080`. `nginx.conf.example` enthält eine
Reverse-Proxy-Vorlage: Domain und Zertifikatpfade anpassen, gültiges Zertifikat
bereitstellen und als Nginx-Site installieren. Die Vorlage übernimmt die
Forwarded-Header kontrolliert; die API vertraut ihnen ausschließlich vom
Loopback-Proxy. So verwenden Anmeldung und Cookies das öffentliche HTTPS-Schema.
Die Proxyparameter sind in der
[Nginx-Dokumentation](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) beschrieben.
Vor dem ersten Start auf dem Linux-Zielsystem prüfen:
```sh
sudo systemd-analyze verify /etc/systemd/system/viano-bug-analysis-api.service /etc/systemd/system/viano-bug-analysis-worker.service
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl enable --now viano-bug-analysis-api.service viano-bug-analysis-worker.service
sudo systemctl status viano-bug-analysis-api.service viano-bug-analysis-worker.service
```
Sobald der Worker aktiviert ist, kann er vorhandene Aufträge verarbeiten und
kostenpflichtige Modellaufrufe senden. Erst mit leerem Eingang starten, dann einen
kontrollierten Feldtest über die Übergabe-API oder Weboberfläche übergeben.
Anmeldung, Auftragsannahme, Fortschritt, menschliche Testanfrage und Outbox dabei
gemeinsam prüfen. Die automatisierte Einrichtung ersetzt diesen Feldtest nicht.
## Laufender Betrieb
Die Dienste starten beim Booten und nach unerwartetem Prozessende erneut.
Fehlende Startvoraussetzungen werden nach zehn Sekunden erneut geprüft.
Externe DB und Sourcebereitstellung werden nicht von diesen Units installiert.
API und Worker können unabhängig voneinander laufen.
```sh
sudo journalctl -u viano-bug-analysis-api -u viano-bug-analysis-worker -f
sudo systemctl stop viano-bug-analysis-worker
```
Der Worker beendet beim Stoppen den aktuellen Dispatch kontrolliert; seine Unit
setzt dafür kein hartes Stop-Zeitlimit. Ein Stop kann daher während einer
langlaufenden Anfrage dauern. Für Code-/Profiländerungen den Worker zuerst
anhalten. Profilbindungen laufender Fälle nicht beiläufig ändern: Unterschiede
werden als Aufmerksamkeit erfordernder Zustand behandelt, Budgets nicht erneuert.
Codeänderungen danach in die root-eigene venv installieren und Dienste neu starten.
Backups umfassen die Fallablage, Konfiguration einschließlich geschützter Secrets
und Nutzer-SQLite. Für eine einfache konsistente Dateisicherung beide Dienste
anhalten. Sessions sind keine dauerhaft nötigen Fachdaten. Produktive Fallaufbewahrung
separat festlegen; das 20-GB-Entwicklungslimit ist kein Produktionslimit.
Unter Windows bleibt die vorhandene PowerShell-Umgebungsvariable für Entwicklung
unterstützt. Dort installiert dieser Installer keine Dienste; `--dry-run` ist möglich.
+163
View File
@@ -0,0 +1,163 @@
# Projekt und Recherchezugriffe konfigurieren
Die Projektkonfiguration wird über Dateien verwaltet, nicht über die Webseite.
Sie legt fest, welche Werkzeuge ein Auftrag verwenden darf. Ein aufrufendes
Programm kann weder Repository noch DB-Zugänge oder Budgets mit einem Auftrag
überschreiben. Aktuell ist das Profil `wow/vcore` mit dem Importadapter `vcore`
implementiert; andere Projekttypen erfordern entsprechende Adapter und Profile.
## Zuordnung in api.toml
Ein Projektelement ordnet eine feste Projekt-ID einem Profil und dessen
Konfigurationsdateien zu. Relative Pfade beziehen sich auf die API-Konfigurationsdatei.
Der Erfassungsworker muss genau dieselbe Projekt-/Profilzuordnung senden und
sein Integrationsschlüssel muss für das Projekt freigegeben sein.
```toml
[[projects]]
id = "viano-core"
type = "wow"
profile = "vcore"
adapter = "vcore"
planning_mode = "joint"
[projects.settings]
project_config = "project.toml"
llm_config = "llm.toml"
investigation_config = "investigation.bounded.toml"
budget_config = "budget.human-tests.toml"
```
Die Linux-Vorlagen stehen unter `deploy/linux/`; der Installer legt die
Konfiguration unter `/etc/viano-bug-analysis` an. Er überschreibt bestehende
Dateien nicht. Die ausführliche Vcore-Projektvorlage steht unter
`config/project.example.toml`, die Relationsregeln unter
`config/project-relations.vcore.toml`.
## Source und Datenbank in project.toml
```toml
relations_file = "project-relations.vcore.toml"
[project]
type = "wow"
profile = "vcore"
[source]
path = "/srv/viano-bug-analysis/viano-core"
url = "https://gitea.viano-software.de/Nico/Viano-Core"
commit = "VOLLSTAENDIGEN_40_STELLIGEN_COMMIT_EINTRAGEN"
[database]
host = "127.0.0.1"
port = 3306
database = "cata_world"
user = "viano_reader"
password_env = "VIANO_DB_PASSWORD"
snapshot_id = "KENNUNG_DER_TATSAECHLICHEN_DATENGRUNDLAGE"
tables = ["creature_template", "creature"]
```
Das Beispiel zeigt nur den Aufbau und enthält absichtlich ungültige Platzhalter.
Die beiden Tabellen sind keine vollständige Vcore-Freigabeliste. Für das echte
Profil die vollständige Vorlage einschließlich Limits, Enrichment und
Analysewerkzeugregeln verwenden und passend prüfen.
Der Source-Checkout muss lokal vorhanden sein und den konfigurierten Commit
enthalten. Die URL allein klont oder aktualisiert kein Repository. Der Worker
liest Git-Objekte dieses festen Stands und benötigt keine Schreibrechte auf den
Checkout. Die Linux-Vorlage enthält eine gezielte Git-Vertrauenskonfiguration
für den root-eigenen Checkout. Neue Source-Stände bewusst bereitstellen und
deren vollständigen Commit konfigurieren.
Der DB-Administrator legt einen Benutzer mit ausschließlich passenden SELECT-
Rechten an. Zusätzlich begrenzt `tables` die zugänglichen Tabellen. Diese
Freigabeliste ersetzt keine serverseitigen Rechte. Account- oder Charakterdaten
gehören nicht zur standardmäßigen World-Recherche. Für entfernte DBs einen
geschützten Netzwerkweg nutzen; der aktuelle Provider konfiguriert selbst kein TLS.
Das Passwort steht entweder in der durch `password_env` benannten
Umgebungsvariable oder einer separaten geschützten Datei über `password_file`.
Nur eine dieser Varianten setzen. Unter Linux lädt der Worker beispielsweise
`VIANO_DB_PASSWORD` aus seiner root-geschützten `worker.env`.
Passwörter nicht in Fallakten, LLM-Prompts oder Versionsverwaltung ablegen.
Die LLM bekommt Werkzeugergebnisse statt Zugangsdaten.
## Mehrere Datenbanken pro Projekt
Eine Projektverbindung kann mehrere Datenbanken derselben MariaDB-Instanz
ansprechen. Host, Port, DB-Benutzer und Passwortbezug werden gemeinsam verwendet.
`database` benennt die Standarddatenbank; unqualifizierte Tabellennamen beziehen
sich ausschließlich auf diese. Zusätzliche Datenbanken werden ausdrücklich
freigegeben, etwa für Vcore:
```toml
# Im vorhandenen [database]-Abschnitt: database = "cata_world", user = "buganalysis"
[database.additional_databases]
cata_hotfixes = ["*"]
cata_locale = ["*"]
```
Den neuen Abschnitt beispielsweise am Ende der vorhandenen Datei ergänzen.
`[database]` nicht ein zweites Mal anlegen und die übrigen Projektregeln behalten.
Die vollständige alternative Vorlage steht unter
`config/project.vcore-multidb.example.toml`.
`["*"]` gibt ausdrücklich alle metadaten-sichtbaren Tabellen der genannten DB
frei. Alternativ eine nichtleere Liste konkreter Tabellen verwenden. Auch die
Standarddatenbank unterstützt `tables = ["*"]`; die bisherige konkrete Liste
bleibt genauso gültig. Ein leeres Array ist keine pauschale Freigabe.
Die tatsächlich gewährten DB-Rechte bleiben zusätzlich maßgeblich.
Nicht aufgeführte Datenbanken sind selbst bei weitergehenden DB-Grants gesperrt.
In diesem Beispiel sind `cata_auth`, `cata_characters` und
`cata_locale_reference` nicht für Recherche freigegeben.
Werkzeuge verwenden in zusätzlichen DBs qualifizierte Tabellennamen wie
`cata_locale.NAME_DER_TABELLE`. `database.tables` entdeckt die zugänglichen Namen
über alle freigegebenen DBs; Suchtext und Seitengrenzen gelten weiterhin.
Gleichnamige Tabellen werden nicht verwechselt. Die Datenbank steht in der
Belegherkunft und bei Mehrdatenbank-Ergebnissen auch in den Ergebniseinträgen.
Die LLM erhält keine Serveradresse, Anmeldenamen oder Passwörter.
Namenskataloge, Enrichment-Regeln und Beziehungsprofile können ebenfalls
qualifizierte Tabellen referenzieren. Die Beziehungsanalyse führt die
konfigurierten Schritte innerhalb einer gemeinsamen lesenden Transaktion aus;
sie prüft die Transaktionsfähigkeit der beteiligten Tabellen. Dieses Format
konfiguriert keine unterschiedlichen DB-Server oder getrennten Zugangsdaten
innerhalb derselben Projektverbindung.
Die Bereitschaftsprüfung prüft alle freigegebenen Tabellen einschließlich
Wildcard-Inventaren. Eine nicht erreichbare oder nicht lesbare zusätzliche DB
wird nicht stillschweigend ausgelassen. Bestehende Einzel-DB-Konfigurationen
benötigen keine Änderung. Bei aktiven Fallakten trotzdem die bestehende
Konfigurationsbindung beachten; ein Update setzt keine Budgets zurück.
## Weitere Konfigurationen
| Datei | Zuständigkeit |
| --- | --- |
| api.toml | HTTP-Bindung, Workspace, Projekte, Nutzerdatei und optionale env-basierte Maschinenclients |
| worker.toml | Verweis auf api.toml, Polling, Wiederholungsabstände, Speicherreserve und Telemetrie |
| llm.toml | Anbieter, Modell, Schlüssel-Environment, Timeouts, Ausgabe-/Denkeinstellungen und Cache |
| investigation.bounded.toml | Untersuchungsmodus und begrenztes Kontextfenster |
| budget.human-tests.toml | Fachliche Budgetregeln und menschliche Testanfragen |
| telemetry.toml | Heartbeats und lokale Betriebsbeobachtung |
| project-relations.vcore.toml | Projektspezifische Beziehungen für Recherchewerkzeuge |
Die versionierte Modellvorlage `config/llm.gemini-cache.example.toml` verwendet
`GEMINI_API_KEY`. Das ist unabhängig vom Integrationsschlüssel für externe
Auftragsübergaben. Die API erhält `api.env`; der Analyseworker erhält
`worker.env` mit Cloud- und DB-Zugangsdaten.
## Prüfen und ändern
Der Befehl `python -m viano_bug_analysis.deployment check` prüft mit Rolle und
Konfigurationspfad die Betriebsbereitschaft ohne Modellanfrage. Die
[Linux-Anleitung](linux-deployment.md) zeigt die vollständigen Befehle unter der
tatsächlichen Dienstidentität. Die Prüfung umfasst Git-Objekte und freigegebene
DB-Schemata; die Gültigkeit des Cloud-Schlüssels wird nicht durch einen bezahlten
Modellaufruf getestet. `--offline` prüft keine Git-/DB-Verbindung.
Vor Code- oder Profiländerungen den Worker kontrolliert anhalten und die
Auswirkungen auf laufende Akten prüfen. Der Worker bindet Fälle an ihren
Konfigurationsstand. Eine Änderung ist kein Weg zum Zurücksetzen von Budgets;
abweichende Bindungen können eine Betreiberprüfung erfordern. Bestehende Dateien
und Zugangsdaten vor Änderungen sichern.
+1 -1
View File
@@ -36,7 +36,7 @@ und `arguments` gemäß `project-query-v1.schema.json`.
| `source.registration` | Symbolvorkommen als Ausgangspunkt einer Registrierungsprüfung |
| `source.schema` | Literale Suche ausschließlich in SQL-Dateien |
| `source.read` | Begrenzten Zeilenbereich einer bekannten Datei lesen |
| `database.tables` | Namen in der konfigurierten Tabellen-Allowlist finden |
| `database.tables` | Namen in den konfigurierten Datenbanken und Tabellenfreigaben finden |
| `database.schema` | Tatsächliche Spalten, Typen, Nullbarkeit und Schlüssel lesen |
| `database.rows` | Spalten auswählen, explizite Filter und begrenzte Seite lesen |
| `database.count` | Vollständige Trefferzahl für dieselben Filter bestimmen |
+65
View File
@@ -0,0 +1,65 @@
# Begrenzte Diagnose und ehrliche Unsicherheit
Neue Abschlussanfragen verwenden `diagnosis_v8` beziehungsweise
`diagnosis_early_v8`; neue Übergaben `change_request_v9`.
Die Diagnose trennt in den vorhandenen Feldern beobachtete Ergebnisse von
kausalen Ableitungen. `remaining_uncertainty` enthält offene Annahmen,
`decision_basis.scope_limits` den tatsächlich untersuchten Geltungsbereich.
Ein Quellenverweis belegt nicht automatisch alle Aussagen über die Quelle.
Fehlende Fundstellen in einem Ausschnitt beweisen keine globale Nichtausführung;
eine vorhandene Methode beweist umgekehrt keinen tatsächlich erfolgten Aufruf.
Die Anleitung gilt projektunabhängig und enthält keine bekannten Buglösungen.
Ein plausibler, evidenzgestützter und begrenzter Änderungsversuch bleibt mit
Restunsicherheit zulässig. Weder ein lückenloser Negativbeweis noch der Ausschluss
aller alternativen Ausführungspfade wird gefordert. Die bestehenden Prüfungen
für unbekannte Belege, fehlende Gegenprüfung und ausdrücklich ungelöste materielle
Widersprüche bleiben erhalten. Es gibt keinen zusätzlichen LLM-Aufruf und keine
neue pauschale Abschlusssperre. Das Programm erkennt nicht deterministisch alle
inhaltlichen Widersprüche in Freitext; dies bleibt Aufgabe der Diagnose-LLM.
Die Auftragserstellung soll offene Annahmen nicht zu gesicherten Fakten erklären.
Ihre bestehenden `validation_requirements` sollen beobachtbare Ergebnisse nennen,
die die Erklärung nach einer Änderung stützen oder infrage stellen, und relevantes
unverändertes Verhalten berücksichtigen. Ein erfolgreicher Build allein bestätigt
keine Verhaltensursache. Die externe Pipeline implementiert und testet; BugAnalysis
wartet darauf nicht und erzwingt keine Rückgabe.
## Verlustfreie Übergabe der Einschränkungen
Neue Übergabekontexte speichern `uncertainty_handoff_version=1`. Der Controller
kopiert `remaining_uncertainty` und `decision_basis.scope_limits` aus der akzeptierten
Diagnose unverändert nach `change_request.json.diagnostic_caveats`. Dieser Block
steht auch in der menschenlesbaren Coding-Zusammenfassung. Er wird nicht von der
Auftrags-LLM erzeugt und verändert weder Assignment noch Status oder Human-Auftrag.
Es werden keine zusätzlichen LLM-Ausgabefelder verlangt. Bestehende Dokumente ohne
den Kontextmarker bleiben bytegleich rekonstruierbar; abgeschlossene Artefakte
werden nicht nachträglich ergänzt. Die Replay-Prüfung vergleicht neue Dokumente
weiterhin vollständig mit ihrer deterministisch rekonstruierten Fassung.
## Abgrenzung und Nachweis
Server-/Erfassungs-/Repository-Versionserfassung bleibt ein gesonderter Ausbau.
Die Investigation, deren Budgets, Zeichenlimits und der Lifecycle ändern sich nicht.
`docs/architecture.md` bleibt unverändert. Alle Prüfungen erfolgen lokal mit
Fixture-Adaptern; die tatsächliche Wirkung der Promptänderung muss ein späterer
LLM-Test zeigen. Die bereits abgeschlossene Bug17-Akte g228 bleibt unverändert
und besteht weiterhin die vollständige Ausgabevalidierung ohne Modellaufruf.
Die Abschlussphasen-Testvorbereitung verwendet jetzt die begrenzte Startbewertung
mit einer Untersuchungsiteration pro Hypothese. Die frühere unbegrenzte Vorbereitung
scheiterte bereits im unveränderten HEAD am 20.000-Zeichen-Limit, bevor eine finale
Diagnose aufgerufen wurde. Das Produktionslimit wird für Tests nicht gelockert.
Validierung am 20.10.2026: 97 Tests im abschließenden Regressionslauf bestanden
(317,63 Sekunden), dazu der anschließend separat geprüfte zusätzliche Test gegen
modellseitiges Setzen des Controller-Blocks. Insgesamt 98 unterschiedliche lokale
Tests bestanden. Die acht gezielten Tests in `tests/test_qualified_handoff.py`
bestanden ebenfalls vollständig (sieben davon im Regressionslauf enthalten).
Geprüft wurden unveränderte Modell-Ausgabeverträge, normale und frühe Diagnose,
weiterhin zulässige Restunsicherheit, verlustfreie Übernahme ohne gemeinsame
mutierbare Listen, alte Kontexte ohne den neuen Block, ready/template/none,
Budgeterhaltung, Wiederaufnahme, Korrekturversuche und portable Ausgabevalidierung.
`git diff --check` ohne Befund. Keine kostenpflichtigen API-Aufrufe.
+75
View File
@@ -0,0 +1,75 @@
# Begrenzte Source-Lesefenster
`project.query` mit `kind: source.read` liest weiterhin ausschließlich aus dem
konfigurierten Git-Snapshot. Übersteigt ein ansonsten gültiger inklusiver
Zeilenbereich `ProjectLimits.max_lines` (Default 80), wird er ab der angeforderten
Startzeile begrenzt ausgeführt. Die ursprüngliche Anfrage wird nicht verändert.
Die Grenze ist konfigurierbar und keine Grenze des Case-Paketformats.
Beispiel: 115–215 fordert 101 Zeilen an. Geliefert werden höchstens 115–194.
Das Capture enthält zusätzlich:
- `requested_line_count`, `line_limit`, `line_limit_exceeded`
- `returned_line_count` sowie angeforderten und gelieferten Start-/Endbereich
- `requested_range_complete`, `next_start_line` und einen kurzen `read_notice`
`truncated: true` und `requested_range_complete: false` bedeuten, dass noch
existierende Zeilen des angeforderten Bereichs fehlen. `next_start_line` nennt
dann die nächste lesbare Fortsetzungszeile. Zum Weiterlesen ursprünglichen Endwert
beibehalten; keine Zeilen überspringen oder erneut als neue Erkenntnis werten.
`eof` bezieht sich auf den tatsächlich gelieferten Ausschnitt, nicht auf den
ursprünglich gewünschten Endwert.
Erreicht das begrenzte Fenster bereits das Dateiende, ist keine weitere Ausgabe
nötig: `eof: true`, `truncated: false`, `next_start_line: null`. Dies gilt auch bei
einem Start hinter dem Dateiende mit leerem Ergebnis; das bisherige kontrollierte
EOF-Verhalten bleibt erhalten. Vollständigkeit bezieht sich ausschließlich auf
den angefragten Zeilenbereich bis EOF, nicht auf andere Dateien oder die gesamte
Implementierung. Bestehende `text_truncated`-Angaben einzelner langer Codezeilen
bleiben unabhängig davon erhalten.
Originalquery und Ergebnis werden gemeinsam unveränderlich im Capture gesichert.
Das Ergebnisschema erlaubt die zusätzlichen Metadaten optional, damit historische
Captures weiterhin gültig bleiben. Die begrenzte Investigation-Darstellung erhält
diese Bereichs-/Fortsetzungsdaten auch außerhalb paginierter JSON-Fragmente.
Normale Anfragen innerhalb der Grenze behalten ihre bisherige Ergebnisform.
Abgelehnt bleiben insbesondere nicht ganzzahlige oder nicht positive Startwerte,
umgekehrte Bereiche, unsichere Pfade und nicht vorhandene Dateien. Die anderen
Tooloperationen und deren Grenzen werden hierdurch nicht gelockert. Es findet
keine automatische Folgeabfrage statt und kein Inhalt wird erfunden.
Lokale Tests verwenden beide kuratierten Bug-17-Antworten mit 101 und 91 Zeilen,
prüfen exakt die zurückgelieferten Zeilen und lückenlose Fortsetzung, konfigurierbare
Grenzen, EOF, sichere Ablehnung, Capture-Persistenz, kompakte Scope-Angaben und drei
Controller-Startabfragen ohne Korrekturversuch. Keine bezahlten LLM-Aufrufe.
## Prüfergebnis am 20.10.2026
16 neue Tests bestanden. Gemeinsame Prüfung mit Projekt-Recherche, Source-Kontext,
begrenzter Investigation v1/v2 und Startup: 126 bestanden, 1 übersprungen,
5 fehlgeschlagen. Alle fünf Fehler wurden zusätzlich gegen den unveränderten
Commit `ab31924` reproduziert: ältere unbeschränkte Prompt-Tests treffen die
bereits bestehende 20.000-Zeichen-Sicherung statt ihres erwarteten Folgeschritts.
Betroffen sind `test_model_loop_uses_project_tools_and_compact_previous_result`
(Varianten True, unknown, upgrade), `test_started_project_loop_keeps_legacy_prompt_protocol`
und `test_budgeted_evidence_and_portable_hybrid_resume`. Keine dieser bestehenden
Grenzen wurde für diese Änderung gelockert. `git diff --check` ohne Befund.
## Explizite Wiederaufnahme nach technischer Reparatur
`CheckpointStore.advance(..., manual_retry=True)` erlaubt die vom Betreiber
bewusst angeforderte sofortige Wiederaufnahme eines mit `INVALID_LLM_RESPONSES`
blockierten Falls ausschließlich in dessen gespeicherten Fortsetzungszustand.
Ohne dieses ausdrückliche Argument gilt weiterhin `retry_not_before`.
Die manuelle Wiederaufnahme darf keine Artefakte oder zusätzlichen Dateien
ändern. Sie setzt weder Budget noch fachliche/technische Untersuchungsstände
zurück. `manual_retry: true` wird im neuen unveränderlichen Lifecycle-Checkpoint
protokolliert. Andere Blockierungsgründe, insbesondere `AWAITING_TEST_FEEDBACK`,
werden dadurch nicht entsperrt. Idempotenz und Generationserwartung bleiben aktiv.
65 lokale Tests für Checkpoints, Queue und asynchrone Tests bestanden. Bug17
wurde auf ausdrücklichen Nutzerwunsch von Generation 47 auf 48 fortgesetzt;
Artefakthashes und Budgeterhalt sind im separaten Wiederaufnahmebericht gesichert.
Keine kostenpflichtige LLM-Ausführung durch den Entwicklungsagenten.
@@ -0,0 +1,56 @@
# Lokale Prüfung des dauerhaften Analyseworkers – 2026-10-21
Ausgangspunkt: `27feda6` (Übergabe-API). Keine echten Provideranfragen, keine
kostenpflichtigen LLM-Tests und kein Start gegen produktive Aufträge.
## Umfang und Ergebnis
252 Tests bestanden, fünf bestehende Trialfälle und ein bestehender
Telemetrie-Integrationstest separat ausgeklammert.
Geprüft wurden Worker, API-Intake, Vcore-Import, Checkpoints, Queue, Casebuilder,
Paketfabrik und Paketwriter sowie die übrigen 15 Trialtests und 27 Telemetrietests.
Die gezielten Diensttests umfassen:
- Übernahme einer API-Einlieferung und tatsächlichen Casebau ohne manuellen Trial;
- Interpretation mit lokalem Fixture-Provider und Wiederanlauf aus einem neuen Workerobjekt;
- Wiedereröffnung einer Akte: alte Interpretation bleibt erhalten, neue Revision wird neu interpretiert;
- Projekttrennung, Fortschritt anderer Fälle trotz fehlerhaftem Fall;
- persistente Wartezeiten, unveränderte LLM-Versuchskennung;
- Bewahrung menschlicher/technischer BLOCKED-Sperren und ausgeschöpfter Modellversuche;
- explizit zugelassene technische Wiederaufnahme;
- Dienst- und Fall-Leases, geordneten Stopp, Konfigurationswechsel und Speicherreserve;
- Attention-Markierung der tatsächlich neuesten Generation bei Exception nach einem Checkpoint;
- keine Wiederveröffentlichung bei unverändertem abgeschlossenem Scheduler-Ergebnis;
- CLI-Prüfung/Status und leeren Einmalbetrieb ohne API-Clienttoken.
Die vorhandenen fünf Trialfehler sind `INVESTIGATION_PROMPT_LIMIT` in alten
synthetischen Untersuchungsfixtures. Gegenprobe: Der vollständige unveränderte
`trial.py`-Dispatcher aus `27feda6` wurde ausschließlich im Arbeitsspeicher geladen;
dieselben fünf Tests scheiterten, 15 bestanden. Keine Quelldatei wurde dafür
zurückgesetzt. Die 20.000-Zeichen-Grenze und die Produktionsprompts wurden nicht
verändert, um diese alten Tests passend zu machen.
Betroffene Tests:
- `test_trial_full_investigation_delivery_and_resume` (beide Parameterfälle)
- `test_cli_run_connects_telemetry_and_publishes`
- `test_human_test_returns_blocked_with_pending_budget`
- `test_dispatch_yield_resumes_without_repeating_first_model_call`
Der zusätzliche bestehende Test
`test_full_pipeline_observed_without_telemetry_artifacts_or_double_accounting`
scheitert in seiner alten synthetischen Pipeline vor dem Codingauftrag mit
`CHANGE_REQUEST_DIAGNOSIS_NOT_READY`. Eine Gegenprobe mit der unveränderten
Telemetrie-Allowlist aus `27feda6` scheiterte ebenfalls. Dieser Test verwendet
keinen Worker; seine Pipeline-/Prompt-Fixtures wurden hier nicht umgebaut.
Ein Deployment als Betriebssystemdienst und echte Provider-/DB-Erreichbarkeit
wurden nicht getestet. Eine einzelne externe Modellanfrage kann bei hartem
Prozessabbruch vor dem Antwort-Checkpoint erneut erforderlich werden; die lokalen
Tests belegen keine Exactly-once-Garantie des Modellanbieters.
Vor den Tests geprüft: Test-Workspaces 16.939.129.428 Bytes, kuratiertes Fehlerkorpus
2.471.041 Bytes und vorhandene pytest-Temporärkopien 6.143.826 Bytes. Damit bestand
Reserve unter dem Entwicklungsbudget von 20.000.000.000 Bytes. Die neuen Tests
verwenden kleine künstliche Archive.
@@ -0,0 +1,13 @@
# BUG-000021: independent citation diagnostics
Date: 2026-10-24. Input: operator-supplied `BUG-000021-Fallakte.zip`, analysis revision 1, review reason `MODEL_VALIDATION_EXHAUSTED`. No cloud calls were executed for this investigation or patch.
The interpretation-only fallback omitted the identity evidence for Furien in `/relevant_entities/1` and independently cited a report in `/described_behavior/0`, where local-description facts are required. The existing statement collector diagnosed only the first issue. The next response correctly repaired the requested entity citation, but final validation rejected the previously undisclosed description citation.
The collector now reports both independent paths. Interpretation-only fallback rejections persist their diagnostics just like joint and statement-repair outputs. Feedback uses the saved diagnostics. Historical rejections without this diagnostic field retain the legacy collector, and statement-patch validation accepts the exact legacy or current deterministic issue list, preserving request and parent-call binding. No source rule or final validation was relaxed.
The curated rejection fixture is `tests/fixtures/llm_rejections/20261024/bug21-independent-citation-errors/`. It includes a rejected interpretation, source-validation context and analysis, not a full package or run dump. The independent usage report is `docs/test-results/token-usage/bug21-first-field-review-20261024.json`.
Validation: 92 passed, 1 skipped across joint-v2, early correction and entity-resolution tests; one subsequently added frozen-feedback regression passed separately. The unchanged operator package also passes `correction.validate_review`, including replay of its rejected calls. An additional joint-planning pipeline test fails at `BLOCKED` instead of `OUTPUT_READY`; the same test fails on the pre-patch HEAD source extracted to a temporary directory. The other 26 tests in that correction/joint-planning run pass; one is skipped.
The case detail page now distinguishes failed analysis from successful handoff. Recovery of an already exhausted revision uses the existing case-return contract with `review_feedback`, not a fabricated failed patch and not an in-place alteration of rejected responses. This starts a new analysis revision with the original archives and full history retained. It does not grant extra attempts to the exhausted revision. This operator recovery has not yet been executed on the VPS, and a new revision may repeat planning work. There was no hypothesis investigation budget initialized in this field run.
@@ -0,0 +1,34 @@
# BUG-000021: field-confirmed visibility mechanism and analysis review
Date: 2026-10-25. Evidence: final revision-2 generation-123 case package reviewed previously, followed by operator-supplied SQL outputs, screenshots and in-game experiments. No model calls, DB writes or code changes were executed by the assistant for this review. The earlier completion and usage reports remain unchanged.
## Confirmed operator experiments
- Furien exists as creature 35286, spawn 367807. GM visibility and NPC inspection confirmed the original live spawn.
- The original PhaseId is 169. The inspected Vcore source defines DEFAULT_PHASE as 169; InitDbPhaseShift treats it as Unphased. Both the NPC and the player's reported ordinary phase state had Flags 8. This contradicts the automatic diagnosis's unverified premise that 169 is a nondefault inaccessible phase.
- creature_addon is empty for this spawn. creature_template_addon has StandState 7 and aura 49414; the live aura list identifies Generic Quest Invisibility 1, aura type 18.
- Removing 49414 from the NPC makes him visible without GM mode. Keeping the original NPC aura and adding detection aura 49416 to the player also makes him visible.
- There was no matching spell_area rule for area 405/2404 or the Horde breadcrumb quest. Existing uses of 49416 were confined to other area/quest conditions.
- Operator inserted spell_area (spell=49416, area=405, quest_start=0, quest_end=0, aura_spell=0, racemask=946, gender=2, flags=3, quest_start_status=0, quest_end_status=0), reloaded spell_area, removed the manually applied player aura and left/reentered Desolace. Operator reports automatic Horde visibility, and invisibility to an Alliance character.
- This supports the proposed zone-wide Horde detection rule for the tested scenario. Original retail conditions, all quest-progress states, aura removal on exit and the entire downstream quest chain were not all separately reported as tested. It is not proof that this is the only correct rule.
- Jankie (36410) and mount templates have no static creature rows; an Alliance field test did not find her even in GM mode. No fix applied. This is reserved for a subsequent independent BugAnalysis field test.
## What BugAnalysis did correctly
Intake, project binding, read-only DB tools, actor-audited technical release, bounded name-assessment repair, case continuation, early diagnosis and differentiated coding/human handoff worked. Furien's identity and existing spawn were found correctly. H1 missing-spawn was rejected using actual complete query evidence. H2 appropriately included visibility as a candidate mechanism. Placeholders and human verification prevented a fabricated target PhaseId from becoming an executable hardcoded instruction.
## What failed
The automatic workflow never identified the invisibility aura. Original archive members include an empty creature_addon result but no direct creature_template_addon result for 35286. Numeric 49414 strings exist in historical SQL-reference ID lists; these are not captured evidence of Furien's aura. The relationship tool projects template/script, spawn and event-link information, not template addon/auras or effective visibility. This is a coverage gap, not a reason to treat omitted fields as absent; the read-only DB tool could retrieve them.
The H2 initial brief labels the mere existence of phase-related schema columns as supporting causal evidence. Later the model explicitly calls PhaseId 169 nondefault without checking its core semantics. The next brief presents exclusion of the test player as a fact although no phase-membership measurement was obtained. The root-cause claim thus grew from a real column value through an unverified interpretation into an alleged runtime observation.
Early review used the same spawn records to reject H1 and countercheck H2. Showing that a spawn exists is not a discriminating test of whether phase state or a separate invisibility aura hides it. Neither the source DEFAULT_PHASE definition nor the target's aura state was examined. Final diagnosis repeated the unsupported player-phase assertion and accepted the early conclusion. Contract-valid evidence references establish provenance of the row, not entailment of every causal clause attached to it.
The coding request correctly uses {{TARGET_PHASE_ID}}, but already mandates changing the NPC phase and prohibits changes to other spawn fields. The human task asks which phase is intended; it does not adequately question the unsupported repair mechanism itself. A placeholder does not repair an incorrect causal diagnosis.
## Generalizable improvement candidates, not implemented here
Distinguish captured values, interpreted mechanisms and unverified runtime prerequisites; do not promote schema-only results to causal support. Verify numeric field semantics in the actual source before classifying values as abnormal. Expand visibility research to relevant effective addon/aura sources, keeping spawn-specific versus template precedence explicit. Require a countercheck that probes the selected mechanism rather than only eliminating another hypothesis. Have final review test causal prerequisites and allow a focused tool/human follow-up when they are missing. Review whether the chosen intervention follows from the evidence, separately from whether parameters are known. These measures do not require excluding every alternative, exhausting budgets or disabling early completion.
The run is an infrastructure success and a useful partially correct investigation, but not a successful automatic root-cause diagnosis or repair recommendation. The visibility fix was derived by subsequent human-guided investigation. No claim is made that a single example establishes overall accuracy or that the system should memorize Furien/169/49416 as a special case.
@@ -0,0 +1,15 @@
# BUG-000021 first completed VPS field case
Final input: operator-supplied `BUG-000021-Fallakte.zip`, revision 2, generation 123, OUTPUT_READY/outbox. This analysis read the package without changing it or invoking a model. Earlier blocked snapshots remain separate. The independent usage snapshot is `token-usage/bug21-final-g00000123-20261024.json`.
The explicit operator grant was consumed by entity assessment attempt 4. Its model response repaired only the localized search, changing no_match to ambiguous. The complete base-name identification of Furien (35286) was retained unchanged. Joint planning then encountered a recorded LLM_TIMEOUT/LLM_UNAVAILABLE and resumed successfully in round 2. Thus the apparent period without phase progress has a recorded provider-timeout/retry explanation; it is not evidence of a deadlocked worker.
Research produced six evidence records. The creature relationship tool found a single spawn, GUID 367807, on map 1, zone 405, area 2404, with no game-event link. This refutes the initial missing-spawn hypothesis within the query scope. An attempted startup query requested unverified column `phaseId` and was rejected as PROJECT_DATABASE_COLUMN_UNKNOWN; a schema query followed. The subsequent row query retrieved PhaseId 169, PhaseGroup 0, phaseUseFlags 0, phaseMask 1 and coordinates (189.557,1770.96,91.2064). Other queries obtained creature_questender and conditions schemas and discovered phase table names. They did not retrieve questender row contents, phase definitions or character phase membership.
The model selected H2 (phasing) and requested early diagnosis. The final diagnosis accepted this, rejected H1 and left H3 unresolved. It produced an assigned SQL migration-template coding request using {{TARGET_PHASE_ID}}, together with a human-dev request to verify intended phasing and questender relations. No executable patch was generated or tested. Final output validation status is valid, which establishes contract conformance, not factual correctness of the root-cause conclusion.
Quality assessment: the phasing lead is plausible and backed by actual spawn data. However, the diagnosis claims the reproduction demonstrates that the character was not in phase 169. No character phase-membership observation was located in the supplied reproduction/case records; the research queries did not establish it either. The claim should be treated as an inference, not a measured fact. Likewise the relevant core phasing semantics and intended quest progression were not investigated. The supported suspicion is useful, but the confirmed label and assertions that alternatives were isolated are stronger than the reviewed evidence supports. The coding request allows only an NPC PhaseId update even though the diagnosis explicitly leaves open that the quest should grant the existing phase; human verification is therefore material to the selected repair direction, not merely selection of a numeric placeholder. No program behavior was changed on the basis of this single case.
Operator release to completion: 836.891499 seconds (13 minutes 56.9 seconds), excluding prior manual downtime. Revision-2 recorded model time totals 240.523818 seconds; timeout usage/time is not available in metadata. Revision-2 measured usage: 190037 input, 28659 output including reasoning. Clean usage retaining first regular calls: 116270 input, 27488 output. First metered joint-planning call is classified regular even though its stored label says correction. Entire case including failed revision 1: 268661 input and 42049 output, plus one unmetered timeout. Do not add earlier snapshots to these cumulative totals.
Costs use the saved USD price coefficients, with input/cache ambiguity explicitly bounded. Revision-2 known-usage range is USD 0.129899625–0.207924225; clean range USD 0.116366625–0.178580025. These ranges exclude any unmetered timeout charges and unknown storage, and are not EUR billing totals. No current provider-account balance was supplied. See the JSON for per-call and per-phase estimates and unknown values.
@@ -0,0 +1,13 @@
# BUG-000021 revision 2: scoped entity-assessment repair
Input: operator-provided `BUG-000021-Fallakte (1).zip`, revision 2, generation 43. No paid calls were executed for diagnosis or testing. The original package is unchanged.
All three assessments correctly selected Furien, entry 35286, from the complete base-name lookup. Each incorrectly used `no_match` for a nonempty, truncated German substring lookup containing unrelated harpy names. The validator correctly requires zero rows for `no_match`; previous feedback only supplied the generic `ENTITY_RESOLUTION_SELECTION` code.
The repair now freezes durable, index-specific diagnostics containing the actual status, row count, truncation, allowed candidates and citation constraints. Each structurally and semantically valid sibling entry is retained exactly. Only invalid entries are requested in the model response, with original search indices constrained by the local schema. The program merges them with frozen entries and runs the unchanged full assessment validation. Malformed patches retain the previously frozen entries and receive another bounded repair attempt; they cannot unlock an accepted sibling. No identity is selected automatically and no status is silently changed by string matching on the reason.
Feedback is saved before the call. Existing calls without version-2 feedback retain their exact original request. The projection is also applied when checking completed calls and replaying rejections, so persisted full assessments remain bound to the original partial response and its saved request. Limits and attempt budgets are unchanged. This patch does not silently reopen the already exhausted revision 2 or grant it another attempt.
Curated corpus: `tests/fixtures/llm_rejections/20261024/bug21-localized-no-match/`, approximately 18 KB. Usage snapshot: `docs/test-results/token-usage/bug21-revision2-resolution-blocked-20261024.json`; first-field-run snapshot remains separate. Missing cache/think-token values remain unknown; output totals do not add reasoning twice.
Validation: 60 tests passed across partial entity repair, legacy entity resolution and multidatabase research. Coverage includes the real rejected answer, strict rejection of invalid replacement sources/candidates/status, two-search completion, malformed patch recovery, restart without re-querying research, and portable replay without further model calls. Linux field verification remains pending deployment.
@@ -0,0 +1,29 @@
# BUG-000022: Officer Jankie field analysis
Date: 2026-10-25. Input: `BUG-000022-Fallakte.zip`, revision 1, generation 79, OUTPUT_READY/outbox. No paid calls or code changes were performed for this evaluation. The final package was read directly, without a retained extracted workspace. Usage is archived separately at `token-usage/bug22-final-g00000079-20261025.json`.
## Hypotheses and actual research
H1: missing world spawn. Startup `creature_spawn_context` found template 36410, empty AIName/ScriptName and zero creature rows. H2: existing spawn hidden by phase/quest conditions. A direct creature query for 36410 independently returned zero rows with complete filtered coverage. H3: dynamic summon/movement/despawn. The first requested source.context call omitted required path_prefix and was rejected with INVESTIGATION_OUTPUT; the next call used source.search for 36410. The rejected query is in the curated corpus at `tests/fixtures/llm_rejections/20261025/bug22-source-context-prefix/`.
After startup assessment, H1 became strongly_supported, H2/H3 weakened. H1 then repeated source.search for the same number with a different limit. Both captures show the same historical SQL/numeric lexical matches and partial coverage with skipped files. A smart_scripts query for entryorguid 36410 returned zero rows. The controller accepted an early diagnosis request. Final diagnosis selected missing spawn, rejected H2/H3 and produced a coding SQL template with placeholders for GUID, coordinates and orientation, plus a human request to obtain position/mount requirements.
There are five evidence records: one relationship query, one direct creature query, two lexical source searches and one smart_scripts query. No direct current creature_questender/queststarter row query was made during investigation; SQL-history references were found. No actual spawn/fix was applied by this run. The operator's earlier DB and GM observations independently support the absence diagnosis, but the final success of a patch remains untested.
## Assessment
This is a much more defensible repair candidate than BUG-000021's unverified PhaseId interpretation: the selected missing-static-spawn premise was actually tested with complete query results, and the proposed insertion addresses it directly. Correct identity, sensible initial alternatives, investigation of script possibility, early finish and differentiated placeholder/human handoff are positives. It is reasonable to try this repair within the downstream coding/build/human-test feedback system without proving universal absence of every possible dynamic caller.
Two qualifications matter. Empty own-template script bindings and no own SmartAI rows do not logically exclude summons by external scripts, spells or other entries. The diagnosis acknowledges uninspected C++ in scope_limits but still calls H3 refuted; its confidence language exceeds its coverage. Event-link nodes were skipped because there were no parent spawn GUIDs; that is not an independent investigation of all event logic.
The coding request's only explicit validation requirement is that the new creature row exists. It should also require the original symptom to be checked: a normal Alliance character at the destination can see Jankie and turn in quest 28531. A valid INSERT alone is not proof of behavioral repair. Mount/follow-up behavior remains an explicit human clarification. Coordinates are correctly not invented. The human document's emphasis on authoritative/reference coordinates is stronger than necessary for an operator-approved suitable position; this is secondary to functional correctness.
## Deferred work, explicitly not implemented
User requested retaining the final-review improvement for later evaluation: verify the selected cause's load-bearing premise using targeted evidence/source semantics or a concrete follow-up, rather than adopting investigation narration. Distinguish value capture from semantic abnormality and unmeasured player state. Do not require exhaustive exclusion of every alternative, all budgets to be spent, or guaranteed patch success. BUG-000021's standard PhaseId=169 assumption is the motivating counterexample; BUG-000022 illustrates a reasonable repair trial with narrower coverage language needed. Also retain the source.context missing-prefix case for later form/default-recovery work. No analysis prompts, validators or tool behavior were changed here.
## Metrics
Thirteen measured model calls, one additional startup correction. Total: 106317 input and 21897 output including thinking. Clean: 102446 input and 21265 output. The first joint-planning call is regular despite its recorded correction label; it is counted once. Recorded model time totals 207.939304 seconds; revision checkpoint span 436.431866 seconds (7m16.4s), excluding unrecorded queue time. Investigation prompt message contents ranged from 8865 to 13098 characters.
Saved pricing yields USD 0.0948699–0.150581025 for known total usage, clean USD 0.091244325–0.14695545. Missing cache/storage values prevent an exact total and remain unknown. USD estimates are not EUR billing. No updated provider-account balance was supplied. Full phase and per-call accounting, version/config hashes and cache limitations are in the JSON report.
@@ -0,0 +1,37 @@
# wowdiag-worker-Anschluss – 2026-10-23
Ausgangslage: Nutzer stellte `Z:/Dokumente/Projekte/wowdiag-worker/` bereit.
Quellcode bestätigt WORKER_VERSION 0.3; README/Beispielkonfiguration waren älter.
Die echte Konfiguration wurde nicht gelesen oder geändert. Keine echten Capture-
Jobs, Testserverabfragen, Cloudanfragen oder Dienststarts.
Ausbau v0.4 unter `deploy/capture-worker`: unveränderte Claim-Verarbeitung,
optionale API-Übergabe nach erfolgreicher Erfassung, lokale SQLite-Outbox,
Streaming-Upload beider Archive, feste Idempotenz über Wiederholungen/Neustarts,
Inhaltsprüfung, begrenzte Requests, HTTPS für entfernte Hosts, keine Redirects,
keine Secrets in Quittungen/Logs, separate Status-/Retry-Befehle.
Die tatsächlichen Testerbeobachtungen bleiben in den Originalarchiven.
Lokale Prüfungen:
```text
python -m pytest tests/profiles/vcore/test_capture_handoff.py tests/profiles/vcore/test_intake_api.py tests/test_integration_keys.py -q
```
Prüffälle: URL-Konfiguration, persistente Outbox, Wiederholungsidentität,
Parallel-Lease, Archivänderung, Wiederholung nach verlorener Erfolgsantwort
gegen echte lokale Uvicorn-/Intake-API mit synthetischen Archiven sowie
Staging vor Capture-Abschluss und deaktivierter Übergabe.
15 Tests bestanden; CLI-Hilfe und `git diff --check` ebenfalls erfolgreich.
Feldprüfung mit tatsächlichem Erfassungsserver
steht aus. Keine Token-/Cache-/Abrechnungsmetriken, da keine LLM-Aufrufe.
Speicher vor Tests: Trials 16.939.129.428 Bytes, Fehlerkorpus 2.471.041 Bytes,
pytest-Temporärdateien ca. 4,2 MB. Nur kleine synthetische Archive erzeugt;
keine vollständigen Bug-Paketarchive kopiert. Unterhalb des 20-GB-Budgets.
Nach erfolgreichen Prüfungen wurde v0.4 mit Modul, Anleitung und Beispieldateien
in den vom Nutzer genannten Ordner auf Z: zurückgeschrieben. Vorhandene
Quelldatei, README und Beispielkonfiguration wurden jeweils als
`.before_api_v0_4` gesichert. Die aktive `config.toml` blieb unverändert.
Kein externer Dienst gestartet; Übergabe ist erst nach bewusster Konfiguration aktiv.
@@ -0,0 +1,36 @@
# Menschliche Rückfragen im Web – 2026-10-22
Ziel: Die vorhandene menschliche Testanforderung bedienbar und für neue
Dienstanalysen freigegeben machen. Eigene Seite mit offenen Anfragen, Projekt,
Bug, Zeit, Projektfilter und Sortierungen; Anzeige des Testauftrags und bestätigtes
Textfeedback. Separate Testerrechte bzw. Betreiberrechte erforderlich.
Neue Budgetdatei `config/budget.human-tests.toml`: menschliche Tests 40 fachliche
Einheiten, keine Freigabe automatisierter Tests. Die ignorierte lokale
API-Konfiguration verweist darauf. Vorhandene eingefrorene Revisionen unverändert.
Antworten benutzen den bestehenden AsyncTestCoordinator und dessen Budget-/Identitäts-
und Resume-Prüfungen, keine eigene Zustandsabkürzung. Serverseitige Bestätigung
unter der authentifizierten Clientkennung. Keine kostenpflichtigen LLM-Aufrufe.
Prüfung mit synthetischen Daten:
- API-/Coordinator-/Dashboard-/Worker-Tests: beide Antwortausgänge,
Projektberechtigung, fehlende Rechte, falsche Anfrage, fehlende Bestätigung,
identische bzw. widersprüchliche Wiederholung, unveränderte Budgetkonten und
Fortsetzung in derselben Revision.
Zusammen 51 Tests bestanden.
- Schemavertrag: ohne Budgetfreigabe kein Testzweig, bei menschlicher Freigabe
ausschließlich `human` als Testexecutor.
- Echter Headless-Edge: eigene Seite, Fall-/Projektanzeige, Sortierauswahl,
Auftragsanzeige und Antwortformular, Mobilansicht ohne horizontalen Überlauf,
Datenentfernung bei Abmeldung. Feedbackwirkung separat mit echter Coordinator-
und Budget-Fixture getestet, UI-Anfrage ist ausdrücklich eine Anzeige-Fixture.
- Vor Tests Test-Workspaces 16.939.129.428 Bytes; kleine Fixtures und temporäre
pytest-/Browserdaten bleiben mit Reserve innerhalb des 20-GB-Budgets.
- Breitere Untersuchungstests: 72 bestanden, 26 alte Tests in
`test_investigator.py` scheitern am vorhandenen `INVESTIGATION_PROMPT_LIMIT`.
Vollständige Gegenprobe dieses Moduls mit deaktivierter neuer Schemafilterung:
dieselben 26 Fehler, 6 bestanden. Keine Erweiterung der Zeichengrenze vorgenommen.
Grenzen: Textfeedback; Dateianhänge und automatisierte Testausführung sind keine
Bestandteile dieser Oberfläche. Alte Revisionen benötigen ihre ursprüngliche Policy.
@@ -0,0 +1,33 @@
# Webverwaltung für Integrationsschlüssel – 2026-10-23
Ergebnis: eigene Webseite mit Programmname, Projektauswahl, Erstellen,
erneutem Anzeigen, Verbergen, Kopieren und Widerrufen. API-Schlüssel werden
authentifiziert verschlüsselt in separater SQLite gespeichert; die separate
Serverschlüsseldatei wird beim ersten Erstellen angelegt. Bestehende env-Zugänge
bleiben nutzbar. Menschliche Nutzerverwaltung unverändert ausschließlich per CLI.
Lokale Prüfung ohne LLM-Aufrufe:
```text
python -m pytest tests/test_integration_keys.py tests/test_web_auth.py tests/test_deployment.py tests/test_human_web.py tests/test_dashboard.py tests/profiles/vcore/test_intake_api.py -q
43 passed, 1 dependency deprecation warning
node tests/dashboard-smoke.mjs
PASS, console_errors: []
```
Abgedeckt: Session-/CSRF-Pflicht, keine Maschinenverwaltung von Schlüsseln,
Projektbeschränkung, kein Operatorzugriff, kein Klartext in SQLite oder Listen,
Wiederabruf nach neuer Store-Instanz, sofortiger Widerruf auch für bereits laufende
API-Prozesse, fehlende Masterdatei ohne stille Neuerzeugung, bestehende Web-/API-
Regressionen. Echter Headless-Edge-Test für Erstellen/Anzeigen/Verbergen/Widerrufen
und Löschen sichtbarer Schlüsseldaten beim Logout. Kopieren nutzt die native
Clipboard-API; deren Interaktion wurde nicht automatisiert geprüft.
Die Entwicklungsversion der neuen API-Abhängigkeit cryptography wurde lokal
installiert. Keine realen Schlüssel erzeugt oder ausgegeben; Browser nutzt
temporäre isolierte Testdaten, die nach dem Test entfernt werden.
Vor Testbeginn Trials 16.939.129.428 Bytes, Fehlerkorpus 2.471.041 Bytes;
kleine synthetische Testdaten bleiben innerhalb des 20-GB-Budgets.
Keine kostenpflichtigen Modellaufrufe, keine neuen Token-/Cache-/Kostenwerte.
Kein Deployment und kein Push. Anleitung: `docs/integration-keys.md`.
@@ -0,0 +1,31 @@
# Linux-Betriebspaket – lokale Prüfung 2026-10-22
Ziel: getrennte API-/Worker-Dienste, persistente geschützte Zugangsdaten,
Installation ohne automatische Aktivierung und Bereitschaftsprüfung ohne LLM.
Änderungen: `deploy/install.py`, Linux-Konfigurationsvorlagen, beide systemd-Units,
`viano_bug_analysis.deployment` sowie explizite Loopback-Proxy-Vertrauensgrenze
beim API-Start. Anleitung: `docs/linux-deployment.md`.
Validierung auf Windows mit Python aus `.venv`:
```text
python -m pytest tests/test_deployment.py tests/test_web_auth.py tests/test_worker.py tests/profiles/vcore/test_worker_intake.py -q
31 passed, 1 dependency deprecation warning
git diff --check: keine Whitespacefehler
```
Prüfumfang: Installer-Dry-Run ohne Seiteneffekte, TOML-Vorlagen und Dateiverweise,
getrennte env-Dateien und Unit-Härtung, API-Start mit/ohne erforderliche
Zugangsdaten, Worker-Leseprüfung mit kontrollierten Git-/DB-Testdoubles,
Offline-Modus, keine Modellanfrage, sichere Fehlerausgabe, HTTPS-Login-Cookie
über Uvicorns Proxy-Middleware, bestehende Nutzer-/Worker-/Intake-Tests.
Vor den Tests: Trial-Workspaces 16.939.129.428 Bytes, kuratiertes Fehlerkorpus
2.471.041 Bytes. Nur kleine synthetische Tempdateien; keine Paketkopien oder neuen
LLM-Trials. Das Entwicklungsbudget von 20 GB bleibt eingehalten.
Keine Cloud-/DB-Zugangsdaten im Bericht. Keine realen LLM-Aufrufe oder neuen
Abrechnungskosten. Keine Installation, Dienstaktivierung oder Serveränderung.
Native systemd-/Nginx-Prüfung und produktiver End-to-End-Test stehen aus:
Auf dieser Windows-Umgebung ist kein nutzbares Linux/systemd vorhanden.
@@ -0,0 +1,66 @@
# Mehrere Recherche-Datenbanken pro Projekt – 2026-10-24
Ausbau des SQL-Providers um ausdrücklich konfigurierte zusätzliche Datenbanken
derselben MariaDB-Verbindung. Standarddatenbank und alte Einzel-DB-Konfigurationen
bleiben gültig. Zusätzliche Tabellen verwenden `datenbank.tabelle`; es gibt keine
automatische Suche nach gleichnamigen Tabellen in anderen DBs.
`[database.additional_databases]` unterstützt konkrete Tabellenlisten oder
ausdrücklich `["*"]` für metadaten-sichtbare Tabellen einer benannten DB.
Die Standardliste `tables` unterstützt dieselbe ausdrückliche Wildcard.
Keine implizite Freigabe anderer DBs, keine beliebigen SQL-Befehle, keine
Schreiboperationen. Separate Server/Zugänge innerhalb einer Projektverbindung
sind nicht Bestandteil dieses Formats.
Angepasst: SQL-Auflösung und Metadaten-Caches, Werkzeug-/Capture-/Zustandsschemata,
Belegherkunft, DB-Beziehungsanalyse über mehrere Schemas in einer lesenden
Repeatable-Read-Transaktion, Entity-Namenskataloge, Enrichment-Tabellenvergleiche,
Toolhinweise und vollständige Bereitschaftsprüfung. Vcore-Mehrdatenbankvorlage,
README, Projektanleitung und gebündelte Webanleitung aktualisiert.
## Erfolgreiche lokale Prüfungen
```text
python -m pytest tests/test_multidatabase_research.py tests/test_context_expansion.py tests/test_entity_resolution.py tests/test_database_fact_grounding.py tests/test_deployment.py tests/test_user_manual.py -q
84 passed, 1 dependency deprecation warning
```
Davon 14 Mehrdatenbank-Testfälle einschließlich parametrisierter Ablehnungen.
Reale SQL-Selektion über getrennte SQLite-Attach-Schemas; MariaDB-Metadaten und
Transaktionsbefehle werden im Adapter simuliert. Geprüft: identische Tabellennamen
mit verschiedenen Daten, korrekte Schema-/Belegzuordnung, Abweisung nicht
freigegebener Schemas vor Verbindungsaufbau, Wildcard-Entdeckung und Pagination,
keine Auth-/Charakter-/Locale-Reference-Freigabe, gemeinsame Beziehungstransaktion,
Entity-/Enrichment-Regeln, vollständige Paket-/Evidence-Validierung,
Mehrdatenbank-Startprüfung mit fehlender DB und vollständige Vcore-Vorlage.
Keine Secrets oder Host-/Benutzerdaten im Provider-Binding.
## Bekannte Fehler und Gegenprobe
Zusätzlicher Lauf über Mehrdatenbank-, Relations-, ProjectResearch-, Deployment-
und Manual-Tests vor dem letzten Vorlagentest: 73 bestanden, 1 übersprungen,
5 fehlgeschlagen. Dieselben fünf Tests scheitern auch am unveränderten HEAD
9408af5 (52 bestanden, 1 übersprungen). Die Gegenprobe nutzte eine temporäre
separate Baseline-Sourcekopie; Arbeitsdateien wurden nicht zurückgesetzt.
- test_database_relations.py::test_hybrid_loop_uses_relations_with_fixture_llm_and_can_resume
- test_project_research.py::test_model_loop_uses_project_tools_and_compact_previous_result[True]
- test_project_research.py::test_model_loop_uses_project_tools_and_compact_previous_result[unknown]
- test_project_research.py::test_model_loop_uses_project_tools_and_compact_previous_result[upgrade]
- test_project_research.py::test_started_project_loop_keeps_legacy_prompt_protocol
Diese Alt-Schleifenprüfungen bleiben offen. Die harte Promptgrenze wurde nicht
gelockert; es wurden keine Budgets zurückgesetzt oder Tests zum Bestehen verändert.
## Messumfang und Grenzen
Alle Modellantworten in lokalen Workflow-Fixtures sind Testdoubles; keine echten
LLM-Anfragen. Keine Cloudkosten oder neuen Token-/Cache-Abrechnungsmetriken.
Keine Verbindung zum VPS, keine Änderungen an echten DBs, kein Dienststart.
Echte MariaDB-Verbindungen und Serverrechte werden nach dem Update mit der
Bereitschaftsprüfung auf dem Zielserver kontrolliert.
Vor Testbeginn Trials 16.939.129.428 Bytes, Fehlerkorpus 2.471.041 Bytes und kleine
pytest-Temporärdaten. Nur kleine Source-/SQL-/Case-Fixtures; das 20-GB-Budget bleibt
eingehalten. Temporäre Baseline-Kopie nach Gegenprobe entfernt. Keine vollständigen
LLM-Testarchive angelegt. `docs/architecture.md` unverändert, kein Push.
@@ -0,0 +1,28 @@
# Betriebssteuerung – 2026-10-22
Umfang: projektbezogene Pause neuer Analysen mit Weiterlauf begonnener Fälle,
dauerhafte Fortsetzungsaufträge zwischen Worker-Dispatches, getrennte Betreiberrechte,
Aktionsprotokoll sowie Workerstatus im Web. Keine Prompt-/Budgetänderungen und keine
Änderung der maßgeblichen Designspezifikation.
Eingaben: künstliche CaseBuilder-/Worker-/API-Fixtures und synthetischer UI-Server.
Keine kostenpflichtigen Modellanfragen und keine externen DB-/Repositoryzugriffe.
Prüfungen:
- Worker-, Dashboard-, vcore-Intake- und API-Tests: 50 bestanden.
- Persistente Pause nach Worker-Neustart, Weiterlauf begonnener Fälle,
aktuelle und veraltete Freigaben, Ablehnung von Modellvalidierungssperren.
- API-Berechtigungen, Projektscope, Protokollsichtbarkeit, ungültige/zu große
Steuerungsnachrichten und unbekannte Zusatzfelder.
- Echter Headless-Edge: Pause/Wiederzulassung, Aktionsprotokoll, Desktop/Mobil,
bisherige Diagramme/Falldetails/Abmeldung: PASS, keine Browserfehler/Überläufe.
Nach zwei Fehlern beim Test-Abschluss wurde geordnetes Browserbeenden ergänzt;
der abschließende Test endet erfolgreich einschließlich temporärer Bereinigung.
- Test-Workspaces vor Testbeginn: 16.939.129.428 Bytes; zusammen mit kleinen
Fixtures und temporären lokalen Tests unter 20 GB. Keine alten Akten gelöscht.
Grenzen: HTTP-Annahme bleibt während einer Pause verfügbar; Pause stoppt neue
Analysen an Worker-Grenzen, keine laufenden Modellaufrufe. Freigaben sind asynchron
und können bei erneuter Prüfung abgelehnt werden. Ein gestoppter Worker wird durch
die Weboberfläche nicht als Betriebssystemdienst gestartet.
@@ -0,0 +1,15 @@
# Explicit technical recovery for exhausted entity resolution
The authenticated case detail page now supports a reasoned approval for one additional response attempt after a software correction. Scope is currently `BLOCKED / ENTITY_RESOLUTION_INVALID_RESPONSES` during interpretation, covering plan and assessment. Other technical scheduling failures retain their existing retry paths; human feedback, completed results, final review and investigation-budget limits cannot be bypassed by this action.
Approval is durable intent, not a model call. The worker holds its regular case lock, rechecks generation and project configuration binding, verifies exhaustion and appends a manual-resume checkpoint. Actor, reason, rejected-call hash, implementation hash, stage and next attempt number are recorded. Previous attempts, revision, captures and accepted plan are retained. The entity resolver verifies these grants on replay and extends only that stage's attempt range, by one per explicit grant. A rejected extra attempt blocks again. Grants are not automatic and repeated same-generation web submissions are deduplicated or rejected as stale.
Validation on 2026-10-24, no paid model calls:
- 99 passed across operator repair, worker, entity resolution, lifecycle checkpoints and manual packaging tests.
- 25 passed in the dashboard/operator repair test invocation (includes tests overlapping the previous invocation).
- Node syntax check and real Edge browser smoke passed, including rendering and dispatch arguments of the repair control; no console errors.
- Manual package --check passed after rebuilding the bundled user manual.
- An unchanged copy of the operator-supplied BUG-000021 revision-2 ZIP was admitted into a temporary workspace and explicitly approved. It transitioned to INTERPRETING_CASE in the same revision without a model call. Original file and VPS data were not modified. The stale source generation was correctly rejected first, then the current imported generation was used.
Tests cover one-attempt exhaustion, second explicit grant, plan/capture reuse for assessment recovery, original-byte preservation, portable replay without another model call, CSRF, machine-client rejection, stale generation, invalid reason, queue deduplication and rejection of unrelated block reasons. Native Linux field verification remains pending deployment. No architecture specification was changed.
@@ -0,0 +1,31 @@
# Bearbeitete Fälle – 2026-10-23
Die bisher auf terminale Zustände begrenzte Ergebnisliste wurde zur gemeinsamen
Liste bearbeiteter Fälle erweitert: OUTPUT_READY, HANDED_OFF, BLOCKED und
FAILED_TO_ANALYZE. Filter für Kategorie und Projekt, Suche, Sortierung nach
Aktualisierung/Kategorie/Projekt, Routingziel, Sperrgrund und linksseitiger
Iconknopf für den bestehenden projektgeschützten Paketdownload. Blockierte Fälle
werden nicht als abgeschlossen gewertet. Analysezustände/Budgets unverändert.
Lokale Validierung:
```text
python -m pytest tests/test_dashboard.py tests/test_web_auth.py tests/test_human_web.py -q
26 passed, 1 dependency deprecation warning
node tests/dashboard-smoke.mjs
PASS, console_errors: [], overflow: false
node --check src/viano_bug_analysis/web/case-detail.js
PASS
```
Echter Browser prüft die gemeinsame Liste mit Ergebnis und blockiertem Fall,
linken Downloadknöpfen, Testerantwort-Hinweis, Kategorieauswahl und bestehender
Detailnavigation. Mobile Ansicht visuell kontrolliert. Bestehende Tests sichern
projektgebundene Detail-/ZIP-Endpunkte und Anmeldung ab. Routingdaten werden aus
dem Manifest übernommen; die Liste scannt nicht separat das Exportverzeichnis.
Vor Testbeginn Trials 16.939.129.428 Bytes, Fehlerkorpus 2.471.041 Bytes, nur kleine
temporäre UI-/Unit-Testdaten. Entwicklungsbudget weiterhin unter 20 GB.
Keine LLM-/Cloud-Aufrufe oder Kosten, keine Änderung produktiver Fälle/Dienste.
Serverinstallation, HTTPS, echter automatischer Feldtest und Betriebssicherung
bleiben Aufgaben auf dem Linux-Zielsystem.
+20
View File
@@ -0,0 +1,20 @@
# Dauerhafte Tokenbilanzen
Diese kleinen JSON-Berichte bleiben unabhängig von den Testpaketen versioniert erhalten.
Sie enthalten Einzelaufrufe, Prompt-/Modellversion, Konfigurationshash, Quellenhashes,
Lifecycle-Ergebnis sowie Gesamt- und bereinigte Planungsbilanzen. Keine Prompts,
Antworttexte oder Zugangsdaten. Ein gemeinsamer Aufruf wird nur einmal gezählt.
`output_tokens` enthält bei diesen Providermetriken bereits die Denktokens.
Fehlende Messwerte bleiben null; Summen weisen die Anzahl fehlender Messwerte aus.
API-Zeitsummen sind keine gesamte Falllaufzeit. Annahme/Ablehnung wird nur bei
vorliegenden Artefaktverweisen beziehungsweise Validierungsfehlern ausgewiesen;
fehlende Zuordnung bedeutet nicht automatisch einen erfolgreichen Aufruf.
Nach jeder Testauswertung einen neuen Bericht beziehungsweise einen eindeutig datierten
Snapshot anlegen; vorhandene Messstände nicht mit späteren Fortschritten überschreiben.
Kontostände mit Beginn, Zwischenstand und endgültigem Stand samt Abrechnungsverzögerung
festhalten. Vor dem Löschen eines Test-Workspaces das Vorhandensein der Bilanz prüfen.
Der Vergleich `comparison-separate-vs-joint-20261020.json` sichert den im Chat
besprochenen Vergleich. Der aktuelle Kostenstand 12,47 EUR ist noch vorläufig.
@@ -0,0 +1,63 @@
{
"format": "viano-offline-recovery-regression",
"date": "2026-10-20",
"source_run": "bug17-bounded-full-20261020",
"source_generation": 103,
"cases": [
{
"call_ref": "llm/operations/8f58f73379896f4edda417f564668be151dea6f1dd75d1872c8aeb64d0cef5ce/round-0001.json",
"normalization_rules": [
"non_applicable_budget_assessment:/assessment"
],
"query_preserved": true,
"observation_preserved": true,
"full_controller_validation": "passed"
},
{
"call_ref": "llm/operations/6ccfd3edde468aa5c42f40ec7c75c2117ae13bf79c3eddd91eb4335ab02d4482/round-0001.json",
"normalization_rules": [
"non_applicable_budget_assessment:/assessment"
],
"query_preserved": true,
"observation_preserved": true,
"full_controller_validation": "passed"
},
{
"call_ref": "llm/operations/4115b3b2b3e209ed778e9ec0c51f6e5ce3a4249e00f87c89aeeedead0841f6a2/round-0001.json",
"normalization_rules": [
"non_applicable_budget_assessment:/assessment"
],
"query_preserved": true,
"observation_preserved": true,
"full_controller_validation": "passed"
}
],
"budgets_unchanged": true,
"paid_api_calls": 0,
"scope": "Exact saved request and context; recovery followed by full controller validation including configured project source validation. No action execution or result accounting.",
"tests": {
"broad_suite_passed": 212,
"broad_elapsed_seconds": 191.46,
"final_targeted_passed": 24,
"final_targeted_elapsed_seconds": 6.48,
"note": "Targeted suite rerun after tightening query-kind whitelist and pending-result feedback. Counts overlap; do not add."
},
"manual_resume": {
"from_generation": 103,
"to_generation": 104,
"state": "INVESTIGATING_HYPOTHESES",
"unchanged_artifact_sha256": {
"investigation_state": "1c71126a1460f71c51a1d2866aab07b37797aaf835f6891f1df46529d2bfc476",
"budget_ledger": "68e74e2f64e0d0b43f002a8c6bfe7ba4d765a72a568012e7dd19a939f55f80eb",
"case_interpretation": "0fd3c2a1efe0f229592b3038b66db26e704f2fb1a03b7321ceb76450e3f98cb4",
"hypotheses": "30494a06ce373f4c497b3964524cee21bdf5350eac515f7a0022619879d125c8"
},
"budgets_reset": false,
"invalid_responses_reset": false
},
"source_sha256": {
"src\\viano_bug_analysis\\analysis\\investigation_lean_v20.py": "f58df59fdd423f515dd439dc90479c815918a42856e9c1cb2ae96f1c572a04f2",
"src\\viano_bug_analysis\\analysis\\investigator.py": "ee3db3cb9bfa9a5f6eedf255283a620a77a7d29ee950d4d6adac263e05400d03",
"src\\viano_bug_analysis\\llm\\response_recovery.py": "faabf4e34542375f9d881303bf4c95ba1f0af10e3fab7236b5786a2d99eb222f"
}
}
@@ -0,0 +1,26 @@
{
"format": "viano-test-billing-settlement",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug17-bounded-full-20261020",
"case_id": "BUG-000017",
"package_id": "trial-bounded-full-BUG-000017-20261020",
"package_generation": 228,
"token_report": "bug17-bounded-full-20261020-g00000228.json",
"account_eur": {
"start": 13.01,
"final": 13.37,
"difference": 0.36,
"settlement": "final_user_confirmed_after_waiting"
},
"all_generation_estimate_usd": 0.4110881250000001,
"cleaned_generation_estimate_usd": 0.2835375,
"correction_generation_estimate_usd": 0.127550625,
"cache_storage_estimate_usd": 0.0010264583333333334,
"notes": [
"Actual EUR cost includes the full interrupted trial and its continuations, not only the final seven dispatches.",
"Cleaned costs are estimates, not separately measured EUR billing.",
"The trial ended through early completion, not exhaustion of all hypothesis budgets.",
"Technical result OUTPUT_READY; causal diagnosis contradicted by the verified core dispatch."
]
}
@@ -0,0 +1,592 @@
{
"run": "bug17-bounded-full-20261020",
"case_id": "BUG-000017",
"package_id": "trial-bounded-full-BUG-000017-20261020",
"configuration_sha256": {
"config\\llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config\\project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config\\investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"inputs": [
{
"file": "BUG-000017-20261015-213913.tar.gz",
"sha256": "6fc61e0c54d18eb0673827aa69284f48807b80928c7d68643d2b920584cbcfde"
},
{
"file": "WOWSRC-BUG-000017-20261015-213934.tar.gz",
"sha256": "a189ef80672658466d30812fb095f88ab932870cdadc40d97665b73d31029561"
}
],
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"code_commit": "a3e1ea0429ac7a44832487431b2b49e61114fc0b",
"package_generation": 47,
"analysis_revision": 1,
"state": "BLOCKED",
"routing": {
"destination": "inbox",
"reason": "INVALID_LLM_RESPONSES",
"retry_count": 1,
"retry_not_before": "2026-10-20T20:00:32.238127+00:00"
},
"source_manifest_sha256": "d7750b7c56ef1a298ba8591e94a1aaeeaa9810fb114da9ff42d33527b361819a",
"pricing_snapshot": [
{
"id": "gemini-native",
"model": "gemini-3.8-flash",
"cost_currency": "USD",
"input_cost_per_million": 0.75,
"cached_input_cost_per_million": 0.075,
"output_cost_per_million": 3.75,
"cache_storage_cost_per_million_hour": 0.5
}
],
"pricing_source": "Configured USD snapshot from preceding evaluation; no new price lookup.",
"account_eur": {
"start": 13.01,
"final": null,
"settlement": "pending"
},
"scope": "Technical failure during initial H3; H1 and H2 tool execution succeeded after one correction each. Joint startup review and normal followup never executed.",
"dispatch_count": 10,
"totals_all": {
"call_count": 10,
"usage": {
"input_tokens": {
"known_sum": 78071,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 7696,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 3572,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 12803,
"unknown_call_count": 3
}
},
"api_elapsed_seconds_sum": 73.079,
"conservative_generation_estimate_usd": 0.078771225,
"generation_lower_bound_usd": 0.041108250000000006,
"estimated_cache_storage_usd": 7.620833333333333e-05
},
"totals_cleaned": {
"call_count": 6,
"usage": {
"input_tokens": {
"known_sum": 64912,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 5569,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1820,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 5487,
"unknown_call_count": 3
}
},
"api_elapsed_seconds_sum": 50.358999999999995,
"conservative_generation_estimate_usd": 0.06586402499999999,
"generation_lower_bound_usd": 0.028201050000000002,
"estimated_cache_storage_usd": 7.620833333333333e-05
},
"totals_correction_overhead": {
"call_count": 4,
"usage": {
"input_tokens": {
"known_sum": 13159,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2127,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1752,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 7316,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 22.72,
"conservative_generation_estimate_usd": 0.0129072,
"generation_lower_bound_usd": 0.0129072,
"estimated_cache_storage_usd": 0
},
"phases": {
"entity_resolution_plan_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21434,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 43,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.828,
"conservative_generation_estimate_usd": 0.01623675,
"generation_lower_bound_usd": 0.0017688,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21434,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 43,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.828,
"conservative_generation_estimate_usd": 0.01623675,
"generation_lower_bound_usd": 0.0017688,
"estimated_cache_storage_usd": 0
}
},
"entity_resolution_assessment_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 22050,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 102,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.797,
"conservative_generation_estimate_usd": 0.01692,
"generation_lower_bound_usd": 0.00203625,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 22050,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 102,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.797,
"conservative_generation_estimate_usd": 0.01692,
"generation_lower_bound_usd": 0.00203625,
"estimated_cache_storage_usd": 0
}
},
"case_plan_v2": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 12313,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 4444,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1110,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 30.546,
"conservative_generation_estimate_usd": 0.02589975,
"generation_lower_bound_usd": 0.017588475,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 12313,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 4444,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1110,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 30.546,
"conservative_generation_estimate_usd": 0.02589975,
"generation_lower_bound_usd": 0.017588475,
"estimated_cache_storage_usd": 0
}
},
"investigation_startup_v1": {
"all": {
"call_count": 7,
"usage": {
"input_tokens": {
"known_sum": 22274,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 3107,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2462,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 12803,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 36.908,
"conservative_generation_estimate_usd": 0.019714725000000002,
"generation_lower_bound_usd": 0.019714725000000002,
"estimated_cache_storage_usd": 7.620833333333333e-05
},
"cleaned": {
"call_count": 3,
"usage": {
"input_tokens": {
"known_sum": 9115,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 980,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 710,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 5487,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 14.187999999999999,
"conservative_generation_estimate_usd": 0.006807525000000001,
"generation_lower_bound_usd": 0.006807525000000001,
"estimated_cache_storage_usd": 7.620833333333333e-05
}
}
},
"calls": [
{
"ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"prompt_version": "entity_resolution_plan_v4",
"task": "entity_resolution_plan",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "9bef5293e2a4dc08eeeb33cabbe11994771f9b5baff5857a6a5c44f0d4b18234",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 21434,
"output_tokens_including_reasoning": 43,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 2.828,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.01623675,
"estimated_generation_usd_lower_bound": 0.0017688,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"prompt_version": "entity_resolution_assessment_v4",
"task": "entity_resolution_assessment",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "39b4c8d27eb4b246fdd3fdab06cbe8604e83ead7dbdd1197af34da0506dc9817",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 22050,
"output_tokens_including_reasoning": 102,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 2.797,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.01692,
"estimated_generation_usd_lower_bound": 0.00203625,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"prompt_version": "case_plan_v2",
"task": "interpret_and_propose",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "ac71293ff28b25a954a78c705aa485f28633e1fe657c55d12f17a8c7cfb8f792",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 12313,
"output_tokens_including_reasoning": 4444,
"reasoning_tokens": 1110,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 30.546,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.02589975,
"estimated_generation_usd_lower_bound": 0.017588475,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "89d36bb4e312d218f7a2cb6f5d9793eb361e1b4f7c221eea2f1b925962f9d061",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"code": null,
"input_tokens": 2096,
"output_tokens_including_reasoning": 337,
"reasoning_tokens": 259,
"cached_input_tokens": 1829,
"cache_status": "created",
"api_elapsed_seconds": 5.531,
"logical_wire_characters": 7826,
"estimated_generation_usd_conservative": 0.001601175,
"estimated_generation_usd_lower_bound": 0.001601175,
"estimated_cache_storage_usd": 7.620833333333333e-05
},
{
"ref": "llm/operations/d844b0d123ece7c9861dbe282539f7879e6e6a21b3d1d4575c6e559fd5044aae/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "0d2018a60817afec6a462da6c01f5f3118a6ad9a87e7685501bf86c91a9d364f",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2152,
"output_tokens_including_reasoning": 633,
"reasoning_tokens": 551,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 6.203,
"logical_wire_characters": 8064,
"estimated_generation_usd_conservative": 0.002753175,
"estimated_generation_usd_lower_bound": 0.002753175,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "a1ef119cfb18c96cf64e65b99890f26128d96625fca7da45b62ad7b762cc84b6",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"code": null,
"input_tokens": 3101,
"output_tokens_including_reasoning": 365,
"reasoning_tokens": 268,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 4.407,
"logical_wire_characters": 10040,
"estimated_generation_usd_conservative": 0.0024599250000000004,
"estimated_generation_usd_lower_bound": 0.0024599250000000004,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/9d66012b57395476a4f69c72ffd0b6725da911ede849fc652d48568b73d28480/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "814552c42e71fd75326c7f15dd8b9091571e49d6b2c4a59152bf989b49232bf4",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3145,
"output_tokens_including_reasoning": 688,
"reasoning_tokens": 589,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 7.157,
"logical_wire_characters": 10233,
"estimated_generation_usd_conservative": 0.003704175,
"estimated_generation_usd_lower_bound": 0.003704175,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "c5500907581f95c660d3302d1e2c2a7ebc294653db23452df8884e2a6c529af1",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "TOOL_SOURCE_NOT_DECLARED",
"code": null,
"input_tokens": 3918,
"output_tokens_including_reasoning": 278,
"reasoning_tokens": 183,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 4.25,
"logical_wire_characters": 12241,
"estimated_generation_usd_conservative": 0.0027464250000000003,
"estimated_generation_usd_lower_bound": 0.0027464250000000003,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/7b8f9ecd4cb00c7e1d8bbd314d9ab15032701b76a0d5cf4256b895312b03a731/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "45041335c749468ea29b35ca1efeb5b923cb8dbcc1df2939b0ae1ecf7691f647",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": "PROJECT_SOURCE_RANGE",
"code": null,
"input_tokens": 3933,
"output_tokens_including_reasoning": 514,
"reasoning_tokens": 416,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 5.297,
"logical_wire_characters": 12289,
"estimated_generation_usd_conservative": 0.003642675,
"estimated_generation_usd_lower_bound": 0.003642675,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/cb89815283c33c24b09426c12c79171c3b0edf986d08dd90039905235bfaec70/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "7dd04e1eee14fc72bf0942ef3aa4d2b7d9403e3ca00c37ee7e16cbcfdfce3bd9",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": "PROJECT_SOURCE_RANGE",
"code": null,
"input_tokens": 3929,
"output_tokens_including_reasoning": 292,
"reasoning_tokens": 196,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 4.063,
"logical_wire_characters": 12285,
"estimated_generation_usd_conservative": 0.0028071750000000003,
"estimated_generation_usd_lower_bound": 0.0028071750000000003,
"estimated_cache_storage_usd": 0.0
}
],
"package_valid": true,
"assessment": {
"primary_failure": "Two source.read intervals exceed max_lines=80: 115..215 inclusive=101, then 150..240 inclusive=91. Neither is an EOF failure. No detailed range feedback supplied to model.",
"other_rejections": [
"H1 source.context missing path_prefix and extra scope",
"H2 source.read extra case_sensitive",
"H3 source.read_context uses repository path in source_ref; not a declared case source"
],
"startup_explored": [
"H1",
"H2"
],
"startup_done": false,
"remaining_budget_preserved": true
},
"notes": [
"Output includes reasoning; never add twice.",
"Cleaned totals retain first regular call even if rejected; four additional startup calls excluded.",
"Missing cached counts unknown; conservative estimate charges unknown input as uncached, lower bound as cached. Cache storage separate. USD not EUR billing.",
"No paid API calls or program changes made for this analysis."
],
"trial_process_elapsed_seconds": 111.808704
}
@@ -0,0 +1,898 @@
{
"run": "bug17-bounded-full-20261020",
"case_id": "BUG-000017",
"package_id": "trial-bounded-full-BUG-000017-20261020",
"configuration_sha256": {
"config\\llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config\\project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config\\investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"inputs": [
{
"file": "BUG-000017-20261015-213913.tar.gz",
"sha256": "6fc61e0c54d18eb0673827aa69284f48807b80928c7d68643d2b920584cbcfde"
},
{
"file": "WOWSRC-BUG-000017-20261015-213934.tar.gz",
"sha256": "a189ef80672658466d30812fb095f88ab932870cdadc40d97665b73d31029561"
}
],
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"code_commit": "167d8d5f5e88b64ce9693d08cc5941d87db9475c",
"package_generation": 84,
"analysis_revision": 1,
"state": "BLOCKED",
"routing": {
"destination": "inbox",
"reason": "INVALID_LLM_RESPONSES",
"retry_count": 2,
"retry_not_before": "2026-10-20T20:23:56.063225+00:00"
},
"source_manifest_sha256": "e90f4132e2fd0afa2b558abf4fae0832857739ea7fdca2ee56c99ebf1866cd95",
"pricing_snapshot": [
{
"id": "gemini-native",
"model": "gemini-3.8-flash",
"cost_currency": "USD",
"input_cost_per_million": 0.75,
"cached_input_cost_per_million": 0.075,
"output_cost_per_million": 3.75,
"cache_storage_cost_per_million_hour": 0.5
}
],
"pricing_source": "Configured USD snapshot from preceding evaluation; no new price lookup.",
"account_eur": {
"start": 13.01,
"final": null,
"settlement": "pending"
},
"scope": "Technical block at forced size checkpoint: three answers request recall, forbidden by consolidation action contract. All startup hypotheses explored and group review accepted. Not a completed long-budget analysis.",
"dispatch_count": 17,
"totals_all": {
"call_count": 17,
"usage": {
"input_tokens": {
"known_sum": 100811,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 17814,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 11101,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 22399,
"unknown_call_count": 4
}
},
"api_elapsed_seconds_sum": 152.221,
"conservative_generation_estimate_usd": 0.127291425,
"generation_lower_bound_usd": 0.08696625000000001,
"estimated_cache_storage_usd": 0.0002867083333333333
},
"totals_cleaned": {
"call_count": 10,
"usage": {
"input_tokens": {
"known_sum": 77709,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 9796,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 4350,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 10612,
"unknown_call_count": 4
}
},
"api_elapsed_seconds_sum": 87.11,
"conservative_generation_estimate_usd": 0.08785365,
"generation_lower_bound_usd": 0.047528475,
"estimated_cache_storage_usd": 0.00021050000000000002
},
"totals_correction_overhead": {
"call_count": 7,
"usage": {
"input_tokens": {
"known_sum": 23102,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 8018,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 6751,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 11787,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 65.11099999999999,
"conservative_generation_estimate_usd": 0.039437775,
"generation_lower_bound_usd": 0.039437775,
"estimated_cache_storage_usd": 7.620833333333333e-05
},
"phases": {
"entity_resolution_plan_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21434,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 43,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.828,
"conservative_generation_estimate_usd": 0.01623675,
"generation_lower_bound_usd": 0.0017688,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21434,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 43,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.828,
"conservative_generation_estimate_usd": 0.01623675,
"generation_lower_bound_usd": 0.0017688,
"estimated_cache_storage_usd": 0
}
},
"entity_resolution_assessment_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 22050,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 102,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.797,
"conservative_generation_estimate_usd": 0.01692,
"generation_lower_bound_usd": 0.00203625,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 22050,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 102,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 2.797,
"conservative_generation_estimate_usd": 0.01692,
"generation_lower_bound_usd": 0.00203625,
"estimated_cache_storage_usd": 0
}
},
"case_plan_v2": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 12313,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 4444,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1110,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 30.546,
"conservative_generation_estimate_usd": 0.02589975,
"generation_lower_bound_usd": 0.017588475,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 12313,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 4444,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1110,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 30.546,
"conservative_generation_estimate_usd": 0.02589975,
"generation_lower_bound_usd": 0.017588475,
"estimated_cache_storage_usd": 0
}
},
"investigation_startup_v1": {
"all": {
"call_count": 8,
"usage": {
"input_tokens": {
"known_sum": 26203,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 3421,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2682,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 14632,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 41.799,
"conservative_generation_estimate_usd": 0.022604400000000004,
"generation_lower_bound_usd": 0.022604400000000004,
"estimated_cache_storage_usd": 0.00015241666666666667
},
"cleaned": {
"call_count": 3,
"usage": {
"input_tokens": {
"known_sum": 9115,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 980,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 710,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 5487,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 14.187999999999999,
"conservative_generation_estimate_usd": 0.006807525000000001,
"generation_lower_bound_usd": 0.006807525000000001,
"estimated_cache_storage_usd": 7.620833333333333e-05
}
},
"investigation_startup_review_v1": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 3944,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2237,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1291,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 16.235,
"conservative_generation_estimate_usd": 0.01134675,
"generation_lower_bound_usd": 0.00868455,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 3944,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2237,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1291,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 16.235,
"conservative_generation_estimate_usd": 0.01134675,
"generation_lower_bound_usd": 0.00868455,
"estimated_cache_storage_usd": 0
}
},
"investigation_project_v20": {
"all": {
"call_count": 5,
"usage": {
"input_tokens": {
"known_sum": 14867,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 7567,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 6018,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 7767,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 58.016,
"conservative_generation_estimate_usd": 0.034283775,
"generation_lower_bound_usd": 0.034283775,
"estimated_cache_storage_usd": 0.00013429166666666667
},
"cleaned": {
"call_count": 3,
"usage": {
"input_tokens": {
"known_sum": 8853,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 1990,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1239,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 5125,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 20.516,
"conservative_generation_estimate_usd": 0.010642875,
"generation_lower_bound_usd": 0.010642875,
"estimated_cache_storage_usd": 0.00013429166666666667
}
}
},
"calls": [
{
"ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"prompt_version": "entity_resolution_plan_v4",
"task": "entity_resolution_plan",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "9bef5293e2a4dc08eeeb33cabbe11994771f9b5baff5857a6a5c44f0d4b18234",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 21434,
"output_tokens_including_reasoning": 43,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 2.828,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.01623675,
"estimated_generation_usd_lower_bound": 0.0017688,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"prompt_version": "entity_resolution_assessment_v4",
"task": "entity_resolution_assessment",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "39b4c8d27eb4b246fdd3fdab06cbe8604e83ead7dbdd1197af34da0506dc9817",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 22050,
"output_tokens_including_reasoning": 102,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 2.797,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.01692,
"estimated_generation_usd_lower_bound": 0.00203625,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"prompt_version": "case_plan_v2",
"task": "interpret_and_propose",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "ac71293ff28b25a954a78c705aa485f28633e1fe657c55d12f17a8c7cfb8f792",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 12313,
"output_tokens_including_reasoning": 4444,
"reasoning_tokens": 1110,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 30.546,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.02589975,
"estimated_generation_usd_lower_bound": 0.017588475,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "89d36bb4e312d218f7a2cb6f5d9793eb361e1b4f7c221eea2f1b925962f9d061",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"code": null,
"input_tokens": 2096,
"output_tokens_including_reasoning": 337,
"reasoning_tokens": 259,
"cached_input_tokens": 1829,
"cache_status": "created",
"api_elapsed_seconds": 5.531,
"logical_wire_characters": 7826,
"estimated_generation_usd_conservative": 0.001601175,
"estimated_generation_usd_lower_bound": 0.001601175,
"estimated_cache_storage_usd": 7.620833333333333e-05
},
{
"ref": "llm/operations/d844b0d123ece7c9861dbe282539f7879e6e6a21b3d1d4575c6e559fd5044aae/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "0d2018a60817afec6a462da6c01f5f3118a6ad9a87e7685501bf86c91a9d364f",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2152,
"output_tokens_including_reasoning": 633,
"reasoning_tokens": 551,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 6.203,
"logical_wire_characters": 8064,
"estimated_generation_usd_conservative": 0.002753175,
"estimated_generation_usd_lower_bound": 0.002753175,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "a1ef119cfb18c96cf64e65b99890f26128d96625fca7da45b62ad7b762cc84b6",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"code": null,
"input_tokens": 3101,
"output_tokens_including_reasoning": 365,
"reasoning_tokens": 268,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 4.407,
"logical_wire_characters": 10040,
"estimated_generation_usd_conservative": 0.0024599250000000004,
"estimated_generation_usd_lower_bound": 0.0024599250000000004,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/9d66012b57395476a4f69c72ffd0b6725da911ede849fc652d48568b73d28480/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "814552c42e71fd75326c7f15dd8b9091571e49d6b2c4a59152bf989b49232bf4",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3145,
"output_tokens_including_reasoning": 688,
"reasoning_tokens": 589,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 7.157,
"logical_wire_characters": 10233,
"estimated_generation_usd_conservative": 0.003704175,
"estimated_generation_usd_lower_bound": 0.003704175,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "c5500907581f95c660d3302d1e2c2a7ebc294653db23452df8884e2a6c529af1",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "TOOL_SOURCE_NOT_DECLARED",
"code": null,
"input_tokens": 3918,
"output_tokens_including_reasoning": 278,
"reasoning_tokens": 183,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 4.25,
"logical_wire_characters": 12241,
"estimated_generation_usd_conservative": 0.0027464250000000003,
"estimated_generation_usd_lower_bound": 0.0027464250000000003,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/7b8f9ecd4cb00c7e1d8bbd314d9ab15032701b76a0d5cf4256b895312b03a731/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "45041335c749468ea29b35ca1efeb5b923cb8dbcc1df2939b0ae1ecf7691f647",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": "PROJECT_SOURCE_RANGE",
"code": null,
"input_tokens": 3933,
"output_tokens_including_reasoning": 514,
"reasoning_tokens": 416,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 5.297,
"logical_wire_characters": 12289,
"estimated_generation_usd_conservative": 0.003642675,
"estimated_generation_usd_lower_bound": 0.003642675,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/cb89815283c33c24b09426c12c79171c3b0edf986d08dd90039905235bfaec70/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "7dd04e1eee14fc72bf0942ef3aa4d2b7d9403e3ca00c37ee7e16cbcfdfce3bd9",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": "PROJECT_SOURCE_RANGE",
"code": null,
"input_tokens": 3929,
"output_tokens_including_reasoning": 292,
"reasoning_tokens": 196,
"cached_input_tokens": 1829,
"cache_status": "reused",
"api_elapsed_seconds": 4.063,
"logical_wire_characters": 12285,
"estimated_generation_usd_conservative": 0.0028071750000000003,
"estimated_generation_usd_lower_bound": 0.0028071750000000003,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/35776bc8e579050a79e2de169c495898c8e56cc20bd5fc7414ce3bd8dbb481be/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "7dd04e1eee14fc72bf0942ef3aa4d2b7d9403e3ca00c37ee7e16cbcfdfce3bd9",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3929,
"output_tokens_including_reasoning": 314,
"reasoning_tokens": 220,
"cached_input_tokens": 1829,
"cache_status": "created",
"api_elapsed_seconds": 4.891,
"logical_wire_characters": 12285,
"estimated_generation_usd_conservative": 0.002889675,
"estimated_generation_usd_lower_bound": 0.002889675,
"estimated_cache_storage_usd": 7.620833333333333e-05
},
{
"ref": "llm/operations/0270771b422d04af95c20c38558476ded170af96569985af436406482d8d043a/round-0001.json",
"prompt_version": "investigation_startup_review_v1",
"task": "review_initial_hypotheses",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "b5b1a429d80a277343e192a02dd6728dfaf9d24ce46353635b967bd9d3df921c",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3944,
"output_tokens_including_reasoning": 2237,
"reasoning_tokens": 1291,
"cached_input_tokens": null,
"cache_status": "fallback",
"api_elapsed_seconds": 16.235,
"logical_wire_characters": 12122,
"estimated_generation_usd_conservative": 0.01134675,
"estimated_generation_usd_lower_bound": 0.00868455,
"estimated_cache_storage_usd": null
},
{
"ref": "llm/operations/c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "bfd13932cc6462ccb38516d59f65d45cc9c1e11defdabc46202aed095e5abbe4",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2426,
"output_tokens_including_reasoning": 481,
"reasoning_tokens": 347,
"cached_input_tokens": 1902,
"cache_status": "created",
"api_elapsed_seconds": 5.938,
"logical_wire_characters": 8907,
"estimated_generation_usd_conservative": 0.0023394,
"estimated_generation_usd_lower_bound": 0.0023394,
"estimated_cache_storage_usd": 7.925e-05
},
{
"ref": "llm/operations/b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "e16fd7ba07bb7a919607b94dcb6db3ca49d56f2ad12318f74f714a723f0ed17b",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3466,
"output_tokens_including_reasoning": 317,
"reasoning_tokens": 125,
"cached_input_tokens": 1902,
"cache_status": "reused",
"api_elapsed_seconds": 3.875,
"logical_wire_characters": 11306,
"estimated_generation_usd_conservative": 0.0025044,
"estimated_generation_usd_lower_bound": 0.0025044,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "consolidate_investigation_session",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "12940a9fe7af91b4c6577dbb01c262b1a24676a7c94805b5d1ac1043ca2a1a58",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"code": null,
"input_tokens": 2961,
"output_tokens_including_reasoning": 1192,
"reasoning_tokens": 767,
"cached_input_tokens": 1321,
"cache_status": "created",
"api_elapsed_seconds": 10.703,
"logical_wire_characters": 9967,
"estimated_generation_usd_conservative": 0.005799075,
"estimated_generation_usd_lower_bound": 0.005799075,
"estimated_cache_storage_usd": 5.5041666666666665e-05
},
{
"ref": "llm/operations/dfceb150480e764106de4d51501b6ed0b2daa32533888a9dabcc88114203726d/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "consolidate_investigation_session",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "05bb9f9a10fe0b7e1b58a9f8ba40816087edc39eafd4356f0ce9566c44bcebdf",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"code": null,
"input_tokens": 3007,
"output_tokens_including_reasoning": 2820,
"reasoning_tokens": 2409,
"cached_input_tokens": 1321,
"cache_status": "reused",
"api_elapsed_seconds": 19.61,
"logical_wire_characters": 10157,
"estimated_generation_usd_conservative": 0.011938575,
"estimated_generation_usd_lower_bound": 0.011938575,
"estimated_cache_storage_usd": 0.0
},
{
"ref": "llm/operations/a641cb5c51a47e1e2228d4a99c508446cfa14e6d4f1c8de3f639b6acb4851fb7/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "consolidate_investigation_session",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "05bb9f9a10fe0b7e1b58a9f8ba40816087edc39eafd4356f0ce9566c44bcebdf",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"code": null,
"input_tokens": 3007,
"output_tokens_including_reasoning": 2757,
"reasoning_tokens": 2370,
"cached_input_tokens": 1321,
"cache_status": "reused",
"api_elapsed_seconds": 17.89,
"logical_wire_characters": 10157,
"estimated_generation_usd_conservative": 0.011702325000000001,
"estimated_generation_usd_lower_bound": 0.011702325000000001,
"estimated_cache_storage_usd": 0.0
}
],
"package_valid": true,
"assessment": {
"source_clamp_verified": "Startup read 150..230 (81 lines) accepted; later 90..260 (171) also accepted and limited to 90..169.",
"startup_done": true,
"hypotheses": {
"H1": {
"confidence": "plausible",
"disposition": "active",
"invalid_responses": 3,
"iterations": 4
},
"H2": {
"confidence": "weakened",
"disposition": "active",
"invalid_responses": 0,
"iterations": 1
},
"H3": {
"confidence": "weak",
"disposition": "active",
"invalid_responses": 0,
"iterations": 1
}
},
"primary_failure": "Size-triggered consolidation output next.kind=recall (E000005 page 1), outside allowed checkpoint actions. Three repeated answers rejected, generic /next feedback failed to identify allowed alternatives.",
"remaining_budget_preserved": true,
"other_observation": "H1 repeated a source search already present in prior evidence.",
"no_automatic_salvage": "Do not silently remove or rewrite recall intent; valid analysis portions may be candidates for explicit scoped recovery."
},
"notes": [
"Output includes reasoning, never add twice.",
"Cleaned totals retain initial regular rejected answers. Seven additional calls excluded: four old startup retries, resumed H3 startup retry, two checkpoint retries.",
"Generation estimates conservative for unknown cache counts, lower bound treats unknown cache as cached. Cache storage separate; USD not EUR billing.",
"No paid API calls or program changes made during this evaluation."
],
"trial_process_elapsed_seconds": 236.406847,
"continuation_since_generation_47": {
"call_count": 7,
"usage": {
"input_tokens": {
"known_sum": 22740,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 10118,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 7529,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 9596,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 79.142,
"conservative_generation_estimate_usd": 0.0485202,
"generation_lower_bound_usd": 0.045857999999999996,
"estimated_cache_storage_usd": 0.00021050000000000002
},
"continuation_process_elapsed_seconds": 124.598143,
"trial_process_elapsed_scope": "Sum of first and resumed trial process times, excludes idle/maintenance."
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,21 @@
{
"format": "viano-manual-test-resume",
"date": "2026-10-20",
"run": "bug17-bounded-full-20261020",
"from_generation": 47,
"to_generation": 48,
"state": "INVESTIGATING_HYPOTHESES",
"manual_retry": true,
"prior_retry_not_before": "2026-10-20T20:00:32.238127+00:00",
"reason": "Explicit user-requested test continuation after fixed technical tool failure",
"unchanged_artifact_sha256": {
"investigation_state": "598aeb46462122bd559cee1a7cb162e03db7f0414decb0a8c880d229f240478d",
"budget_ledger": "7e4519804334e16b775a17d89257883fb14c5a05e9d132ba8791156dc9a79c8a",
"case_interpretation": "0fd3c2a1efe0f229592b3038b66db26e704f2fb1a03b7321ceb76450e3f98cb4",
"hypotheses": "30494a06ce373f4c497b3964524cee21bdf5350eac515f7a0022619879d125c8"
},
"budgets_reset": false,
"invalid_responses_reset": false,
"paid_api_calls": 0,
"package_valid": true
}
@@ -0,0 +1,45 @@
{
"format": "viano-trial-preparation",
"run": "bug17-bounded-full-20261020",
"date": "2026-10-20",
"code_commit": "86a02cb8c0d48690f31748ed831a2c297a902604",
"case_id": "BUG-000017",
"package_id": "trial-bounded-full-BUG-000017-20261020",
"account_eur_start": 13.01,
"billing_note": "Prior Bug20 settlement possibly still subject to a few delayed cents.",
"purpose": "Full run against already-fixed Bug17 input; assess unsupported-cause handling, bounded prompt stability, regular and corrected cost. Not a test of recovering the original pre-fix implementation defect.",
"dispatch_safety_limit": 1000,
"budget_and_iteration_limits_unchanged": true,
"inputs": [
{
"file": "BUG-000017-20261015-213913.tar.gz",
"sha256": "6fc61e0c54d18eb0673827aa69284f48807b80928c7d68643d2b920584cbcfde"
},
{
"file": "WOWSRC-BUG-000017-20261015-213934.tar.gz",
"sha256": "a189ef80672658466d30812fb095f88ab932870cdadc40d97665b73d31029561"
}
],
"configuration_sha256": {
"config\\llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config\\project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config\\investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"storage": {
"limit_bytes": 20000000000,
"measured_bytes": 2395792187,
"roots": {
"service-data\\trials": 48069916,
"service-data\\benchmarks": 498385,
"service-data\\test-archive": 1740768879,
"service-data\\inspection": 134752609,
"tests\\fixtures\\llm_rejections": 2268510,
"C:\\Users\\User\\AppData\\Local\\Temp\\pytest-of-User": 469433888
},
"archived_workspace_bytes_removed": 18296667356,
"final_results_and_descriptions_retained_under": "service-data/test-archive/",
"warning": "Reserve is finite; unusually large research payloads may still require storage observation during long execution."
},
"paid_api_calls_by_agent": 0,
"state": "VALIDATED"
}
@@ -0,0 +1,51 @@
{
"format": "viano-offline-regression",
"date": "2026-10-20",
"run": "bug17-bounded-full-20261020",
"source_generation": 84,
"scope": "All three rejected checkpoint replies validated unchanged against their exact saved full contexts; no tool execution, budget mutation or paid LLM request.",
"results": [
{
"call_ref": "llm/operations/6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1/round-0001.json",
"reply_sha256": "44b25b401d7019b6da566658147d28c93e7aeaf22644497200afdb7b3ceae386",
"full_saved_context_validation": "passed",
"request_messages_schema_version_unchanged": true
},
{
"call_ref": "llm/operations/dfceb150480e764106de4d51501b6ed0b2daa32533888a9dabcc88114203726d/round-0001.json",
"reply_sha256": "7ab36e7d2604dc8c4537eef2516f2ed68cdeaa6864d1f4a98b5cd41d16933250",
"full_saved_context_validation": "passed",
"request_messages_schema_version_unchanged": true
},
{
"call_ref": "llm/operations/a641cb5c51a47e1e2228d4a99c508446cfa14e6d4f1c8de3f639b6acb4851fb7/round-0001.json",
"reply_sha256": "5546ff27268c2a0a699280edd3b8d713f0387730499db12ea94e97051e4cdf03",
"full_saved_context_validation": "passed",
"request_messages_schema_version_unchanged": true
}
],
"local_tests": {
"passed": 89,
"elapsed_seconds": 158.35,
"scope": "checkpoint recall, bounded v1/v2, lean loop, canonical decisions and startup"
},
"source_sha256": {
"src\\viano_bug_analysis\\analysis\\investigation_compact.py": "2522b63dd5b4943213afa659b1531aea64231a7a4777f5113f5f8f17f0f7290f",
"src\\viano_bug_analysis\\analysis\\investigation_lean_v20.py": "f6373c0cf6c619129c127784c0ef088f14480f892c9817c12ce6a48e7ffc6d09",
"src\\viano_bug_analysis\\analysis\\investigator.py": "5993ad05bc8a971f167e7056ba66fc2b928f26c7299da744a832d1dd4069cabd"
},
"manual_resume": {
"from_generation": 84,
"to_generation": 85,
"state": "INVESTIGATING_HYPOTHESES",
"unchanged_artifact_sha256": {
"investigation_state": "f469f7431a46880da4ee34ae8912d20977607665bc6985607903086718a48a68",
"budget_ledger": "c501e306fafc85bc63f443c72376d99f5e77311d3fb15cd8b7b3cedcca66282d",
"case_interpretation": "0fd3c2a1efe0f229592b3038b66db26e704f2fb1a03b7321ceb76450e3f98cb4",
"hypotheses": "30494a06ce373f4c497b3964524cee21bdf5350eac515f7a0022619879d125c8"
},
"budgets_reset": false,
"invalid_responses_reset": false,
"paid_api_calls": 0
}
}
@@ -0,0 +1,34 @@
{
"format": "viano-test-preparation",
"format_version": 1,
"recorded_date": "2026-10-21",
"run": "bug17-qualified-review-20261021",
"case_id": "BUG-000017",
"package_id": "trial-qualified-review-BUG-000017-20261021",
"code_commit": "4e8ed1adce50dd6c3196f9d3aace96a7285608ea",
"configuration_sha256": {
"config/llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config/project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config/investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"input_reference": "bug17-bounded-full-20261020-g00000228.json",
"account_eur": {
"last_confirmed": 13.37,
"new_run_start_confirmed": false
},
"storage_bytes_before_preparation": 11598544732,
"storage_limit_bytes": 20000000000,
"database_health": {
"local_server_started": true,
"read_only": true,
"reader_schema_query_ok": true
},
"source_commit": "3a6c0b5575f8aaf1bd12ebca26d52fbeb122f086",
"expected_prompt_versions": [
"diagnosis_v8 or diagnosis_early_v8",
"change_request_v9"
],
"test_goal": "Fresh Bug17 regression with unchanged inputs and pinned research snapshot; evaluate explicit causal inference, retained uncertainty and observable downstream validation requirements without imposing a particular outcome. Compare tokens, corrections, cost and bounded prompt sizes.",
"prepared_state": "VALIDATED",
"paid_api_calls": 0
}
@@ -0,0 +1,20 @@
{
"date": "2026-10-20",
"case_id": "BUG-000017",
"package_id": "trial-bounded-full-BUG-000017-20261020",
"from_generation": 204,
"to_generation": 206,
"state": "INVESTIGATING_HYPOTHESES",
"api_calls": 0,
"full_logical_input_characters": 13849,
"preserved_original_entries": 806,
"budget_unchanged": true,
"hypothesis_states_unchanged": true,
"active_attempt_unchanged": true,
"new_context_ref": "analysis/investigation/0001/contexts/H1-0019-attempt-0003-guidance-v1.json",
"changes": [
"manual technical retry",
"append versioned source guidance and precise rejection details"
],
"package_valid": true
}
@@ -0,0 +1,19 @@
{
"format": "viano-test-cost-update",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-bounded-window-20261020",
"package_generation": 50,
"token_report": "bug20-bounded-window-20261020-g00000050.json",
"account_eur": {
"start": 12.7,
"latest_reported": 12.83,
"difference": 0.13,
"settlement": "user_reported_updated_balance_further_updates_possible"
},
"source": "User-reported Google API account balance",
"notes": [
"Original token report remains unchanged.",
"EUR account difference is separate from USD token cost estimates."
]
}
@@ -0,0 +1,624 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-bounded-window-20261020",
"code_commit": "682f275590a4b1d3ff61d0ebfc974eeb874000c4",
"case_id": "BUG-000020",
"package_id": "trial-bounded-window-BUG-000020-20261020",
"package_generation": 50,
"analysis_revision": 1,
"state": "BLOCKED",
"routing": {
"destination": "inbox",
"reason": "INVALID_LLM_RESPONSES",
"retry_count": 1,
"retry_not_before": "2026-10-20T16:30:55.095729+00:00"
},
"source_manifest_sha256": "942bbcce6c24aed7a1924b2c396a2c28651d1b4bc3e2d409fd54c281dcb93b7e",
"configuration_sha256": {
"config/llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config/project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config/investigation.bounded.toml": "cf5317fbcf43494043ecd574843588888a5f756d8c9c52987b6411df4ba98250"
},
"pricing_snapshot": [
{
"id": "gemini-native",
"model": "gemini-3.8-flash",
"cost_currency": "USD",
"input_cost_per_million": 0.75,
"cached_input_cost_per_million": 0.075,
"output_cost_per_million": 3.75,
"cache_storage_cost_per_million_hour": 0.5
}
],
"account_eur": {
"start": 12.7,
"final": null,
"settlement": "pending"
},
"case_elapsed_seconds_including_local_work_and_idle": 562.670313,
"scope": "Partial failed regression: initial H1/H2 tool executions only, H3 exhausted invalid replies. No joint startup review or normal followup executed.",
"notes": [
"Output tokens include reasoning: never add reasoning twice.",
"Cleaned view retains first regular calls even when rejected; removes additional retries and repairs, including successful replacements.",
"Unknown cached counts remain unknown. Conservative USD estimate charges their entire input at uncached rate; lower bound assumes all unknown input cached. These are estimates, not measured billing.",
"Cache storage is reported separately from generation. USD estimates are not EUR account differences.",
"Protocol-valid gateway metadata is not proof of controller acceptance. Controller rejection codes are listed separately.",
"No additional paid API calls were made for this evaluation."
],
"totals_all": {
"call_count": 11,
"usage": {
"input_tokens": {
"known_sum": 88947,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 23353,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 18769,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 13615,
"unknown_call_count": 4
}
},
"api_elapsed_seconds_sum": 190.904,
"conservative_generation_estimate_usd": 0.14509387499999998,
"generation_lower_bound_usd": 0.09986819999999999,
"estimated_cache_storage_usd": 8.104166666666667e-05
},
"totals_cleaned": {
"call_count": 6,
"usage": {
"input_tokens": {
"known_sum": 69350,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 6318,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2514,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 5835,
"unknown_call_count": 3
}
},
"api_elapsed_seconds_sum": 60.952,
"conservative_generation_estimate_usd": 0.07176637500000001,
"generation_lower_bound_usd": 0.031292025,
"estimated_cache_storage_usd": 8.104166666666667e-05
},
"totals_correction_overhead": {
"call_count": 5,
"usage": {
"input_tokens": {
"known_sum": 19597,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 17035,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 16255,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 7780,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 129.952,
"conservative_generation_estimate_usd": 0.07332749999999999,
"generation_lower_bound_usd": 0.06857617499999999,
"estimated_cache_storage_usd": 0
},
"by_group": {
"entity_resolution": {
"all": {
"call_count": 2,
"usage": {
"input_tokens": {
"known_sum": 46198,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 584,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 2
}
},
"api_elapsed_seconds_sum": 7.374,
"conservative_generation_estimate_usd": 0.036838499999999996,
"generation_lower_bound_usd": 0.0056548499999999995,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 2,
"usage": {
"input_tokens": {
"known_sum": 46198,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 584,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 2
}
},
"api_elapsed_seconds_sum": 7.374,
"conservative_generation_estimate_usd": 0.036838499999999996,
"generation_lower_bound_usd": 0.0056548499999999995,
"estimated_cache_storage_usd": 0
}
},
"investigation_startup": {
"all": {
"call_count": 7,
"usage": {
"input_tokens": {
"known_sum": 21946,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 12167,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 11420,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 13615,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 104.546,
"conservative_generation_estimate_usd": 0.052895625,
"generation_lower_bound_usd": 0.052895625,
"estimated_cache_storage_usd": 8.104166666666667e-05
},
"cleaned": {
"call_count": 3,
"usage": {
"input_tokens": {
"known_sum": 9388,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 1931,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1625,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 5835,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 21.922,
"conservative_generation_estimate_usd": 0.010343625,
"generation_lower_bound_usd": 0.010343625,
"estimated_cache_storage_usd": 8.104166666666667e-05
}
},
"joint_planning": {
"all": {
"call_count": 2,
"usage": {
"input_tokens": {
"known_sum": 20803,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 10602,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 7349,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 2
}
},
"api_elapsed_seconds_sum": 78.984,
"conservative_generation_estimate_usd": 0.05535975,
"generation_lower_bound_usd": 0.041317725,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 13764,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 3803,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 889,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 31.656,
"conservative_generation_estimate_usd": 0.024584250000000002,
"generation_lower_bound_usd": 0.01529355,
"estimated_cache_storage_usd": 0
}
}
},
"calls": [
{
"call_ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"call_sha256": "71183b48fb9031800585296b4600a74b6ea21af7668c710d319838950b1c2f24",
"prompt_version": "entity_resolution_plan_v4",
"phase": "INTERPRETING_CASE",
"group": "entity_resolution",
"hypothesis": null,
"is_extra_correction_or_retry": false,
"status": "SUCCESS",
"controller_rejection": null,
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 21009,
"output_tokens_including_reasoning": 174,
"reasoning_tokens": null,
"cached_input_tokens": null
},
"api_elapsed_seconds": 2.718,
"prompt_size": null,
"cost_estimate_usd": 0.01640925,
"cost_lower_bound_usd": 0.0022281749999999998,
"cost_assumption": "unknown cache treated as uncached for conservative estimate",
"estimated_cache_storage_usd": 0.0
},
{
"call_ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"call_sha256": "ed4335153b356b314bb134ddf8ac72a80d879559ce30ce9a097a23995416a9d6",
"prompt_version": "entity_resolution_assessment_v4",
"phase": "INTERPRETING_CASE",
"group": "entity_resolution",
"hypothesis": null,
"is_extra_correction_or_retry": false,
"status": "SUCCESS",
"controller_rejection": null,
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 25189,
"output_tokens_including_reasoning": 410,
"reasoning_tokens": null,
"cached_input_tokens": null
},
"api_elapsed_seconds": 4.656,
"prompt_size": null,
"cost_estimate_usd": 0.02042925,
"cost_lower_bound_usd": 0.0034266749999999997,
"cost_assumption": "unknown cache treated as uncached for conservative estimate",
"estimated_cache_storage_usd": 0.0
},
{
"call_ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"call_sha256": "e3ce25e9f046c32c85b1f29449e03cab831ff5d0c4a2ab680b37914c6b3bddfc",
"prompt_version": "case_plan_v2",
"phase": "INTERPRETING_CASE",
"group": "joint_planning",
"hypothesis": null,
"is_extra_correction_or_retry": false,
"status": "SUCCESS",
"controller_rejection": null,
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 13764,
"output_tokens_including_reasoning": 3803,
"reasoning_tokens": 889,
"cached_input_tokens": null
},
"api_elapsed_seconds": 31.656,
"prompt_size": null,
"cost_estimate_usd": 0.024584250000000002,
"cost_lower_bound_usd": 0.01529355,
"cost_assumption": "unknown cache treated as uncached for conservative estimate",
"estimated_cache_storage_usd": 0.0
},
{
"call_ref": "llm/operations/cdf9fddd5dccf7c6859f2f4c5aa65e46778d6d44e446cf579fa6b6f462b9b85c/round-0001.json",
"call_sha256": "2286a45b050438a8dcf66ea39d2c3ead8c01a7adb593257eb42a40f9fff42f11",
"prompt_version": "case_plan_statement_repair_v2",
"phase": "INTERPRETING_CASE",
"group": "joint_planning",
"hypothesis": null,
"is_extra_correction_or_retry": true,
"status": "SUCCESS",
"controller_rejection": null,
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 7039,
"output_tokens_including_reasoning": 6799,
"reasoning_tokens": 6460,
"cached_input_tokens": null
},
"api_elapsed_seconds": 47.328,
"prompt_size": null,
"cost_estimate_usd": 0.0307755,
"cost_lower_bound_usd": 0.026024175,
"cost_assumption": "unknown cache treated as uncached for conservative estimate",
"estimated_cache_storage_usd": 0.0
},
{
"call_ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"call_sha256": "688eb5fb8a782cabbf324fa17a54e3b9a368266fdd3a7c7093ae21b1caf41b92",
"prompt_version": "investigation_startup_v1",
"phase": "INVESTIGATING_HYPOTHESES",
"group": "investigation_startup",
"hypothesis": "H1",
"is_extra_correction_or_retry": false,
"status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 2201,
"output_tokens_including_reasoning": 645,
"reasoning_tokens": 570,
"cached_input_tokens": 1945
},
"api_elapsed_seconds": 7.734,
"prompt_size": {
"accounted_characters": 8042,
"limit_characters": 20000,
"message_characters": 6871,
"target_characters": 10000
},
"cost_estimate_usd": 0.002756625,
"cost_lower_bound_usd": 0.002756625,
"cost_assumption": "measured cached token count",
"estimated_cache_storage_usd": 8.104166666666667e-05,
"full_gemini_logical_characters": 8992
},
{
"call_ref": "llm/operations/d844b0d123ece7c9861dbe282539f7879e6e6a21b3d1d4575c6e559fd5044aae/round-0001.json",
"call_sha256": "604896130cedbc14a95f2afd8b9ccab1ceb66345375ed68ec9ef5d348bedeca5",
"prompt_version": "investigation_startup_v1",
"phase": "INVESTIGATING_HYPOTHESES",
"group": "investigation_startup",
"hypothesis": "H1",
"is_extra_correction_or_retry": true,
"status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 2211,
"output_tokens_including_reasoning": 590,
"reasoning_tokens": 526,
"cached_input_tokens": 1945
},
"api_elapsed_seconds": 6.64,
"prompt_size": {
"accounted_characters": 8086,
"limit_characters": 20000,
"message_characters": 6915,
"target_characters": 10000
},
"cost_estimate_usd": 0.0025578750000000003,
"cost_lower_bound_usd": 0.0025578750000000003,
"cost_assumption": "measured cached token count",
"estimated_cache_storage_usd": 0.0,
"full_gemini_logical_characters": 9036
},
{
"call_ref": "llm/operations/68df285004e1ad76029de7884a6b2c77db165a926dd10c44c34c5cf54472af0e/round-0001.json",
"call_sha256": "3e15c66994718137af6547d6f388c5cc2fde0134288d6c262f5d03dbd8aa7798",
"prompt_version": "investigation_startup_v1",
"phase": "INVESTIGATING_HYPOTHESES",
"group": "investigation_startup",
"hypothesis": "H1",
"is_extra_correction_or_retry": true,
"status": "SUCCESS",
"controller_rejection": null,
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 2211,
"output_tokens_including_reasoning": 2096,
"reasoning_tokens": 1982,
"cached_input_tokens": 1945
},
"api_elapsed_seconds": 16.953,
"prompt_size": {
"accounted_characters": 8086,
"limit_characters": 20000,
"message_characters": 6915,
"target_characters": 10000
},
"cost_estimate_usd": 0.008205375,
"cost_lower_bound_usd": 0.008205375,
"cost_assumption": "measured cached token count",
"estimated_cache_storage_usd": 0.0,
"full_gemini_logical_characters": 9036
},
{
"call_ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"call_sha256": "c1a22b89977c92c0d69132e54b974c3582c2391c5c8a8ada4dbdceb574ac8254",
"prompt_version": "investigation_startup_v1",
"phase": "INVESTIGATING_HYPOTHESES",
"group": "investigation_startup",
"hypothesis": "H2",
"is_extra_correction_or_retry": false,
"status": "SUCCESS",
"controller_rejection": null,
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 3145,
"output_tokens_including_reasoning": 586,
"reasoning_tokens": 471,
"cached_input_tokens": 1945
},
"api_elapsed_seconds": 6.36,
"prompt_size": {
"accounted_characters": 11176,
"limit_characters": 20000,
"message_characters": 10005,
"target_characters": 10000
},
"cost_estimate_usd": 0.0032433749999999997,
"cost_lower_bound_usd": 0.0032433749999999997,
"cost_assumption": "measured cached token count",
"estimated_cache_storage_usd": 0.0,
"full_gemini_logical_characters": 12126
},
{
"call_ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"call_sha256": "b927c65761e52d47b0f79f3c8dd2932c9d5561b8a452c217076948a32ef4aea7",
"prompt_version": "investigation_startup_v1",
"phase": "INVESTIGATING_HYPOTHESES",
"group": "investigation_startup",
"hypothesis": "H3",
"is_extra_correction_or_retry": false,
"status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 4042,
"output_tokens_including_reasoning": 700,
"reasoning_tokens": 584,
"cached_input_tokens": 1945
},
"api_elapsed_seconds": 7.828,
"prompt_size": {
"accounted_characters": 14239,
"limit_characters": 20000,
"message_characters": 13068,
"target_characters": 10000
},
"cost_estimate_usd": 0.004343625,
"cost_lower_bound_usd": 0.004343625,
"cost_assumption": "measured cached token count",
"estimated_cache_storage_usd": 0.0,
"full_gemini_logical_characters": 15189
},
{
"call_ref": "llm/operations/7b8f9ecd4cb00c7e1d8bbd314d9ab15032701b76a0d5cf4256b895312b03a731/round-0001.json",
"call_sha256": "4c37abb4a564ffbd7a1516504574b09b903ebb213a971fc5afa2151d1d89ddba",
"prompt_version": "investigation_startup_v1",
"phase": "INVESTIGATING_HYPOTHESES",
"group": "investigation_startup",
"hypothesis": "H3",
"is_extra_correction_or_retry": true,
"status": "ERROR",
"controller_rejection": "LLM_OUTPUT_SCHEMA",
"provider_error": "LLM_OUTPUT_SCHEMA",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 4052,
"output_tokens_including_reasoning": 1454,
"reasoning_tokens": 1319,
"cached_input_tokens": 1945
},
"api_elapsed_seconds": 13.453,
"prompt_size": {
"accounted_characters": 14283,
"limit_characters": 20000,
"message_characters": 13112,
"target_characters": 10000
},
"cost_estimate_usd": 0.007178625,
"cost_lower_bound_usd": 0.007178625,
"cost_assumption": "measured cached token count",
"estimated_cache_storage_usd": 0.0,
"full_gemini_logical_characters": 15233
},
{
"call_ref": "llm/operations/cb89815283c33c24b09426c12c79171c3b0edf986d08dd90039905235bfaec70/round-0001.json",
"call_sha256": "ad3821e4f6d343d2d4fdebd754b2d67bb103697a37d2ed097ef603f5eb514f2c",
"prompt_version": "investigation_startup_v1",
"phase": "INVESTIGATING_HYPOTHESES",
"group": "investigation_startup",
"hypothesis": "H3",
"is_extra_correction_or_retry": true,
"status": "SUCCESS",
"controller_rejection": "INVESTIGATION_OUTPUT",
"provider_error": null,
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"usage": {
"input_tokens": 4084,
"output_tokens_including_reasoning": 6096,
"reasoning_tokens": 5968,
"cached_input_tokens": 1945
},
"api_elapsed_seconds": 45.578,
"prompt_size": {
"accounted_characters": 14399,
"limit_characters": 20000,
"message_characters": 13228,
"target_characters": 10000
},
"cost_estimate_usd": 0.024610124999999997,
"cost_lower_bound_usd": 0.024610124999999997,
"cost_assumption": "measured cached token count",
"estimated_cache_storage_usd": 0.0,
"full_gemini_logical_characters": 15349
}
]
}
@@ -0,0 +1,773 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-contract-v2-20261020",
"code_commit": "3a82a37ee688be35ba636f8659d0ba14fb27351e",
"case_id": "BUG-000020",
"package_id": "trial-contract-v2-BUG-000020-20261020",
"package_generation": 77,
"analysis_revision": 1,
"state": "INVESTIGATING_HYPOTHESES",
"routing": {
"destination": "cases",
"reason": null,
"retry_count": 0,
"retry_not_before": null
},
"source_manifest_sha256": "5bae0f64a5452493edb67a79aea2f7b938e62ff748535c9fdb1911b8af482fdb",
"configuration_sha256": {
"config\\llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config\\project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config\\investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"pricing_snapshot": [
{
"id": "gemini-native",
"model": "gemini-3.8-flash",
"cost_currency": "USD",
"input_cost_per_million": 0.75,
"cached_input_cost_per_million": 0.075,
"output_cost_per_million": 3.75,
"cache_storage_cost_per_million_hour": 0.5
}
],
"pricing_source": "Same configured USD rates as preceding report; not newly fetched market prices. Snapshot 2026-10-20.",
"account_eur": {
"start": 12.83,
"final": null,
"settlement": "pending"
},
"scope": "12 dispatches; three startup hypotheses and joint review completed, three normal H1 queries; checkpoint response rejected for missing uncertainties, retry pending. Not a completed analysis.",
"notes": [
"Output includes reasoning; do not add twice.",
"First regular calls retained in cleaned totals even if rejected. Only second H2 startup is correction overhead so far. No checkpoint correction has executed yet.",
"Missing cached values remain unknown; conservative estimate treats unknown input as uncached, lower bound as cached. Cache storage separate; USD estimate is not EUR billing.",
"Wire counts reconstruct configured stable-cache transport from retained requests, not token estimates.",
"No paid API requests made for evaluation."
],
"totals_all": {
"call_count": 12,
"usage": {
"input_tokens": {
"known_sum": 87349,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 16566,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 10045,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 16005,
"unknown_call_count": 4
}
},
"api_elapsed_seconds_sum": 143.10700000000003,
"conservative_generation_estimate_usd": 0.11683087499999999,
"generation_lower_bound_usd": 0.073790175,
"estimated_cache_storage_usd": 0.00023658333333333333
},
"totals_cleaned": {
"call_count": 11,
"usage": {
"input_tokens": {
"known_sum": 84081,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 15834,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 9425,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 13970,
"unknown_call_count": 4
}
},
"api_elapsed_seconds_sum": 135.82600000000002,
"conservative_generation_estimate_usd": 0.11300849999999998,
"generation_lower_bound_usd": 0.0699678,
"estimated_cache_storage_usd": 0.00023658333333333333
},
"totals_correction_overhead": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 3268,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 732,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 620,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 2035,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 7.281,
"conservative_generation_estimate_usd": 0.003822375,
"generation_lower_bound_usd": 0.003822375,
"estimated_cache_storage_usd": 0
},
"phases": {
"entity_resolution_plan_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21008,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 194,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 3.703,
"conservative_generation_estimate_usd": 0.0164835,
"generation_lower_bound_usd": 0.0023030999999999998,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21008,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 194,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 3.703,
"conservative_generation_estimate_usd": 0.0164835,
"generation_lower_bound_usd": 0.0023030999999999998,
"estimated_cache_storage_usd": 0
}
},
"entity_resolution_assessment_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 25795,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 526,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 6.782,
"conservative_generation_estimate_usd": 0.02131875,
"generation_lower_bound_usd": 0.003907125,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 25795,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 526,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 6.782,
"conservative_generation_estimate_usd": 0.02131875,
"generation_lower_bound_usd": 0.003907125,
"estimated_cache_storage_usd": 0
}
},
"case_plan_v2": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 13944,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 6216,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2300,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 42.015,
"conservative_generation_estimate_usd": 0.033768,
"generation_lower_bound_usd": 0.0243558,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 13944,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 6216,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2300,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 42.015,
"conservative_generation_estimate_usd": 0.033768,
"generation_lower_bound_usd": 0.0243558,
"estimated_cache_storage_usd": 0
}
},
"investigation_startup_v1": {
"all": {
"call_count": 4,
"usage": {
"input_tokens": {
"known_sum": 12388,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2477,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2117,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 8140,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 26.139,
"conservative_generation_estimate_usd": 0.01308525,
"generation_lower_bound_usd": 0.01308525,
"estimated_cache_storage_usd": 8.479166666666666e-05
},
"cleaned": {
"call_count": 3,
"usage": {
"input_tokens": {
"known_sum": 9120,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 1745,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1497,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 6105,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 18.858,
"conservative_generation_estimate_usd": 0.009262875,
"generation_lower_bound_usd": 0.009262875,
"estimated_cache_storage_usd": 8.479166666666666e-05
}
},
"investigation_startup_review_v1": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 3017,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2650,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1985,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 22.219,
"conservative_generation_estimate_usd": 0.01220025,
"generation_lower_bound_usd": 0.010163775,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 3017,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2650,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1985,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 22.219,
"conservative_generation_estimate_usd": 0.01220025,
"generation_lower_bound_usd": 0.010163775,
"estimated_cache_storage_usd": 0
}
},
"investigation_project_v20": {
"all": {
"call_count": 4,
"usage": {
"input_tokens": {
"known_sum": 11197,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 4503,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 3643,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 7865,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 42.248999999999995,
"conservative_generation_estimate_usd": 0.019975125,
"generation_lower_bound_usd": 0.019975125,
"estimated_cache_storage_usd": 0.00015179166666666667
},
"cleaned": {
"call_count": 4,
"usage": {
"input_tokens": {
"known_sum": 11197,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 4503,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 3643,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 7865,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 42.248999999999995,
"conservative_generation_estimate_usd": 0.019975125,
"generation_lower_bound_usd": 0.019975125,
"estimated_cache_storage_usd": 0.00015179166666666667
}
}
},
"calls": [
{
"ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"prompt_version": "entity_resolution_plan_v4",
"task": "entity_resolution_plan",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "993e4d9865e4e44ce59f3d6753713cac5fb009c217a14827b9a935c24be9a280",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 21008,
"output_tokens_including_reasoning": 194,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 3.703,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.0164835,
"estimated_generation_usd_lower_bound": 0.0023030999999999998,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"prompt_version": "entity_resolution_assessment_v4",
"task": "entity_resolution_assessment",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "dc7bcd2f719f6b0c0e104e21868d74809c4aaaad9fc43a40b92b03d886e1706c",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 25795,
"output_tokens_including_reasoning": 526,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 6.782,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.02131875,
"estimated_generation_usd_lower_bound": 0.003907125,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"prompt_version": "case_plan_v2",
"task": "interpret_and_propose",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "90d3e9354a928239039bc3cb3b4c0aad9e21a03c7e30e2c9fac37db66f25327f",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 13944,
"output_tokens_including_reasoning": 6216,
"reasoning_tokens": 2300,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 42.015,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.033768,
"estimated_generation_usd_lower_bound": 0.0243558,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "4430ab1441295f8310c7f4d7f3db6679d1428d3ae2d659b12a88ee40d798f018",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2309,
"output_tokens_including_reasoning": 254,
"reasoning_tokens": 178,
"cached_input_tokens": 2035,
"cache_status": "created",
"api_elapsed_seconds": 5.109,
"logical_wire_characters": 8501,
"estimated_generation_usd_conservative": 0.001310625,
"estimated_generation_usd_lower_bound": 0.001310625,
"estimated_cache_storage_usd": 8.479166666666666e-05,
"normalization_rules": []
},
{
"ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "cbbefac0dbbeddacba3f779db8566e7b46f94014938cdab32c7d199fa17908c5",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "PROJECT_DATABASE_COLUMN_UNKNOWN",
"code": null,
"input_tokens": 3255,
"output_tokens_including_reasoning": 890,
"reasoning_tokens": 779,
"cached_input_tokens": 2035,
"cache_status": "reused",
"api_elapsed_seconds": 7.234,
"logical_wire_characters": 11638,
"estimated_generation_usd_conservative": 0.004405125,
"estimated_generation_usd_lower_bound": 0.004405125,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/9d66012b57395476a4f69c72ffd0b6725da911ede849fc652d48568b73d28480/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "9999501f1cb30251053a33f9c1938361c27ff980458c5bb94f993e43bfd8a97f",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3268,
"output_tokens_including_reasoning": 732,
"reasoning_tokens": 620,
"cached_input_tokens": 2035,
"cache_status": "reused",
"api_elapsed_seconds": 7.281,
"logical_wire_characters": 11693,
"estimated_generation_usd_conservative": 0.003822375,
"estimated_generation_usd_lower_bound": 0.003822375,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "6b950849ec02eccfaaf16daa464a17454104532e38b6a4e77c343585f189adbf",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3556,
"output_tokens_including_reasoning": 601,
"reasoning_tokens": 540,
"cached_input_tokens": 2035,
"cache_status": "reused",
"api_elapsed_seconds": 6.515,
"logical_wire_characters": 12605,
"estimated_generation_usd_conservative": 0.003547125,
"estimated_generation_usd_lower_bound": 0.003547125,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/0270771b422d04af95c20c38558476ded170af96569985af436406482d8d043a/round-0001.json",
"prompt_version": "investigation_startup_review_v1",
"task": "review_initial_hypotheses",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "f6aba1d7fb8441d8e92b02164d2d3be522f756f43869b8ca8a9b83a37ce51a8d",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3017,
"output_tokens_including_reasoning": 2650,
"reasoning_tokens": 1985,
"cached_input_tokens": null,
"cache_status": "fallback",
"api_elapsed_seconds": 22.219,
"logical_wire_characters": 11012,
"estimated_generation_usd_conservative": 0.01220025,
"estimated_generation_usd_lower_bound": 0.010163775,
"estimated_cache_storage_usd": null,
"normalization_rules": []
},
{
"ref": "llm/operations/c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "8aab768fb27cb68e9c5cd8a90a2851fd6495b9bd1f7413bb0bb0be32269551a9",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2609,
"output_tokens_including_reasoning": 345,
"reasoning_tokens": 249,
"cached_input_tokens": 2111,
"cache_status": "created",
"api_elapsed_seconds": 6.781,
"logical_wire_characters": 9430,
"estimated_generation_usd_conservative": 0.001825575,
"estimated_generation_usd_lower_bound": 0.001825575,
"estimated_cache_storage_usd": 8.795833333333333e-05,
"normalization_rules": []
},
{
"ref": "llm/operations/b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "06f2bf0af9139e07d42f73f658b1c027ff450ee15dd67c38bc80158216323492",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2938,
"output_tokens_including_reasoning": 414,
"reasoning_tokens": 212,
"cached_input_tokens": 2111,
"cache_status": "reused",
"api_elapsed_seconds": 4.812,
"logical_wire_characters": 10486,
"estimated_generation_usd_conservative": 0.0023310749999999997,
"estimated_generation_usd_lower_bound": 0.0023310749999999997,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "409b8272bc913ebb496e5bcf36cb029f119dfb6e0f593690884f4a11afe834c2",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3059,
"output_tokens_including_reasoning": 518,
"reasoning_tokens": 350,
"cached_input_tokens": 2111,
"cache_status": "reused",
"api_elapsed_seconds": 6.781,
"logical_wire_characters": 10814,
"estimated_generation_usd_conservative": 0.002811825,
"estimated_generation_usd_lower_bound": 0.002811825,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/475d5f458554c35131f24fc92fb2e762c69a8d9c6d4ab9d6426fbd72e6303af3/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "consolidate_investigation_session",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "bccdc72074422d53720daee19dbe30d7b0b547defa38274bfa5a10fb301972ea",
"correction": false,
"gateway_status": "ERROR",
"controller_rejection": "LLM_OUTPUT_SCHEMA",
"code": "LLM_OUTPUT_SCHEMA",
"input_tokens": 2591,
"output_tokens_including_reasoning": 3226,
"reasoning_tokens": 2832,
"cached_input_tokens": 1532,
"cache_status": "created",
"api_elapsed_seconds": 23.875,
"logical_wire_characters": 9156,
"estimated_generation_usd_conservative": 0.01300665,
"estimated_generation_usd_lower_bound": 0.01300665,
"estimated_cache_storage_usd": 6.383333333333333e-05,
"normalization_rules": []
}
],
"startup_done": true,
"hypotheses": {
"H1": {
"confidence": "strongly_supported",
"iterations": 5,
"invalid_responses": 1,
"disposition": "active"
},
"H2": {
"confidence": "weakened",
"iterations": 1,
"invalid_responses": 0,
"disposition": "active"
},
"H3": {
"confidence": "weakened",
"iterations": 1,
"invalid_responses": 0,
"disposition": "active"
}
},
"package_valid": true,
"trial_process_elapsed_seconds": 248.332418,
"trial_process_elapsed_scope": "Telemetry process start to stop; excludes previous local import/preparation. Includes local processing.",
"assessment": {
"last_rejection": {
"code": "LLM_OUTPUT_SCHEMA",
"task": "consolidate_investigation_session",
"validation_path": "/",
"missing_required_fields": [
"uncertainties"
],
"retry_executed": false
},
"startup_correction": {
"hypothesis": "H2",
"code": "PROJECT_DATABASE_COLUMN_UNKNOWN",
"unknown_column": "InhabitType",
"recovery": "Next LLM query removed the unknown column; valid query executed."
},
"known_redundancy": "H1 repeats the creature_template name search already performed in H2 startup.",
"deterministic_choice_unwrap_exercised": false,
"entity_reference_catalog_exercised_by_source_context_query": false,
"caution": "No source.context query emitted; catalog presence alone is not a live proof of correct N reference usage. No deterministic choice-wrapper recovery observed."
}
}
@@ -0,0 +1,912 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-contract-v2-20261020",
"code_commit": "3a82a37ee688be35ba636f8659d0ba14fb27351e",
"case_id": "BUG-000020",
"package_id": "trial-contract-v2-BUG-000020-20261020",
"package_generation": 97,
"analysis_revision": 1,
"state": "INVESTIGATING_HYPOTHESES",
"routing": {
"destination": "cases",
"reason": null,
"retry_count": 0,
"retry_not_before": null
},
"source_manifest_sha256": "da782e00a19ea780eb01dad707e4bcbc69fb75542416e6f1c5fa3ab411837393",
"configuration_sha256": {
"config\\llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config\\project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config\\investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"pricing_snapshot": [
{
"id": "gemini-native",
"model": "gemini-3.8-flash",
"cost_currency": "USD",
"input_cost_per_million": 0.75,
"cached_input_cost_per_million": 0.075,
"output_cost_per_million": 3.75,
"cache_storage_cost_per_million_hour": 0.5
}
],
"pricing_source": "Same configured USD rates as preceding report; not newly fetched market prices. Snapshot 2026-10-20.",
"account_eur": {
"start": 12.83,
"intermediate": 12.93,
"final": null,
"settlement": "pending"
},
"scope": "17 dispatches cumulative. H1 finished strongly supported; H2 rejected weakened; H3 active after evidence recall. All five continuation replies accepted; no new schema rejection.",
"notes": [
"Output includes reasoning; do not add twice.",
"Missing cached values remain unknown; conservative estimate treats unknown input as uncached, lower bound as cached. Cache storage separate; USD estimate is not EUR billing.",
"Wire counts reconstruct configured stable-cache transport from retained requests, not token estimates.",
"No paid API requests made for evaluation.",
"Cleaned totals retain first regular calls, including rejected calls. Exclude second H2 startup and successful H1 checkpoint retry; two additional correction calls total."
],
"totals_all": {
"call_count": 17,
"usage": {
"input_tokens": {
"known_sum": 100106,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 22751,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 15421,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 25402,
"unknown_call_count": 4
}
},
"api_elapsed_seconds_sum": 195.64000000000001,
"conservative_generation_estimate_usd": 0.1432494,
"generation_lower_bound_usd": 0.10020869999999998,
"estimated_cache_storage_usd": 0.000388375
},
"totals_cleaned": {
"call_count": 15,
"usage": {
"input_tokens": {
"known_sum": 94205,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 20067,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 13225,
"unknown_call_count": 2
},
"cached_input_tokens": {
"known_sum": 21835,
"unknown_call_count": 4
}
},
"api_elapsed_seconds_sum": 173.68699999999998,
"conservative_generation_estimate_usd": 0.13116637499999997,
"generation_lower_bound_usd": 0.08812567499999999,
"estimated_cache_storage_usd": 0.00032454166666666666
},
"totals_correction_overhead": {
"call_count": 2,
"usage": {
"input_tokens": {
"known_sum": 5901,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2684,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2196,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 3567,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 21.953,
"conservative_generation_estimate_usd": 0.012083024999999999,
"generation_lower_bound_usd": 0.012083024999999999,
"estimated_cache_storage_usd": 6.383333333333333e-05
},
"phases": {
"entity_resolution_plan_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21008,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 194,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 3.703,
"conservative_generation_estimate_usd": 0.0164835,
"generation_lower_bound_usd": 0.0023030999999999998,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 21008,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 194,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 3.703,
"conservative_generation_estimate_usd": 0.0164835,
"generation_lower_bound_usd": 0.0023030999999999998,
"estimated_cache_storage_usd": 0
}
},
"entity_resolution_assessment_v4": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 25795,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 526,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 6.782,
"conservative_generation_estimate_usd": 0.02131875,
"generation_lower_bound_usd": 0.003907125,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 25795,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 526,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"unknown_call_count": 1
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 6.782,
"conservative_generation_estimate_usd": 0.02131875,
"generation_lower_bound_usd": 0.003907125,
"estimated_cache_storage_usd": 0
}
},
"case_plan_v2": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 13944,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 6216,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2300,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 42.015,
"conservative_generation_estimate_usd": 0.033768,
"generation_lower_bound_usd": 0.0243558,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 13944,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 6216,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2300,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 42.015,
"conservative_generation_estimate_usd": 0.033768,
"generation_lower_bound_usd": 0.0243558,
"estimated_cache_storage_usd": 0
}
},
"investigation_startup_v1": {
"all": {
"call_count": 4,
"usage": {
"input_tokens": {
"known_sum": 12388,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2477,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2117,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 8140,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 26.139,
"conservative_generation_estimate_usd": 0.01308525,
"generation_lower_bound_usd": 0.01308525,
"estimated_cache_storage_usd": 8.479166666666666e-05
},
"cleaned": {
"call_count": 3,
"usage": {
"input_tokens": {
"known_sum": 9120,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 1745,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1497,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 6105,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 18.858,
"conservative_generation_estimate_usd": 0.009262875,
"generation_lower_bound_usd": 0.009262875,
"estimated_cache_storage_usd": 8.479166666666666e-05
}
},
"investigation_startup_review_v1": {
"all": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 3017,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2650,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1985,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 22.219,
"conservative_generation_estimate_usd": 0.01220025,
"generation_lower_bound_usd": 0.010163775,
"estimated_cache_storage_usd": 0
},
"cleaned": {
"call_count": 1,
"usage": {
"input_tokens": {
"known_sum": 3017,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 2650,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1985,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"unknown_call_count": 1
}
},
"api_elapsed_seconds_sum": 22.219,
"conservative_generation_estimate_usd": 0.01220025,
"generation_lower_bound_usd": 0.010163775,
"estimated_cache_storage_usd": 0
}
},
"investigation_project_v20": {
"all": {
"call_count": 9,
"usage": {
"input_tokens": {
"known_sum": 23954,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 10688,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 9019,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 17262,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 94.782,
"conservative_generation_estimate_usd": 0.04639365,
"generation_lower_bound_usd": 0.04639365,
"estimated_cache_storage_usd": 0.00030358333333333333
},
"cleaned": {
"call_count": 8,
"usage": {
"input_tokens": {
"known_sum": 21321,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 8736,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 7443,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 15730,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 80.11,
"conservative_generation_estimate_usd": 0.038133,
"generation_lower_bound_usd": 0.038133,
"estimated_cache_storage_usd": 0.00023975
}
}
},
"calls": [
{
"ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"prompt_version": "entity_resolution_plan_v4",
"task": "entity_resolution_plan",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "993e4d9865e4e44ce59f3d6753713cac5fb009c217a14827b9a935c24be9a280",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 21008,
"output_tokens_including_reasoning": 194,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 3.703,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.0164835,
"estimated_generation_usd_lower_bound": 0.0023030999999999998,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"prompt_version": "entity_resolution_assessment_v4",
"task": "entity_resolution_assessment",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "dc7bcd2f719f6b0c0e104e21868d74809c4aaaad9fc43a40b92b03d886e1706c",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 25795,
"output_tokens_including_reasoning": 526,
"reasoning_tokens": null,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 6.782,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.02131875,
"estimated_generation_usd_lower_bound": 0.003907125,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"prompt_version": "case_plan_v2",
"task": "interpret_and_propose",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "90d3e9354a928239039bc3cb3b4c0aad9e21a03c7e30e2c9fac37db66f25327f",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 13944,
"output_tokens_including_reasoning": 6216,
"reasoning_tokens": 2300,
"cached_input_tokens": null,
"cache_status": "below_minimum",
"api_elapsed_seconds": 42.015,
"logical_wire_characters": null,
"estimated_generation_usd_conservative": 0.033768,
"estimated_generation_usd_lower_bound": 0.0243558,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "4430ab1441295f8310c7f4d7f3db6679d1428d3ae2d659b12a88ee40d798f018",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2309,
"output_tokens_including_reasoning": 254,
"reasoning_tokens": 178,
"cached_input_tokens": 2035,
"cache_status": "created",
"api_elapsed_seconds": 5.109,
"logical_wire_characters": 8501,
"estimated_generation_usd_conservative": 0.001310625,
"estimated_generation_usd_lower_bound": 0.001310625,
"estimated_cache_storage_usd": 8.479166666666666e-05,
"normalization_rules": []
},
{
"ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "cbbefac0dbbeddacba3f779db8566e7b46f94014938cdab32c7d199fa17908c5",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": "PROJECT_DATABASE_COLUMN_UNKNOWN",
"code": null,
"input_tokens": 3255,
"output_tokens_including_reasoning": 890,
"reasoning_tokens": 779,
"cached_input_tokens": 2035,
"cache_status": "reused",
"api_elapsed_seconds": 7.234,
"logical_wire_characters": 11638,
"estimated_generation_usd_conservative": 0.004405125,
"estimated_generation_usd_lower_bound": 0.004405125,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/9d66012b57395476a4f69c72ffd0b6725da911ede849fc652d48568b73d28480/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "9999501f1cb30251053a33f9c1938361c27ff980458c5bb94f993e43bfd8a97f",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3268,
"output_tokens_including_reasoning": 732,
"reasoning_tokens": 620,
"cached_input_tokens": 2035,
"cache_status": "reused",
"api_elapsed_seconds": 7.281,
"logical_wire_characters": 11693,
"estimated_generation_usd_conservative": 0.003822375,
"estimated_generation_usd_lower_bound": 0.003822375,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"prompt_version": "investigation_startup_v1",
"task": "startup_choose_query",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "6b950849ec02eccfaaf16daa464a17454104532e38b6a4e77c343585f189adbf",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3556,
"output_tokens_including_reasoning": 601,
"reasoning_tokens": 540,
"cached_input_tokens": 2035,
"cache_status": "reused",
"api_elapsed_seconds": 6.515,
"logical_wire_characters": 12605,
"estimated_generation_usd_conservative": 0.003547125,
"estimated_generation_usd_lower_bound": 0.003547125,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/0270771b422d04af95c20c38558476ded170af96569985af436406482d8d043a/round-0001.json",
"prompt_version": "investigation_startup_review_v1",
"task": "review_initial_hypotheses",
"hypothesis": null,
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "f6aba1d7fb8441d8e92b02164d2d3be522f756f43869b8ca8a9b83a37ce51a8d",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3017,
"output_tokens_including_reasoning": 2650,
"reasoning_tokens": 1985,
"cached_input_tokens": null,
"cache_status": "fallback",
"api_elapsed_seconds": 22.219,
"logical_wire_characters": 11012,
"estimated_generation_usd_conservative": 0.01220025,
"estimated_generation_usd_lower_bound": 0.010163775,
"estimated_cache_storage_usd": null,
"normalization_rules": []
},
{
"ref": "llm/operations/c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "8aab768fb27cb68e9c5cd8a90a2851fd6495b9bd1f7413bb0bb0be32269551a9",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2609,
"output_tokens_including_reasoning": 345,
"reasoning_tokens": 249,
"cached_input_tokens": 2111,
"cache_status": "created",
"api_elapsed_seconds": 6.781,
"logical_wire_characters": 9430,
"estimated_generation_usd_conservative": 0.001825575,
"estimated_generation_usd_lower_bound": 0.001825575,
"estimated_cache_storage_usd": 8.795833333333333e-05,
"normalization_rules": []
},
{
"ref": "llm/operations/b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "06f2bf0af9139e07d42f73f658b1c027ff450ee15dd67c38bc80158216323492",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2938,
"output_tokens_including_reasoning": 414,
"reasoning_tokens": 212,
"cached_input_tokens": 2111,
"cache_status": "reused",
"api_elapsed_seconds": 4.812,
"logical_wire_characters": 10486,
"estimated_generation_usd_conservative": 0.0023310749999999997,
"estimated_generation_usd_lower_bound": 0.0023310749999999997,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "409b8272bc913ebb496e5bcf36cb029f119dfb6e0f593690884f4a11afe834c2",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 3059,
"output_tokens_including_reasoning": 518,
"reasoning_tokens": 350,
"cached_input_tokens": 2111,
"cache_status": "reused",
"api_elapsed_seconds": 6.781,
"logical_wire_characters": 10814,
"estimated_generation_usd_conservative": 0.002811825,
"estimated_generation_usd_lower_bound": 0.002811825,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/475d5f458554c35131f24fc92fb2e762c69a8d9c6d4ab9d6426fbd72e6303af3/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "consolidate_investigation_session",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "bccdc72074422d53720daee19dbe30d7b0b547defa38274bfa5a10fb301972ea",
"correction": false,
"gateway_status": "ERROR",
"controller_rejection": "LLM_OUTPUT_SCHEMA",
"code": "LLM_OUTPUT_SCHEMA",
"input_tokens": 2591,
"output_tokens_including_reasoning": 3226,
"reasoning_tokens": 2832,
"cached_input_tokens": 1532,
"cache_status": "created",
"api_elapsed_seconds": 23.875,
"logical_wire_characters": 9156,
"estimated_generation_usd_conservative": 0.01300665,
"estimated_generation_usd_lower_bound": 0.01300665,
"estimated_cache_storage_usd": 6.383333333333333e-05,
"normalization_rules": []
},
{
"ref": "llm/operations/f4fe90305963d57344a3a1c8ae5802807cbb958fded88bf9d350bb0e27b5dfad/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "consolidate_investigation_session",
"hypothesis": "H1",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "9d99bfe7cd72c6895841018a2afa4fed645e5314ca0c923826807f007573d805",
"correction": true,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2633,
"output_tokens_including_reasoning": 1952,
"reasoning_tokens": 1576,
"cached_input_tokens": 1532,
"cache_status": "created",
"api_elapsed_seconds": 14.672,
"logical_wire_characters": 9336,
"estimated_generation_usd_conservative": 0.00826065,
"estimated_generation_usd_lower_bound": 0.00826065,
"estimated_cache_storage_usd": 6.383333333333333e-05,
"normalization_rules": []
},
{
"ref": "llm/operations/a4ed5334e4125ed14bcbca18629a561513bba48ef92afecc570c14d9e90e05cc/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "add3b1238d4f322e4d43cd9f474dbc2d62e3058031f10b2a557d6b076828e208",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2629,
"output_tokens_including_reasoning": 385,
"reasoning_tokens": 281,
"cached_input_tokens": 2111,
"cache_status": "created",
"api_elapsed_seconds": 5.313,
"logical_wire_characters": 9478,
"estimated_generation_usd_conservative": 0.001990575,
"estimated_generation_usd_lower_bound": 0.001990575,
"estimated_cache_storage_usd": 8.795833333333333e-05,
"normalization_rules": []
},
{
"ref": "llm/operations/ddf237df888a860f57b91498528fd599614514dff235353c4f61410ff3594423/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "d1ca9708b5614b67fec437d43768db5c2b308ae4a31f274d1306ac2ea4d78c5a",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2644,
"output_tokens_including_reasoning": 2188,
"reasoning_tokens": 2068,
"cached_input_tokens": 2111,
"cache_status": "reused",
"api_elapsed_seconds": 19.016,
"logical_wire_characters": 9534,
"estimated_generation_usd_conservative": 0.008763075,
"estimated_generation_usd_lower_bound": 0.008763075,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/23e886f4a2c5eeadfea37a9114a2282780ab8a12c14b970fdcc26da184fc793b/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "consolidate_investigation_session",
"hypothesis": "H2",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "1f16fa003424bf3181b9c993a21405cb23689a6c1b189b48eaa4af8c50589c6e",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2232,
"output_tokens_including_reasoning": 1122,
"reasoning_tokens": 958,
"cached_input_tokens": 1532,
"cache_status": "reused",
"api_elapsed_seconds": 8.485,
"logical_wire_characters": 8110,
"estimated_generation_usd_conservative": 0.0048474,
"estimated_generation_usd_lower_bound": 0.0048474,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
},
{
"ref": "llm/operations/b7f2e84e7ce1ab15fea771e71ef5c71f3321d1b419eefa7f3f69f110b5c356c6/round-0001.json",
"prompt_version": "investigation_project_v20",
"task": "investigate_one_step",
"hypothesis": "H3",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"request_sha256": "1110538bfd7948bced62c3b505875561c1aab46992d3d6d0ad3849f2cb78fc3d",
"correction": false,
"gateway_status": "SUCCESS",
"controller_rejection": null,
"code": null,
"input_tokens": 2619,
"output_tokens_including_reasoning": 538,
"reasoning_tokens": 493,
"cached_input_tokens": 2111,
"cache_status": "reused",
"api_elapsed_seconds": 5.047,
"logical_wire_characters": 9470,
"estimated_generation_usd_conservative": 0.002556825,
"estimated_generation_usd_lower_bound": 0.002556825,
"estimated_cache_storage_usd": 0.0,
"normalization_rules": []
}
],
"startup_done": true,
"hypotheses": {
"H1": {
"confidence": "strongly_supported",
"iterations": 5,
"invalid_responses": 0,
"disposition": "finish"
},
"H2": {
"confidence": "weakened",
"iterations": 3,
"invalid_responses": 0,
"disposition": "reject"
},
"H3": {
"confidence": "weakened",
"iterations": 2,
"invalid_responses": 0,
"disposition": "active"
}
},
"package_valid": true,
"trial_process_elapsed_seconds": 341.541109,
"trial_process_elapsed_scope": "Sum of two telemetry process durations, excludes idle between runs and preparation.",
"assessment": {
"checkpoint_correction": "Missing uncertainties supplied in first retry, accepted.",
"continuation_actions": [
"H1 checkpoint corrected and finished",
"H2 queried creature_template_addon",
"H2 requested contradiction checkpoint",
"H2 checkpoint rejected H2",
"H3 recalled E000006"
],
"caution": "No static spawn rows alone do not rule out all dynamic spawn paths. H2 rejection reason is stronger than the evidence strictly establishes.",
"deterministic_choice_unwrap_exercised": false,
"entity_reference_catalog_exercised_by_source_context_query": false
},
"continuation_since_generation_77": {
"call_count": 5,
"usage": {
"input_tokens": {
"known_sum": 12757,
"unknown_call_count": 0
},
"output_tokens_including_reasoning": {
"known_sum": 6185,
"unknown_call_count": 0
},
"reasoning_tokens": {
"known_sum": 5376,
"unknown_call_count": 0
},
"cached_input_tokens": {
"known_sum": 9397,
"unknown_call_count": 0
}
},
"api_elapsed_seconds_sum": 52.532999999999994,
"conservative_generation_estimate_usd": 0.026418524999999998,
"generation_lower_bound_usd": 0.026418524999999998,
"estimated_cache_storage_usd": 0.00015179166666666667
},
"continuation_process_elapsed_seconds": 93.208691
}
@@ -0,0 +1,14 @@
{
"format": "viano-test-cost-update",
"recorded_date": "2026-10-20",
"run": "bug20-contract-v2-20261020",
"package_generation": 122,
"account_eur": {
"start": 12.83,
"intermediate": 12.93,
"latest_reported": 13.01,
"difference": 0.18,
"settlement": "updated_user_report; small further delayed charges not excluded"
},
"token_report": "bug20-contract-v2-20261020-g00000122.json"
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,508 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-joint-planning-20261019",
"case_id": "BUG-000020",
"package_id": "trial-joint-planning-BUG-000020-20261019",
"package_generation": 97,
"analysis_revision": 1,
"state": "OUTPUT_READY",
"routing": {
"destination": "outbox",
"reason": null,
"retry_count": 0,
"retry_not_before": null
},
"source_package": "service-data/trials/bug20-joint-planning-20261019/cases/897a914b67a02e6109a6b567e377e43c72b90ab216bfb9d2dc24485a5a55db8d/60d94dc476555860dafbb6b852fa5a4d763ea432e1f62723280817bafa379d35/g00000097.zip",
"manifest_sha256": "7ac099c9388bd4fc3fa4e929a3d58a0b8ab79f6b1121999cf596f08db83e17ad",
"notes": [
"output_tokens includes reasoning_tokens; never add reasoning to output again",
"Null usage is unavailable, not zero; known sums carry missing counts",
"Accepted planning deduplicates calls used by both phase artifacts",
"Elapsed API sums are not wall-clock trial duration",
"Investigation calls without phase-artifact pointers are not automatically classified as accepted or rejected"
],
"totals_all_calls": {
"call_count": 18,
"input_tokens": {
"known_sum": 254110,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 48571,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 33711,
"missing_call_count": 4
},
"visible_output_tokens": {
"known_sum": 13622,
"missing_call_count": 4
},
"cached_input_tokens": {
"known_sum": 50576,
"missing_call_count": 8
},
"api_elapsed_seconds_sum": 393.686
},
"totals_planning_all_attempts": {
"call_count": 3,
"input_tokens": {
"known_sum": 44531,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 16011,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 8854,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 7157,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 3
},
"api_elapsed_seconds_sum": 106.218
},
"totals_planning_accepted_only": {
"call_count": 2,
"input_tokens": {
"known_sum": 31545,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 9282,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 5714,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 3568,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 2
},
"api_elapsed_seconds_sum": 61.609
},
"calls": [
{
"call_ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"call_sha256": "ea18fbf657b95ee8e52e35062d8aced37fa9204d7bcc8437af9bb9766728099d",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 2.985,
"usage": {
"input_tokens": 21005,
"output_tokens": 180,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"call_sha256": "f4e388bb58162ae651534684aeedc8894892dbc4fbcd731d4a997d2e37b4d969",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 5.078,
"usage": {
"input_tokens": 25764,
"output_tokens": 501,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"call_sha256": "81b5649c121cf83dc049bac836a5fd607aed4031bf1626f6c0768e1ff19f2fa5",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [
"INTERPRETATION_SOURCE_KIND"
],
"accepted_by": [],
"prompt_version": "case_plan_v1",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 44.609,
"usage": {
"input_tokens": 12986,
"output_tokens": 6729,
"reasoning_tokens": 3140,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 3589
}
},
{
"call_ref": "llm/operations/cdf9fddd5dccf7c6859f2f4c5aa65e46778d6d44e446cf579fa6b6f462b9b85c/round-0001.json",
"call_sha256": "640befa42a34ed697eb234d2be12c43033d6aaa78f7c92cc94c9619f8adbfe81",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"case_interpretation"
],
"prompt_version": "case_plan_interpretation_repair_v1",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 26.859,
"usage": {
"input_tokens": 15650,
"output_tokens": 4446,
"reasoning_tokens": 2526,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1920
}
},
{
"call_ref": "llm/operations/5fa06d3e4f4063a74b5818fdba690a7e1cd8b145506fb7c1d2a5deefc421ef98/round-0001.json",
"call_sha256": "a91fc7ebdb21be2bce1281b8d5393371a5483aa2edbdce21488946e1a0894a81",
"phase": "GENERATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"hypotheses"
],
"prompt_version": "hypotheses_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 34.75,
"usage": {
"input_tokens": 15895,
"output_tokens": 4836,
"reasoning_tokens": 3188,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1648
}
},
{
"call_ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"call_sha256": "b938dc074fda1a8fa5a4aa4d9d4b78c76f7b74d38a28ae2ff433f2ad0b71502e",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 11.125,
"usage": {
"input_tokens": 6028,
"output_tokens": 1184,
"reasoning_tokens": 844,
"cached_input_tokens": 5125,
"uncached_input_tokens": 903,
"visible_output_tokens": 340
}
},
{
"call_ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"call_sha256": "39103cc7bfda62cc8956d49d379394f5a23c515219de85d9fe255f1ee5970e50",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 44.469,
"usage": {
"input_tokens": 8448,
"output_tokens": 6491,
"reasoning_tokens": 5965,
"cached_input_tokens": 5125,
"uncached_input_tokens": 3323,
"visible_output_tokens": 526
}
},
{
"call_ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"call_sha256": "8708f97fc082cd4ee6eaa1597bb07e4310a64e60ee58cc23fcfecb22f47eef53",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 70.297,
"usage": {
"input_tokens": 9453,
"output_tokens": 4801,
"reasoning_tokens": 4454,
"cached_input_tokens": 5125,
"uncached_input_tokens": 4328,
"visible_output_tokens": 347
}
},
{
"call_ref": "llm/operations/c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31/round-0001.json",
"call_sha256": "43e2a484b19dac9bb4f53f8ddafd6d2d5fe4d4c1291f93e32d519ff401ce7ff4",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 11.203,
"usage": {
"input_tokens": 13739,
"output_tokens": 1247,
"reasoning_tokens": 1045,
"cached_input_tokens": 6274,
"uncached_input_tokens": 7465,
"visible_output_tokens": 202
}
},
{
"call_ref": "llm/operations/b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383/round-0001.json",
"call_sha256": "4e0e2872ef8b331c69d0d9435b1469b200e41b10ac77cbb24da84c49024def2d",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 6.359,
"usage": {
"input_tokens": 15338,
"output_tokens": 711,
"reasoning_tokens": 541,
"cached_input_tokens": 6274,
"uncached_input_tokens": 9064,
"visible_output_tokens": 170
}
},
{
"call_ref": "llm/operations/6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1/round-0001.json",
"call_sha256": "ef958be97b1cc0217a431a6945f3cdf282bc079392ce379c19279e8ca5fffc4f",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 13.015,
"usage": {
"input_tokens": 13963,
"output_tokens": 1560,
"reasoning_tokens": 1272,
"cached_input_tokens": 6274,
"uncached_input_tokens": 7689,
"visible_output_tokens": 288
}
},
{
"call_ref": "llm/operations/475d5f458554c35131f24fc92fb2e762c69a8d9c6d4ab9d6426fbd72e6303af3/round-0001.json",
"call_sha256": "1e912ee014b2af06b6105be3e9c28940f5e73b37fb8fe9720597d67db19e3671",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 13.093,
"usage": {
"input_tokens": 14745,
"output_tokens": 1485,
"reasoning_tokens": 1208,
"cached_input_tokens": 6274,
"uncached_input_tokens": 8471,
"visible_output_tokens": 277
}
},
{
"call_ref": "llm/operations/8f58f73379896f4edda417f564668be151dea6f1dd75d1872c8aeb64d0cef5ce/round-0001.json",
"call_sha256": "7b101261a0613dec0cb0cc531ca5298b531853e2987087e27204a51c6a6367ed",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 23.562,
"usage": {
"input_tokens": 16348,
"output_tokens": 2930,
"reasoning_tokens": 2461,
"cached_input_tokens": 4469,
"uncached_input_tokens": 11879,
"visible_output_tokens": 469
}
},
{
"call_ref": "llm/operations/a4ed5334e4125ed14bcbca18629a561513bba48ef92afecc570c14d9e90e05cc/round-0001.json",
"call_sha256": "442d679bccdde15911ed18d2c0a620a911d55d825ea53855f39b7f704aec70fe",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 5.391,
"usage": {
"input_tokens": 6521,
"output_tokens": 336,
"reasoning_tokens": null,
"cached_input_tokens": 2818,
"uncached_input_tokens": 3703,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/b7f2e84e7ce1ab15fea771e71ef5c71f3321d1b419eefa7f3f69f110b5c356c6/round-0001.json",
"call_sha256": "a11d6b43f076342897d1e1485fc3bb53ac3b8db7ac0b7ffb1347b78f46d2945f",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 3.719,
"usage": {
"input_tokens": 7431,
"output_tokens": 221,
"reasoning_tokens": null,
"cached_input_tokens": 2818,
"uncached_input_tokens": 4613,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/25febf70da1f602d9d830c61c59e4504617a8bc05beac14676d7fd4e9f6589f9/round-0001.json",
"call_sha256": "0e3dfa99c65c75b58fe6553db44b578b86fe2ef569caa9257e67f4d498aa65f6",
"phase": "BUILDING_DIAGNOSIS",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"diagnosis"
],
"prompt_version": "diagnosis_early_v7",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 25.672,
"usage": {
"input_tokens": 21736,
"output_tokens": 3514,
"reasoning_tokens": 2300,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1214
}
},
{
"call_ref": "llm/operations/17917402a4c04bd20ae3b0a2f256a39daa4c026a0afff5f80f408478611d4e03/round-0001.json",
"call_sha256": "267554a74192630ddabdcd221cf78e62067b58abce18bf5403e9fcf061bfe74d",
"phase": "BUILDING_DIAGNOSIS",
"status": "ERROR",
"code": "LLM_RESPONSE",
"validation_errors": [
"LLM_RESPONSE"
],
"accepted_by": [],
"prompt_version": "change_request_v8",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 26.75,
"usage": {
"input_tokens": 14456,
"output_tokens": 3815,
"reasoning_tokens": 2497,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1318
}
},
{
"call_ref": "llm/operations/c06b231c8faccaeb58e9684b7d28a566e8bd629c8dcd13a423c9ba2a012d27b6/round-0001.json",
"call_sha256": "0f6319fbe2b0defd9bcf0ad6c3ba9ff2ce81e8dcd6750e052552b29158c28d2b",
"phase": "BUILDING_DIAGNOSIS",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"change_request"
],
"prompt_version": "change_request_v8",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 24.75,
"usage": {
"input_tokens": 14604,
"output_tokens": 3584,
"reasoning_tokens": 2270,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1314
}
}
]
}
@@ -0,0 +1,216 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-joint-recovery-20261020",
"case_id": "BUG-000020",
"package_id": "trial-joint-recovery-BUG-000020-20261020",
"package_generation": 22,
"analysis_revision": 1,
"state": "FAILED_TO_ANALYZE",
"routing": {
"destination": "review",
"reason": "MODEL_VALIDATION_EXHAUSTED",
"retry_count": 0,
"retry_not_before": null
},
"source_package": "service-data/trials/bug20-joint-recovery-20261020/cases/897a914b67a02e6109a6b567e377e43c72b90ab216bfb9d2dc24485a5a55db8d/307269a3ff8069115c563dc25fdb9a5f1762815d5e539d78b1c43fa8d6ab73f3/g00000022.zip",
"manifest_sha256": "91010fcbd8556b45af67795d9344cc14e93f57ad273db5028cc7fdcb25b971fc",
"notes": [
"output_tokens includes reasoning_tokens; never add reasoning to output again",
"Null usage is unavailable, not zero; known sums carry missing counts",
"Accepted planning deduplicates calls used by both phase artifacts",
"Elapsed API sums are not wall-clock trial duration",
"Investigation calls without phase-artifact pointers are not automatically classified as accepted or rejected"
],
"totals_all_calls": {
"call_count": 5,
"input_tokens": {
"known_sum": 81023,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 24850,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 19307,
"missing_call_count": 2
},
"visible_output_tokens": {
"known_sum": 4858,
"missing_call_count": 2
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 5
},
"api_elapsed_seconds_sum": 159.578
},
"totals_planning_all_attempts": {
"call_count": 3,
"input_tokens": {
"known_sum": 34252,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 24165,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 19307,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 4858,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 3
},
"api_elapsed_seconds_sum": 151.609
},
"totals_planning_accepted_only": {
"call_count": 0,
"input_tokens": {
"known_sum": 0,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 0,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 0,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 0
},
"api_elapsed_seconds_sum": 0
},
"calls": [
{
"call_ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"call_sha256": "0e346b87943a4ef5bddeb6f213c95b09cb327c983d99c73937adb43ed7d2a1a2",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 3.094,
"usage": {
"input_tokens": 21006,
"output_tokens": 180,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"call_sha256": "10dc5ce6bbb9aa952fed8f7e05be7f3ac3c84b1cdf2fac7c7109c6bdca6cd6c4",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 4.875,
"usage": {
"input_tokens": 25765,
"output_tokens": 505,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"call_sha256": "2ff4e170dc33b33d58ea7c44e497dfc10302a8170248b5789abe67d6107fb72c",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [
"INTERPRETATION_SCHEMA"
],
"accepted_by": [],
"prompt_version": "case_plan_v2",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 28.234,
"usage": {
"input_tokens": 13918,
"output_tokens": 4466,
"reasoning_tokens": 1602,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 2864
}
},
{
"call_ref": "llm/operations/cdf9fddd5dccf7c6859f2f4c5aa65e46778d6d44e446cf579fa6b6f462b9b85c/round-0001.json",
"call_sha256": "4567683fb436d3467c99c720e2721dbf88e9d886927688310daa167c36654bf5",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [
"INTERPRETATION_EXPECTATION_UNKNOWN"
],
"accepted_by": [],
"prompt_version": "case_plan_interpretation_repair_v1",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 26.828,
"usage": {
"input_tokens": 14078,
"output_tokens": 4652,
"reasoning_tokens": 2854,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1798
}
},
{
"call_ref": "llm/operations/2cd36795173fe6d547ff571814187ce1b12b3a7ec6accd4ebd98869d46bad248/round-0001.json",
"call_sha256": "e749e5545c6403ea2f543674d06d8092490ecfaa80e9c8d74c412f1597cc7768",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [
"INTERPRETATION_ENTITY_PROVENANCE"
],
"accepted_by": [],
"prompt_version": "case_plan_statement_repair_v2",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 96.547,
"usage": {
"input_tokens": 6256,
"output_tokens": 15047,
"reasoning_tokens": 14851,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 196
}
}
]
}
@@ -0,0 +1,213 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-joint-structure-20261020",
"case_id": "BUG-000020",
"package_id": "trial-joint-structure-BUG-000020-20261020",
"package_generation": 37,
"analysis_revision": 1,
"state": "INVESTIGATING_HYPOTHESES",
"routing": {
"destination": "cases",
"reason": null,
"retry_count": 1,
"retry_not_before": null
},
"source_package": "service-data/trials/bug20-joint-structure-20261020/cases/897a914b67a02e6109a6b567e377e43c72b90ab216bfb9d2dc24485a5a55db8d/07ef748c1c769f3abd169538220ccd6891f2b1d7556bbb7dde562f4f59ac5900/g00000037.zip",
"manifest_sha256": "7dfa4b9a067e2d5b8449408c8504b42e5d7ea69732c2224f09085cee41957cc1",
"notes": [
"output_tokens includes reasoning_tokens; never add reasoning to output again",
"Null usage is unavailable, not zero; known sums carry missing counts",
"Accepted planning deduplicates calls used by both phase artifacts",
"Elapsed API sums are not wall-clock trial duration",
"Investigation calls without phase-artifact pointers are not automatically classified as accepted or rejected"
],
"totals_all_calls": {
"call_count": 5,
"input_tokens": {
"known_sum": 73501,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 15281,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 11160,
"missing_call_count": 2
},
"visible_output_tokens": {
"known_sum": 3462,
"missing_call_count": 2
},
"cached_input_tokens": {
"known_sum": 9528,
"missing_call_count": 3
},
"api_elapsed_seconds_sum": 113.545
},
"totals_planning_all_attempts": {
"call_count": 1,
"input_tokens": {
"known_sum": 13733,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 7863,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 5247,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 2616,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 1
},
"api_elapsed_seconds_sum": 51.156
},
"totals_planning_accepted_only": {
"call_count": 1,
"input_tokens": {
"known_sum": 13733,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 7863,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 5247,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 2616,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 1
},
"api_elapsed_seconds_sum": 51.156
},
"calls": [
{
"call_ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"call_sha256": "bcde1a08152b25e3794dc9b3c0914c0ad3b2cec9e27a376ca627340865388ad0",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 3.359,
"usage": {
"input_tokens": 21010,
"output_tokens": 162,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"call_sha256": "d31a5173fa6be1c9e8d5b89a2ac62ea82c8c9d93286a5bac5877e489c89cc0aa",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 5.0,
"usage": {
"input_tokens": 25225,
"output_tokens": 497,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"call_sha256": "6d957252d8ca9075f34e2c0e48bef91c5499debcc6c811abcf6224200e10eaa9",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"case_interpretation",
"hypotheses"
],
"prompt_version": "case_plan_v2",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 51.156,
"usage": {
"input_tokens": 13733,
"output_tokens": 7863,
"reasoning_tokens": 5247,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 2616
}
},
{
"call_ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"call_sha256": "d7b3082d06cf3e990dea9c793f7c529d6e731a401c7bca8a8ba2310fd603dbf9",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 13.171,
"usage": {
"input_tokens": 5566,
"output_tokens": 1559,
"reasoning_tokens": 1213,
"cached_input_tokens": 4764,
"uncached_input_tokens": 802,
"visible_output_tokens": 346
}
},
{
"call_ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"call_sha256": "ff3132842acdfb2800c7865c791a2ae78713611ada8fda5b26258de56f19280b",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 40.859,
"usage": {
"input_tokens": 7967,
"output_tokens": 5200,
"reasoning_tokens": 4700,
"cached_input_tokens": 4764,
"uncached_input_tokens": 3203,
"visible_output_tokens": 500
}
}
]
}
@@ -0,0 +1,218 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-joint-v2-20261020",
"case_id": "BUG-000020",
"package_id": "trial-joint-v2-BUG-000020-20261020",
"package_generation": 25,
"analysis_revision": 1,
"state": "GENERATING_HYPOTHESES",
"routing": {
"destination": "cases",
"reason": null,
"retry_count": 0,
"retry_not_before": null
},
"source_package": "service-data/trials/bug20-joint-v2-20261020/cases/897a914b67a02e6109a6b567e377e43c72b90ab216bfb9d2dc24485a5a55db8d/1825790dc2ab9100da82a89d884cd25d31439b888bb7db99aea8f551d9ce65c6/g00000025.zip",
"manifest_sha256": "98e913ceb230a9babc8ada4ad00db896609dce9322b996093ed302794dcf72cf",
"notes": [
"output_tokens includes reasoning_tokens; never add reasoning to output again",
"Null usage is unavailable, not zero; known sums carry missing counts",
"Accepted planning deduplicates calls used by both phase artifacts",
"Elapsed API sums are not wall-clock trial duration",
"Investigation calls without phase-artifact pointers are not automatically classified as accepted or rejected"
],
"totals_all_calls": {
"call_count": 5,
"input_tokens": {
"known_sum": 82295,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 16520,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 9624,
"missing_call_count": 2
},
"visible_output_tokens": {
"known_sum": 6341,
"missing_call_count": 2
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 5
},
"api_elapsed_seconds_sum": 113.108
},
"totals_planning_all_attempts": {
"call_count": 3,
"input_tokens": {
"known_sum": 36118,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 15965,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 9624,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 6341,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 3
},
"api_elapsed_seconds_sum": 106.187
},
"totals_planning_accepted_only": {
"call_count": 2,
"input_tokens": {
"known_sum": 22495,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 10075,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 7763,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 2312,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 2
},
"api_elapsed_seconds_sum": 68.765
},
"calls": [
{
"call_ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"call_sha256": "5b082a63e935f68306a691452e5f59c21aa8bd4c621be1431748869de36de836",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 2.734,
"usage": {
"input_tokens": 21009,
"output_tokens": 134,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"call_sha256": "9536197fbdb90d354a08c307434fad54ad5b1e50684fc42ec6284c36d670293c",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 4.187,
"usage": {
"input_tokens": 25168,
"output_tokens": 421,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"call_sha256": "07eb2df391d4abca1c85733f8fc4f2559dcc3c71033c92022cfc70b3812e4f94",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [
"INTERPRETATION_SCHEMA"
],
"accepted_by": [],
"prompt_version": "case_plan_v2",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 37.422,
"usage": {
"input_tokens": 13623,
"output_tokens": 5890,
"reasoning_tokens": 1861,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 4029
}
},
{
"call_ref": "llm/operations/cdf9fddd5dccf7c6859f2f4c5aa65e46778d6d44e446cf579fa6b6f462b9b85c/round-0001.json",
"call_sha256": "c2ea0441d010892218604a27cb1246bdcf1691f31c228f811e272db8e76fc7c9",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [
"HYPOTHESIS_PREMISE_SOURCE"
],
"accepted_by": [
"case_interpretation"
],
"prompt_version": "case_plan_statement_repair_v2",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 39.812,
"usage": {
"input_tokens": 7116,
"output_tokens": 6023,
"reasoning_tokens": 5269,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 754
}
},
{
"call_ref": "llm/operations/b58ae687fdde681ed31f46a21147298ced592a1fb391d86a3f346bfd3e648096/round-0001.json",
"call_sha256": "8347b755c200a36efa80bafcb4100bf812de861d4589eef9a19619a738e80e94",
"phase": "GENERATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"hypotheses"
],
"prompt_version": "hypotheses_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 28.953,
"usage": {
"input_tokens": 15379,
"output_tokens": 4052,
"reasoning_tokens": 2494,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1558
}
}
]
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,38 @@
{
"format": "viano-test-preparation",
"format_version": 1,
"recorded_date": "2026-10-21",
"run": "bug20-qualified-review-20261021",
"case_id": "BUG-000020",
"package_id": "trial-qualified-review-BUG-000020-20261021",
"code_commit": "a33cee0cf86595baa03919d7530f3ac5107ebf06",
"configuration_sha256": {
"config/llm.early-review.local.toml": "ff3296f9a902e4e67861929e584d3629d76edd0d77898c3817ae7f44f50d7ef0",
"config/project.local.toml": "235016a23be2d8aa7aed7f450fd77792ccbf0fb9b24c05b65d4771782249f5e3",
"config/investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"inputs": [
{
"name": "BUG-000020-20261008-130429.tar.gz",
"sha256": "a3ddbde9d046dbbe65354ca8bababc78a689e0a10e0935fb1f109d3a92d75c7e"
},
{
"name": "WOWSRC-BUG-000020-20261008-130446.tar.gz",
"sha256": "ee82031e2a085e2da1db348a298a9f8defdb866796917277a2a98c8890551d6d"
}
],
"account_eur": {
"last_confirmed": 13.37,
"new_run_start_confirmed": false
},
"storage_bytes_before_preparation": 11646616228,
"storage_limit_bytes": 20000000000,
"replaces_preparation": "bug17-qualified-review-20261021; user corrected intended regression case; Bug17 not executed",
"test_goal": "Bug20 functional regression with qualified diagnosis and coding caveats. Evaluate missing-spawn diagnosis, suitable coding/template and human handoff, observed validation requirements, retained uncertainty, tokens/corrections/cost.",
"expected_prompt_versions": [
"diagnosis_v8 or diagnosis_early_v8",
"change_request_v9"
],
"prepared_state": "VALIDATED",
"paid_api_calls": 0
}
@@ -0,0 +1,530 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-shared-recovery-20261019",
"case_id": "BUG-000020",
"package_id": "trial-shared-recovery-BUG-000020-20261019",
"package_generation": 100,
"analysis_revision": 1,
"state": "OUTPUT_READY",
"routing": {
"destination": "outbox",
"reason": null,
"retry_count": 0,
"retry_not_before": null
},
"source_package": "service-data/trials/bug20-shared-recovery-20261019/cases/897a914b67a02e6109a6b567e377e43c72b90ab216bfb9d2dc24485a5a55db8d/49c833d7194c687b04596c9b9a4bd0f4f021f54171839fb8336fc85296f98ed6/g00000100.zip",
"manifest_sha256": "849c54c0324094dfa0ed61b28802bebf27a29dadd8c15674013689ebf9b1ba15",
"notes": [
"output_tokens includes reasoning_tokens; never add reasoning to output again",
"Null usage is unavailable, not zero; known sums carry missing counts",
"Accepted planning deduplicates calls used by both phase artifacts",
"Elapsed API sums are not wall-clock trial duration",
"Investigation calls without phase-artifact pointers are not automatically classified as accepted or rejected"
],
"totals_all_calls": {
"call_count": 19,
"input_tokens": {
"known_sum": 295146,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 63527,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 49718,
"missing_call_count": 4
},
"visible_output_tokens": {
"known_sum": 12441,
"missing_call_count": 4
},
"cached_input_tokens": {
"known_sum": 69687,
"missing_call_count": 7
},
"api_elapsed_seconds_sum": 509.249
},
"totals_planning_all_attempts": {
"call_count": 4,
"input_tokens": {
"known_sum": 63120,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 19587,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 12903,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 6684,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 14024,
"missing_call_count": 3
},
"api_elapsed_seconds_sum": 162.937
},
"totals_planning_accepted_only": {
"call_count": 2,
"input_tokens": {
"known_sum": 31170,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 11757,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 8328,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 3429,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 14024,
"missing_call_count": 1
},
"api_elapsed_seconds_sum": 97.422
},
"calls": [
{
"call_ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"call_sha256": "705adf20ab5efe08abfe681e41e988038f7967b230eb485e235bb1f5c60b2e5f",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 3.547,
"usage": {
"input_tokens": 21008,
"output_tokens": 194,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"call_sha256": "f1b86b6be890ad059d389f6dfe790da972a34664076b9d3a71a50f6b8adc5e54",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 5.656,
"usage": {
"input_tokens": 25795,
"output_tokens": 521,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"call_sha256": "66bf6ec1b261a088dabe25cc1ac9718e502dac35a65ba342ff61d924dcf07f49",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"case_interpretation"
],
"prompt_version": "case_interpretation_resolved_v8",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 46.922,
"usage": {
"input_tokens": 15109,
"output_tokens": 6992,
"reasoning_tokens": 5155,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1837
}
},
{
"call_ref": "llm/operations/5fa06d3e4f4063a74b5818fdba690a7e1cd8b145506fb7c1d2a5deefc421ef98/round-0001.json",
"call_sha256": "bc380985aadade22f74e06b73d0bac5a5bded15078f9fd44884625971fb98d57",
"phase": "GENERATING_HYPOTHESES",
"status": "ERROR",
"code": "LLM_RESPONSE",
"validation_errors": [
"LLM_RESPONSE"
],
"accepted_by": [],
"prompt_version": "hypotheses_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 30.094,
"usage": {
"input_tokens": 15889,
"output_tokens": 3578,
"reasoning_tokens": 1963,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1615
}
},
{
"call_ref": "llm/operations/b58ae687fdde681ed31f46a21147298ced592a1fb391d86a3f346bfd3e648096/round-0001.json",
"call_sha256": "5fd4b4625d59cfa6409ffe8bd69d3dbb19a2fcc48dd0ffd08a2c2db08718b781",
"phase": "GENERATING_HYPOTHESES",
"status": "ERROR",
"code": "LLM_RESPONSE",
"validation_errors": [
"LLM_RESPONSE"
],
"accepted_by": [],
"prompt_version": "hypotheses_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 35.421,
"usage": {
"input_tokens": 16061,
"output_tokens": 4252,
"reasoning_tokens": 2612,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1640
}
},
{
"call_ref": "llm/operations/7a2157eed9ff7b1494fcc4bd20246322278721c551c2fa3f2efbc7c6ad88484e/round-0001.json",
"call_sha256": "f290eddf7cf0101f766ae9572dd525d1f7ab5802ce5d690bb064bd232bfc9365",
"phase": "GENERATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"hypotheses"
],
"prompt_version": "hypotheses_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 50.5,
"usage": {
"input_tokens": 16061,
"output_tokens": 4765,
"reasoning_tokens": 3173,
"cached_input_tokens": 14024,
"uncached_input_tokens": 2037,
"visible_output_tokens": 1592
}
},
{
"call_ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"call_sha256": "a7c442ae8d23276b64163c0837b1bde689e41148a1f8902b5e222aa003aefcb3",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 13.031,
"usage": {
"input_tokens": 6088,
"output_tokens": 1407,
"reasoning_tokens": 1057,
"cached_input_tokens": 5119,
"uncached_input_tokens": 969,
"visible_output_tokens": 350
}
},
{
"call_ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"call_sha256": "73cdd99e946df223e0d2473742cd64532a7c4b8bb17d2fe7083f9788e45bb41d",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 47.25,
"usage": {
"input_tokens": 8462,
"output_tokens": 6040,
"reasoning_tokens": 5554,
"cached_input_tokens": 5119,
"uncached_input_tokens": 3343,
"visible_output_tokens": 486
}
},
{
"call_ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"call_sha256": "a6a08a0d40b10272895171f82bcd4f28dccf9b6f46cead9e34894f64fa57747a",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 101.89,
"usage": {
"input_tokens": 16254,
"output_tokens": 14508,
"reasoning_tokens": 13965,
"cached_input_tokens": 5119,
"uncached_input_tokens": 11135,
"visible_output_tokens": 543
}
},
{
"call_ref": "llm/operations/7b8f9ecd4cb00c7e1d8bbd314d9ab15032701b76a0d5cf4256b895312b03a731/round-0001.json",
"call_sha256": "fa50b565159984b7481c306e18eb37cfd2ae23e3a88c666456cc7c294230b41b",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_bootstrap_v23",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 55.703,
"usage": {
"input_tokens": 16350,
"output_tokens": 8197,
"reasoning_tokens": 7739,
"cached_input_tokens": 5119,
"uncached_input_tokens": 11231,
"visible_output_tokens": 458
}
},
{
"call_ref": "llm/operations/c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31/round-0001.json",
"call_sha256": "a8286c3aefd694e23c7ae3920dadbbd8d977ff53c56caa1ef5e8ba73180a48c6",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 9.219,
"usage": {
"input_tokens": 13303,
"output_tokens": 733,
"reasoning_tokens": 489,
"cached_input_tokens": 6271,
"uncached_input_tokens": 7032,
"visible_output_tokens": 244
}
},
{
"call_ref": "llm/operations/b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383/round-0001.json",
"call_sha256": "fd33521b4d8adc676dc5030df2b229bd333f244a073bc26215ae6c015a44db65",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 7.454,
"usage": {
"input_tokens": 12258,
"output_tokens": 752,
"reasoning_tokens": 605,
"cached_input_tokens": 6271,
"uncached_input_tokens": 5987,
"visible_output_tokens": 147
}
},
{
"call_ref": "llm/operations/6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1/round-0001.json",
"call_sha256": "031712383a580693e1704d204378ddfb43bc38259e8290714f2e0e372a1929c6",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 6.516,
"usage": {
"input_tokens": 13836,
"output_tokens": 611,
"reasoning_tokens": 395,
"cached_input_tokens": 6271,
"uncached_input_tokens": 7565,
"visible_output_tokens": 216
}
},
{
"call_ref": "llm/operations/475d5f458554c35131f24fc92fb2e762c69a8d9c6d4ab9d6426fbd72e6303af3/round-0001.json",
"call_sha256": "18826877271bb0f7f96bcc6426bfa7538a2876a6aa6bd7b9dabe6bacff93a29a",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 15.265,
"usage": {
"input_tokens": 14727,
"output_tokens": 1608,
"reasoning_tokens": 1411,
"cached_input_tokens": 6271,
"uncached_input_tokens": 8456,
"visible_output_tokens": 197
}
},
{
"call_ref": "llm/operations/8f58f73379896f4edda417f564668be151dea6f1dd75d1872c8aeb64d0cef5ce/round-0001.json",
"call_sha256": "ffe30d21f4f51828fcdac8e3b5b5f9e935f335b66c9ea8f020ff44f905e896ac",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 13.625,
"usage": {
"input_tokens": 14221,
"output_tokens": 1291,
"reasoning_tokens": 904,
"cached_input_tokens": 4463,
"uncached_input_tokens": 9758,
"visible_output_tokens": 387
}
},
{
"call_ref": "llm/operations/a4ed5334e4125ed14bcbca18629a561513bba48ef92afecc570c14d9e90e05cc/round-0001.json",
"call_sha256": "0cf4f485d9ff4d0d9573c74d40af4561a8314cda3ce214ec02e9fc1e4b23ecea",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 5.922,
"usage": {
"input_tokens": 15391,
"output_tokens": 301,
"reasoning_tokens": null,
"cached_input_tokens": 2820,
"uncached_input_tokens": 12571,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/b7f2e84e7ce1ab15fea771e71ef5c71f3321d1b419eefa7f3f69f110b5c356c6/round-0001.json",
"call_sha256": "0a7c1d0be70b47185884c534b166b4c7192c952ee44dc5accbcc7f842e8e2b0f",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 4.14,
"usage": {
"input_tokens": 6565,
"output_tokens": 352,
"reasoning_tokens": null,
"cached_input_tokens": 2820,
"uncached_input_tokens": 3745,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/25febf70da1f602d9d830c61c59e4504617a8bc05beac14676d7fd4e9f6589f9/round-0001.json",
"call_sha256": "c96450d455d354e827206c97915f537e042252e49ae2a107145d79a4889808b2",
"phase": "BUILDING_DIAGNOSIS",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"diagnosis"
],
"prompt_version": "diagnosis_early_v7",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 24.938,
"usage": {
"input_tokens": 27266,
"output_tokens": 3140,
"reasoning_tokens": 1752,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1388
}
},
{
"call_ref": "llm/operations/17917402a4c04bd20ae3b0a2f256a39daa4c026a0afff5f80f408478611d4e03/round-0001.json",
"call_sha256": "7766d97a27a0ee0387f28b18db1f9ee83c86c58e6610626e27dcd28236b6bdc9",
"phase": "BUILDING_DIAGNOSIS",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"change_request"
],
"prompt_version": "change_request_v8",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 32.156,
"usage": {
"input_tokens": 20502,
"output_tokens": 4285,
"reasoning_tokens": 2944,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 1341
}
}
]
}
@@ -0,0 +1,496 @@
{
"format": "viano-token-usage-report",
"format_version": 1,
"recorded_date": "2026-10-20",
"run": "bug20-startup-batch-20261020",
"code_commit": "b332083",
"case_id": "BUG-000020",
"package_id": "trial-startup-batch-BUG-000020-20261020",
"package_generation": 67,
"analysis_revision": 1,
"state": "INVESTIGATING_HYPOTHESES",
"source_package": "service-data/trials/bug20-startup-batch-20261020/cases/897a914b67a02e6109a6b567e377e43c72b90ab216bfb9d2dc24485a5a55db8d/85f677c2e2c1e217563aa83ce86ad38ef239eb1143795161d0c706dbba3a8d21/g00000067.zip",
"manifest_sha256": "cf721c7c2b152f9decc0c51d7c1574f120a0dd95ee8c33305472bc3f9abf6d46",
"account_eur": {
"start": 12.55,
"final": null,
"settlement": "pending"
},
"startup": {
"order": [
"H1",
"H2",
"H3"
],
"done": true,
"review_rounds": 1,
"confidence_after_current_snapshot": {
"H1": "strongly_supported",
"H2": "weakened",
"H3": "weakened"
}
},
"notes": [
"output_tokens already includes reasoning; never add reasoning twice",
"Unknown values stay null and known sums carry missing counts",
"API elapsed sums are not wall-clock case duration",
"accepted_by refers to the immediate phase artifact; contributes_to includes retained source calls behind scoped repair",
"Planning excluding repair calls is not the same as accepted-only or all necessary planning work",
"This is a partial investigation snapshot, not a final diagnosis"
],
"totals_all_calls": {
"call_count": 10,
"input_tokens": {
"known_sum": 138418,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 25494,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 20456,
"missing_call_count": 2
},
"visible_output_tokens": {
"known_sum": 4401,
"missing_call_count": 2
},
"cached_input_tokens": {
"known_sum": 37767,
"missing_call_count": 4
},
"api_elapsed_seconds_sum": 188.033
},
"totals_by_group": {
"entity_resolution": {
"call_count": 2,
"input_tokens": {
"known_sum": 46745,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 637,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 0,
"missing_call_count": 2
},
"visible_output_tokens": {
"known_sum": 0,
"missing_call_count": 2
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 2
},
"api_elapsed_seconds_sum": 8.984
},
"investigation_followup": {
"call_count": 2,
"input_tokens": {
"known_sum": 27792,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 1309,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 1004,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 305,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 12154,
"missing_call_count": 0
},
"api_elapsed_seconds_sum": 14.11
},
"planning": {
"call_count": 2,
"input_tokens": {
"known_sum": 21352,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 12087,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 9006,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 3081,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 2
},
"api_elapsed_seconds_sum": 78.922
},
"startup_joint_review": {
"call_count": 1,
"input_tokens": {
"known_sum": 9442,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 2953,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 2239,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 714,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 2060,
"missing_call_count": 0
},
"api_elapsed_seconds_sum": 22.204
},
"startup_queries": {
"call_count": 3,
"input_tokens": {
"known_sum": 33087,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 8508,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 8207,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 301,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 23553,
"missing_call_count": 0
},
"api_elapsed_seconds_sum": 63.813
}
},
"totals_planning_excluding_corrections": {
"call_count": 1,
"input_tokens": {
"known_sum": 13886,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 5878,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 3057,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 2821,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 1
},
"api_elapsed_seconds_sum": 39.672
},
"totals_planning_contributing_calls": {
"call_count": 2,
"input_tokens": {
"known_sum": 21352,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 12087,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 9006,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 3081,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 2
},
"api_elapsed_seconds_sum": 78.922
},
"calls": [
{
"call_ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"call_sha256": "1a030b2a58045b475ba33e8652dd659432aeb9f522a375a41f38680a4202332e",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"contributes_to": [],
"group": "entity_resolution",
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 2.984,
"usage": {
"input_tokens": 21007,
"output_tokens": 166,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"call_sha256": "0db1c3697d2502946077a94ccf7eb93b9d0fe6b84312023c55f0aaba64b18826",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"contributes_to": [],
"group": "entity_resolution",
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 6.0,
"usage": {
"input_tokens": 25738,
"output_tokens": 471,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": null
}
},
{
"call_ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"call_sha256": "0f2b7690a9b10e46bee94bccd19cd7b75a42feec34f5f6d113edb26b62d0b971",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [
"INTERPRETATION_SOURCE_KIND"
],
"accepted_by": [],
"contributes_to": [
"case_interpretation",
"hypotheses"
],
"group": "planning",
"prompt_version": "case_plan_v2",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 39.672,
"usage": {
"input_tokens": 13886,
"output_tokens": 5878,
"reasoning_tokens": 3057,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 2821
}
},
{
"call_ref": "llm/operations/cdf9fddd5dccf7c6859f2f4c5aa65e46778d6d44e446cf579fa6b6f462b9b85c/round-0001.json",
"call_sha256": "b085af1baf09f197207746c601ba9f3962650d3edc3041fade197bf13b64ea35",
"phase": "INTERPRETING_CASE",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"case_interpretation",
"hypotheses"
],
"contributes_to": [
"case_interpretation",
"hypotheses"
],
"group": "planning",
"prompt_version": "case_plan_statement_repair_v2",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 39.25,
"usage": {
"input_tokens": 7466,
"output_tokens": 6209,
"reasoning_tokens": 5949,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"visible_output_tokens": 260
}
},
{
"call_ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"call_sha256": "098318f88855084294844cf53f0e496e781251aee4b877ca67f4e834b6027e19",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"contributes_to": [],
"group": "startup_queries",
"prompt_version": "investigation_startup_v1",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 7.969,
"usage": {
"input_tokens": 8168,
"output_tokens": 656,
"reasoning_tokens": 550,
"cached_input_tokens": 7851,
"uncached_input_tokens": 317,
"visible_output_tokens": 106
}
},
{
"call_ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"call_sha256": "b000f97d74f9cab3c117acc3c8b9c1c71f8ed5f5bf1c19acfa7289b0a16a6869",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"contributes_to": [],
"group": "startup_queries",
"prompt_version": "investigation_startup_v1",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 27.891,
"usage": {
"input_tokens": 11394,
"output_tokens": 3528,
"reasoning_tokens": 3415,
"cached_input_tokens": 7851,
"uncached_input_tokens": 3543,
"visible_output_tokens": 113
}
},
{
"call_ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"call_sha256": "d757391eb9bb08ee868ae017a9bc0f091cc80cf87b7d888af4a69d5110920894",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"contributes_to": [],
"group": "startup_queries",
"prompt_version": "investigation_startup_v1",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 27.953,
"usage": {
"input_tokens": 13525,
"output_tokens": 4324,
"reasoning_tokens": 4242,
"cached_input_tokens": 7851,
"uncached_input_tokens": 5674,
"visible_output_tokens": 82
}
},
{
"call_ref": "llm/operations/0270771b422d04af95c20c38558476ded170af96569985af436406482d8d043a/round-0001.json",
"call_sha256": "15fc914607b6316571d7ec23dfa3586dddff0d4953a6bb7efd860bdfb96dc4af",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [
"startup_review_H1",
"startup_review_H2",
"startup_review_H3"
],
"contributes_to": [
"startup_review_H1",
"startup_review_H2",
"startup_review_H3"
],
"group": "startup_joint_review",
"prompt_version": "investigation_startup_review_v1",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 22.204,
"usage": {
"input_tokens": 9442,
"output_tokens": 2953,
"reasoning_tokens": 2239,
"cached_input_tokens": 2060,
"uncached_input_tokens": 7382,
"visible_output_tokens": 714
}
},
{
"call_ref": "llm/operations/c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31/round-0001.json",
"call_sha256": "eb5809d3035ca00eeb51403ff2b1c56e1bd0020f9092369c101704e892b76af7",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"contributes_to": [],
"group": "investigation_followup",
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 6.813,
"usage": {
"input_tokens": 7704,
"output_tokens": 423,
"reasoning_tokens": 329,
"cached_input_tokens": 6077,
"uncached_input_tokens": 1627,
"visible_output_tokens": 94
}
},
{
"call_ref": "llm/operations/b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383/round-0001.json",
"call_sha256": "6b73f365694e2a4cb8e745fd2c82025ee0309d3a317151377e803a3aa06d5f3e",
"phase": "INVESTIGATING_HYPOTHESES",
"status": "SUCCESS",
"code": null,
"validation_errors": [],
"accepted_by": [],
"contributes_to": [],
"group": "investigation_followup",
"prompt_version": "investigation_project_v20",
"provider": "gemini-native",
"model": "gemini-3.8-flash",
"config_hash": "249a08e844d8a62c6b202c0bf856d2fa67f9c77f7a1f03174e79f874bf24ac69",
"elapsed_seconds": 7.297,
"usage": {
"input_tokens": 20088,
"output_tokens": 886,
"reasoning_tokens": 675,
"cached_input_tokens": 6077,
"uncached_input_tokens": 14011,
"visible_output_tokens": 211
}
}
]
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,215 @@
{
"case_id": "BUG-000021",
"snapshot": "review-after-entity-origin-fix",
"result": "FAILED_TO_ANALYZE",
"reason": "MODEL_VALIDATION_EXHAUSTED",
"recorded_at": "2026-10-24",
"scope": "Six saved model calls; no new model calls executed.",
"calls": [
{
"ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "022e6abbf1925482838f81b0a3a8b1994afe54835adc0510707b4a3ea00a88be",
"phase": "INTERPRETING_CASE",
"usage_classification": "regular",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": null,
"cost_currency": "USD",
"elapsed_seconds": 71.552436,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": null,
"estimated_cost": null,
"estimated_input_cost": null,
"estimated_output_cost": 0.00036,
"input_tokens": 15626,
"model": "gemini-3.8-flash",
"output_tokens": 96,
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"reasoning_tokens": null,
"uncached_input_tokens": null
}
},
{
"ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "aae23ca176952a643fb9a5f5546e2f003eb0af9ce1fe1b3c6e3d4d4a852ad33f",
"phase": "INTERPRETING_CASE",
"usage_classification": "regular",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": null,
"cost_currency": "USD",
"elapsed_seconds": 4.446479,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": null,
"estimated_cost": null,
"estimated_input_cost": null,
"estimated_output_cost": 0.00103875,
"input_tokens": 18384,
"model": "gemini-3.8-flash",
"output_tokens": 277,
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"reasoning_tokens": null,
"uncached_input_tokens": null
}
},
{
"ref": "llm/operations/e6f77de4396a9e8dc19665d9f8d2544febad7983aa8797141760c691a4d2a805/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "3715adca8b12d9e2b10dedc65c07ff801e659bda71db5042fc6e63b0e9420e8b",
"phase": "INTERPRETING_CASE",
"usage_classification": "correction",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": 16341,
"cost_currency": "USD",
"elapsed_seconds": 4.580154,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": 0.001225575,
"estimated_cost": 0.004089074999999999,
"estimated_input_cost": 0.00160725,
"estimated_output_cost": 0.00125625,
"input_tokens": 18484,
"model": "gemini-3.8-flash",
"output_tokens": 335,
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"reasoning_tokens": null,
"uncached_input_tokens": 2143
}
},
{
"ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"status": "ERROR",
"code": "LLM_RESPONSE",
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "33b5c731797a37d26f4d7ac5f560573bbe576db6a51fe099f2952ecfa818c33f",
"phase": "INTERPRETING_CASE",
"usage_classification": "correction",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": null,
"cost_currency": "USD",
"elapsed_seconds": 26.257507,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": null,
"estimated_cost": null,
"estimated_input_cost": null,
"estimated_output_cost": 0.01366875,
"input_tokens": 11100,
"model": "gemini-3.8-flash",
"output_tokens": 3645,
"prompt_version": "case_plan_v2",
"provider": "gemini-native",
"reasoning_tokens": 783,
"uncached_input_tokens": null
}
},
{
"ref": "llm/operations/cdf9fddd5dccf7c6859f2f4c5aa65e46778d6d44e446cf579fa6b6f462b9b85c/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "6038fe06c92ae2093575231052b86d9c9336db7c1be6db290d38788247acac54",
"phase": "INTERPRETING_CASE",
"usage_classification": "correction",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": null,
"cost_currency": "USD",
"elapsed_seconds": 36.071492,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": null,
"estimated_cost": null,
"estimated_input_cost": null,
"estimated_output_cost": 0.02161875,
"input_tokens": 10867,
"model": "gemini-3.8-flash",
"output_tokens": 5765,
"prompt_version": "case_plan_interpretation_repair_v1",
"provider": "gemini-native",
"reasoning_tokens": 4138,
"uncached_input_tokens": null
}
},
{
"ref": "llm/operations/2cd36795173fe6d547ff571814187ce1b12b3a7ec6accd4ebd98869d46bad248/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "6ca3f5d95072a753690196dd2bb30d8df60d75c6d3fc41c64f4e736dfb64ab18",
"phase": "INTERPRETING_CASE",
"usage_classification": "correction",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": null,
"cost_currency": "USD",
"elapsed_seconds": 24.407819,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": null,
"estimated_cost": null,
"estimated_input_cost": null,
"estimated_output_cost": 0.01227,
"input_tokens": 4163,
"model": "gemini-3.8-flash",
"output_tokens": 3272,
"prompt_version": "case_plan_statement_repair_v2",
"provider": "gemini-native",
"reasoning_tokens": 3064,
"uncached_input_tokens": null
}
}
],
"pricing": {
"currency": "USD",
"source": "saved per-call metadata; local example rates match output 3.75/million, input .75/million, cache .075/million",
"captured_at": "2026-10-24",
"storage": "saved estimate 0; no additional estimate"
},
"totals": {
"input_tokens": 78624,
"output_tokens_including_reasoning": 13390,
"reasoning_tokens": "unknown for entity resolution calls; included in output_tokens elsewhere"
},
"account_balance_eur": "unknown",
"clean_accounting_note": "First case_plan_v2 call mislabeled correction; count as regular. Entity assessment second attempt and two interpretation repair calls are corrections.",
"limitations": [
"Cache token counts missing for five calls; exact total USD estimate unknown.",
"Reasoning must not be added again to output_tokens."
],
"total_balance": {
"input_tokens": 78624,
"output_tokens_including_reasoning": 13390,
"model_seconds": 167.315887,
"estimated_usd": "unknown (missing cache accounting)",
"per_call_output_cost_usd": 0.05021250000000001
},
"clean_balance": {
"input_tokens": 45110,
"output_tokens_including_reasoning": 4018,
"model_seconds": 102.256422,
"estimated_usd": "unknown (missing cache accounting)",
"per_call_output_cost_usd": 0.015067500000000001
}
}
@@ -0,0 +1,150 @@
{
"case_id": "BUG-000021",
"analysis_revision": 2,
"package_generation": 43,
"result": "BLOCKED",
"reason": "ENTITY_RESOLUTION_INVALID_RESPONSES",
"recorded_at": "2026-10-24",
"scope": "revision 2 only; prior snapshot retained separately",
"calls": [
{
"ref": "llm/operations/2bb2e79d81a427683503f00f994096c132e4f3996cdd1250c22e65b5345c47b6/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "498c1d4c6fb3b32da6ad143ba78b533fbc7ce88d84ed656a26c659ede7a60e40",
"classification": "regular",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": null,
"cost_currency": "USD",
"elapsed_seconds": 2.865948,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": null,
"estimated_cost": null,
"estimated_input_cost": null,
"estimated_output_cost": 0.00043875,
"input_tokens": 20304,
"model": "gemini-3.8-flash",
"output_tokens": 117,
"prompt_version": "entity_resolution_plan_v4",
"provider": "gemini-native",
"reasoning_tokens": null,
"uncached_input_tokens": null
}
},
{
"ref": "llm/operations/f3b089e666430152253a7ad993e97035bd9b964286b1fad8fdc3df2f1815ee5c/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "a88dd9acdf5bdbfac2eb2f6962d20e77dcaa6c6e52d23ba2cc180bc11e1cc950",
"classification": "regular",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": null,
"cost_currency": "USD",
"elapsed_seconds": 3.737966,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": null,
"estimated_cost": null,
"estimated_input_cost": null,
"estimated_output_cost": 0.0010275,
"input_tokens": 23234,
"model": "gemini-3.8-flash",
"output_tokens": 274,
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"reasoning_tokens": null,
"uncached_input_tokens": null
}
},
{
"ref": "llm/operations/3237e2db6c942e4528382afeac6bbed66cce7c9b54a7c2bc8e1601ca9943b1fb/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "aa49d9159ae7894e5870e2c0abebded94877f7f23201741c79066ab37264d623",
"classification": "correction",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": 21188,
"cost_currency": "USD",
"elapsed_seconds": 5.118418,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": 0.0015891,
"estimated_cost": 0.0042336000000000006,
"estimated_input_cost": 0.0016095,
"estimated_output_cost": 0.001035,
"input_tokens": 23334,
"model": "gemini-3.8-flash",
"output_tokens": 276,
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"reasoning_tokens": null,
"uncached_input_tokens": 2146
}
},
{
"ref": "llm/operations/4a0ee3b438d0e207215ca4a5dddc522f11ac8756afc4a85b3c768815a69ce1e8/round-0001.json",
"status": "SUCCESS",
"code": null,
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_hash": "61283f3a158d361b9842431609b826d5d353b3de4c7b387a8d97fb413791d234",
"classification": "correction",
"metadata": {
"attempts": [],
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"cached_input_tokens": 21288,
"cost_currency": "USD",
"elapsed_seconds": 5.437512,
"estimated_cache_storage_cost": 0.0,
"estimated_cached_input_cost": 0.0015965999999999999,
"estimated_cost": 0.0043251,
"estimated_input_cost": 0.00153225,
"estimated_output_cost": 0.00119625,
"input_tokens": 23331,
"model": "gemini-3.8-flash",
"output_tokens": 319,
"prompt_version": "entity_resolution_assessment_v4",
"provider": "gemini-native",
"reasoning_tokens": null,
"uncached_input_tokens": 2043
}
}
],
"model": "gemini-3.8-flash",
"pricing": {
"currency": "USD",
"input_per_million": 0.75,
"cached_input_per_million": 0.075,
"output_including_reasoning_per_million": 3.75,
"source": "saved API metadata and configured pricing",
"captured_at": "2026-10-24"
},
"account_balance_eur": "unknown",
"limits": "Missing cache counts are unknown, not zero; reasoning tokens unknown and not added to output. No new cloud calls.",
"total": {
"input_tokens": 90203,
"output_tokens": 986,
"model_seconds": 17.159844,
"estimated_cost_usd": "unknown (missing cache counts)",
"output_cost_usd": 0.0036975000000000003,
"cache_storage_cost_usd": 0.0
},
"clean": {
"input_tokens": 43538,
"output_tokens": 391,
"model_seconds": 6.603914,
"estimated_cost_usd": "unknown (missing cache counts)",
"output_cost_usd": 0.00146625,
"cache_storage_cost_usd": 0.0
}
}
@@ -0,0 +1,659 @@
{
"case_id": "BUG-000022",
"package_id": "api-04e95ed5d97043810706ce14ff101d8cb29778bea835bd190d7bbdb5578e9f8b",
"analysis_revision": 1,
"package_generation": 79,
"result": "OUTPUT_READY",
"recorded_at": "2026-10-25",
"scope": "Final package, all recorded model calls once; joint interpretation/hypotheses counted once. No new model calls.",
"package_sha256": "33ad04882c92fdb37df9a6452b7bb30243a511cd28ea55b36a4d6600aeff8361",
"pricing": {
"model": "gemini-3.8-flash",
"currency": "USD",
"recorded_at": "2026-10-25",
"source": "saved per-call cost metadata and configured table, not independently refreshed vendor pricing",
"input_per_million": 0.75,
"cache_input_per_million": 0.075,
"output_including_reasoning_per_million": 3.75,
"storage": "reported estimates separately; missing values unknown"
},
"classification_note": "First case_plan_v2 response is a regular joint call despite recorded correction label. Additional startup response is excluded from clean balance.",
"account_balance_eur": null,
"account_status": "No EUR balance supplied",
"runtime": {
"first_revision_checkpoint": "2026-10-24T22:14:39.788595+00:00",
"completed": "2026-10-24T22:21:56.220461+00:00",
"checkpoint_span_seconds": 436.431866,
"note": "Checkpoint span includes local overhead, excludes any unrecorded queue waiting before first revision checkpoint"
},
"total": {
"calls": 13,
"measured_calls": 13,
"input_tokens": 106317,
"output_including_reasoning_tokens": 21897,
"known_reasoning_tokens": 13570,
"reasoning_complete": false,
"known_cached_input_tokens": 16697,
"cache_complete": false,
"model_seconds_known_sum": 207.939304,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.09486990000000001,
0.15058102499999998
],
"cache_storage_cost_usd": null,
"phases": {
"diagnosis": {
"calls": 1,
"measured_calls": 1,
"input_tokens": 20463,
"output_including_reasoning_tokens": 2188,
"known_reasoning_tokens": 1013,
"reasoning_complete": true,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 14.279153,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.009739725000000001,
0.02355225
],
"cache_storage_cost_usd": 0.0
},
"entity_resolution": {
"calls": 2,
"measured_calls": 2,
"input_tokens": 32272,
"output_including_reasoning_tokens": 422,
"known_reasoning_tokens": 0,
"reasoning_complete": false,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 42.703409,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.004002899999999999,
0.0257865
],
"cache_storage_cost_usd": 0.0
},
"handoff": {
"calls": 1,
"measured_calls": 1,
"input_tokens": 15533,
"output_including_reasoning_tokens": 4177,
"known_reasoning_tokens": 2808,
"reasoning_complete": true,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 28.14314,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.016828725,
0.0273135
],
"cache_storage_cost_usd": 0.0
},
"investigation": {
"calls": 8,
"measured_calls": 8,
"input_tokens": 27305,
"output_including_reasoning_tokens": 10148,
"known_reasoning_tokens": 8480,
"reasoning_complete": true,
"known_cached_input_tokens": 16697,
"cache_complete": false,
"model_seconds_known_sum": 90.76304400000001,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.04488525,
0.04726327500000001
],
"cache_storage_cost_usd": null
},
"joint_planning": {
"calls": 1,
"measured_calls": 1,
"input_tokens": 10744,
"output_including_reasoning_tokens": 4962,
"known_reasoning_tokens": 1269,
"reasoning_complete": true,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 32.050558,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.019413299999999998,
0.026665499999999998
],
"cache_storage_cost_usd": 0.0
}
}
},
"clean": {
"calls": 12,
"measured_calls": 12,
"input_tokens": 102446,
"output_including_reasoning_tokens": 21265,
"known_reasoning_tokens": 13030,
"reasoning_complete": false,
"known_cached_input_tokens": 14256,
"cache_complete": false,
"model_seconds_known_sum": 200.814912,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.091244325,
0.14695545
],
"cache_storage_cost_usd": null,
"phases": {
"diagnosis": {
"calls": 1,
"measured_calls": 1,
"input_tokens": 20463,
"output_including_reasoning_tokens": 2188,
"known_reasoning_tokens": 1013,
"reasoning_complete": true,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 14.279153,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.009739725000000001,
0.02355225
],
"cache_storage_cost_usd": 0.0
},
"entity_resolution": {
"calls": 2,
"measured_calls": 2,
"input_tokens": 32272,
"output_including_reasoning_tokens": 422,
"known_reasoning_tokens": 0,
"reasoning_complete": false,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 42.703409,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.004002899999999999,
0.0257865
],
"cache_storage_cost_usd": 0.0
},
"handoff": {
"calls": 1,
"measured_calls": 1,
"input_tokens": 15533,
"output_including_reasoning_tokens": 4177,
"known_reasoning_tokens": 2808,
"reasoning_complete": true,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 28.14314,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.016828725,
0.0273135
],
"cache_storage_cost_usd": 0.0
},
"investigation": {
"calls": 7,
"measured_calls": 7,
"input_tokens": 23434,
"output_including_reasoning_tokens": 9516,
"known_reasoning_tokens": 7940,
"reasoning_complete": true,
"known_cached_input_tokens": 14256,
"cache_complete": false,
"model_seconds_known_sum": 83.63865200000001,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.041259675,
0.0436377
],
"cache_storage_cost_usd": null
},
"joint_planning": {
"calls": 1,
"measured_calls": 1,
"input_tokens": 10744,
"output_including_reasoning_tokens": 4962,
"known_reasoning_tokens": 1269,
"reasoning_complete": true,
"known_cached_input_tokens": 0,
"cache_complete": false,
"model_seconds_known_sum": 32.050558,
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.019413299999999998,
0.026665499999999998
],
"cache_storage_cost_usd": 0.0
}
}
},
"calls": [
{
"ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
"operation_key": "6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548",
"analysis_revision": 1,
"phase": "entity_resolution",
"prompt_version": "entity_resolution_plan_v4",
"prompt_characters": 33168,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "645b6f2cd80737162108331f6fcf9da8f086dcacc635b3375dec16c9c71e7f4b",
"usage": {
"input_tokens": 14980,
"output_tokens": 112,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"elapsed_seconds": 39.040508
},
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.0015435,
0.011655
],
"cache_storage_cost_usd": 0.0
},
{
"ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
"operation_key": "88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea",
"analysis_revision": 1,
"phase": "entity_resolution",
"prompt_version": "entity_resolution_assessment_v4",
"prompt_characters": 39785,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "94cd9df23849fa4c59d4cfa06b69627c3978b912ba16d6c90a7bafa1ff84d5ae",
"usage": {
"input_tokens": 17292,
"output_tokens": 310,
"reasoning_tokens": null,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"elapsed_seconds": 3.662901
},
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.0024593999999999996,
0.0141315
],
"cache_storage_cost_usd": 0.0
},
{
"ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
"operation_key": "572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65",
"analysis_revision": 1,
"phase": "joint_planning",
"prompt_version": "case_plan_v2",
"prompt_characters": 33025,
"classification": "regular",
"recorded_classification": "correction",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "1fcd4e5cad0b961240236d3146b60de4a07bc14962e98626b020b457bafc2fdf",
"usage": {
"input_tokens": 10744,
"output_tokens": 4962,
"reasoning_tokens": 1269,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"elapsed_seconds": 32.050558
},
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.019413299999999998,
0.026665499999999998
],
"cache_storage_cost_usd": 0.0
},
{
"ref": "llm/operations/ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112/round-0001.json",
"operation_key": "ca6cdff81de3cbae0492c26802daa287b11bf4fabefad477a9b64f1b6db30112",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_startup_v1",
"prompt_characters": 8865,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "18e1a41a7c31942556f3c7be6793762fce43220ee6d671866c0d14d6dc2f3c7f",
"usage": {
"input_tokens": 2697,
"output_tokens": 393,
"reasoning_tokens": 318,
"cached_input_tokens": 2441,
"uncached_input_tokens": 256,
"cache_created_tokens": 2441,
"cache_status": "created",
"elapsed_seconds": 5.655612
},
"estimated_cost_usd": 0.0018488250000000001,
"known_usage_usd_range": [
0.0018488250000000001,
0.0018488250000000001
],
"cache_storage_cost_usd": 0.00010170833333333334
},
{
"ref": "llm/operations/54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc/round-0001.json",
"operation_key": "54ef9b495e10fe49a2ffad5909c89efdbfe7ef7645b601865d12e5223b0651bc",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_startup_v1",
"prompt_characters": 11950,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "6269dd79ef6176ff248f206613f469444e080b423cc8b7a12518f9701f61ac60",
"usage": {
"input_tokens": 3566,
"output_tokens": 677,
"reasoning_tokens": 561,
"cached_input_tokens": 2441,
"uncached_input_tokens": 1125,
"cache_created_tokens": 0,
"cache_status": "reused",
"elapsed_seconds": 6.459214
},
"estimated_cost_usd": 0.0035655750000000005,
"known_usage_usd_range": [
0.0035655750000000005,
0.0035655750000000005
],
"cache_storage_cost_usd": 0.0
},
{
"ref": "llm/operations/71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4/round-0001.json",
"operation_key": "71fd77c20b2af9bb2d842927c7a39cc8e1cf3e15541f387a26054fdb1047b6e4",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_startup_v1",
"prompt_characters": 12860,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "3ab7cf7e3d8e9137d558c15c2012140f0a0618f8cca9e70f7eef14bf02bb0c41",
"usage": {
"input_tokens": 3815,
"output_tokens": 1001,
"reasoning_tokens": 875,
"cached_input_tokens": 2441,
"uncached_input_tokens": 1374,
"cache_created_tokens": 0,
"cache_status": "reused",
"elapsed_seconds": 7.44411
},
"estimated_cost_usd": 0.004967325,
"known_usage_usd_range": [
0.004967325,
0.004967325
],
"cache_storage_cost_usd": 0.0
},
{
"ref": "llm/operations/7b8f9ecd4cb00c7e1d8bbd314d9ab15032701b76a0d5cf4256b895312b03a731/round-0001.json",
"operation_key": "7b8f9ecd4cb00c7e1d8bbd314d9ab15032701b76a0d5cf4256b895312b03a731",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_startup_v1",
"prompt_characters": 13098,
"classification": "correction",
"recorded_classification": "correction",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "747d5e6358c32804aabf93970ef4889b3c1bc809254b05efaeb0df61e1897873",
"usage": {
"input_tokens": 3871,
"output_tokens": 632,
"reasoning_tokens": 540,
"cached_input_tokens": 2441,
"uncached_input_tokens": 1430,
"cache_created_tokens": 0,
"cache_status": "reused",
"elapsed_seconds": 7.124392
},
"estimated_cost_usd": 0.0036255750000000002,
"known_usage_usd_range": [
0.0036255750000000002,
0.0036255750000000002
],
"cache_storage_cost_usd": 0.0
},
{
"ref": "llm/operations/0270771b422d04af95c20c38558476ded170af96569985af436406482d8d043a/round-0001.json",
"operation_key": "0270771b422d04af95c20c38558476ded170af96569985af436406482d8d043a",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_startup_review_v1",
"prompt_characters": 11179,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "7a6617bb65d9d93dd8aa0e8d85b629909e7fb9c39ec270db8bb60511e3dde5b7",
"usage": {
"input_tokens": 3523,
"output_tokens": 2374,
"reasoning_tokens": 1773,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"cache_created_tokens": null,
"cache_status": "fallback",
"elapsed_seconds": 18.078619
},
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.009166725,
0.011544750000000001
],
"cache_storage_cost_usd": null
},
{
"ref": "llm/operations/c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31/round-0001.json",
"operation_key": "c619a7901de5674f54e8371759fba596a7746f67d62499b198780813912e5c31",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_project_v20",
"prompt_characters": 9612,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "f50e57d329485610f657a47c5d22a120750a049ed368a54ba6127671ad942b09",
"usage": {
"input_tokens": 2920,
"output_tokens": 291,
"reasoning_tokens": 198,
"cached_input_tokens": 2497,
"uncached_input_tokens": 423,
"cache_created_tokens": 2497,
"cache_status": "created",
"elapsed_seconds": 4.425924
},
"estimated_cost_usd": 0.001595775,
"known_usage_usd_range": [
0.001595775,
0.001595775
],
"cache_storage_cost_usd": 0.00010404166666666667
},
{
"ref": "llm/operations/b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383/round-0001.json",
"operation_key": "b5de43dfa1122fa86decfa538047ee813621839eded8ed15356d341f3439e383",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_project_v20",
"prompt_characters": 12076,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "7cb224250e9557d857268001dcecf8cba78fa509081eb13e8fe22ed66a85379f",
"usage": {
"input_tokens": 4132,
"output_tokens": 624,
"reasoning_tokens": 321,
"cached_input_tokens": 2511,
"uncached_input_tokens": 1621,
"cache_created_tokens": 2511,
"cache_status": "created",
"elapsed_seconds": 7.509486
},
"estimated_cost_usd": 0.0037440750000000004,
"known_usage_usd_range": [
0.0037440750000000004,
0.0037440750000000004
],
"cache_storage_cost_usd": 0.00010462500000000001
},
{
"ref": "llm/operations/6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1/round-0001.json",
"operation_key": "6849c974442865e5ca3e8f146ef4520c275f2e37a25fb7caa498f17089ed6dc1",
"analysis_revision": 1,
"phase": "investigation",
"prompt_version": "investigation_project_v20",
"prompt_characters": 9159,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "ff3c7cd769e708cf4cb6ff98e19f2aff507841f046e9d178076c1b6339102560",
"usage": {
"input_tokens": 2781,
"output_tokens": 4156,
"reasoning_tokens": 3894,
"cached_input_tokens": 1925,
"uncached_input_tokens": 856,
"cache_created_tokens": 1925,
"cache_status": "created",
"elapsed_seconds": 34.065687
},
"estimated_cost_usd": 0.016371375,
"known_usage_usd_range": [
0.016371375,
0.016371375
],
"cache_storage_cost_usd": 8.020833333333334e-05
},
{
"ref": "llm/operations/25febf70da1f602d9d830c61c59e4504617a8bc05beac14676d7fd4e9f6589f9/round-0001.json",
"operation_key": "25febf70da1f602d9d830c61c59e4504617a8bc05beac14676d7fd4e9f6589f9",
"analysis_revision": 1,
"phase": "diagnosis",
"prompt_version": "diagnosis_early_v8",
"prompt_characters": 48403,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "569ec836dd3f078c5cbaf46f32f3ea5e330654219f6723a691133b1e732e746f",
"usage": {
"input_tokens": 20463,
"output_tokens": 2188,
"reasoning_tokens": 1013,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"elapsed_seconds": 14.279153
},
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.009739725000000001,
0.02355225
],
"cache_storage_cost_usd": 0.0
},
{
"ref": "llm/operations/17917402a4c04bd20ae3b0a2f256a39daa4c026a0afff5f80f408478611d4e03/round-0001.json",
"operation_key": "17917402a4c04bd20ae3b0a2f256a39daa4c026a0afff5f80f408478611d4e03",
"analysis_revision": 1,
"phase": "handoff",
"prompt_version": "change_request_v9",
"prompt_characters": 38336,
"classification": "regular",
"recorded_classification": "regular",
"status": "SUCCESS",
"code": null,
"model": "gemini-3.8-flash",
"provider": "gemini-native",
"config_sha256": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
"request_sha256": "aaf9aaa1e371329ba165cd131f64e4cd574e98ef55e129defe9ecf0cee055342",
"usage": {
"input_tokens": 15533,
"output_tokens": 4177,
"reasoning_tokens": 2808,
"cached_input_tokens": null,
"uncached_input_tokens": null,
"cache_created_tokens": 0,
"cache_status": "below_minimum",
"elapsed_seconds": 28.14314
},
"estimated_cost_usd": null,
"known_usage_usd_range": [
0.016828725,
0.0273135
],
"cache_storage_cost_usd": 0.0
}
],
"limitations": [
"Unknown cached_input_tokens are not zero. USD bounds apply to known usage and exclude unreported charges.",
"Output includes thinking; known reasoning tokens must not be added again."
]
}
@@ -0,0 +1,117 @@
{
"recorded_date": "2026-10-20",
"baseline_report": "bug20-shared-recovery-20261019.json",
"candidate_report": "bug20-joint-structure-20261020.json",
"scope": "interpretation and hypotheses only; excludes entity resolution and investigation",
"accepted_only": {
"baseline": {
"call_count": 2,
"input_tokens": {
"known_sum": 31170,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 11757,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 8328,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 3429,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 14024,
"missing_call_count": 1
},
"api_elapsed_seconds_sum": 97.422
},
"candidate": {
"call_count": 1,
"input_tokens": {
"known_sum": 13733,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 7863,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 5247,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 2616,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 1
},
"api_elapsed_seconds_sum": 51.156
}
},
"all_attempts": {
"baseline": {
"call_count": 4,
"input_tokens": {
"known_sum": 63120,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 19587,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 12903,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 6684,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 14024,
"missing_call_count": 3
},
"api_elapsed_seconds_sum": 162.937
},
"candidate": {
"call_count": 1,
"input_tokens": {
"known_sum": 13733,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 7863,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 5247,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 2616,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 0,
"missing_call_count": 1
},
"api_elapsed_seconds_sum": 51.156
}
},
"account_eur": {
"candidate_start": 12.46,
"candidate_latest_reported": 12.47,
"candidate_final": null,
"settlement": "pending_provider_delay"
},
"limitations": [
"Single runs with different prompt versions, not a controlled paired benchmark",
"Baseline accepted hypothesis call reports 14024 cached input tokens; candidate planning reports no cached count",
"Token reductions do not imply proportional price reductions"
]
}
@@ -0,0 +1,83 @@
{
"date": "2026-10-20",
"baseline": "bug20-joint-planning-20261019.json",
"candidate": "bug20-startup-batch-20261020-g00000067.json",
"old_three_verbose_starts": {
"call_count": 3,
"input_tokens": {
"known_sum": 23929,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 12476,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 11263,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 1213,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 15375,
"missing_call_count": 0
},
"api_elapsed_seconds_sum": 125.891
},
"new_three_lean_queries": {
"call_count": 3,
"input_tokens": {
"known_sum": 33087,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 8508,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 8207,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 301,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 23553,
"missing_call_count": 0
},
"api_elapsed_seconds_sum": 63.813
},
"new_queries_plus_joint_review": {
"call_count": 4,
"input_tokens": {
"known_sum": 42529,
"missing_call_count": 0
},
"output_tokens": {
"known_sum": 11461,
"missing_call_count": 0
},
"reasoning_tokens": {
"known_sum": 10446,
"missing_call_count": 0
},
"visible_output_tokens": {
"known_sum": 1015,
"missing_call_count": 0
},
"cached_input_tokens": {
"known_sum": 25613,
"missing_call_count": 0
},
"api_elapsed_seconds_sum": 86.017
},
"limitations": [
"Different individual runs and different queries, not a controlled paired benchmark",
"The new joint review settles all initial results; the three old startup calls left own result assessments for subsequent loop calls",
"Includes joint review cost; excludes planning, name resolution, later investigation and any final diagnosis",
"No final euro cost reported yet; input/cache/storage pricing must be considered separately"
]
}
@@ -0,0 +1,58 @@
{
"format": "viano-cost-projection",
"recorded_date": "2026-10-20",
"source_report": "bug20-contract-v2-20261020-g00000122.json",
"currency": "USD",
"pricing_snapshot": [
{
"id": "gemini-native",
"model": "gemini-3.8-flash",
"cost_currency": "USD",
"input_cost_per_million": 0.75,
"cached_input_cost_per_million": 0.075,
"output_cost_per_million": 3.75,
"cache_storage_cost_per_million_hour": 0.5
}
],
"account_eur_settlement": "pending; no exchange-rate conversion assumed",
"assumptions": {
"hypotheses": 3,
"units_per_hypothesis": 100,
"cheapest_action_cost": 10,
"max_refund_fraction": 0.8,
"net_cost_after_full_refund": 2,
"maximum_actions_each": 46,
"total_research_actions": 138,
"startup_research_actions": 3,
"following_research_actions": 135,
"thin_call_average_usd": 0.0033548249999999996,
"consolidation_call_average_usd_excluding_retry": 0.007716150000000001,
"baseline_including_successful_handoff_usd": 0.14092312499999998,
"normal_observed_tool_queries": 5,
"normal_observed_thin_calls_including_recall_and_checkpoint_requests": 8,
"accepted_consolidations": 3
},
"scenarios": [
{
"name": "138 thin calls plus checkpoint overhead at three per eight following thin calls",
"following_thin_calls": 135,
"consolidations": 51,
"estimate_usd": 0.9873481500000001
},
{
"name": "Full research-action count with observed recall/checkpoint-request/consolidation overhead per five normal queries",
"following_thin_calls": 216,
"consolidations": 81,
"estimate_usd": 1.4905734750000001
}
],
"limitations": [
"Small successful-case sample, not measured failed full-budget run.",
"No correction overhead included in scenarios. First regular rejected outputs remain in empirical averages where applicable.",
"Cache storage and variable corrections additional; late cache expiry/recreation can change costs.",
"Prices remain configured snapshot, not newly researched provider prices.",
"50 iterations per hypothesis may end actual run before 46 research actions when extra consolidation/recall iterations intervene. This is a cost scenario, not an executable guarantee of 138 actions.",
"Successful change-request generation retained in baseline as conservative allowance; failed run may omit it.",
"No fixed worst-case financial bound: reasoning intensity and failures may differ."
]
}
@@ -0,0 +1,124 @@
{
"kind": "offline_rendering_comparison",
"paid_api_calls": 0,
"legacy_requests_exact_messages_schema_version": 7,
"target": 10000,
"limit": 20000,
"note": "Counts include system, stable cache prefix and live input. Local schema is not duplicated as text in v2. No quality or cost claim from offline rendering. Existing v1 contexts unchanged.",
"measurements": [
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H1-0001.json",
"legacy_policy": 1,
"old_characters": 8992,
"v2_characters": 8460
},
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H1-0001-attempt-0001.json",
"legacy_policy": 1,
"old_characters": 9036,
"v2_characters": 8504
},
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H1-0001-attempt-0002.json",
"legacy_policy": 1,
"old_characters": 9036,
"v2_characters": 8504
},
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H2-0001.json",
"legacy_policy": 1,
"old_characters": 12126,
"v2_characters": 11594
},
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H3-0001.json",
"legacy_policy": 1,
"old_characters": 15189,
"v2_characters": 14657
},
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H3-0001-attempt-0001.json",
"legacy_policy": 1,
"old_characters": 15233,
"v2_characters": 14701
},
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H3-0001-attempt-0002.json",
"legacy_policy": 1,
"old_characters": 15349,
"v2_characters": 14817
},
{
"trial": "bug20-bounded-window-20261020",
"context": "analysis/investigation/0001/contexts/H3-0001-attempt-0003.json",
"legacy_policy": 1,
"old_characters": 15233,
"v2_characters": 14701
},
{
"trial": "bug20-startup-batch-20261020",
"context": "analysis/investigation/0001/contexts/H1-0001.json",
"legacy_policy": 0,
"old_characters": 25910,
"v2_characters": 8483
},
{
"trial": "bug20-startup-batch-20261020",
"context": "analysis/investigation/0001/contexts/H2-0001.json",
"legacy_policy": 0,
"old_characters": 33693,
"v2_characters": 11648
},
{
"trial": "bug20-startup-batch-20261020",
"context": "analysis/investigation/0001/contexts/H3-0001.json",
"legacy_policy": 0,
"old_characters": 39998,
"v2_characters": 14693
},
{
"trial": "bug20-startup-batch-20261020",
"context": "analysis/investigation/0001/contexts/H1-0002.json",
"legacy_policy": 0,
"old_characters": 24422,
"v2_characters": 9331
},
{
"trial": "bug20-startup-batch-20261020",
"context": "analysis/investigation/0001/contexts/H1-0003.json",
"legacy_policy": 0,
"old_characters": 52425,
"v2_characters": 12064
}
],
"source_sha256": {
"src/viano_bug_analysis/analysis/investigation_contract.py": "3b034fe557abf004d104525a0b771dfb8b45b6e4dd273f0993fc0c680df71537",
"src/viano_bug_analysis/analysis/investigation_window.py": "d468d896d81c4eb49f2eccf640e45ed378cdde2df1c934fbce3893dec5d537d8",
"src/viano_bug_analysis/llm/gemini.py": "9933052061298218bf574875cc8e9eb96de349e167fbc2e11379023f20d0d962",
"config/investigation.bounded.toml": "b3693a0eab479b67af1049dd0725e8d8e18b30d70eea176fa6c30a7bba723cf9"
},
"storage_audit": {
"limit_bytes": 20000000000,
"measured_roots": {
"service-data\\trials": 11174795619,
"service-data\\benchmarks": 498385,
"service-data\\test-archive": 1401997078,
"tests\\fixtures\\llm_rejections": 2268510,
"C:\\Users\\User\\AppData\\Local\\Temp\\pytest-of-User": 843846710
},
"note": "Read-only audit; no trial data deleted."
},
"local_tests": {
"passed": 307,
"elapsed_seconds": 171.87,
"paid_api_calls": 0,
"scope": "bounded v1/v2, startup, lean loop, gateway, caching, stable context, recovery, diagnostics, tool feedback"
}
}
@@ -0,0 +1,95 @@
{
"format": "viano-offline-prompt-window-measurement",
"format_version": 1,
"date": "2026-10-20",
"source_trial": "bug20-startup-batch-20261020",
"source_generation": 67,
"paid_llm_calls": 0,
"target_characters": 10000,
"hard_limit_characters": 20000,
"notes": [
"Offline reconstruction, not an LLM quality or token benchmark.",
"Full Gemini character counts include system, cached prefix, live input, response contract and outer schema.",
"Archived contexts and source packages were not modified.",
"Original message characters exclude provider-added framing; new accounted counts include separately supplied schema."
],
"measurements": [
{
"context_ref": "analysis/investigation/0001/contexts/H1-0001.json",
"old_message_characters": 25084,
"new_accounted_characters": 8106,
"new_full_gemini_json_object_characters": 9056
},
{
"context_ref": "analysis/investigation/0001/contexts/H2-0001.json",
"old_message_characters": 32867,
"new_accounted_characters": 11271,
"new_full_gemini_json_object_characters": 12221
},
{
"context_ref": "analysis/investigation/0001/contexts/H3-0001.json",
"old_message_characters": 39172,
"new_accounted_characters": 14316,
"new_full_gemini_json_object_characters": 15266
},
{
"context_ref": "analysis/investigation/0001/startup/contexts/H1.json",
"old_message_characters": 29981,
"new_accounted_characters": 9821,
"new_full_gemini_json_object_characters": 10771
},
{
"context_ref": "analysis/investigation/0001/startup/contexts/H2.json",
"old_message_characters": 30075,
"new_accounted_characters": 9780,
"new_full_gemini_json_object_characters": 10730
},
{
"context_ref": "analysis/investigation/0001/startup/contexts/H3.json",
"old_message_characters": 29352,
"new_accounted_characters": 7997,
"new_full_gemini_json_object_characters": 8947
},
{
"context_ref": "analysis/investigation/0001/contexts/H1-0002.json",
"old_message_characters": 23596,
"new_accounted_characters": 8148,
"new_full_gemini_json_object_characters": 9098
},
{
"context_ref": "analysis/investigation/0001/contexts/H1-0003.json",
"old_message_characters": 51599,
"new_accounted_characters": 10881,
"new_full_gemini_json_object_characters": 11831
},
{
"phase": "startup_joint_review",
"new_accounted_characters": 12576,
"new_full_gemini_json_object_characters": 12594
}
],
"source_manifest_sha256": "cf721c7c2b152f9decc0c51d7c1574f120a0dd95ee8c33305472bc3f9abf6d46",
"implementation_sha256": {
"src/viano_bug_analysis/analysis/investigation_window.py": "9f219c67535aec01d73a85675c4ab4be591ad2c95f30091fb00f6db1150fa95f",
"src/viano_bug_analysis/llm/investigation_size.py": "425f3d983da62b0ed7ffacf3e7119612f1736d0a7e4cb32545f368ee1f8bd41b",
"config/investigation.bounded.toml": "cf5317fbcf43494043ecd574843588888a5f756d8c9c52987b6411df4ba98250"
},
"local_verification": {
"passed_tests": 286,
"elapsed_seconds": 150.04,
"paid_api_calls": 0,
"coverage": [
"bounded window",
"startup batch",
"lean loop and controller",
"gateway",
"Gemini caching",
"stable case cache",
"response recovery",
"repair admission",
"failure diagnostics",
"tool repair feedback",
"bootstrap schemas"
]
}
}
@@ -0,0 +1,59 @@
{
"trial": "bug20-startup-batch-20261020",
"snapshot": "g00000067",
"account_eur": {
"start": 12.55,
"final": 12.7,
"difference": 0.15,
"scope": "Complete ten-dispatch trial snapshot, not startup calls alone"
},
"comparison": {
"baseline": "bug20-joint-planning-20261019",
"old_three_start_calls_input_tokens": 23929,
"new_three_start_calls_input_tokens": 33087,
"new_joint_review_input_tokens": 9442,
"new_startup_total_input_tokens": 42529
},
"request_component_characters": {
"measurement": "Compact JSON sections; section sizes do not sum to serialized request size",
"old_h1": {
"system": 5950,
"user": 13730,
"output_schema": 2279,
"tool_schema": 3020,
"hypotheses": 2107,
"interpretation": 3371
},
"new_h1": {
"system": 2162,
"user": 22922,
"output_schema": 6718,
"tool_schema": 9535,
"hypothesis": 346,
"interpretation": 2715
},
"old_evidence_by_hypothesis": [
2,
5466,
6211
],
"new_evidence_by_hypothesis": [
2,
7065,
11644
]
},
"findings": [
"Shorter instructions were offset by larger strict response and tool schemas.",
"The startup builder duplicates output_schema.properties.next in input.tool_schema.request_contract.",
"Later startup calls also carry larger shared evidence payloads.",
"The joint review is an additional call performing assessment work deferred by the baseline.",
"Input totals include cached tokens; they are not equivalent to uncached billable input."
],
"uncached_input_tokens": {
"old_three": 8554,
"new_three": 9534,
"new_joint_review": 7382,
"new_total": 16916
}
}
+42
View File
@@ -0,0 +1,42 @@
# Benutzeranleitung in der Weboberfläche – 2026-10-23
Ergebnis: eigener Reiter mit neun Dokumenten, Inhaltsverzeichnis, sicheren
Markdown-Darstellungen und Markdown-Download. Neue allgemeine Bedienungs- und
Funktionsbeschreibung sowie Projekt-/Source-/DB-/Modellkonfigurationsanleitung.
Vorhandene Einrichtungsanleitungen werden eingebunden, nicht als Serverpfade
verlinkt. Die Übergabe-API-Dokumentation wurde an den vorhandenen Webbetrieb
und die Web-Schlüsselverwaltung angepasst.
Quellen: `docs/` und `deploy/capture-worker/README.md`, feste Auswahlliste in
`scripts/build_user_manual.py`. Die generierte Webressource wird mit dem Paket
ausgeliefert. Ein Drift-Test verhindert unbemerkte Abweichungen von den Quellen.
Keine tatsächlichen Konfigurationen oder Zugangsdaten im Bundle.
Validierung:
```text
python -m pytest tests/test_user_manual.py tests/test_dashboard.py tests/test_web_auth.py tests/test_human_web.py -q
28 passed, 1 dependency deprecation warning
node tests/dashboard-smoke.mjs
PASS, console_errors: [], overflow: false
python scripts/build_user_manual.py --check
PASS
node --check src/viano_bug_analysis/web/user-manual.js
PASS
pip wheel --no-deps --no-index --no-build-isolation .
PASS, manual JSON and renderer included in wheel
```
Nach Ergänzung des Pflegehinweises die manuelspezifischen Tests erneut bestanden.
Browser prüft Login, Dokumentauswahl, Inhaltsverzeichnis, Linux-Befehle,
Konfigurationstabellen, HTML-/URL-Abwehr im Renderer und Logout. Desktop- und
Mobilansicht visuell kontrolliert. Quellen bleiben als Markdown separat pflegbar.
Die Darstellung unterstützt die im Korpus verwendeten Überschriften, Listen,
Tabellen, Codeblöcke, Inline-Code, Hervorhebungen und bekannte Dokumentverweise;
beliebiges HTML wird als Text angezeigt.
Vor lokalen Tests Trials 16.939.129.428 Bytes und Fehlerkorpus 2.471.041 Bytes;
kleine temporäre synthetische Testdaten und Paket-Builds halten das Gesamtbudget
weiter unter 20 GB. Temporäres Wheel nach Prüfung entfernt. Keine realen
Fallkopien, Modellanfragen, Cloudkosten, Dienststarts oder Serveränderungen.
`docs/architecture.md` unverändert. Kein Push.
@@ -0,0 +1,29 @@
# Falldetailansicht und Ergebnisliste – 2026-10-21
Ziel: Erhaltene Fallakten direkt im Browser lesen, ohne ZIP-Verzeichnisse manuell
zu durchsuchen. Keine Änderung an Analyseprompts, Budgets oder Architekturvorgaben.
Implementierung: projektgebundene Leseendpunkte, Ergebnisliste mit Suche und
Projektfilter, Revisionsauswahl, Beobachtungen, Interpretation, Hypothesen mit
Confidence und Befunden, Diagnose, Coding-/Human-Dev-Aufträge, API-Patchfeedback,
Sperrhinweise und vollständiger aktueller ZIP-Download.
Prüfungen:
- `pytest tests/test_dashboard.py -q`: 18 bestanden. Authentifizierung, Projektscope,
vollständiger ZIP-Download, ungültige Revisionen und wiedereröffnete Fallakte:
alte Interpretation bleibt in Revision 1, erscheint nicht in Revision 2.
- Zusammen mit `tests/test_worker.py`: 36 Tests bestanden.
- `node tests/dashboard-smoke.mjs`: PASS im echten unsichtbaren Edge-Browser,
Desktop und 390-Pixel-Mobilansicht, keine horizontalen Überläufe oder JS-Fehler.
Ergebnisnavigation, Coding-/Human-Aufträge und Datenentfernung bei Abmeldung.
- Browserdaten sind rein synthetisch; ihre 35.300 Tokens sind Anzeigeprüfwerte,
keine realen Modellmessungen. Keine kostenpflichtigen LLM-/DB-Anfragen.
- Vor Testbeginn: Test-Workspaces 16.939.129.428 Bytes, zusätzlich kleines
Fehlerkorpus und temporäre pytest-Daten deutlich unter 20 GB insgesamt.
Browser-/Server-Testverzeichnisse werden nach geprüften Pfaden entfernt.
Grenzen: Sperrhinweise sind Information, keine administrative Freigabeoberfläche.
Das Belegverzeichnis ersetzt nicht die vollständigen Recherchepayloads im ZIP.
Große Darstellungen werden gekennzeichnet gekürzt; Paketinhalt bleibt unverändert.
Die Revisionshistorie benötigt keine aufbewahrten älteren ZIP-Generationen.
+40
View File
@@ -0,0 +1,40 @@
# Webübersicht – lokale Prüfung vom 2026-10-21
Ausgangspunkt `012a8d8`. Keine kostenpflichtigen Modellanfragen und kein echter
Analyseworker gegen Nutzeraufträge gestartet.
224 automatisierte Tests bestanden: Dashboard/Zuordnung, Worker/Intake,
Antwortreparatur, Response-Recovery, Gateway, Fehlerdiagnostik und Cache.
Die Verbrauchszuordnung ergänzt ein optionales Feld im gespeicherten LLM-Aufruf;
vorhandene Aufrufe bleiben unverändert und bestehende Schemas kompatibel.
Geprüft wurden insbesondere:
- Zugriffsschutz und Projektfreigaben des Overview-Endpunkts;
- Fallname, Fortschritt nach abgeschlossenen Stufen und Ausblenden abgeschlossener Fälle;
- keine Anzeige alter Worker-Snapshots als lebender Worker;
- regulärer erster Aufruf und zusätzliche Korrektur als disjunkte Kategorien;
- abgeleitete Dokumente und doppelte Checkpoint-Verweise nicht erneut als Aufrufe gezählt;
- Denktokens nicht erneut auf die Ausgabe addiert;
- unbekannte Messwerte/Zuordnungen kenntlich gemacht;
- Auslieferung lokaler Assets mit Content Security Policy.
Zusätzlich realer Browser-Smoke-Test mit unsichtbarem Edge und synthetischer
temporärer API: Desktop 1440×1200 und Mobil 390×1200, keine horizontale Überbreite,
keine JavaScript-/CSP-Konsolenfehler. Projektfilter liefert dieselbe Summe,
Rückgabeformular schaltet korrekt um, Abmeldung entfernt angezeigte Daten. Kein
Token wurde im Local Storage abgelegt. Die erste Wiederholung des Browsertests
traf eine zu frühe Testinteraktion vor Ausführung des defer-Scripts; die
Wartebedingung wurde auf vollständige Dokument-/Scriptbereitschaft korrigiert.
Die Vorschau zeigte genau einen aktiven Worker/Fall bei 57 %, einen bereits
abgeschlossenen Fall ausschließlich in der Verbrauchsbilanz und 37.800 synthetische
Tokens mit 20,6 % Korrekturanteil. Diese Werte sind **UI-Fixtures, keine gemessenen
Analyse- oder Abrechnungskosten**. Screenshots liegen als lokale Prüfergebnisse
unter `service-data/ui-preview/desktop.png` und `mobile.png`. Vollständige
Testpakete und Browserprofile werden nicht als dauerhaftes Ergebnis archiviert.
Speicheraudit vor den Tests: 16.939.129.428 Bytes Trial-Workspaces,
2.471.041 Bytes Fehlerkorpus und 11.156.187 Bytes vorhandene pytest-Temporärdaten;
die neuen synthetischen Tests/Screenshots sind klein und bleiben innerhalb der
20-GB-Grenze. Temporäre Vorschauakten wurden entfernt.
@@ -0,0 +1,19 @@
# Kreisdiagramm über alle Phasen – 2026-10-21
Ausgangspunkt `58fc006`. Die tatsächliche Phasenzuordnung unterstützte bereits den
gesamten Ablauf, aber die erste Browservorschau enthielt ausschließlich synthetische
Untersuchungs-/Korrekturaufrufe. Die Vorschau wurde deshalb um Fallaufbau, Planung,
Hypothesen, Diagnose und Codingauftrag ergänzt. Die Legende zeigt diese Phasen nun
auch dann an, wenn noch kein Verbrauch gemessen wurde; Nullwerte erhalten keinen
erfundenen Flächenanteil.
Der neue Regressionstest prüft die Zuordnung aller sechs LLM-Phasenkategorien sowie
die zusätzliche, disjunkte Korrekturkategorie. Ein gemeinsamer Planungsaufruf wird
weiterhin nicht doppelt gezählt. Die Browserprüfung verlangt jede Phasenkategorie
in der Legende und prüft weiterhin Projektfilter, Mobilansicht und Abmeldung.
Die neue Vorschau enthält 35.300 synthetische Tokens und 22,1 % Korrekturanteil. Ein
abgeschlossener Testfall steuert auch Diagnose und Codingauftrag bei; der noch
laufende Testfall enthält keine erfundenen künftigen Abschlussaufrufe. Dies sind
ausschließlich Testdaten, keine tatsächlichen Providerkosten. Der vorherige
Prüfbericht bleibt als eigener Snapshot erhalten.
+40
View File
@@ -0,0 +1,40 @@
# Benutzeranmeldung und Bearbeitungssperren – 2026-10-22
Umfang: SQLite-Benutzer mit gesalzenen scrypt-Passworthashes, getrennte
Sitzungs-/Sperrendatenbank, Cookie-Anmeldung, CSRF-Schutz, Abmeldung,
Konsolenbefehle create_user/delete_user/change_pw_user mit Privilegienprüfung.
Alle Webbenutzer besitzen dieselben Rechte für alle Projekte. Keine Webverwaltung
von Benutzern und keine Benutzerklassen. Bearer-Tokens bleiben für Maschinen.
Konsole: Linux-root/sudo oder Windows-elevierte Administratorberechtigung.
Die Privilegienprüfung wurde mit simuliertem unprivilegiertem Aufrufer getestet;
Benutzerbefehle mit temporärer Datenbank unter kontrollierter Testfreigabe geprüft.
Keine realen Benutzerkonten wurden im Dienst-Workspace erzeugt.
Prüfungen:
- 57 lokale Tests bestanden: API, Benutzer/Sitzungen, menschliches Feedback,
Dashboard, Worker und vcore-Übergabe.
- Gleichzeitige SQLite-Übernahmen aus zwei Threads/Sitzungen: genau ein Gewinner.
- HTTP: ohne Bearbeiten kein Feedback, fremde Sitzung weder Übernahme noch Antwort.
- Abmeldung/Sitzungsablauf geben Sperren frei; Passwortwechsel/Löschung sperren
alte Sitzungen. Falsches altes Passwort wird abgewiesen.
- Alle Webbenutzer sehen alle Projekte/Betriebsaktionen. Fehlender CSRF-Header
wird abgewiesen; fremder Login-Origin wird abgewiesen; Anmeldeversuche begrenzt.
- Beide Feedbackausgänge bleiben möglich; unveränderte Budgets/Revision und
idempotente Antworten erhalten. Maschinen-Bearer können menschliche Antworten
nicht ohne Benutzersitzung bestätigen.
- Echter Headless-Edge mit ausschließlich temporärem Testbenutzer: normale
Anmeldung, UI-Projektsteuerung, Testanfrage zuerst schreibgeschützt, Bearbeiten
aktiviert Formular, Navigation/Diagramme/Mobilansicht/Logout: PASS.
Keine JS-Ausnahmen. Die erwartete 401 beim Prüfen einer noch nicht bestehenden
Sitzung wird separat vom Browserfehlercheck ausgenommen.
Testdaten vor Ausführung: Trials 16.939.129.428 Bytes, kleine Fixtures/temporäre
Dateien mit Reserve innerhalb des 20-GB-Budgets. Keine kostenpflichtigen
LLM-Anfragen, keine Änderung an Analysebudgets oder der Designspezifikation.
Deployment: Benutzerdatei in root-/administratorgeschütztem Verzeichnis mit
passenden Dienst-Leserechten betreiben; SQLite allein ersetzt keine OS-Dateirechte.
Native Linux-Dateirechte/Chown und reale Windows-UAC/NTFS-ACLs sind beim Server-
Deployment zu prüfen. Die API öffnet die Benutzerdatei ausschließlich read-only.
+103
View File
@@ -0,0 +1,103 @@
# Benutzeranmeldung und exklusive Bearbeitung
Webbenutzer melden sich mit Benutzername und Passwort an. Alle Benutzer besitzen
dieselben Rechte für alle Projekte. Es gibt weder Administrator-/Normalbenutzer-
Klassen noch eine Benutzerverwaltung im Web. Bestehende Bearer-Tokens bleiben
ausschließlich für externe API-Integrationen nutzbar und behalten deren bisherigen
Zugriffsgrenzen. Fehlende Token-Umgebungsvariablen deaktivieren die jeweilige
Integration; die Benutzeranmeldung benötigt keine Token-Zufallsgenerierung.
## Konsolenverwaltung
Die Befehle erfordern unter Linux effektive root-Rechte (normalerweise `sudo`),
unter Windows eine als Administrator gestartete Konsole. Sie benötigen keinen
Gemini-Schlüssel und senden keine Modellanfrage.
```bash
sudo .venv/bin/python -m viano_bug_analysis.api create_user nico --config config/api.local.toml --service-group buganalysis
sudo .venv/bin/python -m viano_bug_analysis.api change_pw_user nico --config config/api.local.toml
sudo .venv/bin/python -m viano_bug_analysis.api delete_user nico --config config/api.local.toml
```
Ohne Passwortargumente erfolgt eine verdeckte Abfrage. Die gewünschten expliziten
Argumentformen funktionieren ebenfalls:
```text
create_user NAME PASSWORT --config DATEI
delete_user NAME --config DATEI
change_pw_user NAME ALTES_PASSWORT NEUES_PASSWORT --config DATEI
```
Explizite Passwortargumente können in Shellhistorie/Prozessargumenten auftauchen;
für den normalen Betrieb die verdeckte Eingabe verwenden. Benutzernamen bestehen
aus 1–64 ASCII-Buchstaben/Ziffern sowie Punkt, Unterstrich oder Bindestrich und
beginnen mit einem Buchstaben oder einer Ziffer. Namen sind nicht case-sensitiv.
Beim Passwortwechsel wird das alte Passwort geprüft. Passwortwechsel und Löschung
entwerten bestehende Sitzungen und deren Bearbeitungssperren ohne API-Neustart.
Windows, in einer Administrator-PowerShell:
```powershell
.\.venv\Scripts\python.exe -m viano_bug_analysis.api create_user nico --config config/api.local.toml
```
## SQLite-Dateien und Betriebssystemrechte
Benutzer liegen standardmäßig in `<workspace>/auth/users.sqlite3`. Die API öffnet
diese Datei ausschließlich schreibgeschützt. Gesalzene scrypt-Hashes ersetzen
Klartextpasswörter. Sitzungen, Anmeldebegrenzung und Bearbeitungssperren liegen
separat in `<workspace>/runtime/web-sessions/sessions.sqlite3`; Sitzungstokens
werden dort nur als Hash gespeichert.
Produktionskonfiguration, Pfade relativ zur Konfigurationsdatei oder absolut:
```toml
[auth]
users_database = "/etc/viano-bug-analysis/users.sqlite3"
session_seconds = 3600
```
Die Benutzerdatei und ihr Verzeichnis gehören unter Linux root; CLI-Befehle setzen
0640 bzw. 0750. `--service-group buganalysis` erlaubt dem dedizierten Dienstkonto
das Lesen, nicht die Benutzerverwaltung. Verzeichnisvorfahren dürfen nicht durch
unvertrauenswürdige Benutzer austauschbar sein. Der Dienst benötigt Schreibzugriff
auf seinen Workspace und die Sitzungsdatei. Unter Windows entsprechend geschützte
NTFS-Verzeichnisse/ACLs verwenden: Administratoren verwalten die Benutzerdatei,
das Dienstkonto liest sie. Die Konsolenbefehle prüfen auch dort die erhöhte
Administratorberechtigung. Wer Programmcode oder Authentifizierungsdateien selbst
ändern kann, liegt außerhalb der Web-Zugriffsgrenze; deshalb sind diese OS-Rechte
Bestandteil der Servereinrichtung.
SQLite benötigt keinen MariaDB-Dienst. Für einen Umzug die Benutzerdatei und die
Projekt-/Workspace-Daten sichern; die separate Sitzungsdatei kann bei gestoppter
API bewusst verworfen werden, um alle Sitzungen und Sperren zu beenden.
## Sitzungen und Bearbeiten
Die Anmeldung erzeugt ein HttpOnly-/SameSite-Strict-Cookie; unter HTTPS zusätzlich
Secure. Entfernte Zugriffe über HTTPS betreiben. Mutationen benötigen den an die
Sitzung gebundenen CSRF-Header. Die Oberfläche hält nur diesen CSRF-Wert im
Arbeitsspeicher; Passwörter und Sitzungstokens werden nicht im Local Storage
gespeichert. Sitzungen gelten standardmäßig absolut eine Stunde, konfigurierbar
von 60 Sekunden bis 24 Stunden; regelmäßige Seitenaktualisierungen verlängern sie
nicht endlos. Nach einem Neuladen kann eine gültige Sitzung weiterverwendet werden.
Anmeldeversuche werden serverseitig zeitlich begrenzt.
Eine Testanfrage lässt sich zunächst nur ansehen. Erst **Bearbeiten** übernimmt
die Anfrage atomar für die aktuelle Sitzung. Eine zweite Sitzung erhält
`API_TEST_CLAIMED` und eine verständliche Meldung. Erst dann erscheinen Eingabefelder.
Die Serverprüfung verlangt dieselbe Sperre auch beim Absenden; das Ausblenden
von Feldern allein ist nicht die Zugriffskontrolle. Identische Wiederholungen
bleiben idempotent, abweichende zweite Antworten werden zurückgewiesen.
**Bearbeitung freigeben**, Abmeldung oder Sitzungsablauf machen die Anfrage für
andere Sitzungen verfügbar. Der Ablauf wird bei erneuter Übernahme anhand der
serverseitigen Zeit geprüft; es wird kein Hintergrundtimer benötigt. Zwei Tabs
derselben Sitzung gehören derselben Bearbeitung; zwei getrennte Sitzungen auch
desselben Benutzers konkurrieren um die Sperre.
HTTP: `POST /v1/auth/login`, `GET /v1/auth/session`, `POST /v1/auth/logout`.
Testübernahme/-freigabe: `POST /v1/test-requests/{key}/claim` mit
`{request_id,analysis_revision,action:"edit"|"release"}`. Feedback bestätigt wie
bisher die konkrete Anfrage und führt dieselbe Analyse-Revision fort. Bearer-
Clients können keine menschliche Bearbeitungssperre oder Antwort übernehmen.
+153
View File
@@ -0,0 +1,153 @@
# BugAnalysis verwenden
BugAnalysis untersucht gemeldete Softwarefehler und übergibt das Ergebnis an die
nächste zuständige Stelle. Das Programm erstellt selbst keinen fertigen Patch
und spielt keine Änderungen auf einen Server ein. Der aktuelle Erfassungsadapter
ist für WoW/Vcore eingerichtet.
## So arbeitet BugAnalysis
1. Eine Person oder ein Erfassungsprogramm übergibt Bugbeschreibung und
Diagnosearchive. Die Übergabe-API erstellt daraus eine Fallakte.
2. Ein dauerhaft laufender Analyseworker übernimmt den Auftrag und lädt die
Konfiguration des angegebenen Projekts.
3. Der Casebuilder wertet Beobachtungen und Telemetrie aus. Er kann relevante
Identitäten mit den konfigurierten Recherchewerkzeugen auflösen.
4. Die LLM interpretiert den Fall und entwickelt Hypothesen. Im gemeinsamen
Planungsmodus geschieht beides in einem Aufruf.
5. Die Untersuchung prüft Hypothesen mit Source- und DB-Werkzeugen. Eine knappe
Untersuchungsschleife sammelt Ergebnisse; Prüfungen und Konsolidierungen
übernehmen diese in den strukturierten Arbeitsstand. Werkzeuge lesen Daten;
Zugangsdaten erhält die LLM nicht.
6. Die finale Diagnose bewertet die Befunde und kann einen Frühabschluss
annehmen oder weitere Untersuchung verlangen. Fachliche Budgets begrenzen
einzelne Untersuchungen. Ein bestimmter Erfolg ist nicht garantiert.
7. Das Ergebnis enthält Diagnose und Aufträge für Codingagent und menschlichen
Entwickler. Ein Auftrag darf ausdrücklich erklären, dass keine Arbeit für
den jeweiligen Empfänger vorliegt. Fehlende Daten zur Umsetzung können als
menschlicher Auftrag übergeben werden, ohne die erfolgreiche Analyse zu sperren.
Ein Ergebnis bleibt eine begründete Analyse, keine Garantie für einen wirksamen
Fix. Nach Umsetzung und Tests können Rückmeldungen eine neue Analyserevision
derselben Akte auslösen. Behauptungen, Testerbeobachtungen und bestätigte Befunde
sollten bei der Bewertung auseinandergehalten werden.
## Anmeldung und Start
Die Webadresse im Browser öffnen und mit Benutzername und Passwort anmelden.
Benutzerkonten werden ausschließlich per privilegierter Konsole angelegt;
eine Selbstregistrierung gibt es nicht. Alle menschlichen Benutzer haben die
gleichen Rechte für alle Projekte. Externe Programme benutzen eigene
Integrationsschlüssel mit Projektfreigaben.
API und Analyseworker sind getrennte Dienste. Das Öffnen der Webseite startet
keinen Worker und sendet keine Modellanfrage. Der laufende Worker verarbeitet
Aufträge selbstständig; die Webseite ist die Übersicht und alternative Bedienung.
## Übersicht und laufende Fälle
Die Übersicht zeigt erreichbare Worker, den bearbeiteten Fall und dessen
Fortschrittsbalken. Der Balken folgt abgeschlossenen Phasen, nicht vergangener
Zeit. Während einer längeren Untersuchung kann er daher unverändert bleiben.
Abgeschlossene Fälle verschwinden aus der aktiven Workeransicht.
Die Diagramme zeigen gemessenen Tokenverbrauch. Korrektur- und Wiederholungsaufrufe
bilden eine eigene Kategorie. Denktokens sind bereits in den Ausgabetokens
enthalten und werden nicht doppelt addiert. Fehlende Messwerte werden als solche
ausgewiesen. Diese Zahlen sind keine verbindliche Cloud-Abrechnung und umfassen
nur die erhaltenen Akten im gewählten Messumfang.
Über Fallnummern lässt sich die Detailansicht öffnen: Beobachtungen, Einordnung,
Hypothesen, Befunde, Diagnose und Aufträge. Frühere Revisionen bleiben über die
Revisionsauswahl einsehbar. Die vollständigen Daten stehen im herunterladbaren ZIP.
## Neue Aufträge und Rückgaben
Unter **Auftrag übergeben** Projekt, Bug-ID, Fallname und Beobachtungen eingeben.
Für einen neuen Vcore-Fall das wowdiag-Archiv und möglichst das dazugehörige
wowsrc-Archiv derselben Erfassung auswählen. Die Bug-ID muss mit den Archiven
übereinstimmen. Zusätzliche Dateien lassen sich als Anhänge hinzufügen.
Nach dem Absenden bestätigt die API die Annahme. Das ist noch kein Analyseerfolg.
Bei einer unterbrochenen Übergabe verwendet das Formular bei unveränderten
Eingaben denselben Idempotenzschlüssel, damit kein doppelter Auftrag entsteht.
Für eine Rückgabe den Auftragstyp **Abgeschlossene Akte zurückgeben** wählen,
die aktuelle abgeschlossene Case-ZIP hochladen und Ergebnis sowie neue
Beobachtungen eintragen. Beispielsweise kann ein getesteter Patch den Fehler
nicht behoben haben. BugAnalysis ergänzt die Akte und öffnet eine neue Revision.
Blockierte oder noch laufende Akten sind keine Abschlussrückgaben.
Automatische Erfassung erfolgt über den wowdiag-Worker und dieselbe Übergabe-API.
Externe Programme erstellen keine internen Case-Manifeste selbst.
## Testanfragen beantworten
Die Seite **Testanfragen** listet offene menschliche Recherche- und Testfragen
mit Projekt. Nach Zeitpunkt oder Projekt sortieren, eine Anfrage auswählen und
zunächst **Bearbeiten** drücken. Erst dann wird das Antwortformular freigegeben.
Die Anfrage ist während der Session exklusiv gebunden. Andere Personen können
sie nicht gleichzeitig bearbeiten. Beobachtungen und verlangte Angaben sachlich
eintragen und absenden. Bei Sessionablauf oder Abmeldung wird die Bearbeitung
wieder freigegeben. Nach gültiger Antwort setzt der Worker die Analyse mit dem
vorhandenen Stand fort; fachliche Budgets werden nicht erneuert.
Eine Testanfrage während der Ursachenklärung ist etwas anderes als ein
Human-Dev-Auftrag im fertigen Ergebnis. Letzterer gehört zur weiteren Umsetzung.
## Bearbeitete Fälle und Downloads
Unter **Bearbeitete Fälle** stehen Ergebnisse, übergebene Fälle, blockierte Fälle
und gescheiterte Analysen in einer gemeinsamen Liste. Projekt, Kategorie und
Suchbegriff können kombiniert werden; die Sortierung ist separat wählbar.
Links lädt der Pfeilknopf die aktuelle vollständige Fallakte als ZIP herunter.
Ein Download ändert den Fallstatus nicht und bestätigt keine Übergabe.
| Zustand | Bedeutung |
| --- | --- |
| Ergebnis bereit / OUTPUT_READY | Analyseergebnis für die weitere Bearbeitung; Routingziel Outbox |
| Übergeben / HANDED_OFF | Die Akte wurde intern als übergeben markiert |
| Blockiert / BLOCKED | Analyse wartet, beispielsweise auf Testerantwort oder technische Behebung |
| Analyse gescheitert / FAILED_TO_ANALYZE | Analyse konnte nicht erfolgreich abschließen; Routingziel Review |
Blockiert bedeutet nicht abgeschlossen. Sperrgrund und Detailansicht erklären
die nächsten Schritte. Technische Fehler oder unzureichende Eingaben sind von
einem fachlichen Diagnoseergebnis zu unterscheiden. Die Ablagespalte zeigt das
Routingziel, keinen unabhängigen Verzeichnisbestand.
## Betrieb steuern
Die Betriebssteuerung in der Übersicht erlaubt das Pausieren neuer Fälle eines
Projekts. Bereits begonnene Fälle dürfen weiterlaufen. Geeignete technische
Fehlerfälle können über eine Fortsetzungsanforderung nach Behebung wieder
freigegeben werden. Diese Aktion ist kein beliebiger Neustart und setzt keine
Budgets zurück. Menschliche Testantworten werden auf ihrer eigenen Seite erfasst.
## Programme anbinden
Unter **API-Schlüssel** einen Programmnamen und die erlaubten Projekte auswählen.
Den erzeugten Schlüssel über **Anzeigen** oder **Kopieren** abrufen und im
aufrufenden Dienst geschützt hinterlegen. Schlüssel sind später erneut anzeigbar.
**Widerrufen** verhindert weitere authentifizierte Anfragen mit diesem Schlüssel.
Die Schlüssel dienen zur Auftragsübergabe und zum lesenden Projektzugriff;
Maschinenprogramme können darüber keine anderen Schlüssel verwalten oder
menschliche Testerantworten ausfüllen. Ein Integrationsschlüssel ist kein
Gemini- oder anderer Modellanbieter-Schlüssel.
## Einrichtung und Hilfe
- [Linux-Installation und Betrieb](linux-deployment.md)
- [Projekt-, Source-, DB- und Modellkonfiguration](project-configuration.md)
- [Übergabe-API und Rückgaben](intake-api.md)
- [Analyseworker und Wiederanlauf](analysis-worker.md)
- [Benutzerkonten](user-accounts.md)
- [Integrationsschlüssel und deren Sicherung](integration-keys.md)
- [Weboberfläche im Detail](web-console.md)
- [Erfassungsworker v0.4](capture-worker.md)
Vor dem ersten Feldbetrieb auf dem Zielserver Bereitschaftsprüfung, HTTPS,
Dienstneustart und Backups prüfen. Danach einen kontrollierten echten Auftrag
einschließlich Rückfrage und Ergebnisabholung durchführen. Die LLM-Zugriffe
erzeugen erst beim laufenden Analysebetrieb Kosten.
+245
View File
@@ -0,0 +1,245 @@
# Webübersicht
Die Betriebsübersicht wird durch die bestehende Übergabe-API ausgeliefert:
```powershell
.\.venv\Scripts\python.exe -m viano_bug_analysis.api serve --config config/api.local.toml
```
Anschließend `http://127.0.0.1:8080/` öffnen und mit **Benutzername und Passwort**
anmelden. Benutzer werden ausschließlich über privilegierte Konsolenbefehle
angelegt, geändert und gelöscht, siehe [Benutzerverwaltung](user-accounts.md).
Alle Webbenutzer haben dieselben Rechte für alle Projekte. Die unten beschriebenen
Client-/Projektberechtigungen gelten weiterhin für externe API-Integrationen.
Für entfernte Zugriffe HTTPS verwenden. Der Analyseworker läuft unabhängig davon wie unter
[Analyseworker](analysis-worker.md) beschrieben. Das Öffnen der Übersicht löst
keine Modellanfragen aus.
## Benutzeranleitung
Der Reiter **Benutzeranleitung** enthält die allgemeine Bedienung und
Funktionsweise sowie Anleitungen für Linux, Projekt-/DB-/Sourcekonfiguration,
Übergabe-API, Analyseworker, Nutzerkonten, Integrationsschlüssel, Weboberfläche
und Erfassungsworker. Dokumentauswahl, Inhaltsverzeichnis und interne Verweise
erlauben Navigation ohne Server-Dateizugriff. Markdown-Downloads sind ebenfalls
möglich. Der Reiter benötigt eine angemeldete Sitzung; sein Aufruf startet keine
Analyse. Tabellen, Codebeispiele und Überschriften werden als sichere DOM-Elemente
dargestellt, eingebettetes HTML wird nicht ausgeführt.
Für Dokumentationsänderungen die ursprünglichen Markdown-Dateien unter `docs/`
beziehungsweise `deploy/capture-worker/README.md` bearbeiten und danach
`python scripts/build_user_manual.py` ausführen. Die feste Auswahlliste steht im
Skript; tatsächliche lokale Konfigurationen oder Secrets werden nicht gebündelt.
`python scripts/build_user_manual.py --check` und die Tests erkennen veraltete
Webfassungen. Das erzeugte `web/user-manual.json` wird mit dem Python-Paket
ausgeliefert, sodass keine lokale Kopie des Dokumentationsordners nötig ist.
## Worker und Fortschritt
Die Startseite listet lebende Worker und darunter den jeweils bearbeiteten Fall
mit seinem Namen und einem Ladebalken. Der bestehende Dienst erlaubt einen Worker
je Workspace; die Darstellung ist bereits als Liste aufgebaut. Die Einführung
eines parallelen Worker-Pools ist damit nicht verbunden.
Der Balken folgt abgeschlossenen Arbeitsschritten, nicht vergangener Zeit. Seine
sieben Anteile entsprechen intern Aufnahme, Fallaufbau, Interpretation,
Hypothesenbildung, Untersuchung, Diagnose und Codingauftrag. Die Oberfläche führt
diese Stufen nicht einzeln auf. Der Codingauftrag ist die letzte Stufe, auch wenn
sein Dokument fachlich erklärt, dass kein Codingauftrag benötigt wird. Bei
gemeinsamer Interpretation/Hypothesengenerierung können zwei Anteile gleichzeitig
fertig werden. Eine lang laufende Untersuchung füllt den Balken nicht künstlich.
Der aktive Fall verschwindet bei `OUTPUT_READY`, `HANDED_OFF` oder
`FAILED_TO_ANALYZE` aus der Workeransicht und der Tabelle laufender Fälle. Er bleibt
in der Verbrauchsstatistik enthalten. Wartende Fälle bleiben in der Fallübersicht,
belegen aber keinen arbeitenden Worker. Ein alter Dienstsnapshot ohne lebenden
Telemetrie-Heartbeat wird nicht als aktiver Worker dargestellt.
## Verbrauch
- Kreisdiagramm: bekannte Eingabe- und Ausgabetokens je Phase; zusätzliche
Korrektur-/Reparatur-/Wiederholungsaufrufe haben ein eigenes orangefarbenes Segment.
Die Legende zeigt Fallaufbau, Fallplanung, Hypothesen, Untersuchung, Diagnose und
Codingauftrag auch bei null gemessenen Tokens. Nullwerte erzeugen keinen
künstlichen Tortenanteil. Gemeinsame Planungsaufrufe bleiben einmal gezählt.
- Balkendiagramm: Eingabe und Ausgabe einschließlich Denken je Kategorie.
- Der erste reguläre Aufruf bleibt bei seiner Phase, auch wenn sein Ergebnis später
zurückgewiesen wurde. Seine Korrektur wird ausschließlich dem Korrektursegment
zugeordnet. Abgeleitete, deterministisch reparierte Antwortdokumente sind keine
zusätzlichen Anbieteraufrufe und werden nicht erneut gezählt.
- Denktokens sind bereits Bestandteil der Ausgabetokens. Sie werden weder zum
Kreisdiagramm noch zum Gesamtverbrauch noch einmal hinzuaddiert.
- Neue LLM-Runden speichern ihre Verbrauchszuordnung deterministisch aus der
Operationskennung. Das verändert keine Prompts, Modellparameter oder Budgets.
Bereits gespeicherte Aufrufe bleiben unverändert. Bei älteren Akten wird nur
eindeutig erkennbare Korrekturinformation übernommen; sonst erscheint der Anteil
als „Nicht zugeordnet“.
- Fehlende Messwerte bleiben unbekannt. Die Diagramme summieren nur bekannte Werte
und weisen unvollständige Aufrufe aus. Bei vollständig fehlender Tokennutzung
lässt sich deren Größe nicht als Kreisanteil darstellen.
Der Messumfang umfasst **alle erhaltenen, für den Client freigegebenen Akten und
deren Revisionen** im konfigurierten Workspace. Er ist keine Google-Abrechnung und
keine lebenslange Statistik bereits gelöschter Akten. Dauerhafte Testbilanzen unter
`docs/test-results/token-usage/` bleiben davon unabhängig. Ein Projektfilter wendet
sich auf Fallliste, Worker und Diagramme gleichzeitig an. Gemeinsame Planungsaufrufe
werden einmal als Fallplanung gezählt, nicht zusätzlich als Hypothesengenerierung.
## Übergabe
Die Oberfläche bietet ein einfaches Formular für neue wowdiag-/wowsrc-Aufträge und
für abgeschlossene ZIP-Akten mit Testerfeedback. Es verwendet dieselbe Multipart-
API und denselben Idempotenzmechanismus wie externe Programme. Bei unveränderten
Eingaben verwendet eine Wiederholung denselben Schlüssel. Anhänge und Fallakten
werden nicht clientseitig bearbeitet. Betreiberaktionen stehen separat berechtigten
Clients zur Verfügung.
## Fallakte und Ergebnisse
Fallnamen verlinken auf eine lesbare Detailansicht mit Testerbeobachtungen,
Interpretation, Hypothesen, Confidence, stützenden und widersprechenden Befunden,
Diagnose sowie Coding- und Human-Dev-Auftrag. Befunde bleiben ausdrücklich
KI-Bewertungen mit Belegreferenzen. Das Belegverzeichnis zeigt Herkunft und
Abdeckungsinformationen; die vollständigen Recherchepayloads stehen im ZIP.
Ein expliziter Auftrag „Kein Auftrag“ wird von einem noch nicht erstellten Dokument
unterschieden. Die gemeinsame Liste **Bearbeitete Fälle** enthält Ergebnisse
(`OUTPUT_READY`, Ziel Outbox), bereits übergebene Fälle (`HANDED_OFF`), blockierte
Fälle (`BLOCKED`) und gescheiterte Analysen (`FAILED_TO_ANALYZE`, Ziel Review).
Blockierte Fälle bleiben ausdrücklich unvollständig und können weiterhin auch
in der Übersicht wartender Fälle erscheinen. Ein Sperrgrund wird angezeigt;
`AWAITING_TEST_FEEDBACK` erscheint als „Wartet auf Testerantwort“.
Projekt- und Kategoriefilter sowie Suche sind kombinierbar. Die Sortierung erlaubt
neueste/älteste Aktualisierung, Kategorie oder Projekt. Links in jeder Zeile lädt
ein beschrifteter Iconknopf die vollständige aktuelle Fallakte herunter, auch für
blockierte oder gescheiterte Analysen. Der Download ändert keinen Status und löst
keine Analyse aus. Die Ablagespalte zeigt das im Manifest gespeicherte Routingziel;
es ist keine unabhängige Bestandsprüfung des Outbox-Dateiverzeichnisses. Der Download
liest die verwaltete aktuelle Akte und funktioniert auch ohne separate Exportkopie.
Angezeigt wird der aktuelle Stand je Fall/Paket. Nach Wiedereröffnung erscheinen
aktive Fälle wieder in der laufenden Übersicht; ältere Revisionen bleiben in der
Detailansicht erhalten. Berechtigungen und Projektgrenzen gelten auch für Downloads.
Die Revisionsauswahl liest akzeptierte Artefakte aus der Checkpointhistorie der
aktuellen vollständigen Akte. Ergebnisse neuerer Revisionen erscheinen nicht in
älteren Ansichten. Über die Übergabe-API erfasste Patch-Rückmeldungen werden bis
zur gewählten Revision dargestellt. Bei gesperrten Fällen erscheinen Sperrgrund
und passende Betreiberhinweise. Für berechtigte Betreiber kann eine zulässige
Fortsetzung angefordert werden; Budgets werden dabei nicht zurückgesetzt.
## Betriebssteuerung
Alle angemeldeten Webbenutzer können die Betriebssteuerung verwenden. Externe
API-Clients erhalten standardmäßig keine Betreiberrechte. Ein eigener Client mit
eigenem Token und `operator = true` in der API-Konfiguration erhält Aktionen für
seine freigegebenen Projekte (Beispiel in `config/api.example.toml`). API nach einer
Rechteänderung neu starten. Der Gemini-Schlüssel ist dafür nicht geeignet.
- **Neue Fälle pausieren / wieder zulassen:** gilt je Projekt und bleibt nach
Neustart erhalten. HTTP-Aufträge werden weiterhin dauerhaft angenommen. Der
Worker lässt sie im Eingang bzw. wartet bei noch nicht begonnenen Fällen.
Begonnene Analysen laufen weiter. Eine Pause unterbricht keinen Modellaufruf.
- **Fortsetzung nach Fehlerbehebung anfordern:** in der aktuellen Falldetailansicht
bei passenden Schedulerfehlern bzw. `RESEARCH_UNAVAILABLE`. Die API bestätigt
nur `QUEUED`, nicht bereits eine Freigabe. Der lebende Worker prüft den Auftrag
zwischen Dispatches erneut; ein gestoppter Worker bearbeitet ihn nach Neustart.
- Veraltete Paketgeneration, geänderte Konfigurationsbindung, noch nicht fällige
Research-Sperre und unzulässige fachliche Sperren werden abgewiesen. Keine
Zurücksetzung von Hypothesenbudgets, Versuchszählern oder LLM-Operationen.
- Das Aktionsprotokoll dokumentiert Clientkennung, UTC-Zeit, Projekt, Aktion und
Ergebnis. Fortsetzungen haben getrennte Eingangs- und Ausführungseinträge mit
derselben Auftragskennung. Die Ansicht zeigt die letzten 100 berechtigten
Einträge; das vollständige Protokoll bleibt unter `runtime/worker/control/`.
Es enthält keine Tokens oder Konfigurationsinhalte. Erfolgreiche lokale
CLI-Freigaben erscheinen als `local-cli`.
- Workerdetails zeigen Erreichbarkeit, letzten Zustand, Aktivität und Fehlercode.
Ein alter Snapshot gilt nicht als lebender Worker. Globale Workerdetails sind
nur Betreibern mit Zugriff auf alle konfigurierten Projekte zugänglich.
`GET /v1/operations` liefert Rechte, projektbezogenen Pausenzustand und für Betreiber
Protokoll/Workerzustand. `POST /v1/operations` benötigt Betreiberrechte und JSON:
`{"action":"pause","project_id":"viano-core"}` bzw. `resume`, oder
`{"action":"retry","key":"<Schlüssel aus der Übersicht>","package_generation":42}`.
Bei gleichzeitigem Zugriff kann `API_CONTROL_BUSY` auftreten; nach Aktualisierung
erneut versuchen. Der Worker muss nach diesem Softwareupdate neu gestartet werden.
## Menschliche Testanfragen
Die eigene Seite **Testanfragen** listet offene menschliche Rückfragen mit
Eingangszeit, Projekt, Bug-ID, Falltitel und Frage. Projektfilter sowie Sortierung
„Älteste zuerst“, „Neueste zuerst“ und „Projekt, dann älteste zuerst“ ermöglichen
chronologisches oder projektweises Abarbeiten. Die Liste aktualisiert sich mit der
Übersicht; eine noch offene Eingabe wird dabei nicht überschrieben.
„Ansehen / beantworten“ zeigt Umgebung, Voraussetzungen, Testschritte, benötigte
Beobachtungen und angefragten Termin. Die Antwort erfasst die tatsächliche Umgebung,
Beobachtungen und „Test durchgeführt“ oder „Nicht durchführbar“. Die ausdrückliche
Bestätigung ist erforderlich. Textdaten bleiben untrusted observations, keine
auszuführenden Befehle. Diese erste Oberfläche nimmt Text, keine Dateianhänge an.
Menschliche Antworten erfordern eine angemeldete Benutzersitzung und die exklusive
Übernahme über **Bearbeiten**, siehe [Benutzeranmeldung](user-accounts.md).
Es gibt keine gesonderten Testerrollen für Webbenutzer. Menschliche Zugänge
ausschließlich mit `create_user` anlegen.
Die bestätigende Identität und Zeit stammen vom Server, nicht aus frei editierbaren
Formularfeldern. `GET /v1/test-requests` liefert ausschließlich freigegebene Projekte;
`POST /v1/test-requests/{case-key}` bestätigt die konkrete Anfrage/Revision.
Kollisionen, veraltete Anfragen und widersprüchliche Wiederholungen werden abgewiesen.
Eine identische erneute Übermittlung derselben Sitzung bleibt ohne doppelte Wirkung.
Eine bestätigte Antwort setzt `AWAITING_TEST_FEEDBACK` über den vorhandenen
Coordinator auf `INVESTIGATING_HYPOTHESES` zurück. Revision, Budget und ursprüngliche
Belege bleiben erhalten. Der laufende Worker verarbeitet die Rückmeldung regulär;
eine besondere Betreiberfreigabe ist dafür nicht erforderlich. Der Termin führt
auch nach Ablauf zu keiner automatischen Fortsetzung und verwirft die Anfrage nicht.
Die Werkzeugfreigabe erfolgt über `budget_config = "budget.human-tests.toml"` in
den vertrauenswürdigen Projekteinstellungen. Die lokale Dienstkonfiguration wurde
entsprechend ergänzt. Diese Policy erlaubt `testing.request_human` für 40 fachliche
Einheiten, automatisierte Tests bleiben ohne Eintrag gesperrt. Bei Trial-Läufen
die Datei ausdrücklich mit `--budget-config config/budget.human-tests.toml` angeben.
Bestehende Revisionen behalten ihre eingefrorene Policy; sie werden nicht migriert.
Nach Konfigurationsänderung API und Worker neu starten. Keine Modellanfrage wird
allein durch Öffnen oder Beantworten der Seite gestartet; der Worker läuft separat.
`GET /v1/cases/{key}?revision=N` liefert diese projektgebundene Ansicht.
`GET /v1/cases/{key}/package` lädt die vollständige aktuelle Akte einschließlich
aller erhaltenen Revisionen herunter, auch als Zwischenstand eines laufenden Falls.
Beide Endpunkte benötigen denselben Bearer-Token und verwenden `no-store`.
Der Schlüssel stammt aus der Übersicht, nicht aus einem lokalen Dateipfad.
Große Anzeigeinhalte werden begrenzt und als gekürzt gekennzeichnet. Der Download
bleibt vollständig; die Anzeige verändert keine Paketgeneration und löst keine
LLM-Aufrufe aus.
## Datenschutz und Betrieb
`GET /v1/overview` benötigt eine Benutzersitzung oder einen Maschinen-Bearer-Token.
Webbenutzer sehen alle Projekte; Maschinenclients nur ihre freigegebenen Projekte.
Prompts, vollständige Modellantworten, lokale Pfade und Zugangsdaten werden nicht
an den Browser übergeben. Fallnamen werden als Text dargestellt. Die Seite lädt
keine externen Fonts, Chartbibliotheken oder Analysedienste; Diagramme werden lokal
mit Canvas/CSS gezeichnet. Eine Content Security Policy begrenzt Ressourcen auf
denselben Ursprung. Abmeldung entfernt dargestellte Daten und Formularinhalte;
verzögert eintreffende Antworten aus einer vorherigen Anmeldung werden ignoriert.
Die Ansicht aktualisiert sich alle vier Sekunden. Validierte Darstellungen werden
für unveränderte Paketgenerationen im API-Prozess zwischengespeichert; dies ist
eine Anzeigeoptimierung, kein fachlicher Zustand und kein Analysecache.
## Lokale Prüfung
```powershell
.\.venv\Scripts\python.exe -m pytest tests/test_dashboard.py -q
node tests/dashboard-smoke.mjs
```
Der Browser-Smoke-Test verwendet einen lokalen temporären API-Server, einen
unsichtbaren Edge-Browser und ausdrücklich künstliche Fall-/Verbrauchsdaten. Er
prüft Desktop, Mobilansicht, Projektfilter, Formularumschaltung, Abmeldung,
Tokenanzeige, Fortschritt, Ergebnisliste, Falldetails, Aufträge und Browserfehler.
Die API-Tests prüfen zusätzlich Projektzugriff, ZIP-Download und Revisionsisolation.
Unter Windows wird der installierte
Edge erwartet; über `BROWSER_PATH` lässt sich ein anderes Chromium angeben.
Die Testserver/-browser werden beendet, ihre erzeugten temporären Verzeichnisse
nach Pfadprüfung entfernt. Screenshots als Prüfergebnis liegen unter
`service-data/ui-preview/`. Es werden keine LLM- oder Datenbankanbieter aufgerufen.
+3
View File
@@ -12,6 +12,8 @@ dependencies = ["jsonschema>=4.18,<5"]
[project.optional-dependencies]
test = ["pytest>=8,<10"]
research = ["PyMySQL>=1.1,<2", "zstandard>=0.23,<1"]
api = ["starlette>=0.52.1,<0.53", "uvicorn>=0.35,<1", "python-multipart>=0.0.32,<1", "cryptography>=46,<47"]
api-test = ["httpx>=0.28,<1", "pytest>=8,<10"]
[tool.setuptools.packages.find]
where = ["src"]
@@ -19,6 +21,7 @@ where = ["src"]
[tool.setuptools.package-data]
"viano_bug_analysis.schemas" = ["*.json"]
"viano_bug_analysis.llm.prompts" = ["*.txt"]
"viano_bug_analysis.web" = ["*.html", "*.css", "*.js", "user-manual.json"]
[tool.pytest.ini_options]
testpaths = ["tests"]
Loaded 100 of 375 files, more files were not shown because too many files have changed in this diff. Show more