fix(vision): self-heal local real ANPR — dev scripts sync the alpr extra
The dev box runs vision as bare `uv run uvicorn`, and a plain uv run/uv sync
re-resolves the venv to the lockfile DEFAULTS, stripping fast-alpr/onnxruntime.
So after any `pnpm dev` real ANPR silently degraded to "snapshot, no plate"
(diagnosed 2026-06-25: real reads through 06-22, venv frozen lean since 06-19,
no other env with fast_alpr). The BOOTH was never affected — it runs the Docker
image, which bakes `uv sync --frozen --extra alpr` at build (immutable, weights
pre-warmed); a booth ModuleNotFoundError is a STALE image (fix: booth.sh update).
Vision package.json dev/start/recognize now run `uv sync --extra alpr &&` first
so pnpm dev is self-healing; added a dev:stub escape hatch for a lean run.
Documented in wiki/decisions/vision-service-packaging.md ("Two runtimes, one
fragile") + a log entry.
Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
type: decision
|
||||
tags: [parking, decisions, vision, anpr, monorepo, packaging]
|
||||
sources: []
|
||||
updated: 2026-06-19
|
||||
updated: 2026-06-25
|
||||
status: settled
|
||||
---
|
||||
|
||||
@@ -114,3 +114,29 @@ The skeleton is **built and wired** (no recognizer models yet):
|
||||
> **Resolved 2026-06-22 → [[container-deployment]]:** the vision service now ships as the
|
||||
> `parking-vision` Docker image (uv base, `--extra alpr`), model weights **pre-warmed into the image
|
||||
> layer** at build (offline-first), and runs under **docker-compose** (base + per-env override).
|
||||
|
||||
## Two runtimes, one fragile (the `uv run` strips-the-extra trap) — 2026-06-25
|
||||
|
||||
Real ANPR runs **completely differently on the two machines**, and only the dev path was fragile:
|
||||
|
||||
- **Booth (deployment) = the Docker image.** The `Dockerfile` runs `uv sync --frozen --extra alpr`
|
||||
at build, so fast-alpr/onnxruntime are **baked into an immutable image layer** and the weights are
|
||||
pre-warmed in. `docker-compose.prod.yml` forces `VISION_RECOGNIZER=fast_alpr`. Nothing at runtime
|
||||
re-resolves the venv → **the booth's real ANPR cannot silently degrade.** (A booth
|
||||
`ModuleNotFoundError: fast_alpr` is a STALE image, not this bug — fix with `booth.sh update` to pull
|
||||
the current image.)
|
||||
- **Dev machine = bare `uv run uvicorn …`** against `apps/vision/.venv`. **This is the trap:** a plain
|
||||
`uv run` (or `uv sync` with no `--extra alpr`) re-resolves the venv to the lockfile **defaults** and
|
||||
**REMOVES** the alpr stack — leaving the model weights orphaned in `~/.cache/open-image-models` but
|
||||
no recognizer in the venv. So a dev box that ran real ANPR (weights downloaded, plate reads
|
||||
recorded) silently degrades to "**snapshot captured but no plate**" after the next `pnpm dev`. This
|
||||
exactly explains a gap observed 2026-06-25: real reads on 06-22, then nothing — the venv (frozen
|
||||
since 06-19, lean) had been stripped, while the Docker/compose work (06-23) was an innocent
|
||||
coincidence, not the cause.
|
||||
|
||||
**Fix (2026-06-25):** the vision `package.json` `dev`/`start`/`recognize` scripts now run
|
||||
`uv sync --extra alpr &&` FIRST, so `pnpm dev` is **self-healing** — the recognizer survives every
|
||||
run. A `dev:stub` script is the lean, model-free escape hatch. The booth (Docker) is untouched.
|
||||
**Implication:** local real-ANPR and booth real-ANPR are now both reliable; CI/light contributors who
|
||||
don't want the heavy stack use `dev:stub` or run the suite (tests are stub-mode, offline). See
|
||||
[[opencv-anpr-service]].
|
||||
|
||||
Reference in New Issue
Block a user