| # AVIS β Project Status & Context Tracker |
|
|
| > Living document for managing context across sessions. Update it as work lands. |
| > Source of truth for *design* stays `docs/DESIGN.md`; this file tracks *state*. |
| > Last updated: **2026-06-21**. |
|
|
| --- |
|
|
| ## 1. One-line status |
|
|
| End-to-end vertical slice works and is demo-ready: upload β detect β evidence graph β |
| rules β confidence routing β (optional VLM audit) β legal mapping β annotated evidence β |
| **interpretable React dashboard**. Helmet detection now runs on a **local model (zero API |
| calls)**; plate OCR works via **fast-alpr**; all 7 violation types are represented. |
| **Quality gates green:** 49 tests pass, ruff clean, ruff-format clean, mypy clean. |
|
|
| --- |
|
|
| ## 2. Architecture snapshot |
|
|
| ``` |
| upload (api/) β queue (quality gate β preprocess) β pipeline: |
| detect (YOLO11 COCO) core/detect |
| β build Evidence Graph core/graph (single source of truth) |
| β helmet attrs (LOCAL YOLO model) core/detect (no API; was Gemini) |
| β plates (fast-alpr β Gemini fb) core/plates |
| β light state (HSV) core/detect |
| β load calibration zones core/calibration configs/<camera>.json |
| β run rules (pure) core/rules |
| β fuse scores + route + VLM audit core/pipeline (VLM = auditor only) |
| β legal mapping core/legal |
| β hash + annotate + persist core/evidence + core/storage |
| React dashboard (frontend/) β FastAPI (api/main.py) β storage (SQLite/Postgres + files/MinIO) |
| ``` |
|
|
| Invariants held: VLM is an auditor (never the detector); only Tier A may auto-confirm; |
| abstain over guess; the Evidence Graph drives all reasoning; rules are pure/deterministic. |
|
|
| --- |
|
|
| ## 3. Violation coverage (vs the problem statement's 7) |
|
|
| | Violation | Tier | Status | How it's decided | |
| |---|---|---|---| |
| | Helmet non-compliance | A | β
Working, **offline** | Local 7-class YOLO model β rider helmet status; auto-confirm/VLM-skip | |
| | Triple riding | A | β
Working | Count `rides` edges β₯ 3; routed (VLM/human) unless very high fused | |
| | Seatbelt non-compliance | B | β
Implemented (gated) | `SEATBELT_CHECK=true` β speculative candidate β VLM verify; dropped if not confirmed | |
| | Stop-line crossing | C | β
Working w/ calibration | Vehicle ground-point in `stop_line` zone; never auto-confirm | |
| | Red-light violation | C | β
Working w/ calibration | Red light + vehicle past stop-line; candidate | |
| | Illegal parking | C | β
Working w/ calibration | Vehicle in `no_parking` zone; candidate | |
| | Wrong-side driving | D | βͺ Inert by design | A single frame can't prove direction β abstains (needs video) | |
|
|
| Plate OCR (all types): β
fast-alpr (ONNX) + Indian-plate regex; Gemini fallback when empty. |
|
|
| --- |
|
|
| ## 4. Problem-statement task coverage |
|
|
| | Task | Status | Notes | |
| |---|---|---| |
| | Image preprocessing (low-light/blur/etc.) | β
| CLAHE + denoise + gamma; quality gate abstains on too-dark/blurry/over-exposed | |
| | Vehicle + road-user detection & classification | β
| YOLO11 COCO; rider/driver/pedestrian roles in the graph | |
| | Violation detection (7 types) | β
6 active + 1 inert | see Β§3 | |
| | Violation classification + confidence | β
| per-source scores (detection/rule/attribute/vlm) β fused; tier-aware routing | |
| | License-plate detection + OCR | β
| fast-alpr + regex; Gemini fallback | |
| | Evidence generation (annotated + metadata + timestamps) | β
| annotated copy, SHA-256 hash, audit trail, created_at | |
| | Analytics & reporting (trends/search/summary) | β
| `/analytics`, charts, review queue, search filters | |
| | Performance evaluation (P/R/F1, etc.) | βοΈ harness ready | `eval/` computes P/R/F1, ablation, OCR acc, latency β **needs labelled images in `data/eval/`** | |
| | Efficiency / scalability | β
design | modular monolith; Redis-worker + Postgres + MinIO documented scale-out | |
| |
| --- |
| |
| ## 5. Task board |
| |
| **Done (this iteration)** |
| - [x] Local helmet model wired in (`models/helmet/best.pt`, 7-class) β helmet detection needs **zero** API calls. |
| - [x] Plate OCR fixed (root cause: missing `onnxruntime`) + per-char-confidence bug + Gemini fallback chain. |
| - [x] Seatbelt (Tier B) rule + speculative drop-on-negative adjudication (off by default). |
| - [x] Interpretability API: `GET /violations/{id}`, image dims on `/images/{id}`, extended `/runtime`. |
| - [x] New **React + Vite + Chart.js** dashboard with full interpretability + e-challan view. |
| - [x] Tests: 33 β **49**; ruff/format/mypy all clean. |
| |
| **Backlog / next** |
| - [ ] Add a labelled `data/eval/` set and publish real P/R/F1 + ablation numbers. |
| - [ ] Persist the Evidence Graph (per image) to enable client-side bbox overlays in the detail view. |
| - [ ] Optional: seatbelt via a local classifier (avoid VLM quota) instead of VLM-only. |
| - [ ] Optional: ChromaDB legal-RAG bonus (static table stays load-bearing). |
| - [x] Docker: multi-stage build compiles `frontend/dist` in a node stage (one-command deploy). |
| |
| --- |
| |
| ## 6. Change log |
| |
| - **2026-06-21** |
| - Helmet: replaced per-rider Gemini classification with a local YOLO11 model run once on |
| the full image; matches helmet boxes to riders by containment (head boxes have tiny IoU |
| but high containment) and augments riders COCO missed. Fixes the free-tier rate-limit flood. |
| - Plates: added `onnxruntime` (the missing piece that made fast-alpr silently return nothing); |
| fixed `confidence`-is-a-list crash; added `GeminiPlateRecognizer` + `ChainPlateRecognizer`. |
| - Seatbelt: new Tier-B rule (gated by `SEATBELT_CHECK`); `Candidate.speculative` + adjudication |
| that **drops** unconfirmed guesses instead of flooding human review. |
| - API: `GET /violations/{id}`, `width`/`height` on `GET /images/{id}`, `vlm_enabled` + thresholds on `/runtime`. |
| - Frontend: full React rewrite (interpretable cards, confidence breakdown, route explainer, |
| e-challan, audit trail, evidence hash, charts, review, search). |
| - Quality: brought the whole repo to ruff/format/mypy clean (cleared pre-existing debt). |
| - Config fix: `.env` had `GEMINI_MODEL=gGemma-4-31B` (invalid id) β `gemma-3-27b-it` |
| (vision-capable; Gemma 3 free tier ~30 RPM / ~15,000 RPD, much higher than Flash). |
| |
| --- |
|
|
| ## 7. Issue / error log (root causes) |
|
|
| | Symptom | Root cause | Fix | |
| |---|---|---| |
| | "VLM unavailable" flooding human review on busy images | ~14 Gemini calls/image (helmet ΓN + verify ΓN) > 10 req/min free limit | Local helmet model (0 calls) + helmet candidates `pre_verified` (skip 2nd call) + retry/backoff | |
| | Number plate never shown | `fast_alpr` installed but `onnxruntime` missing β ONNX models couldn't run β silent "no plate" | `pip install onnxruntime` (added to requirements) | |
| | fast-alpr crash `float() ... not 'list'` | OCR `confidence` is a per-character list | `_as_conf()` collapses list β mean | |
| | Dashboard "too raw" | vanilla HTML dumped enums | React dashboard with friendly labels, badges, breakdowns, e-challan | |
|
|
| --- |
|
|
| ## 8. Known honest limitations |
|
|
| - **Seatbelt (Tier B)** is genuinely unreliable from a traffic cam; it never auto-confirms and |
| is dropped unless the VLM can substantiate it. Off by default to protect quota. |
| - **Wrong-side (Tier D)** is inert β direction needs video; a single frame abstains. |
| - **Tier C** (stop-line/red-light/parking) needs per-camera calibration (`configs/<camera>.json`); |
| without it, those rules simply don't fire (no fabrication). |
| - **Eval numbers** require a labelled `data/eval/` set β not shipped, so we publish no fake metrics. |
| - **Gemini free tier** (~1,500/day, ~10/min): plate fallback + seatbelt are the only paths that |
| can spend it; both are sparing/optional. |
|
|
| --- |
|
|
| ## 9. Setup & run (quick reference) |
|
|
| ```powershell |
| # deps (one-time) |
| venv\Scripts\python.exe -m pip install -r requirements.txt # incl. onnxruntime |
| cd frontend ; npm install ; npm run build ; cd .. # builds frontend/dist |
| |
| # run (serves the built React app at http://127.0.0.1:8000) |
| venv\Scripts\python.exe -m uvicorn api.main:app --reload |
| |
| # frontend dev mode (hot reload, proxies API to :8000) |
| cd frontend ; npm run dev |
| |
| # quality gates |
| venv\Scripts\python.exe -m pytest -q |
| venv\Scripts\python.exe -m ruff check . ; venv\Scripts\python.exe -m ruff format --check . |
| venv\Scripts\python.exe -m mypy core/ api/ |
| ``` |
|
|
| Key env (`.env`): `HELMET_WEIGHTS=models/helmet/best.pt`, `PLATE_PROVIDER=fastalpr`, |
| `LLM_PROVIDER=gemini`, `GEMINI_MODEL=gemini-2.5-flash`, `SEATBELT_CHECK=false`. |
| **Security:** rotate `GEMINI_API_KEY` (it was shared in chat); `.env` is gitignored. |
|
|