feat(scanner): complete localized artifact quality checkpoint

This commit is contained in:
AzuTear
2026-07-11 15:59:19 +02:00
parent 639b0b7f59
commit 8b9f948c6b
215 changed files with 35440 additions and 7273 deletions
@@ -0,0 +1,235 @@
# Native Scanner Live Acceptance - 2026-07-10
## Ergebnis
Die Artifact-first Scanner-Kette ist fuer den validierten Zustand `1920x1080`,
16:9, englische Artifact-Inventaransicht mit sichtbarer Detailkarte live
abgenommen. Dev- und Packaged-Runtime nutzten denselben Runtime-Vertrag
`2026-07-10-packaged-runtime-acceptance`. Alle Scans blieben read-only und
liefen mit `persist=false`.
Die Abnahme umfasst inzwischen auch das komplette OCR-bestaetigte Inventar:
Run `20260710-223233` erfasste exakt 2.211 Artifacts ueber 70 Seiten. Der erste
Parserstand verfehlte den Review-Grenzwert ehrlich; nach einer strukturell
belegten +0-Korrektur reprozessierte das aktuelle Paket denselben vollstaendigen
Corpus mit 136 Review (6,15%), 0 Fehlern und 0 Store-Writes. Der gespeicherte
Run-Validator meldet 0 Issues.
Der Scanner-Core darf damit in die naechste Produktphase uebergehen. Der
strikte End-to-End-Zielwert von drei Artifacts pro Sekunde ist dagegen nicht
erreicht und wird nicht behauptet.
## Live-Matrix
| Runtime | Run | Ziel | Seiten | Reset | Capture | Capture/s | Processing | Processing/s | Review | Fehler | Store |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| Dev | `20260710-102344` | 5 | 1 | 1.701 ms | 1.123 ms | 4,45 | 1.806 ms | 2,77 | 0 | 0 | 0 |
| Dev | `20260710-102421` | 20 | 1 | 1.704 ms | 4.443 ms | 4,50 | 6.430 ms | 3,11 | 0 | 0 | 0 |
| Dev | `20260710-102450` | 50 | 2 | 1.744 ms | 11.328 ms | 4,41 | 15.579 ms | 3,21 | 0 | 0 | 0 |
| Dev | `20260710-102547` | 100 | 4 | 1.718 ms | 22.877 ms | 4,37 | 31.731 ms | 3,15 | 0 | 0 | 0 |
| Packaged | `20260710-103736` | 5 | 1 | 1.702 ms | 1.162 ms | 4,30 | 1.801 ms | 2,78 | 0 | 0 | 0 |
| Packaged streaming UI | `20260710-201614` | 20 | 1 | 1.701 ms | 4.486 ms | 4,46 | 8.032 ms | 2,49 | 0 | 0 | 0 |
| Packaged full inventory | `20260710-223233` | 2.211 | 70 | 1.739 ms | 522.005 ms | 4,24 | 722.164 ms | 3,06 | 490* | 0 | 0 |
`*` Der Vollinventar-Runner lehnte diesen ersten Endstand wegen 22,16% Review
korrekt ab. Die anschliessende Reprozessierung mit dem reparierten aktuellen
Parser verarbeitete 2.211/2.211 in 689.049 ms (3,21/s) und endete bei 136 Review
(6,15%), 0 Fehlern, 0 Writes und 2.211 Results. Capture/Streaming und aktuelle
Parserqualitaet sind damit als zwei explizite, gespeicherte Evidenzschritte
akzeptiert; ein nachtraeglich behaupteter Ein-Pass-Lauf wird nicht erfunden.
Die fruehere `1,77/s`-Aussage beschreibt ausschliesslich den historischen,
seriellen Dev-100-Smoke: `100 / (24.623 ms Reset/Capture + 31.731 ms
Batch-Processing)`. `native-live-smoke.ps1` wartete dort bewusst auf das
Capture-Ende und startete erst danach den Processor. Die Zahl ist rechnerisch
korrekt, aber keine aktuelle End-to-End-Messung der Streaming-Pipeline.
Der erneute erhoehte Streaming-Livetest am 2026-07-11 (`20260711-090019`)
lief dry mit 20/20 Capture, Parse und Resultaten, 0 Review, 0 Fehlern und 0
Writes. Das erste Resultat war sichtbar, bevor Capture endete. Die gemessenen
Teilwerte waren `4,43 Capture/s` (`4.517 ms` active) und `7.668 ms`
Processor-Laufzeit; die beobachtete Zeit vom Startrequest bis zur finalen
Result-Reconciliation betrug `8.370 ms` (`2,39/s`). Diese kleine,
clientseitige Beobachtung ist kein allgemeiner Durchsatzclaim, weil der
gemeinsame Clock-Contract noch nicht als dauerhafter Run-Wert gespeichert wird.
Bei ueberlappenden Phasen duerfen Capture- und Processing-Dauer nie addiert
werden. Kuenftige End-to-End-Claims muessen Start, Capture-Start/-Ende,
Processing-Start/-Ende und finale Result-Reconciliation auf einer gemeinsamen
Wall-Clock belegen; Capture- und Processing-Raten bleiben getrennte Werte. Das
3/s-Gesamtziel ist weiterhin nicht bewiesen.
## Qualitaets- und Dateivertraege
- Alle neuen 5/20/50/100-Runs hatten exakt so viele Jobs, PNGs, Klicks,
verarbeitete Zeilen und geladene Results wie angefordert.
- Jeder Job war an genau eine nichtleere `artifact-NNNN.png`, eine eindeutige
Sequenz, den erwarteten absoluten Pfad und genau zwei Click-Events gebunden.
- Der 100er verteilte sich auf `32/32/32/4` Captures ueber vier Seiten.
- Der Validator fand im 100er keine PNG-Hash-Duplikatgruppen, keine komplett
wiederholten Seiten und keine identischen Seiten-Grenzpaare.
- Der Vollinventar-Run enthielt exakt 2.211 Jobs, PNGs und Results. Der letzte
Job war Sequenz 2.211 auf Seite 70, Zeile 0, Spalte 2, passend zur partiellen
Schlussseite nach 69 vollen 32er-Seiten.
- Der gespeicherte Vollinventar-Validator fand zwar vier Gruppen identischer
Einzel-Crops, aber keine wiederholten Seitenpaare und keine identischen
Seiten-Grenzpaare; sein gesamter Run-Vertrag bestand mit 0 Issues. Identische
Einzelkarten werden daher nicht mit einem haengenden Scroll verwechselt.
- Der aktuelle Vollinventar-Replay ist ueber fuenf Wiederholungen deterministisch:
2.075 Results sind `evaluated`, 136 bleiben `review`, 0 sind `unknown`.
1.952 unterlevelte Results haben eine Projektion, 123 sind bereits komplett.
- Fuenf Offline-Replays des neuen 100ers waren hashidentisch. Alle 100 Results
waren `parsed` und `evaluated`; Scorebereich `76.1-92.5`, 0 Review, 0 unknown.
- Die neuen 100 Artifacts waren alle +20, daher korrekt 0 offene Projektionen.
Die Projektionslogik bleibt durch die vorhandene Offline-Evidenz fuer
unterlevelte Artifacts abgedeckt.
- Artifact-Store und `review-samples.jsonl` waren innerhalb jedes Dry-Runs vor
und nach dem Scan bytegleich. Die Review-Datei blieb bei
`83A222F49E7246054B16363C0CA7083168F7CE0AB595916313B44CB279BF9B8C`.
## Safety-Nachweise
- Probe-Klick: Genshin-Fenster, erkanntes 4x8-Grid, sichtbare Detailkarte und
geaenderter Detail-Fingerprint wurden vor dem breiten Lauf bewiesen.
- Fokusverlust-Run `20260710-101820`: `blocked`, 0 Klicks, 0 Captures; der
Helper refokussierte nicht automatisch.
- Stop-Run `20260710-102735`: Stop waehrend des Initial-Resets nach `87 ms`,
Status `stopped`, 0 Klicks, 0 Captures.
- Foreground-HWND wird vor jedem Reset-/Scroll-Event, Klick und Crop-Capture
geprueft. ESC, Enter, F9 und expliziter Stop bleiben auch im Reset aktiv.
- Der vollstaendige Top-Reset bleibt auf 3.200 Events begrenzt, pausiert aber
nur noch nach jeweils 39 Events. Live sank er dadurch von `50.698 ms` auf
stabil rund `1.7 s`, ohne Guard oder Reichweite zu lockern.
- Native Helper und PowerShell-Fallback erkennen nur die exakten Prozessnamen
`GenshinImpact` oder `YuanShen` und validieren gecachte HWNDs erneut. Nachdem
das Spiel waehrend der Reprozessierung extern geschlossen war, konnte die App
sich dadurch nicht mehr selbst als Genshin-Ziel erfassen. Der finale
No-Genshin-Smoke meldete `genshinFound=false`, HWND 0, leeren Zielprozess,
keine Capture-Quelle und 0 Renderer-/Konsolenfehler.
## Packaged-Runtime
- Start aus `%TEMP%`, `isDev=false`, Runtime und Helper-Guard beide
`isElevated=true`.
- Renderer wurde aus `resources/app.asar` geladen; relative Vite-Assets waren
vorhanden.
- Helper lief aus `resources/input-helper/InputHelper.exe`.
- IK 6.7.0 wurde aus `resources/ik-inventorylists` geladen: 61 Sets,
289 Pieces.
- Die Preload-Bridge stellte 36 erwartete Methoden bereit.
- Vor dem neuen Scan wurde automatisch der neueste vollstaendige 100er geladen;
neuere gestoppte oder unprozessierte Runs wurden korrekt ignoriert.
- Der paketierte 5er lief ueber Renderer -> Preload -> IPC -> C# Helper und
bestand Capture, Processing, Result-Load und Non-Persistence.
- Finale Inventory-Ansicht: 5/5 geparst, 0 Review, 5 bewertet,
`0 speicherbar - 5 im Store - 0 Review - 0 blockiert`.
- Der aktuelle paketierte Renderer bestand zusaetzlich den echten
Settings-UI-Pfad `Eigenes Limit -> Reihen -> 1`: das erkannte 8-Spalten-Raster
ergab Ziel 8; Run `20260710-180851` endete mit 8/8 Captures, 8/8 Processing,
8/8 Parsing, 0 Review, 0 Fehlern und `persist=false`. Der Top-Reset brauchte
1.715 ms. Zwei vorherige Vordergrundverluste blockierten sicher mit 0 Klicks.
- Der echte Settings-UI-Streamingpfad mit Artifact-Limit 20 bewies die
Phasenueberlappung: waehrend der Helper noch `running` meldete, waren bereits
11 Ergebnisse komplett geparst, bewertet und in der Rail sichtbar. Neue
Karten verwendeten die konfigurierte Slide-in-Mountanimation. Final standen
20 eindeutige Sequenzen 1-20, 20 evaluierte Results, 0 Review, 0 Fehler und
0 Persistenzwrites. Der Dokument-Viewport blieb 1304x821 ohne Overflow; die
Ergebnis-Rail scrollte intern.
- Der Vollinventar-Settings-Pfad las als Ziel ausschliesslich den aktuellen
OCR-Besitzwert 2.211, nie die Kapazitaet. Capture erreichte 2.211/2.211 auf 70
Seiten, waehrend der laufenden Erfassung waren bereits bis zu 1.656 Result-
Rows und 1.659 Auswertungen sichtbar, alle 2.211 Zeilen standen am Ende in der
Rail, die Slide-in-Mountanimation wurde beobachtet und der 1304x821-Dokument-
Viewport blieb ohne Overflow.
- Das paketierte `reprocess-run`-Gate reprozessierte denselben Corpus mit dem
aktuellen Parser vollstaendig und non-persistent: 2.211 processed/parsed,
136 Review, 0 Fehler, 0 gespeichert, 2.211 Result-Eintraege.
Lokale Evidenz zum Abnahmezeitpunkt:
Die folgenden Pfade bezeichneten temporaere lokale Testartefakte. Sie wurden
bei der angeforderten Workspace-Bereinigung am 2026-07-11 entfernt; die oben
dokumentierten Run-IDs, Messwerte und Vertragspruefungen bleiben der dauerhafte
Nachweis.
- `outputs/offline-acceptance/offline-acceptance-report.json`
- `outputs/packaging/offline-package-report.json`
- `outputs/native-live-smoke/20260710-102341/`
- `outputs/native-live-smoke/20260710-102418/`
- `outputs/native-live-smoke/20260710-102447/`
- `outputs/native-live-smoke/20260710-102544/`
- `outputs/native-replay/saved-native-validation-report.json`
- `outputs/packaged-live/packaged-final-scan5.json`
- `outputs/packaged-live/packaged-final-inventory-fixed.json`
- `outputs/packaged-live/packaged-final-inventory-fixed.png`
- `outputs/packaged-live/final-artifact-probe.json`
- `outputs/packaged-live/final-ui-row1-pass.json`
- `outputs/packaged-live/final-ui-row1-pass.png`
- `outputs/packaged-live/streaming-ui-20.json`
- `outputs/packaged-live/streaming-ui-20.png`
- `outputs/packaged-live/streaming-ui-20-results-view.json`
- `outputs/packaged-live/streaming-ui-20-results-view.png`
- `outputs/full-inventory-phase/packaged-preflight-restored.json`
- `outputs/full-inventory-phase/packaged-ui-full-inventory.json`
- `outputs/full-inventory-phase/packaged-ui-full-inventory.png`
- `outputs/native-review-analysis/20260710-223233/native-review-analysis.json`
- `outputs/full-inventory-phase/packaged-reprocess-2211.json`
- `outputs/full-inventory-phase/packaged-reprocess-2211.png`
- `outputs/full-inventory-phase/packaged-no-genshin-safety.json`
- `outputs/full-inventory-phase/packaged-no-genshin-safety.png`
## Waehrend der Abnahme behobene Fehler
1. Eigene App-Titel mit `Genshin` konnten als Capture-Quelle erscheinen.
2. Dev-Cleanup konnte den Codex-CUA-Node allein wegen seines Working Directory
als alte App-Instanz klassifizieren.
3. Native Runs starteten nicht garantiert am Inventaranfang und prueften den
Foreground nicht waehrend jedes Input-Schritts.
4. Der sichere Initial-Reset dauerte wegen Windows-Timer-Rundung etwa 50 s.
5. Smoke-Gates akzeptierten zu schwache Summen-/Cleanup-Vertraege.
6. Run-Aufloesung konnte ohne explizites `runDir` unvollstaendige Runs waehlen.
7. Packaged Runtime-Pfade und absolute Vite-Assets konnten durch das Repo-CWD
kaschiert werden.
8. Helper-Guard verlor das echte Elevation-Signal.
9. Inventory-Metriken lagen wegen einer impliziten dritten Grid-Zeile ueber der
View; ein Store-Duplikat mit unsicherem optionalem Feld erschien irrefuehrend
als Promotion-Review.
10. Capture und Auswertung liefen seriell; die Result-Rail blieb bis zum Ende
leer. Der Processor tailt jetzt JSONL, ist pro Run single-flight, liefert
Sequenz-Deltas und reconciled vor dem Abschluss den Vollbestand.
11. Vier-Substat-+0-Fuenfsterne wurden wegen OCR-unsicherem Main Value
uebermaessig in Review geschickt. Nur die strukturell eindeutige Kombination
`level === 0` plus vier Substats erhaelt jetzt den kanonischen Fuenfsterne-
Startwert; Drei-Substat-Faelle bleiben absichtlich unsicher.
12. Eine breite Prozessnamensuche konnte die eigene App als Genshin erkennen.
Exakte Allowlist und gecachte-HWND-Revalidierung schliessen dieses Ziel aus.
13. Die Scan-Zusammenfassung addierte Capture- und Processing-Zeit trotz echter
Ueberlappung. Sie verwendet jetzt die groessere Wall-Clock-Zeit.
## Offene Grenzen und naechste Phase
- Aktiv bleibt nur Artifact-Scanning. Weapons, Materials und Character Details
sind weiterhin Katalogdaten, keine Scannerfeatures.
- Nicht-16:9, andere Sprachen und ungewoehnliche UI-Zustaende bleiben bewusst
blockiert, bis eigene Profile live validiert sind.
- Der Renderer-Chunk von rund 586 kB und das Default-Electron-Icon sind
nicht-blockierende technische/cosmetische Arbeit.
- Eine echte Review-Korrektur oder Promotion wurde nicht absichtlich in den
Store geschrieben. Die statischen und Main-Process-Gates bestehen; der
Mutation-Pfad bleibt ein separater, explizit bestaetigter QA-Fall.
- Die verbliebenen 136 Review-Faelle des kompletten Corpus sind der naechste
Scanner-Qualitaetsbestand: 128 tragen `substats_implausible`, 65
`substats_incomplete`, 28 eine niedrige Main-Value-Konfidenz und 4 einen
IK-Mismatch; Gruende koennen sich ueberlappen. Sie werden nicht automatisch
als sauber umetikettiert.
Die score-freie Grundlage von `build-fit-contract-v1` ist inzwischen
implementiert: gesourcte Eingaben, OCR-/Review-Gates, Set-/Mainstat-/Substat-
Regeln, Gesamtziele und Konflikte sind versioniert, waehrend echte lokale
Snapshots keine Legacy-Demo-Empfehlungen mehr erzeugen. Der deterministische
Fuenfer-Verifier prueft inzwischen Slot-/Set-Form, verschachtelte Gates,
gesourcte Gesamtwerte und Konflikte, bleibt aber score-frei. Ein erster enger
Furina-`Luna II`-Candidate ist samt IK-Key- und Kontext-Fixtures versioniert.
Vor sichtbaren charakterbezogenen Empfehlungen fehlen weiterhin breitere
Profile, eine validierte Rangfolge und weitere Golden Fixtures fuer sichere
sowie adversarielle Eingaben. Das ist jetzt die aktive Produktphase.