--- convoy: scan-visual-catalog-search brief_number: 3 depends_on: [1] recommended_model: composer-2.5-fast model_tier: fast files: - lib/card-visual-match.js - pages/api/scan/identify-by-image.js - lib/scanner-card-identify.js - lib/use-scanner-identification.js - test/lib/card-visual-match.test.js --- # Brief 3: Layer-0 identify route + client orchestration ## Goal kNN visual match before L1/L2; log `scan_attempts.layer = 0`. ## Acceptance criteria - [ ] `POST /api/scan/identify-by-image` — auth + `checkScanRateLimit` + embed + kNN - [ ] `identifyTrackedCardCapture` order: L0 → L1 → L2 - [ ] Gallery path runs L0 → L1 → L2 - [ ] Skip auto Gemini refine when disambiguation from L0 (same as L1) - [ ] Thresholds: match 0.82, disambiguation 0.58