docs(wiki): record fast-alpr as the evaluated ANPR recognizer baseline

Research note from the recognizer-options query. fast-alpr v0.4.0 (MIT) — a swappable
YOLOv9-detector + CCT-OCR pipeline on ONNX Runtime, CPU-only and offline — fits the
decided vision-service architecture and is MIT end-to-end (code + published weights),
so the ANPR path may not need the scoped AGPL exception. Flags the open caveats:
verify model-weight provenance, and benchmark AL-plate accuracy (default global vs.
the 40+ country EU model). fast-alpr is plate-only, so the vehicle-verification job
stays ours to build. Decision kept open. Updates opencv-anpr-service (new "Recognizer
evaluation" section + licensing nuance), vision-service (open/next), index, log.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-06-19 14:19:16 +02:00
parent c0a775818b
commit e4827c9651
4 changed files with 67 additions and 7 deletions
+4
View File
@@ -904,3 +904,7 @@ FLAW found: the entry button could be pressed without limit — each press minte
## [2026-06-19] feat | Application logs — backend pino DB sink + frontend error collection (app_logs)
Added a THIRD data stream (`app_logs`) alongside the signed ledger and device telemetry — operational/diagnostic logs, since an OFFLINE appliance has no Sentry to ship to. BACKEND: a pino stream tees warn/error/fatal into app_logs (info/debug stay stdout-only — no bloat) with NO call-site change; the DB is now built BEFORE Fastify so the logger stream has its sink. FRONTEND (lib/logger.ts): always ships failed API requests (apiFetch non-OK path, minus 401 pre-login churn), window.onerror, unhandledrejection, and a top-level React ErrorBoundary (render crash → fatal, not a white screen); console.warn/error forwarded ONLY at client debug/trace level (noisy otherwise). Batched/throttled POST, flush via raw fetch + sendBeacon on pagehide. Reliability invariants: never log the /api/logs call itself (loop guard), LogService reentrancy guard, all writes best-effort/swallowed, bounded queue + clamped rows. API: POST /api/logs (any signed-in user, CSRF, tolerant — never 4xx on a bad entry) + GET /api/logs gated by a NEW `log:read` permission (new `log` resource in the RBAC grid; admin holds it). Retention: pruned by age (LOG_RETENTION_DAYS=30) AND row cap (MAX_ROWS=50k), hourly + at startup. UI: a Logs screen under /setup (filter level/source/since, expand to context+stack, 15s poll), sq+en. DB migration 0009_app_logs (+journal idx 9, seeds admin log:read) applied to the live apps/server DB. Verified end-to-end via app.inject: login→POST 204→GET 200 with the record; backend warn/error persisted + info dropped; non-admin GET 403 / POST 204 (the intended split). Build+lint green. New page [[app-logs]]; updated [[event-streams-split]], [[device-events]], index.
## [2026-06-19] query | ANPR recognizer options — fast-alpr evaluated as the baseline
Q: LPR/ANPR options — YOLO, OpenCV, both, another framework? Reframed: "YOLO vs OpenCV" is a category error — they're different pipeline LAYERS (YOLO = plate detector; OpenCV = Apache-2.0 image-handling glue, used regardless; plus an OCR stage). The real choice is which end-to-end recognizer. Researched [fast-alpr](https://github.com/ankandrew/fast-alpr) (latest **v0.4.0, 15 Mar 2026, MIT**): a thin orchestrator over two swappable ONNX stages — detection via [open-image-models](https://github.com/ankandrew/open-image-models) (`yolo-v9-t-384-license-plate-end2end`, MIT) + OCR via [fast-plate-ocr](https://github.com/ankandrew/fast-plate-ocr) (`cct-xs-v2-global-model`, MIT; also has a EUROPEAN model trained on 40+ countries — relevant for AL plates). MIT top-to-bottom (code AND published weights), one maintainer across all three repos, CPU-only + fully offline, backend extras for CPU/CUDA/OpenVINO/DirectML/QNN. KEY FINDING: its detector is open-image-models' OWN YOLOv9 ONNX export, NOT the Ultralytics AGPL package — so fast-alpr is a PERMISSIVE baseline that may not even need the scoped AGPL exception from [[vision-service]]. CAVEAT (flagged, not closed): a repo's LICENSE covers code, not necessarily redistributed model WEIGHTS (YOLOv9 upstream is GPL-3.0; Ultralytics YOLO AGPL) — verify weight provenance before relying on "MIT weights". fast-alpr is PLATE-ONLY → Job 2 (vehicle-attribute anti-spoofing) is still ours to build, but shares the same ONNX runtime. Recommendation: prototype fast-alpr now; Ultralytics-YOLO+PaddleOCR fine-tune only if accuracy disappoints. Recorded as an evaluated-options note; decision kept status:open pending the provenance check + an AL-plate accuracy benchmark. Updated [[opencv-anpr-service]] (new "Recognizer evaluation" section + licensing nuance), [[vision-service]] (open/next), index.