File size: 8,562 Bytes
1c0c94d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | # 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.
|