Commit Graph

2 Commits

Author SHA1 Message Date
Oleksandr Bezdieniezhnykh 9fe0bbeac9 [AZ-683] scan_controller POI queue + 5/min cap + decision window
ci/woodpecker/push/build-arm Pipeline failed
Adds the prioritized POI queue on top of the AZ-682 FSM substrate:
priority = confidence x proximity x age_factor; rolling 60s window
caps surfaces at 5; confidence-scaled decision window (40% -> 30s,
100% -> 120s, linear; <40% never surfaces); tick() runs the timeout
sweep and silently forgets expired POIs (no IgnoredItem per spec);
DeclinePoi via operator command returns a DeclineAction for AZ-685
to persist.

ScanControllerHandle gains submit_poi_candidate /
next_poi_for_surface / decline_poi / poi_queue_len /
pois_in_window. submit_operator_cmd return type widens from
Result<()> to Result<SubmitOutcome>. ScanMetrics and health()
surface queue depth and counters.

Tests: 26 unit + 11 integration in scan_controller (all AC1..AC5 +
DeclinePoi end-to-end). Workspace clippy on scan_controller clean.
Pre-existing autopilot::Runtime::vlm_provider_name dead-code error
from batch 4 still open (see cumulative C5).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 09:04:29 +03:00
Oleksandr Bezdieniezhnykh 745ab806f1 [AZ-657] [AZ-682] frame_ingest RTSP lifecycle + scan_controller FSM (batch 12)
ci/woodpecker/push/build-arm Pipeline failed
AZ-657 (frame_ingest): RTSP session lifecycle FSM with bounded
exponential backoff (1 s → 30 s cap), AI-lock plumb through
watch::Sender that stamps every emitted Frame, and SPS/PPS
hard-fail via OpenError::UnsupportedProfile. The actual RTSP wire
client is abstracted behind an RtspTransport trait so AZ-658 can
pin retina/FFmpeg alongside the decoder; the lifecycle FSM itself
is production code today. tokio::select! around every transport
call so a hung open/read cannot wedge graceful shutdown. 10 unit +
5 integration tests cover happy path, bounded reconnect, stream-
drop reopen, hard-fail no-retry, and AI-lock toggle.

AZ-682 (scan_controller): typed ScanState (ZoomedOut / ZoomedIn /
TargetFollow) with a complete pure transition catalogue, every
(state, trigger) → next_state from description.md §1/§4/§5 covered;
spec-disallowed combos return TransitionOutcome.accepted = false
with RejectReason::UnsupportedTransition (loud, not silent). Frame-
rate floor monitor with hysteresis suppresses ZoomedOut → ZoomedIn
while sustained FPS < 10 fps per description.md §5/§6. Rolling
100-sample tick-latency window surfaces p99; health goes yellow
above the 10 ms budget. 18 unit + 5 integration tests cover the
catalogue, fps-floor activate/clear, and tick-latency budget.

Cumulative review (batches 10-12): all OPEN findings carried
forward without regressions. See
_docs/03_implementation/batch_12_cycle1_report.md §6.

Notes: pre-existing dead-code error in autopilot::Runtime::
vlm_provider_name (origin batch 4) blocks workspace -D warnings
clippy. Recorded in _docs/_process_leftovers/ — not in batch 12
scope.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 08:17:27 +03:00