mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
3318467857
The maintenance sweep graduated a stalled session to terminal Failed via the repo (MaintenanceService Stage 2, SessionTimeoutHours=5h default) but wrote no event into the session stream and never enqueued analyze. The analyze pipeline fires on stream events, so a server-timed-out session analyzed to totalIssues:0 — unlike the agent max-lifetime path, which emits a real enrollment_failed and is correctly analyzed. - New server-authored event type Constants.EventTypes.SessionTimeout = "session_timeout" (+ MCP termination_events catalog; drift test green). - MaintenanceService Stage 2 now captures the UpdateSessionStatusAsync result and, only on the real first transition (idempotent — the sweep never re-collects a Failed session), emits a session_timeout event (new pure static BuildSessionTimeoutEvent: Sequence = max(session events)+1 so it sorts last, Phase=Unknown, Source=System. Maintenance, Severity=Error) and enqueues auto-analyze with ReasonEnrollmentFailed. Best-effort try/catch — never blocks the timeout transition. Producer injected. - RuleEngine: EvaluatePrecondition gains a pure event-type-presence gate (no-dataField exists/not_exists) — additive (no rule used dataField-less preconditions), enables a session-level suppression with no shared join field. - New rule ANALYZE-ENRL-002 "Session Timed Out": fires on session_timeout, suppressed when enrollment_complete OR enrollment_failed exists (5h<6h late-completion race + no double-report with ANALYZE-ENRL-001). dist regenerated via combine.js. - Web: session_timeout treated as terminal for stale-status refetch (the sweep sends no SignalR delta). Tests: +3 RuleEngine pure-type precondition, SessionTimeoutRuleTests (real shipped rule fire/suppress), MaintenanceServiceSessionTimeoutEventTests (shape/sequence). Backend 2168 pass, web 434 pass, MCP 177 pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>