--- type: decision tags: [parking, decisions, vision, anpr, anti-fraud] sources: [] updated: 2026-06-15 status: open --- # Decision: Host-side Vision Service (ANPR + vehicle verification) Taken 2026-06-15, as part of the business-layer build ([[session-model]]). ## Decisions 1. **Build a host-side vision service** ([[opencv-anpr-service]]) that does ANPR (plate → identity) **and** vehicle-attribute verification (anti-spoofing witness) on snapshots from ordinary Hikvision/Dahua cameras. 2. **It replaces the dedicated edge-AI [[lpr-camera]]** as the recognition path: ordinary IP cam → snapshot (`Snapshot.bytes`, already pulled by the camera driver) → vision service → plate + vehicle. Removes the special LPR camera from the [[bom]] as a requirement (still allowed as an option). 3. **Deployment: a separate local Python/OpenCV microservice** on the appliance, called over **localhost HTTP** by the Node backend. Fully offline ([[offline-first]]); its own process and failure domain; the host falls back to the ticket path if it's unavailable. 4. **Licensing exception:** AGPL components (e.g. YOLO plate/vehicle models, OpenALPR) are **permitted inside this service only**, because it's a separate process not linked into the app — the app stays strictly MIT/Apache/BSD. Amends [[standing-decisions]]. 5. **Recognition is advisory, evidence is authoritative.** A read never single-handedly authorizes a paid/access barrier open; it flags for [[reconciliation]] and attaches (with the source image) to the signed [[append-only-event-chain]] entry. Low confidence → fallback, never strand a car ([[fail-state-safety]]). ## Why - **Replace vs. edge-AI camera:** host-side recognition on cheap IP cams shifts cost from per-lane smart cameras to one compute box + our software; gives us the raw image for the second job below. - **Vehicle verification is the real prize (user-driven, 2026-06-15):** plate-only ANPR can't catch a **printed/spoofed plate on a different car**. Extracting vehicle attributes/fingerprint lets the system reconcile *the car*, not just the number — directly filling the independent-witness gap the [[append-only-event-chain]] calls out as unbuilt. - **Separate-process + AGPL-scoped** keeps the app's permissive-license guarantee intact while not crippling accuracy (the strict permissive-only ANPR path is markedly weaker — that tradeoff was weighed and the scoped exception chosen). ## Rejected / alternatives - **Strict permissive-only ANPR in-app** — license-clean but weaker accuracy and more build; the separate-process AGPL exception was chosen instead. - **Keep the edge-AI LPR camera as primary** — viable fallback if host-side accuracy disappoints; not chosen now, kept on the table in [[opencv-anpr-service]]. - **Embed OpenCV in Node** (opencv4nodejs/WASM) — rejected: native-build pain, weaker model ecosystem, no process isolation, shares the app's failure + license surface. ## Open / next - Recognizer selection: **fast-alpr (MIT, YOLOv9 detector + CCT OCR on ONNX Runtime) is the evaluated baseline** as of 2026-06-19 — fits this decision's shape (separate offline localhost process, swappable) and is permissive end-to-end, so the ANPR path may not need the AGPL exception (pending a model-**weight-provenance** check). Plate-only: it does NOT cover the vehicle-verification job. Open: the provenance check + an accuracy benchmark on real Albanian plates (default global vs. the 40+ country EU model). See [[opencv-anpr-service]] "Recognizer evaluation". - Vehicle-model selection + fingerprint method + anomaly threshold (the Job-2 anti-spoofing stage, still ours to build on the same ONNX runtime) ([[opencv-anpr-service]]). - Appliance compute footprint (CPU vs. small GPU/NPU) — [[bom]] / [[open-questions]]. - Service API + the Node-side adapter; per-camera opt-in wiring. - Reconciliation logic that consumes plate+vehicle witness vs. commanded opens (still unbuilt — see [[append-only-event-chain]], [[reconciliation]]).