Improve scanner repeatability guardrails
This commit is contained in:
@@ -268,10 +268,20 @@ Latest live timing evidence on 2026-07-08:
|
||||
signature `2026-07-08-direct-gdi-reviewfix` completed `20/20`, `18` stored,
|
||||
`0` review, `2` duplicates, `0` misses, `7973 ms` elapsed, or
|
||||
`399 ms/artifact`. 3 artifacts/second is not proven.
|
||||
- Follow-up 3 artifacts/second attempts on 2026-07-09:
|
||||
after the distinctive partial piece parser fix, the best clean repeatability
|
||||
run reached `336 ms/artifact` with `20/20` parsed, `0` review, `0` misses,
|
||||
`318 ms` average capture roundtrip, and `138 ms` roundtrip overhead. Later
|
||||
runs with crop priority and image-payload cleanup stayed clean but ranged
|
||||
around `346-351 ms/artifact`; the strict `333 ms/artifact` budget remains
|
||||
unproven.
|
||||
- Rejected speed experiments:
|
||||
detail-region capture, `GAA_OCR_WORKERS=5`, DataURL-to-buffer decode, and
|
||||
substat OCR `PSM.SINGLE_COLUMN` were all live/benchmark tested and were slower
|
||||
than the direct-GDI baseline. Keep `GAA_OCR_WORKERS=4` for current runs.
|
||||
than the direct-GDI baseline. Later checks also rejected skipping
|
||||
`analyzePaimonMenu`, skipping lock-state as a production shortcut, reducing
|
||||
the artifact-level crop scale, and `GAA_OCR_WORKERS=6` as the default.
|
||||
Keep `GAA_OCR_WORKERS=4` for current runs.
|
||||
- Quality-gated current-vs-IK comparison:
|
||||
`npm run scan:goal:compare:validated` produced
|
||||
`outputs/live-soak/2026-07-08T18-38-35/scan-performance-assessment.json`
|
||||
@@ -449,15 +459,17 @@ uses the default `current` scan engine; use `scan:goal:ik` for a native
|
||||
IK-traineddata scan pass. Use `scan:goal:compare` to run both scan engines
|
||||
back-to-back with the same limits and one combined CSV. The CSV is the quickest evidence for
|
||||
`averageMsPerParsed`, `activeAverageMsPerParsed`, `averageCaptureMs`,
|
||||
`averageCaptureRoundTripMs`, `averageCaptureRoundTripOverheadMs`,
|
||||
`captureP50Ms`, `captureP90Ms`, `averageOcrMs`, `ocrP50Ms`, `ocrP90Ms`,
|
||||
`averageCardReadyMs`, `averageScrollReadyMs`, `artifactsPerMinute`, and
|
||||
`projectedMsFor100`.
|
||||
The run also writes `scan-performance-assessment.json`, which groups results by
|
||||
limit, picks the best qualified engine, and labels the dominant bottleneck as
|
||||
OCR, capture, card-ready, or scroll-ready. A qualified winner must finish the
|
||||
run, parse the requested count, keep miss rate under 2%, and keep review rate
|
||||
at or below 15%; review and miss rates are penalized before active average speed
|
||||
is used as the tie-breaker. For IK-target claims, check `goal100Decision`; it
|
||||
OCR, capture-roundtrip-overhead, capture, card-ready, or scroll-ready. A
|
||||
qualified winner must finish the run, parse the requested count, keep miss rate
|
||||
under 2%, and keep review rate at or below 15%; review and miss rates are
|
||||
penalized before active average speed is used as the tie-breaker. For IK-target
|
||||
claims, check `goal100Decision`; it
|
||||
must read `qualified-comparison: winner=<engine>`, and
|
||||
`goal100.comparisonComplete` must be `true` so a single-engine 100-artifact run
|
||||
is not mistaken for a current-vs-IK comparison.
|
||||
@@ -478,12 +490,38 @@ instead of the final 100-artifact proof. Add `--summary` when you want a short
|
||||
report-ready PASS/FAIL output that includes the input assessment path and
|
||||
assessment `createdAt` timestamp.
|
||||
|
||||
Optional budget flags are useful for the current speed work:
|
||||
|
||||
```powershell
|
||||
npm run scan:assessment:validate -- --latest --summary --limit=20 --max-active-average-ms=333 --max-capture-roundtrip-overhead-ms=120
|
||||
```
|
||||
|
||||
`--max-active-average-ms=333` is the strict 3 artifacts/second check. Use a
|
||||
separate `--max-capture-roundtrip-overhead-ms` budget when deciding whether the
|
||||
next optimization belongs in native capture transport instead of OCR.
|
||||
Single-engine repeatability runs may be validated with `--allow-single-engine`,
|
||||
but that mode is only for repeatability evidence and must not be used for IK
|
||||
parity claims.
|
||||
|
||||
`npm run scan:goal:compare:validated` is the preferred final command: it runs
|
||||
the live preflight first, then the full comparison, and then validates the
|
||||
newest assessment with `--summary`. Use
|
||||
`npm run scan:goal:compare:validated:wait` for the same final flow when starting
|
||||
immediately after UAC.
|
||||
|
||||
For later-session repeatability without changing OCR engines, use:
|
||||
|
||||
```powershell
|
||||
npm run scan:repeatability:wait
|
||||
```
|
||||
|
||||
That command runs the current visible-inventory engine at 20, 45, and 100
|
||||
artifacts, then validates the 100-artifact result as single-engine evidence.
|
||||
It uses the `live-soak.ps1 -RepeatabilityRun` switch instead of passing a
|
||||
comma-separated `-Limits` value through npm/cmd, because Windows argument
|
||||
parsing can collapse `20,45,100` into one unsafe number. The script also refuses
|
||||
limits above 1800 as a final guard.
|
||||
|
||||
The assessment ranking can be verified without Genshin or the Electron app:
|
||||
|
||||
```powershell
|
||||
|
||||
@@ -15,6 +15,7 @@ npm run eval:review-candidates # export unconfirmed review samples for human la
|
||||
npm test # runs the eval gate alongside the rest of the suite
|
||||
npm run scan:assessment:test # verifies quality-first scan ranking logic
|
||||
npm run scan:iterate:compare:validated:wait # 20-artifact live comparison
|
||||
npm run scan:repeatability:wait # 20/45/100 current-engine repeatability
|
||||
npm run scan:goal:compare:validated:wait # final 100-artifact live comparison
|
||||
```
|
||||
|
||||
@@ -22,6 +23,10 @@ The report prints exact-match rate, overall field accuracy, a per-field
|
||||
breakdown (critical fields marked with `*`), and every failing case with an
|
||||
`expected "..." got "..."` diff.
|
||||
|
||||
Repeatability runs are single-engine evidence. Use them to prove that the
|
||||
visible-inventory scanner stays stable across later sessions, but keep
|
||||
current-vs-IK claims on `scan:goal:compare:validated:*`.
|
||||
|
||||
## How it works
|
||||
|
||||
- `src/eval/ocrEvalHarness.ts` - pure metric functions. `runOcrEval(cases)`
|
||||
|
||||
@@ -144,6 +144,37 @@ Current status after the 2026-07-09 merge to `main`:
|
||||
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.
|
||||
- **Repeatability and capture-overhead guardrails (2026-07-09)** -
|
||||
`scripts/live-soak.ps1` now writes capture roundtrip and roundtrip-overhead
|
||||
timing into `scan-performance-assessment.json`. The assessment validator can
|
||||
enforce optional speed budgets with `--max-active-average-ms` and
|
||||
`--max-capture-roundtrip-overhead-ms`, and `npm run scan:repeatability:wait`
|
||||
runs 20/45/100 current-engine passes as repeatability evidence without
|
||||
presenting them as an IK comparison. `-RepeatabilityRun` now sets those limits
|
||||
inside PowerShell, and the script refuses unsafe limits above 1800 so npm/cmd
|
||||
argument parsing cannot accidentally turn `20,45,100` into one oversized run.
|
||||
- **Distinctive partial piece recovery (2026-07-09)** - a live repeatability run
|
||||
exposed four identical OCR misses where the piece name was read as
|
||||
`Wontiroms Creation pan`. The parser now derives a piece only when a long OCR
|
||||
fragment uniquely matches exactly one known artifact piece. This recovered the
|
||||
local case as `Sharpness That Ceased Upon Wondrous Creation` /
|
||||
`Disenchantment in Deep Shadow` without adding a broad fuzzy exception.
|
||||
- **Repeatability live pass after parser fix (2026-07-09)** -
|
||||
`outputs/live-soak/2026-07-09T09-29-11/scan-performance-assessment.json`
|
||||
captured a clean current-engine 20-artifact run: `20/20` parsed, `0` review,
|
||||
`0` misses, `336 ms/artifact` active average, `318 ms` average capture
|
||||
roundtrip, and `138 ms` average roundtrip overhead. The strict 3 artifacts per
|
||||
second budget still failed by 3 ms (`336 ms` vs `333 ms`).
|
||||
- **3/s follow-up experiments (2026-07-09)** - tested and rejected several
|
||||
shortcut-style optimizations because live runs got slower or added risk:
|
||||
skipping Paimon-menu analysis, skipping lock-state as a production shortcut,
|
||||
reducing the artifact-level crop scale, and raising the OCR worker pool to 6.
|
||||
The kept low-risk changes are fast-profile OCR crop priority and avoiding a
|
||||
duplicate DataURL string when the native helper already returns Base64. A
|
||||
follow-up clean 20-artifact run after payload cleanup reached `351 ms/artifact`,
|
||||
`331 ms` capture roundtrip, and `146 ms` roundtrip overhead, so the next
|
||||
credible 3/s work is native capture transport/roundtrip reduction, not UI
|
||||
recommendation work.
|
||||
- **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.
|
||||
@@ -218,14 +249,17 @@ resolution or without UI work best tested live:
|
||||
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.
|
||||
review regression. The latest clean 20-artifact repeatability run reached
|
||||
`336 ms/artifact`, so 3/s remains close but unproven.
|
||||
|
||||
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.
|
||||
`20/20`, `45/45`, and `100/100` with 0 misses. Continue with
|
||||
`npm run scan:repeatability:wait` in later sessions to check duplicate rate,
|
||||
scroll behavior, and capture roundtrip timing without changing defaults.
|
||||
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.
|
||||
claims beyond this environment. Current-engine-only repeatability is useful
|
||||
evidence, but it is not an IK parity claim.
|
||||
|
||||
Visible-page limits up to 20, scroll/page-transition limit 45, the final
|
||||
100-artifact current-vs-IK-traineddata comparison, equipped footer live smokes,
|
||||
|
||||
Reference in New Issue
Block a user