de0effc40b
The scan terminal service had grown into a 3.5k-line file that mixed endpoint orchestration, AI provider calls, fallback copy, JSON repair, and deterministic evidence guards. This extracts the city-AI helper layer into a focused module while preserving the old private names through imports for existing tests and callers. Constraint: Keep behavior unchanged after the previous evidence-guard fixes and avoid a broad service rewrite. Rejected: Split every scan-terminal concern at once | too much regression risk for this maintenance pass. Confidence: high Scope-risk: narrow Tested: pytest tests/test_web_observability.py -q Tested: npm run build