Files
AutopilotMonitor/rules
Oliver Kieselbach 3318467857 fix(sessions): emit terminal session_timeout event so 5h-timeout sessions analyze
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>
2026-05-31 18:09:39 +02:00
..
2026-03-17 22:43:17 +01:00