Recon Service v2 Surface
Status
Implemented
Date
2026-04-22
Purpose
Document the implemented servers_v2 reconciliation surface so future changes can stay
document-driven and compatibility-safe.
This document captures the actual v2 shape after implementation, not just the intended target state.
Service Topology
Runtime services:
admin_service- external compatibility edge for
bo/admin - legacy auth and
Authorizationheader refresh - websocket top-info aggregation
- external compatibility edge for
recon_service- internal HTTP owner of recon state
- route prefix:
/internal/recon/*
recon_worker- background ingestion, parsing, matching, and retry loops
wallet_service- final money writer for auto-approved deposits
Local compose ports:
admin_service:8016recon_service:8017
External Compatibility Mapping
bo/admin continues to call admin_service.
Implemented compatibility routes in servers_v2/admin_service/app/api/routes/legacy_recon.py:
/api/admin/pushbullet/list->/internal/recon/pushbullet/list/api/admin/pushbullet/add_device->/internal/recon/pushbullet/add_device/api/admin/pushbullet/delete->/internal/recon/pushbullet/delete/api/admin/shooter/template/recharge/list->/internal/recon/shooter/template/recharge/list/api/admin/shooter/template/recharge/add->/internal/recon/shooter/template/recharge/add/api/admin/shooter/template/recharge/delete->/internal/recon/shooter/template/recharge/delete/api/admin/shooter/phone/list->/internal/recon/shooter/phone/list/api/admin/shooter/phone/add->/internal/recon/shooter/phone/add/api/admin/shooter/phone/delete->/internal/recon/shooter/phone/delete/api/admin/shooter/sms/list->/internal/recon/shooter/sms/list/api/admin/shooter/sms/get->/internal/recon/shooter/sms/get/api/admin/shooter/sms/reset->/internal/recon/shooter/sms/reset/api/admin/shooter/sms/check->/internal/recon/shooter/sms/check/api/admin/shooter/device/list->/internal/recon/shooter/device/list/api/admin/shooter/device/trust->/internal/recon/shooter/device/trust/api/admin/shooter/device/delete->/internal/recon/shooter/device/delete/shooter/device/list->/internal/recon/shooter/device/list/shooter/device/trust->/internal/recon/shooter/device/trust/shooter/device/delete->/internal/recon/shooter/device/delete
Compatibility guarantees implemented at the admin edge:
- legacy admin token/session validation
- successful response
Authorizationrefresh - preserved
status/msg/dataenvelope - preserved lowercase recon success message:
success
Internal Recon Routes
Implemented in servers_v2/recon_service/app/api/routes/*:
POST /internal/recon/pushbullet/listPOST /internal/recon/pushbullet/add_devicePOST /internal/recon/pushbullet/deletePOST /internal/recon/shooter/template/recharge/listPOST /internal/recon/shooter/template/recharge/addPOST /internal/recon/shooter/template/recharge/deletePOST /internal/recon/shooter/phone/listPOST /internal/recon/shooter/phone/addPOST /internal/recon/shooter/phone/deletePOST /internal/recon/shooter/sms/listPOST /internal/recon/shooter/sms/getPOST /internal/recon/shooter/sms/resetPOST /internal/recon/shooter/sms/checkPOST /internal/recon/shooter/device/listPOST /internal/recon/shooter/device/trustPOST /internal/recon/shooter/device/deletePOST /internal/recon/stats/top-infoGET /health
Protection model:
- all
/internal/recon/*routes requireX-Internal-Service-Token admin_serviceis the intended caller for back-office compatibility trafficGET /healthstays public for local and orchestration health probes
Worker Loops
Implemented in servers_v2/recon_service/app/tasks/worker_loops.py:
pushbullet_listener_supervisormissing_sms_sync_loopsms_id_sync_loopphone_whitelist_loopparse_looporder_match_looptelegram_poll_loop
Freshness windows implemented in servers_v2/recon_service/app/tasks/loop_health.py:
pushbullet_listener_supervisor:20smissing_sms_sync_loop:90ssms_id_sync_loop:30sphone_whitelist_loop:30sparse_loop:30sorder_match_loop:90stelegram_poll_loop:60s
Worker health behavior:
- task exit still fails the worker immediately
- readiness now also fails when a critical loop stops reporting fresh success within its TTL
- container health is backed by the worker heartbeat file
Data and Approval Contract
Shared migration introduced:
servers_v2/shared/rgb_db/migrations/versions/0017_add_recon_tables.py
Tables added for v2 compatibility:
shooter_deviceshooter_phoneshooter_pushbulletshooter_smsshooter_template_recharge
Approval boundary:
recon_workermatches pending deposits byfrom_bank_owner + amount- duplicate-name players are still routed to manual review with
task_status=6 - final auto-approval flows through
wallet_service wallet_service /internal/wallet/deposit/agreenow accepts optionalsms_id- approved deposit rows can now persist the linked shooter SMS id for idempotent replay parity
Admin Top-Info
admin_service top-info aggregation now merges recon-owned counters from
POST /internal/recon/stats/top-info:
sms_need_check_cntparse_fail_cntunmatched_sms_cntduplicate_sms_cnt
Immediate refresh path implemented for worker-driven manual-review changes:
recon_worker->POST /internal/meta/ws/synconadmin_servicewithX-Internal-Service-Token- used when order matching promotes rows into manual-review state
task_status=6
Compose and Environment
Compose services added:
recon_servicerecon_worker
Compose env keys added or required for the recon path:
RECON_SERVICE_URLonadmin_serviceRGB_INTERNAL_SERVICE_TOKEN_ADMINon internal-service consumers that accept calls fromadmin_serviceRGB_INTERNAL_SERVICE_TOKEN_RECONon internal-service consumers that accept calls fromrecon_workerRGB_PER_CALLER_TOKEN_REQUIRED=onafter the Stage C hard flipRGB_INTERNAL_SERVICE_TOKENonly during Stage A/B migration fallback; it must be empty or absent onceRGB_PER_CALLER_TOKEN_REQUIRED=onRGB_RECON_OPENROUTER_API_KEYRGB_RECON_OPENROUTER_MODELRGB_RECON_TELEGRAM_BOT_TOKEN
Optional integrations:
- OpenRouter is only required when template
ruleis omitted and AI regex generation is desired - Telegram bot token is only required when Telegram ingestion is enabled
- disabled Telegram mode still refreshes worker freshness so the worker stays healthy without that optional integration
Test Coverage
Implemented regression coverage:
servers_v2/admin_service/tests/test_admin_integration.py- legacy recon proxy path
- hidden
/shooter/device/*compatibility path - top-info aggregation
servers_v2/admin_service/tests/test_client_urls.pyReconClientbase URL and circuit-breaker behavior
servers_v2/recon_service/tests/test_recon_routes.py- template validation compatibility
- missing SMS compatibility
- top-info counters
- Pushbullet delete behavior
servers_v2/recon_service/tests/test_worker_health.py- loop freshness behavior
servers_v2/rolling_service/tests/test_events_health.py- rolling worker freshness and unhealthy escalation behavior
servers_v2/tests/test_compose_contract.py- compose service, healthcheck, and dependency contract
Verification Commands
cd servers_v2/admin_service && uv run pytestcd servers_v2/recon_service && uv run pytestcd servers_v2/rolling_service && uv run pytestcd servers_v2/wallet_service && uv run pytestcd servers_v2 && uv run pytest tests/test_compose_contract.py