diff --git a/src/core/observability.rs b/src/core/observability.rs index 8f685f17d8..91332de1dd 100644 --- a/src/core/observability.rs +++ b/src/core/observability.rs @@ -1643,6 +1643,54 @@ mod tests { } } + /// OPENHUMAN-TAURI-SG (33 events, escalating, release `0.53.43+2b64ea8…`): + /// pre-#1763 leak of the `resolve_bearer` sentinel through + /// `agent.run_single`. PR #1763 (1fb0bef5) wired the `SessionExpired` + /// arm and the existing `classifies_session_expired_messages` test + /// covers the same byte string — this test pins the *Sentry-event + /// verbatim* shape (taken from the OPENHUMAN-TAURI-SG event payload) + /// so a future tweak to `is_session_expired_message` cannot regress + /// this exact wire form without a red test. + #[test] + fn session_expired_sg_wire_shape_matches() { + let msg = "SESSION_EXPIRED: backend session not active — sign in to resume LLM work"; + assert_eq!( + expected_error_kind(msg), + Some(ExpectedErrorKind::SessionExpired), + "OPENHUMAN-TAURI-SG wire shape must classify as SessionExpired — \ + a regression here re-leaks 33+ events/cycle to Sentry" + ); + } + + /// The two sibling `SESSION_EXPIRED:` bail sites in + /// `providers::factory::verify_session_active` emit different message + /// suffixes but the same sentinel prefix. They route through the same + /// classifier as the run_single bail at + /// `providers::openhuman_backend::resolve_bearer`, and any matcher + /// tweak that breaks the family (e.g. moving from `contains` to a + /// stricter prefix/suffix match) would re-leak ALL of them. Pin every + /// variant the codebase actually emits so a future regression on the + /// matcher is caught for the whole family, not just the SG instance. + #[test] + fn session_expired_sibling_family_factory_strings_match() { + // src/openhuman/inference/provider/factory.rs:247 + // (verify_session_active — scheduler_gate signed-out path) + let custom_providers_variant = + "SESSION_EXPIRED: backend session not active — sign in to use custom providers"; + // src/openhuman/inference/provider/factory.rs:266 + // (verify_session_active — empty auth-profile JWT path) + let no_backend_session_variant = + "SESSION_EXPIRED: no backend session — sign in to use OpenHuman"; + + for raw in [custom_providers_variant, no_backend_session_variant] { + assert_eq!( + expected_error_kind(raw), + Some(ExpectedErrorKind::SessionExpired), + "factory.rs sibling sentinel must classify as SessionExpired: {raw}" + ); + } + } + #[test] fn does_not_classify_byo_key_provider_401_as_session_expired() { // Critical: a BYO-key 401 from OpenAI / Anthropic etc. is an