Files
genshin-assistant/docs/scanner-rework-status.md
T
2026-07-09 08:53:57 +02:00

15 KiB

Scanner rework status

Progress on the approved scanner/OCR rework. See ADR-007/008/009/010 in DECISIONS.md for the decisions behind these. For the current live automation runbook, see AUTOMATION_LIVE_SCAN.md.

Current Scanner Status

See scanner-ik-progress-report.md for the full report.

Current status after the 2026-07-09 merge to main:

  • The scanner architecture now follows the relevant Inventory Kamera model: 32 artifact targets per page, lookup-derived fields, fast artifact OCR profile, direct detail-fingerprint verification from the OCR capture, page-overlap planning, and batched store work.
  • The live runner can compare current and ik-traineddata engines and rejects runs that are fast but fail miss/review quality thresholds.
  • The final current-vs-IK-traineddata 100-artifact comparison is now proven for the current live environment. On 2026-07-08, npm run scan:goal:compare:validated passed with evidence at outputs/live-soak/2026-07-08T18-38-35/scan-performance-assessment.json. current won with 100/100 parsed, 0 review, 0 misses, and 378 ms/artifact active average. ik-traineddata was rejected at 100 because it parsed 97/100, had 5 review and 3 misses. The next optional speed target remains 3 artifacts/second, which means 333 ms/artifact or faster on clean 20-artifact iterations.
  • The merge-ready default is the visible-inventory path. The app blocks normal guided Auto-Scan unless Artifact inventory and a visible detail card are detected. auto-entry, direct-inventory, and paimon-menu remain explicit Dev-Control experiments.
  • Ownership and lock-state proof is no longer theoretical: live captures parsed equipped characters (Citlali, Linnea), unlocked artifacts reported locked: false, a visibly locked artifact reported locked: true, and a bounded auto-scan persisted the locked/equipped state.

Done (implemented, unit-tested, build green)

  • OCR eval harnesssrc/eval/, npm run eval, gate in npm test. See ocr-eval.md.
  • C# input/capture sidecarnative/input-helper/, npm run helper:build. Replaces the PowerShell helper on the same JSON protocol; PowerShell remains a fallback. Verified end-to-end (spawn, runtime, base64 capture).
  • Layout profiles + OCR preprocessingsrc/lib/layoutProfile.ts (pure geometry, 16:9 detection), src/lib/ocrPreprocess.ts (grayscale + Otsu binarize). main.ts now uses calibrated 16:9 detail/count/grid coordinates first and OCRs an upscaled + binarized copy.
  • Card-ready gatingsrc/lib/cardReadyGate.ts replaces the fixed 280 ms settle with change+stability polling; robust to animation.
  • GOOD interopsrc/lib/goodInterop.ts (export + best-effort import for scanned records), Electron file-picker import/export, and store merge.
  • Rescan-mergesrc/lib/artifactMerge.ts collapses leveled re-scan duplicates by a level-independent identity.
  • Data staleness warningsrc/lib/dataPackageStatus.ts, surfaced in the Scanner Diagnose data-package line.
  • Lock detection (experimental)src/lib/lockDetection.ts, wired into live capture as a read-only locked flag and persisted with scanned records.
  • Elevated live automation pathnpm run dev:admin now starts through scripts/dev-admin.ps1 and logs to outputs/admin-start/admin-dev.log. Live status confirmed isElevated: true, genshinFound: true, and targetProcess: "GenshinImpact".
  • Read-only click probe/automation/probe-click?index=1 verified that the app can focus Genshin, move to a visible inventory tile, click it, and observe a changed detail panel fingerprint (clicked: true, inputBlocked: false, changed: true).
  • Bounded auto-scan validation/scanner/start?limit=2 completed live with 2 clicks, 2 verified detail views, 2 parsed artifacts, 2 stored records, 2 review samples, and 0 misses.
  • Auto-scan OCR performance pass - auto-scan captures now use an artifact OCR mode that skips inventory-count OCR on each tile, keeps equipped-character OCR on the real artifact-read captures, raises the substat crop to catch artifact level, stores automatic review samples without full-screen/inventory screenshots, reads only the tail of large JSONL files, avoids review noise when only level/equipped is missing, starts the scan with an OCR-free preflight capture, prevents repeated startup review reprocessing, omits full-frame and inventory-preview Base64 payloads from tile captures, and applies crop-specific Tesseract page-segmentation/whitelist parameters.
  • Visible-page live soak helper - scripts/live-soak.ps1 now drives the dev-control health/status, smart-capture, probe-click, bounded scan, and review-tail endpoints and writes evidence to outputs/live-soak/. On 2026-07-07 it completed probes at indices 1 and 3 plus scan limits 2, 5, 10, and 20 against the elevated running app. The limit 20 run finished done with 20 attempted, 20 verified, 18 parsed, 18 stored, 1 review, 1 duplicate, 1 miss, and 1 page.
  • Scroll/page-transition live soak - after the helper and loop fixes, scripts/live-soak.ps1 -Limits 45 -ProbeIndices 1 -SkipSmartCapture completed done on 2026-07-07 with 45 attempted, 45 verified, 35 parsed, 35 stored, 9 review, 1 duplicate, 9 misses, and 2 pages. This validates that the scanner can cross from the first visible page into a scrolled page in the live 1920x1080 setup.
  • Lookup package layer - scripts/generate-genshin-data.cjs now emits normalized lookup keys, GOOD keys, piece/set/slot links, aliases, source version metadata, generated time, and validation summary. src/lib/genshinLookup.ts provides pure matching and validation APIs, and the scanner status/dev-control path exposes lookup validity. Auto-scan preflight blocks when the lookup package is invalid.
  • Inventory-Kamera-style field split - artifact detail crops now separate name, slot, main-stat label, main-stat value, level, substats, set effects, and footer. OCR uses field-specific PSM/whitelist cleanup, and the parser derives slot/set/main-stat through lookup constraints before falling back to review.
  • Paimon-menu auto-entry scaffold - auto-scan supports scanEntryMode: "paimon-menu" and /scanner/start?entry=paimon-menu&limit=N. The entry sends only read-only navigation (ESC, B, artifact-tab click), then requires a valid lookup, supported layout, and detected artifact grid before the scan loop starts. The existing visible-inventory start remains the fallback/debug path.
  • OCR benchmark endpoint scaffold - /scanner/benchmark-ocr?limit=N captures identical artifact crops with the current engine and returns timing/field counts. /scanner/benchmark-ocr?engine=compare can also compare the local Inventory-Kamera-traineddata Tesseract.js path when genshin_fast_09_04_21.traineddata is present in data/tessdata, work/, or IK_TESSDATA_DIR. The OCR worker pool defaults to four workers and can be tuned with GAA_OCR_WORKERS=1..8. Native Tesseract is still not the default and should only replace tesseract.js after the benchmark proves it faster and more accurate on the same crops.
  • Quality-gated live comparison - scripts/live-soak.ps1 now supports goal runs for current, ik-traineddata, and compare, writes CSV/JSON summaries, groups results by limit, identifies timing bottlenecks, and rejects winners that miss the requested count, exceed 2% misses, or exceed 15% review. npm run scan:assessment:test verifies this ranking logic without Genshin. The assessment also reports goal100Decision and goal100.comparisonComplete, so a single-engine 100-artifact run cannot be misread as the final IK comparison. Use npm run scan:iterate:compare:validated:wait for the 20-artifact live iteration and npm run scan:goal:compare:validated:wait for the final proof when starting directly after UAC. The validator --summary output includes the assessment path and timestamp for reporting.
  • State-polled guided entry - the guided auto-entry waits for Inventory, artifact grid, and first detail card evidence instead of sleeping the full fixed delay every time. OCR/review/store work still starts only after artifact detail preflight passes.
  • Hot-loop speed pass (2026-07-08) - the scan loop no longer performs a separate card-ready capture before OCR; the artifact OCR capture itself verifies detail-fingerprint change. Routine click diagnostics and scan stat publishes are throttled. Auto-scan artifact captures no longer update the full preview/topbar UI on every tile. Store writes can be batched so the scan path avoids per-artifact save/reload churn. Auto-scan artifact captures now use a direct GDI hot path and skip Electron desktopCapturer.getSources() in the per-artifact loop.
  • 3/s instrumentation pass (2026-07-08) - artifact hot-path captures omit the detail-preview payload, and scan stats now split inner capture time from end-to-end capture roundtrip time. Use averageCaptureRoundTripMs and averageCaptureRoundTripOverheadMs in the next limit=20 live iteration to decide whether the next cut belongs in native capture transport or OCR.
  • 3/s live attempt (2026-07-08) - the missing-detail-preview review trigger was fixed and tested. The best clean 20-artifact run reached 7285 ms (364 ms/artifact, about 2.75 artifacts/second) with 0 review and 0 misses. The final stable run on 2026-07-08-direct-gdi-reviewfix completed 20/20 with 0 review, 0 misses, and 7973 ms elapsed (399 ms/artifact). Detail region capture, 5 OCR workers, DataURL buffer decode, and substat PSM.SINGLE_COLUMN were tested and rejected as slower.
  • Review-to-eval loop (2026-07-08) - npm run eval:review-candidates exports the local review queue into outputs/review-eval-candidates/ as a human-labeling worklist. The exporter deduplicates samples, surfaces complete fast-field captures first, marks stale captures, and now surfaces equipped footer OCR plus locked=true/false payload counts for the next ownership/lock validation pass. Its output is deliberately ignored by Git and must not be treated as ground truth until fields are confirmed against the real artifact. Confirmed review labels now have a dedicated corpus file, src/eval/corpus/confirmedReviewCorpus.ts, with tests that reject duplicate ids, empty labels, and unconfirmed entries. The helper npm run eval:prepare-confirmed generates a paste-ready confirmed-case snippet only when explicit expected labels are provided.
  • Prepared ownership/learning loop (2026-07-08) - fast auto-scan no longer drops the artifact footer by profile alone; it omits footer OCR only when the capture option explicitly requests that or when the footer marker is absent. Parser tests cover noisy equipped names, split Equipped:/name footers, and one-letter OCR fragments that must stay Not detected. Scanner learning now persists text replacements, field aliases, constrained fixes, crop adjustment proposals, and UI-profile adjustment proposals instead of truncating everything back to text replacements.
  • Visible-inventory merge guard (2026-07-09) - the normal guided Auto-Scan start no longer falls back into auto-entry when the artifact detail card is missing. It now blocks and asks the operator to open the Artifact inventory with a visible detail card. The explicit auto-entry, direct-inventory, and paimon-menu Dev-Control modes remain available for targeted experiments, but they are not the merge-ready default path.
  • Ownership live smoke (2026-07-09) - live artifact detail capture parsed and stored an equipped footer as equipped: "Citlali" and the grey lock state as locked: false. A same-session visible-inventory run with /scanner/start?entry=visible-inventory&limit=20&engine=current completed 20/20 verified and parsed, 19 stored, 1 duplicate, 0 review, and 0 misses in 8047 ms elapsed (402 ms/artifact).
  • Locked artifact live proof (2026-07-09) - a visibly locked artifact was selected through a read-only inventory tile click. Smart Capture reported locked: true with lockSignal.ratio: 0.14797913950456323 over threshold 0.06, and /scanner/start?entry=visible-inventory&limit=1&engine=current persisted the same artifact with equipped: "Citlali" and locked: true. Lock detection now decodes the lock crop PNG before measuring active lock pixels because Electron's native bitmap channel order was ambiguous in live captures.

Remaining — needs the live environment or a UI pass

These cannot be finished/validated without Genshin running at the user's resolution or without UI work best tested live:

  1. Validate/tune OCR preprocessing on more real captures — confirm invert + threshold + upscale factor help (not hurt) actual Tesseract reads. The text-level eval harness cannot measure image preprocessing.

  2. Wire and benchmark native IK-traineddata OCR against the same crop set. The current benchmark can use IK-traineddata through Tesseract.js; native Tesseract integration remains the next implementation step before any engine default changes.

  3. Validate explicit entry modes separately from world, direct inventory, and Paimon/menu states with low limits only. These are now Dev-Control experiments, not the normal merge path; the normal Auto-Scan button blocks unless the visible artifact detail card is already present.

  4. Repeat locked=true on another page/session if lock behavior changes. The first positive live proof passed on 2026-07-09, including store persistence. Further repeats are useful for confidence but no longer block the merge.

  5. 3 artifacts/second iteration - not reached yet. The next credible path is either native Tesseract/IK-traineddata integration that materially reduces substat OCR time, or a larger capture pipeline change that avoids full-frame PNG/Base64 transport without hurting safety checks. The target remains <= 6667 ms elapsed for 20 parsed artifacts with 0 misses and no silent OCR review regression.

  6. Broader scan soak test — direct-GDI current-engine runs now passed at 20/20, 45/45, and 100/100 with 0 misses. Continue with repeat runs if duplicate rate needs tuning.

  7. Repeatability pass — repeat the qualified current-vs-IK-traineddata run in a later live session before making major OCR-engine defaults or speed claims beyond this environment.

Visible-page limits up to 20, scroll/page-transition limit 45, the final 100-artifact current-vs-IK-traineddata comparison, equipped footer live smokes, and one positive locked-artifact persistence proof have passed for the current environment. Remaining soak work is repeatability, OCR corpus growth, additional equipped/locked repeats, and optional 3 artifacts/second speed work.

Grow the eval corpus

Every low-confidence review sample already stores its crops + OCR. Confirm/correct those via reviewSampleToEvalCase and commit them into src/eval/corpus/ so the harness keeps measuring real-world accuracy across patches. See ocr-eval.md.