tests/gateway/test_35809_auto_reset_clean_context.py::TestAutoResetBlockReSyncsBinding::test_reset_session_return_is_captured tests/gateway/test_35809_auto_reset_clean_context.py::TestAutoResetBlockReSyncsBinding::test_topic_binding_is_resynced_after_reset tests/gateway/test_35809_auto_reset_clean_context.py::TestAutoResetLoadsCleanContext::test_clean_context_survives_gateway_restart tests/gateway/test_35809_auto_reset_clean_context.py::TestAutoResetLoadsCleanContext::test_next_turn_transcript_is_empty_after_auto_reset tests/gateway/test_42039_duplicate_user_message.py::test_agent_failed_early_no_skip_db_when_no_session_db tests/gateway/test_42039_duplicate_user_message.py::test_agent_failed_early_skip_db_when_agent_has_session_db tests/gateway/test_42039_duplicate_user_message.py::test_normal_path_skip_db_when_agent_has_session_db tests/gateway/test_42039_duplicate_user_message.py::test_not_new_messages_skip_db_when_agent_has_session_db tests/gateway/test_7100_transient_failure_transcript.py::TestContextOverflowStillSkipsTranscript::test_compression_exhausted_is_context_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestContextOverflowStillSkipsTranscript::test_explicit_context_length_error_is_context_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestContextOverflowStillSkipsTranscript::test_generic_400_on_large_session_is_context_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestSuccessfulResultUnaffected::test_successful_result_neither_failed_nor_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestTransientFailureKeepsUserMessage::test_connection_reset_is_not_context_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestTransientFailureKeepsUserMessage::test_generic_400_on_short_session_is_not_context_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestTransientFailureKeepsUserMessage::test_provider_500_is_not_context_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestTransientFailureKeepsUserMessage::test_rate_limit_429_is_not_context_overflow tests/gateway/test_7100_transient_failure_transcript.py::TestTransientFailureKeepsUserMessage::test_read_timeout_is_not_context_overflow tests/gateway/test_active_session_text_merge.py::test_active_drain_force_flushes_debounce_before_release tests/gateway/test_active_session_text_merge.py::test_adapter_defaults_to_interrupt_mode tests/gateway/test_active_session_text_merge.py::test_adapter_is_queue_text_debounce_candidate_when_queue_set tests/gateway/test_active_session_text_merge.py::test_busy_text_mode_respects_env_var_override tests/gateway/test_active_session_text_merge.py::test_command_messages_bypass_debounce_even_in_queue_mode tests/gateway/test_active_session_text_merge.py::test_control_and_clarify_messages_bypass_text_debounce tests/gateway/test_active_session_text_merge.py::test_debounce_buffers_rapid_text_then_flushes_to_pending tests/gateway/test_active_session_text_merge.py::test_debounce_cleanup_in_cancel_background_tasks tests/gateway/test_active_session_text_merge.py::test_debounce_resets_timer_on_new_arrival tests/gateway/test_active_session_text_merge.py::test_debounce_respects_env_var_override tests/gateway/test_active_session_text_merge.py::test_debounce_skipped_when_busy_text_mode_not_queue tests/gateway/test_active_session_text_merge.py::test_force_flush_cancels_timer_without_duplicate_processing tests/gateway/test_active_session_text_merge.py::test_rapid_text_followups_accumulate_instead_of_replacing tests/gateway/test_active_session_text_merge.py::test_single_followup_is_stored_as_is tests/gateway/test_active_session_text_merge.py::test_text_debounce_does_not_merge_different_senders tests/gateway/test_adaptive_nutrition.py::test_activation_crash_before_receipt_commits_missing_receipt_on_recovery tests/gateway/test_adaptive_nutrition.py::test_activation_crash_between_overlay_and_epoch_aborts_after_recovery tests/gateway/test_adaptive_nutrition.py::test_activation_recovery_rejects_document_digest_rotation tests/gateway/test_adaptive_nutrition.py::test_adaptive_config_is_exact_topic_and_disabled_by_default tests/gateway/test_adaptive_nutrition.py::test_adaptive_delivery_result_text_is_safe[result0-\uc804\uc1a1 \uacb0\uacfc\ub97c \ud655\uc778\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \ubcf4\ub0b4\uc9c0 \ub9c8\uc138\uc694. \uc870\uc815\uc774 \ud544\uc694\ud569\ub2c8\ub2e4.] tests/gateway/test_adaptive_nutrition.py::test_adaptive_delivery_result_text_is_safe[result1-\uace0\uac1d \uc804\uc1a1 \uc601\uc218\uc99d\uc740 \ud655\uc778\ub410\uc2b5\ub2c8\ub2e4. \uc7ac\uc804\uc1a1\ud558\uc9c0 \ub9d0\uace0 \uac10\uc0ac \uae30\ub85d\uc744 \ubcf5\uad6c\ud574 \uc8fc\uc138\uc694.] tests/gateway/test_adaptive_nutrition.py::test_adaptive_delivery_result_text_is_safe[result2-\uace0\uac1d \uc804\uc1a1\uacfc \uac10\uc0ac \uae30\ub85d\uc774 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.] tests/gateway/test_adaptive_nutrition.py::test_adaptive_delivery_result_text_is_safe[result3-\uc774\ubbf8 \ucc98\ub9ac\ub41c \uc804\uc1a1\uc785\ub2c8\ub2e4.] tests/gateway/test_adaptive_nutrition.py::test_adaptive_reconcile_callback_completes_without_provider_retry tests/gateway/test_adaptive_nutrition.py::test_adaptive_send_callback_duplicate_is_exact_and_does_not_retry tests/gateway/test_adaptive_nutrition.py::test_adaptive_transport_rejects_raw_and_unreserved_calls tests/gateway/test_adaptive_nutrition.py::test_approve_revalidation_rejects_source_or_registration_change_before_append[registration] tests/gateway/test_adaptive_nutrition.py::test_approve_revalidation_rejects_source_or_registration_change_before_append[source] tests/gateway/test_adaptive_nutrition.py::test_approved_delivery_calls_strict_sender_once_and_audits tests/gateway/test_adaptive_nutrition.py::test_async_registered_transport_success_is_audited tests/gateway/test_adaptive_nutrition.py::test_async_registered_transport_unknown_is_terminal tests/gateway/test_adaptive_nutrition.py::test_base_rollback_crash_restores_prior_state_idempotently tests/gateway/test_adaptive_nutrition.py::test_callback_claim_race_dispatches_create_once tests/gateway/test_adaptive_nutrition.py::test_callback_claim_race_dispatches_mutation_once tests/gateway/test_adaptive_nutrition.py::test_coaching_facts_binding_changes_for_omitted_projection_field_drift tests/gateway/test_adaptive_nutrition.py::test_coaching_facts_reject_forged_digest_before_mutation tests/gateway/test_adaptive_nutrition.py::test_competing_revision_children_leave_stale_child_unapprovable_and_undeliverable tests/gateway/test_adaptive_nutrition.py::test_concurrent_coordinators_reserve_once_before_async_provider_call tests/gateway/test_adaptive_nutrition.py::test_config_epoch_requires_exact_live_fanout_and_digest[duplicate_customer] tests/gateway/test_adaptive_nutrition.py::test_config_epoch_requires_exact_live_fanout_and_digest[extra_customer] tests/gateway/test_adaptive_nutrition.py::test_config_epoch_requires_exact_live_fanout_and_digest[mismatched_digest] tests/gateway/test_adaptive_nutrition.py::test_config_epoch_requires_exact_live_fanout_and_digest[missing_digest] tests/gateway/test_adaptive_nutrition.py::test_config_epoch_requires_exact_live_fanout_and_digest[omitted_enabled_customer] tests/gateway/test_adaptive_nutrition.py::test_current_coaching_facts_binding_match_and_mismatch_are_read_only tests/gateway/test_adaptive_nutrition.py::test_d_plus_transport_gate_revalidates_feature_config_digest tests/gateway/test_adaptive_nutrition.py::test_delivery_disabled_rejects_before_provider_call tests/gateway/test_adaptive_nutrition.py::test_delivery_enable_does_not_rebind_after_document_digest_rotation tests/gateway/test_adaptive_nutrition.py::test_delivery_reservation_revalidation_records_unknown_for_each_authority_change[consent] tests/gateway/test_adaptive_nutrition.py::test_delivery_reservation_revalidation_records_unknown_for_each_authority_change[owner] tests/gateway/test_adaptive_nutrition.py::test_delivery_reservation_revalidation_records_unknown_for_each_authority_change[registration] tests/gateway/test_adaptive_nutrition.py::test_delivery_reservation_revalidation_records_unknown_for_each_authority_change[source] tests/gateway/test_adaptive_nutrition.py::test_empty_or_mismatched_journals_block_production tests/gateway/test_adaptive_nutrition.py::test_forged_capability_without_durable_session_fails_before_mutation tests/gateway/test_adaptive_nutrition.py::test_forged_runtime_paths_fail_before_store_or_provider_mutation tests/gateway/test_adaptive_nutrition.py::test_humanizer_adaptive_grounding_accepts_only_production_fact_schema tests/gateway/test_adaptive_nutrition.py::test_live_feature_config_digest_is_verified tests/gateway/test_adaptive_nutrition.py::test_live_telegram_adaptive_callback_rejects_non_owner_or_wrong_space tests/gateway/test_adaptive_nutrition.py::test_live_telegram_adaptive_callback_requires_configured_review_space tests/gateway/test_adaptive_nutrition.py::test_live_telegram_adaptive_callback_requires_exact_owner_topic tests/gateway/test_adaptive_nutrition.py::test_low_adherence_and_safety_fail_closed tests/gateway/test_adaptive_nutrition.py::test_missing_goal_prompts_and_never_sends tests/gateway/test_adaptive_nutrition.py::test_missing_review_operator_version_is_rejected tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[activate] tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[approve] tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[delivery_enable] tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[delivery_revoke] tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[hold] tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[reconcile] tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[release] tests/gateway/test_adaptive_nutrition.py::test_mutating_action_pin_toctou_rejects_before_downstream_mutation[send] tests/gateway/test_adaptive_nutrition.py::test_negative_provider_receipt_is_unknown_and_never_retried tests/gateway/test_adaptive_nutrition.py::test_opaque_adaptive_callbacks_are_bounded_and_stale_safe tests/gateway/test_adaptive_nutrition.py::test_operator_card_exposes_only_state_appropriate_primary_action tests/gateway/test_adaptive_nutrition.py::test_operator_edit_note_returns_identity_envelope tests/gateway/test_adaptive_nutrition.py::test_operator_sessions_bind_action_provenance_and_expiry tests/gateway/test_adaptive_nutrition.py::test_owner_can_persist_and_revoke_delivery_capability tests/gateway/test_adaptive_nutrition.py::test_owner_rotation_aborts_activation_before_transition_append tests/gateway/test_adaptive_nutrition.py::test_owner_rotation_aborts_persisted_delivery_before_append tests/gateway/test_adaptive_nutrition.py::test_owner_rotation_aborts_rollback_before_transition_append tests/gateway/test_adaptive_nutrition.py::test_p2_p6_fresh_revisions_have_exact_terminal_rows_and_provider_counts tests/gateway/test_adaptive_nutrition.py::test_production_journal_reload_uses_persisted_rows tests/gateway/test_adaptive_nutrition.py::test_production_lifecycle_rejects_raw_operator_identity tests/gateway/test_adaptive_nutrition.py::test_production_lifecycle_rejects_source_mutation_and_wrong_destination tests/gateway/test_adaptive_nutrition.py::test_production_lifecycle_requires_exact_configured_owner tests/gateway/test_adaptive_nutrition.py::test_production_proposal_uses_canonical_events_and_pins_artifacts tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[consent-activate] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[consent-approve] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[consent-deliver] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[destination-activate] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[destination-approve] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[destination-deliver] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[owner-activate] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[owner-approve] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[owner-deliver] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[safety-activate] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[safety-approve] tests/gateway/test_adaptive_nutrition.py::test_production_revocation_matrix_fails_closed[safety-deliver] tests/gateway/test_adaptive_nutrition.py::test_profile_authority_flock_serializes_processes_and_owner_change_is_stale tests/gateway/test_adaptive_nutrition.py::test_proposal_append_recheck_rejects_source_or_registration_change[registration] tests/gateway/test_adaptive_nutrition.py::test_proposal_append_recheck_rejects_source_or_registration_change[source] tests/gateway/test_adaptive_nutrition.py::test_provider_receipt_reconciles_missing_delivery_audit_without_resend tests/gateway/test_adaptive_nutrition.py::test_public_delivery_false_uses_persisted_enable_then_fresh_revoke_fails_closed tests/gateway/test_adaptive_nutrition.py::test_public_shadow_constructor_flag_cannot_enable_raw_runtime_paths tests/gateway/test_adaptive_nutrition.py::test_publication_recovery_claims_once_across_services tests/gateway/test_adaptive_nutrition.py::test_publication_unknown_outcome_is_not_retried tests/gateway/test_adaptive_nutrition.py::test_publish_pending_card_recovers_once tests/gateway/test_adaptive_nutrition.py::test_real_adaptive_transport_window_covers_baseline_and_extension[0-None-True] tests/gateway/test_adaptive_nutrition.py::test_real_adaptive_transport_window_covers_baseline_and_extension[27-None-True] tests/gateway/test_adaptive_nutrition.py::test_real_adaptive_transport_window_covers_baseline_and_extension[28-None-False] tests/gateway/test_adaptive_nutrition.py::test_real_adaptive_transport_window_covers_baseline_and_extension[28-extended_through3-True] tests/gateway/test_adaptive_nutrition.py::test_real_adaptive_transport_window_covers_baseline_and_extension[83-extended_through4-True] tests/gateway/test_adaptive_nutrition.py::test_real_adaptive_transport_window_covers_baseline_and_extension[84-extended_through5-False] tests/gateway/test_adaptive_nutrition.py::test_real_telegram_transport_checks_authority_before_consuming_reservation[d_plus_85] tests/gateway/test_adaptive_nutrition.py::test_real_telegram_transport_checks_authority_before_consuming_reservation[positive] tests/gateway/test_adaptive_nutrition.py::test_real_telegram_transport_checks_authority_before_consuming_reservation[revoked] tests/gateway/test_adaptive_nutrition.py::test_receipt_only_audit_pending_recovery_survives_restart_without_provider tests/gateway/test_adaptive_nutrition.py::test_reload_delivery_rejects_hash_consistent_noncanonical_customer_body tests/gateway/test_adaptive_nutrition.py::test_reload_rejects_hash_consistent_persisted_explanation_and_body tests/gateway/test_adaptive_nutrition.py::test_replacement_overlay_epoch_failure_aborts_and_restores_predecessor tests/gateway/test_adaptive_nutrition.py::test_replacement_rollback_crash_restores_prior_state_idempotently tests/gateway/test_adaptive_nutrition.py::test_review_ingress_is_distinct_from_canonical_owner_and_sessions_are_exact tests/gateway/test_adaptive_nutrition.py::test_review_session_wrong_user_and_stale_duplicate_are_terminal tests/gateway/test_adaptive_nutrition.py::test_revision_requires_reapproval_and_exact_digest tests/gateway/test_adaptive_nutrition.py::test_safety_callback_cannot_approve_or_activate tests/gateway/test_adaptive_nutrition.py::test_shadow_factory_requires_the_exact_private_token tests/gateway/test_adaptive_nutrition.py::test_source_day_mapping_identity_is_one_to_one[duplicate_mapping_id] tests/gateway/test_adaptive_nutrition.py::test_source_day_mapping_identity_is_one_to_one[duplicate_root] tests/gateway/test_adaptive_nutrition.py::test_source_day_mapping_identity_is_one_to_one[missing] tests/gateway/test_adaptive_nutrition.py::test_source_day_mapping_identity_is_one_to_one[unmapped] tests/gateway/test_adaptive_nutrition.py::test_subprocess_shared_directory_reservation_race tests/gateway/test_adaptive_nutrition.py::test_telegram_registry_authority_is_configured_and_contained tests/gateway/test_adaptive_nutrition.py::test_terminal_delivery_card_removes_send_and_exposes_only_valid_recovery[audit_pending-\uac10\uc0ac \uae30\ub85d \ubcf5\uad6c] tests/gateway/test_adaptive_nutrition.py::test_terminal_delivery_card_removes_send_and_exposes_only_valid_recovery[delivery_unknown-None] tests/gateway/test_adaptive_nutrition.py::test_terminal_delivery_card_removes_send_and_exposes_only_valid_recovery[duplicate-None] tests/gateway/test_adaptive_nutrition.py::test_terminal_delivery_card_removes_send_and_exposes_only_valid_recovery[sent_audited-None] tests/gateway/test_adaptive_nutrition.py::test_topic_59_only tests/gateway/test_adaptive_nutrition.py::test_unknown_delivery_is_never_retried tests/gateway/test_adaptive_nutrition.py::test_untyped_approved_schedule_fails_closed tests/gateway/test_adaptive_nutrition.py::test_view_and_back_callbacks_replay_without_claiming_or_reissuing tests/gateway/test_adaptive_nutrition.py::test_view_callback_stale_forwarded_or_pinned_replay_rejects[message] tests/gateway/test_adaptive_nutrition.py::test_view_callback_stale_forwarded_or_pinned_replay_rejects[pins] tests/gateway/test_agent_cache.py::TestAgentCacheActiveSafety::test_cap_evicts_when_multiple_excess_and_some_inactive tests/gateway/test_agent_cache.py::TestAgentCacheActiveSafety::test_cap_leaves_cache_over_limit_if_all_active tests/gateway/test_agent_cache.py::TestAgentCacheActiveSafety::test_cap_pending_sentinel_does_not_block_eviction tests/gateway/test_agent_cache.py::TestAgentCacheActiveSafety::test_cap_skips_active_lru_entry tests/gateway/test_agent_cache.py::TestAgentCacheActiveSafety::test_eviction_does_not_close_active_agent_client tests/gateway/test_agent_cache.py::TestAgentCacheActiveSafety::test_idle_sweep_skips_active_agent tests/gateway/test_agent_cache.py::TestAgentCacheBoundedGrowth::test_cap_evicts_lru_when_exceeded tests/gateway/test_agent_cache.py::TestAgentCacheBoundedGrowth::test_cap_respects_move_to_end tests/gateway/test_agent_cache.py::TestAgentCacheBoundedGrowth::test_cap_triggers_cleanup_thread tests/gateway/test_agent_cache.py::TestAgentCacheBoundedGrowth::test_idle_sweep_skips_agents_without_activity_ts tests/gateway/test_agent_cache.py::TestAgentCacheBoundedGrowth::test_idle_ttl_sweep_evicts_stale_agents tests/gateway/test_agent_cache.py::TestAgentCacheBoundedGrowth::test_main_lookup_updates_lru_order tests/gateway/test_agent_cache.py::TestAgentCacheBoundedGrowth::test_plain_dict_cache_is_tolerated tests/gateway/test_agent_cache.py::TestAgentCacheIdleResume::test_close_vs_release_full_teardown_difference tests/gateway/test_agent_cache.py::TestAgentCacheIdleResume::test_idle_evicted_session_rebuild_inherits_task_id tests/gateway/test_agent_cache.py::TestAgentCacheIdleResume::test_release_clients_closes_llm_client tests/gateway/test_agent_cache.py::TestAgentCacheIdleResume::test_release_clients_does_not_touch_process_registry tests/gateway/test_agent_cache.py::TestAgentCacheIdleResume::test_release_clients_does_not_touch_terminal_or_browser tests/gateway/test_agent_cache.py::TestAgentCacheLifecycle::test_cache_hit_returns_same_agent tests/gateway/test_agent_cache.py::TestAgentCacheLifecycle::test_cache_miss_on_model_change tests/gateway/test_agent_cache.py::TestAgentCacheLifecycle::test_callbacks_update_without_cache_eviction tests/gateway/test_agent_cache.py::TestAgentCacheLifecycle::test_evict_does_not_affect_other_sessions tests/gateway/test_agent_cache.py::TestAgentCacheLifecycle::test_evict_on_session_reset tests/gateway/test_agent_cache.py::TestAgentCacheLifecycle::test_reasoning_config_updates_in_place tests/gateway/test_agent_cache.py::TestAgentCacheLifecycle::test_system_prompt_frozen_across_cache_reuse tests/gateway/test_agent_cache.py::TestAgentCacheMessageCountRebaseline::test_cross_process_write_still_invalidates tests/gateway/test_agent_cache.py::TestAgentCacheMessageCountRebaseline::test_rebaseline_is_fail_safe_and_skips_legacy_and_pending tests/gateway/test_agent_cache.py::TestAgentCacheMessageCountRebaseline::test_same_process_turns_preserve_cached_agent tests/gateway/test_agent_cache.py::TestAgentCacheSpilloverLive::test_evicted_session_next_turn_gets_fresh_agent tests/gateway/test_agent_cache.py::TestAgentCacheSpilloverLive::test_fill_to_cap_then_spillover tests/gateway/test_agent_cache.py::TestAgentCacheSpilloverLive::test_spillover_all_active_keeps_cache_over_cap tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_cache_keys_default_omitted_matches_empty tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_cache_keys_key_order_does_not_matter tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_compression_enabled_toggle_busts_cache tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_compression_threshold_change_busts_cache tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_context_length_change_busts_cache tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_max_tokens_change_busts_cache tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_model_change_different_signature tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_provider_change_different_signature tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_reasoning_not_in_signature tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_same_config_same_signature tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_same_token_prefix_different_full_token_changes_signature tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_tool_registry_generation_change_busts_cache tests/gateway/test_agent_cache.py::TestAgentConfigSignature::test_toolset_change_different_signature tests/gateway/test_agent_cache.py::TestAgentConfigSignatureUserId::test_signature_changes_with_user_id tests/gateway/test_agent_cache.py::TestAgentConfigSignatureUserId::test_signature_changes_with_user_id_alt tests/gateway/test_agent_cache.py::TestAgentConfigSignatureUserId::test_signature_omits_user_id_when_absent tests/gateway/test_agent_cache.py::TestAgentConfigSignatureUserId::test_signature_stable_with_same_user_id tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_api_call_count_reset_regardless_of_depth tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_deep_interrupt_recursion_preserves_idle_clock tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_fresh_turn_resets_desc tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_fresh_turn_resets_flush_cursor tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_fresh_turn_resets_idle_clock tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_interrupt_turn_preserves_desc tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_interrupt_turn_preserves_flush_cursor tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_interrupt_turn_preserves_idle_clock tests/gateway/test_agent_cache.py::TestCachedAgentInactivityReset::test_watchdog_accumulation_across_recursive_turns tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_extract_includes_live_tool_registry_generation tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_full_round_trip_busts_cache_on_real_edit tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_honcho_cache_busting_config_memoized_by_mtime tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_memory_provider_change_busts_signature tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_missing_keys_yield_none tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_non_dict_section_treated_as_missing tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_none_config_is_safe tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_reads_compression_subkeys tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_reads_honcho_config_only_when_provider_is_honcho tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_reads_model_context_length tests/gateway/test_agent_cache.py::TestExtractCacheBustingConfig::test_skips_honcho_config_read_when_provider_is_not_honcho tests/gateway/test_allowed_channels_widening.py::TestDingTalkAllowedChats::test_blocks_non_whitelisted_group tests/gateway/test_allowed_channels_widening.py::TestDingTalkAllowedChats::test_config_bridge tests/gateway/test_allowed_channels_widening.py::TestDingTalkAllowedChats::test_csv_form tests/gateway/test_allowed_channels_widening.py::TestDingTalkAllowedChats::test_dm_unaffected tests/gateway/test_allowed_channels_widening.py::TestDingTalkAllowedChats::test_empty_is_no_restriction tests/gateway/test_allowed_channels_widening.py::TestDingTalkAllowedChats::test_env_var_fallback tests/gateway/test_allowed_channels_widening.py::TestDingTalkAllowedChats::test_list_form tests/gateway/test_allowed_channels_widening.py::TestMatrixAllowedRooms::test_block_logic tests/gateway/test_allowed_channels_widening.py::TestMatrixAllowedRooms::test_config_bridge tests/gateway/test_allowed_channels_widening.py::TestMatrixAllowedRooms::test_empty_env_empty_set tests/gateway/test_allowed_channels_widening.py::TestMatrixAllowedRooms::test_env_var_parsed_to_set tests/gateway/test_allowed_channels_widening.py::TestMattermostAllowedChannels::test_config_bridge tests/gateway/test_allowed_channels_widening.py::TestMattermostAllowedChannels::test_config_list_blocks_non_whitelisted_channel tests/gateway/test_allowed_channels_widening.py::TestMattermostAllowedChannels::test_config_list_permits_whitelisted_channel tests/gateway/test_allowed_channels_widening.py::TestMattermostAllowedChannels::test_dm_unaffected tests/gateway/test_allowed_channels_widening.py::TestMattermostAllowedChannels::test_empty_config_is_no_restriction tests/gateway/test_allowed_channels_widening.py::TestMattermostAllowedChannels::test_env_var_fallback_when_no_config tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_blocks_non_whitelisted_group tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_config_bridge tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_config_bridge_env_takes_precedence tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_csv_form tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_dms_unaffected tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_empty_is_no_restriction tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_env_var_fallback tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_list_form tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_mention_cannot_bypass_whitelist tests/gateway/test_allowed_channels_widening.py::TestTelegramAllowedChats::test_permits_whitelisted_group tests/gateway/test_allowlist_startup_check.py::TestAllowlistStartupCheck::test_gateway_allow_all_users_suppresses_warning tests/gateway/test_allowlist_startup_check.py::TestAllowlistStartupCheck::test_no_config_emits_warning tests/gateway/test_allowlist_startup_check.py::TestAllowlistStartupCheck::test_signal_group_allowed_users_suppresses_warning tests/gateway/test_allowlist_startup_check.py::TestAllowlistStartupCheck::test_telegram_allow_all_users_suppresses_warning tests/gateway/test_api_server.py::TestAdapterInit::test_config_from_env tests/gateway/test_api_server.py::TestAdapterInit::test_create_agent_forwards_config_reasoning_effort tests/gateway/test_api_server.py::TestAdapterInit::test_create_agent_refreshes_max_iterations_from_runtime_config tests/gateway/test_api_server.py::TestAdapterInit::test_custom_config_from_extra tests/gateway/test_api_server.py::TestAdapterInit::test_default_config tests/gateway/test_api_server.py::TestAdapterInit::test_invalid_port_from_env_falls_back_to_default tests/gateway/test_api_server.py::TestAgentExecution::test_run_agent_uses_session_id_as_task_id tests/gateway/test_api_server.py::TestAuth::test_invalid_key_returns_401 tests/gateway/test_api_server.py::TestAuth::test_malformed_auth_header_returns_401 tests/gateway/test_api_server.py::TestAuth::test_missing_auth_header_returns_401 tests/gateway/test_api_server.py::TestAuth::test_no_key_configured_allows_all tests/gateway/test_api_server.py::TestAuth::test_valid_key_passes tests/gateway/test_api_server.py::TestCORS::test_browser_origin_rejected_by_default tests/gateway/test_api_server.py::TestCORS::test_cors_allows_idempotency_key_header tests/gateway/test_api_server.py::TestCORS::test_cors_headers_for_origin_disabled_by_default tests/gateway/test_api_server.py::TestCORS::test_cors_headers_for_origin_matches_allowlist tests/gateway/test_api_server.py::TestCORS::test_cors_headers_for_origin_rejects_unknown_origin tests/gateway/test_api_server.py::TestCORS::test_cors_headers_not_present_by_default tests/gateway/test_api_server.py::TestCORS::test_cors_headers_present_for_allowed_origin tests/gateway/test_api_server.py::TestCORS::test_cors_options_preflight_allowed_for_configured_origin tests/gateway/test_api_server.py::TestCORS::test_cors_options_preflight_rejected_by_default tests/gateway/test_api_server.py::TestCORS::test_cors_preflight_sets_max_age tests/gateway/test_api_server.py::TestCORS::test_cors_sets_vary_origin_header tests/gateway/test_api_server.py::TestCORS::test_origin_allowed_for_allowlist_match tests/gateway/test_api_server.py::TestCORS::test_origin_allowed_for_non_browser_client tests/gateway/test_api_server.py::TestCORS::test_origin_rejected_by_default tests/gateway/test_api_server.py::TestCapabilitiesEndpoint::test_capabilities_advertises_plugin_safe_contract tests/gateway/test_api_server.py::TestCapabilitiesEndpoint::test_capabilities_requires_auth_when_key_configured tests/gateway/test_api_server.py::TestChatCompletionsAgentIncomplete::test_failure_with_no_text_returns_502_error_envelope tests/gateway/test_api_server.py::TestChatCompletionsAgentIncomplete::test_normal_completion_unchanged tests/gateway/test_api_server.py::TestChatCompletionsAgentIncomplete::test_truncation_with_partial_text_uses_length_finish_reason tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_agent_error_returns_500 tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_conversation_history_passed tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_different_conversations_get_different_session_ids tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_empty_messages_returns_400 tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_invalid_json_returns_400 tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_missing_messages_returns_400 tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_no_user_message_returns_400 tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stable_session_id_across_turns tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_emits_tool_lifecycle_with_call_id tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_includes_tool_progress tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_sends_keepalive_during_quiet_tool_gap tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_string_false_returns_json_completion tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_survives_tool_call_none_sentinel tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_task_done_callback_enqueues_eos_for_chat_completions tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_tool_lifecycle_skips_internal_and_orphan_completes tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_tool_progress_skips_internal_events tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_stream_true_returns_sse tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_successful_completion tests/gateway/test_api_server.py::TestChatCompletionsEndpoint::test_system_prompt_extracted tests/gateway/test_api_server.py::TestCheckRequirements::test_returns_false_without_aiohttp tests/gateway/test_api_server.py::TestCheckRequirements::test_returns_true_when_aiohttp_available tests/gateway/test_api_server.py::TestConfigIntegration::test_api_server_in_connected_platforms tests/gateway/test_api_server.py::TestConfigIntegration::test_api_server_not_in_connected_when_disabled tests/gateway/test_api_server.py::TestConfigIntegration::test_env_override_cors_origins tests/gateway/test_api_server.py::TestConfigIntegration::test_env_override_enables_api_server tests/gateway/test_api_server.py::TestConfigIntegration::test_env_override_port_and_host tests/gateway/test_api_server.py::TestConfigIntegration::test_env_override_with_key tests/gateway/test_api_server.py::TestConfigIntegration::test_platform_enum_has_api_server tests/gateway/test_api_server.py::TestConversationParameter::test_conversation_and_previous_response_id_conflict tests/gateway/test_api_server.py::TestConversationParameter::test_conversation_chains_automatically tests/gateway/test_api_server.py::TestConversationParameter::test_conversation_creates_new tests/gateway/test_api_server.py::TestConversationParameter::test_conversation_reuse_after_eviction_no_404 tests/gateway/test_api_server.py::TestConversationParameter::test_conversation_store_false_no_mapping tests/gateway/test_api_server.py::TestConversationParameter::test_separate_conversations_are_isolated tests/gateway/test_api_server.py::TestDeleteResponse::test_delete_not_found tests/gateway/test_api_server.py::TestDeleteResponse::test_delete_requires_auth tests/gateway/test_api_server.py::TestDeleteResponse::test_delete_stored_response tests/gateway/test_api_server.py::TestDeriveChatSessionId::test_deterministic tests/gateway/test_api_server.py::TestDeriveChatSessionId::test_different_first_message tests/gateway/test_api_server.py::TestDeriveChatSessionId::test_different_system_prompt tests/gateway/test_api_server.py::TestDeriveChatSessionId::test_none_system_prompt tests/gateway/test_api_server.py::TestDeriveChatSessionId::test_prefix tests/gateway/test_api_server.py::TestEndpointAuth::test_chat_completions_requires_auth tests/gateway/test_api_server.py::TestEndpointAuth::test_health_does_not_require_auth tests/gateway/test_api_server.py::TestEndpointAuth::test_models_requires_auth tests/gateway/test_api_server.py::TestEndpointAuth::test_responses_requires_auth tests/gateway/test_api_server.py::TestGetResponse::test_get_not_found tests/gateway/test_api_server.py::TestGetResponse::test_get_requires_auth tests/gateway/test_api_server.py::TestGetResponse::test_get_stored_response tests/gateway/test_api_server.py::TestHealthDetailedEndpoint::test_health_detailed_does_not_require_auth tests/gateway/test_api_server.py::TestHealthDetailedEndpoint::test_health_detailed_no_runtime_status tests/gateway/test_api_server.py::TestHealthDetailedEndpoint::test_health_detailed_returns_ok tests/gateway/test_api_server.py::TestHealthEndpoint::test_health_reports_version tests/gateway/test_api_server.py::TestHealthEndpoint::test_health_returns_ok tests/gateway/test_api_server.py::TestHealthEndpoint::test_security_headers_present tests/gateway/test_api_server.py::TestHealthEndpoint::test_v1_health_alias_returns_ok tests/gateway/test_api_server.py::TestIdempotencyCache::test_cancelled_waiter_does_not_drop_shared_inflight_task tests/gateway/test_api_server.py::TestIdempotencyCache::test_concurrent_same_key_and_fingerprint_runs_once tests/gateway/test_api_server.py::TestIdempotencyCache::test_different_fingerprint_does_not_reuse_inflight_task tests/gateway/test_api_server.py::TestModelsEndpoint::test_models_requires_auth tests/gateway/test_api_server.py::TestModelsEndpoint::test_models_returns_explicit_model_name tests/gateway/test_api_server.py::TestModelsEndpoint::test_models_returns_hermes_agent tests/gateway/test_api_server.py::TestModelsEndpoint::test_models_returns_profile_name tests/gateway/test_api_server.py::TestModelsEndpoint::test_models_with_valid_auth tests/gateway/test_api_server.py::TestModelsEndpoint::test_resolve_model_name_default_profile tests/gateway/test_api_server.py::TestModelsEndpoint::test_resolve_model_name_explicit tests/gateway/test_api_server.py::TestModelsEndpoint::test_resolve_model_name_named_profile tests/gateway/test_api_server.py::TestMultipleSystemMessages::test_multiple_system_messages_concatenated tests/gateway/test_api_server.py::TestResponseStore::test_access_refreshes_lru tests/gateway/test_api_server.py::TestResponseStore::test_delete_clears_conversation_mapping tests/gateway/test_api_server.py::TestResponseStore::test_delete_existing tests/gateway/test_api_server.py::TestResponseStore::test_delete_missing tests/gateway/test_api_server.py::TestResponseStore::test_eviction_clears_conversation_mapping tests/gateway/test_api_server.py::TestResponseStore::test_file_store_created_owner_only_under_permissive_umask tests/gateway/test_api_server.py::TestResponseStore::test_get_missing_returns_none tests/gateway/test_api_server.py::TestResponseStore::test_lru_eviction tests/gateway/test_api_server.py::TestResponseStore::test_put_and_get tests/gateway/test_api_server.py::TestResponseStore::test_update_existing_key tests/gateway/test_api_server.py::TestResponsesEndpoint::test_agent_error_returns_500 tests/gateway/test_api_server.py::TestResponsesEndpoint::test_instructions_as_ephemeral_prompt tests/gateway/test_api_server.py::TestResponsesEndpoint::test_instructions_inherited_from_previous tests/gateway/test_api_server.py::TestResponsesEndpoint::test_invalid_input_type_returns_400 tests/gateway/test_api_server.py::TestResponsesEndpoint::test_invalid_json_returns_400 tests/gateway/test_api_server.py::TestResponsesEndpoint::test_invalid_previous_response_id_returns_404 tests/gateway/test_api_server.py::TestResponsesEndpoint::test_missing_input_returns_400 tests/gateway/test_api_server.py::TestResponsesEndpoint::test_previous_response_id_chaining tests/gateway/test_api_server.py::TestResponsesEndpoint::test_previous_response_id_outputs_only_current_turn_items tests/gateway/test_api_server.py::TestResponsesEndpoint::test_previous_response_id_preserves_session tests/gateway/test_api_server.py::TestResponsesEndpoint::test_previous_response_id_stores_full_agent_transcript_once tests/gateway/test_api_server.py::TestResponsesEndpoint::test_store_false_does_not_store tests/gateway/test_api_server.py::TestResponsesEndpoint::test_store_string_false_does_not_store tests/gateway/test_api_server.py::TestResponsesEndpoint::test_successful_response_with_array_input tests/gateway/test_api_server.py::TestResponsesEndpoint::test_successful_response_with_string_input tests/gateway/test_api_server.py::TestResponsesStreaming::test_stream_cancelled_persists_incomplete_snapshot tests/gateway/test_api_server.py::TestResponsesStreaming::test_stream_client_disconnect_persists_incomplete_snapshot tests/gateway/test_api_server.py::TestResponsesStreaming::test_stream_emits_function_call_and_output_items tests/gateway/test_api_server.py::TestResponsesStreaming::test_stream_string_false_returns_json_response tests/gateway/test_api_server.py::TestResponsesStreaming::test_stream_task_done_callback_enqueues_eos_for_responses tests/gateway/test_api_server.py::TestResponsesStreaming::test_stream_true_returns_responses_sse tests/gateway/test_api_server.py::TestResponsesStreaming::test_streamed_previous_response_id_stores_full_agent_transcript_once tests/gateway/test_api_server.py::TestResponsesStreaming::test_streamed_response_is_stored_for_get tests/gateway/test_api_server.py::TestSendMethod::test_send_returns_not_supported tests/gateway/test_api_server.py::TestSessionIdHeader::test_db_failure_falls_back_to_empty_history tests/gateway/test_api_server.py::TestSessionIdHeader::test_new_session_response_includes_session_id_header tests/gateway/test_api_server.py::TestSessionIdHeader::test_provided_session_id_is_used_and_echoed tests/gateway/test_api_server.py::TestSessionIdHeader::test_provided_session_id_loads_history_from_db tests/gateway/test_api_server.py::TestSessionKeyHeader::test_capabilities_advertises_session_key_header tests/gateway/test_api_server.py::TestSessionKeyHeader::test_responses_endpoint_accepts_session_key tests/gateway/test_api_server.py::TestSessionKeyHeader::test_session_key_absent_yields_none tests/gateway/test_api_server.py::TestSessionKeyHeader::test_session_key_independent_of_session_id tests/gateway/test_api_server.py::TestSessionKeyHeader::test_session_key_passed_to_agent_and_echoed tests/gateway/test_api_server.py::TestSessionKeyHeader::test_session_key_rejected_without_api_key tests/gateway/test_api_server.py::TestSessionKeyHeader::test_session_key_rejects_control_chars tests/gateway/test_api_server.py::TestSessionKeyHeader::test_session_key_rejects_oversized tests/gateway/test_api_server.py::TestSessionKeyHeader::test_session_key_threads_into_create_agent tests/gateway/test_api_server.py::TestSkillsEndpoint::test_skills_handles_enumeration_failure tests/gateway/test_api_server.py::TestSkillsEndpoint::test_skills_requires_auth_when_key_configured tests/gateway/test_api_server.py::TestSkillsEndpoint::test_skills_returns_list_envelope tests/gateway/test_api_server.py::TestToolCallsInOutput::test_no_tool_calls_still_works tests/gateway/test_api_server.py::TestToolCallsInOutput::test_tool_calls_in_output tests/gateway/test_api_server.py::TestToolsetsEndpoint::test_toolsets_handles_resolution_failure_per_toolset tests/gateway/test_api_server.py::TestToolsetsEndpoint::test_toolsets_requires_auth_when_key_configured tests/gateway/test_api_server.py::TestToolsetsEndpoint::test_toolsets_returns_resolved_tools tests/gateway/test_api_server.py::TestTruncation::test_no_truncation_keeps_full_history tests/gateway/test_api_server.py::TestTruncation::test_truncation_auto_limits_history tests/gateway/test_api_server.py::TestUsageCounting::test_chat_completions_usage tests/gateway/test_api_server.py::TestUsageCounting::test_responses_usage tests/gateway/test_api_server_bind_guard.py::TestConnectBindGuard::test_allows_wildcard_with_key tests/gateway/test_api_server_bind_guard.py::TestConnectBindGuard::test_refuses_ipv4_wildcard_without_key tests/gateway/test_api_server_bind_guard.py::TestConnectBindGuard::test_refuses_ipv6_wildcard_without_key tests/gateway/test_api_server_bind_guard.py::TestConnectBindGuard::test_refuses_loopback_without_key tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_dns_failure_fails_closed tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_hostname_mixed_resolution tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_hostname_resolving_to_non_loopback tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_ipv4_loopback tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_ipv4_mapped_loopback tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_ipv4_mapped_unspecified tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_ipv4_wildcard tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_ipv6_loopback tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_ipv6_wildcard tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_localhost_resolves_to_loopback tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_private_ipv4 tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_private_ipv4_class_c tests/gateway/test_api_server_bind_guard.py::TestIsNetworkAccessible::test_public_ipv4 tests/gateway/test_api_server_jobs.py::TestAuthRequired::test_auth_passes_with_valid_key tests/gateway/test_api_server_jobs.py::TestAuthRequired::test_auth_required_create_job tests/gateway/test_api_server_jobs.py::TestAuthRequired::test_auth_required_delete_job tests/gateway/test_api_server_jobs.py::TestAuthRequired::test_auth_required_get_job tests/gateway/test_api_server_jobs.py::TestAuthRequired::test_auth_required_list_jobs tests/gateway/test_api_server_jobs.py::TestCreateJob::test_create_job tests/gateway/test_api_server_jobs.py::TestCreateJob::test_create_job_invalid_repeat tests/gateway/test_api_server_jobs.py::TestCreateJob::test_create_job_missing_name tests/gateway/test_api_server_jobs.py::TestCreateJob::test_create_job_missing_schedule tests/gateway/test_api_server_jobs.py::TestCreateJob::test_create_job_name_too_long tests/gateway/test_api_server_jobs.py::TestCreateJob::test_create_job_prompt_too_long tests/gateway/test_api_server_jobs.py::TestCronPromptScanParity::test_create_job_allows_benign_prompt tests/gateway/test_api_server_jobs.py::TestCronPromptScanParity::test_create_job_rejects_malicious_prompt tests/gateway/test_api_server_jobs.py::TestCronPromptScanParity::test_update_job_allows_benign_prompt tests/gateway/test_api_server_jobs.py::TestCronPromptScanParity::test_update_job_rejects_malicious_prompt tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_cron_unavailable_create tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_cron_unavailable_delete tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_cron_unavailable_get tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_cron_unavailable_list tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_cron_unavailable_pause tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_cron_unavailable_resume tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_cron_unavailable_run tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_list_handler_no_self_binding tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_pause_handler_no_self_binding tests/gateway/test_api_server_jobs.py::TestCronUnavailable::test_update_handler_no_self_binding tests/gateway/test_api_server_jobs.py::TestDeleteJob::test_delete_job tests/gateway/test_api_server_jobs.py::TestDeleteJob::test_delete_job_not_found tests/gateway/test_api_server_jobs.py::TestGetJob::test_get_job tests/gateway/test_api_server_jobs.py::TestGetJob::test_get_job_invalid_id tests/gateway/test_api_server_jobs.py::TestGetJob::test_get_job_not_found tests/gateway/test_api_server_jobs.py::TestGetJob::test_invalid_job_id_logs_source_context tests/gateway/test_api_server_jobs.py::TestListJobs::test_list_jobs tests/gateway/test_api_server_jobs.py::TestListJobs::test_list_jobs_default_excludes_disabled tests/gateway/test_api_server_jobs.py::TestListJobs::test_list_jobs_include_disabled tests/gateway/test_api_server_jobs.py::TestPauseJob::test_pause_job tests/gateway/test_api_server_jobs.py::TestResumeJob::test_resume_job tests/gateway/test_api_server_jobs.py::TestRunJob::test_run_job tests/gateway/test_api_server_jobs.py::TestUpdateJob::test_update_job tests/gateway/test_api_server_jobs.py::TestUpdateJob::test_update_job_no_valid_fields tests/gateway/test_api_server_jobs.py::TestUpdateJob::test_update_job_rejects_unknown_fields tests/gateway/test_api_server_multimodal.py::TestChatCompletionsMultimodalHTTP::test_file_part_returns_400 tests/gateway/test_api_server_multimodal.py::TestChatCompletionsMultimodalHTTP::test_inline_image_preserved_to_run_agent tests/gateway/test_api_server_multimodal.py::TestChatCompletionsMultimodalHTTP::test_non_image_data_url_returns_400 tests/gateway/test_api_server_multimodal.py::TestChatCompletionsMultimodalHTTP::test_text_only_array_collapses_to_string tests/gateway/test_api_server_multimodal.py::TestContentHasVisiblePayload::test_list_with_image_only tests/gateway/test_api_server_multimodal.py::TestContentHasVisiblePayload::test_list_with_only_empty_text tests/gateway/test_api_server_multimodal.py::TestContentHasVisiblePayload::test_non_empty_string tests/gateway/test_api_server_multimodal.py::TestContentHasVisiblePayload::test_whitespace_only_string tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_bad_scheme_rejected tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_data_image_url_accepted tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_file_part_rejected tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_image_url_preserved_with_text tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_input_file_part_rejected tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_input_image_converted_to_canonical_shape tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_missing_url_rejected tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_non_image_data_url_rejected tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_none_returns_empty_string tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_responses_input_text_canonicalized tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_string_passthrough tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_text_only_list_collapses_to_string tests/gateway/test_api_server_multimodal.py::TestNormalizeMultimodalContent::test_unknown_part_type_rejected tests/gateway/test_api_server_multimodal.py::TestResponsesMultimodalHTTP::test_input_file_returns_400 tests/gateway/test_api_server_multimodal.py::TestResponsesMultimodalHTTP::test_input_image_canonicalized_and_forwarded tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_boolean_content_converted tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_deeply_nested_list_respects_depth_limit tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_dict_without_type_skipped tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_empty_list_returns_empty tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_empty_string_returned_as_is tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_empty_text_parts_filtered tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_image_url_parts_silently_skipped tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_input_text_content_part tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_integer_content_converted tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_large_list_capped tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_many_small_parts_normalize_without_quadratic_rescan tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_mixed_string_and_dict_parts tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_multiple_text_parts_joined_with_newline tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_none_returns_empty_string tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_output_text_content_part tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_oversized_string_truncated tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_plain_string_returned_as_is tests/gateway/test_api_server_normalize.py::TestNormalizeChatContent::test_text_content_part tests/gateway/test_api_server_runs.py::TestRunEvents::test_approval_response_without_pending_returns_409 tests/gateway/test_api_server_runs.py::TestRunEvents::test_approval_string_false_does_not_resolve_all tests/gateway/test_api_server_runs.py::TestRunEvents::test_events_not_found_returns_404 tests/gateway/test_api_server_runs.py::TestRunEvents::test_events_requires_auth tests/gateway/test_api_server_runs.py::TestRunEvents::test_events_stream_returns_completed tests/gateway/test_api_server_runs.py::TestRunStatus::test_status_completed_run_includes_output_and_usage tests/gateway/test_api_server_runs.py::TestRunStatus::test_status_not_found_returns_404 tests/gateway/test_api_server_runs.py::TestRunStatus::test_status_reflects_explicit_session_id tests/gateway/test_api_server_runs.py::TestRunStatus::test_status_requires_auth tests/gateway/test_api_server_runs.py::TestStartRun::test_start_empty_input_returns_400 tests/gateway/test_api_server_runs.py::TestStartRun::test_start_invalid_history_does_not_allocate_run tests/gateway/test_api_server_runs.py::TestStartRun::test_start_invalid_json_returns_400 tests/gateway/test_api_server_runs.py::TestStartRun::test_start_missing_input_returns_400 tests/gateway/test_api_server_runs.py::TestStartRun::test_start_requires_auth tests/gateway/test_api_server_runs.py::TestStartRun::test_start_returns_202 tests/gateway/test_api_server_runs.py::TestStartRun::test_start_with_valid_auth tests/gateway/test_api_server_runs.py::TestStopRun::test_stop_already_completed_run_returns_404 tests/gateway/test_api_server_runs.py::TestStopRun::test_stop_interrupt_exception_does_not_crash tests/gateway/test_api_server_runs.py::TestStopRun::test_stop_nonexistent_run_returns_404 tests/gateway/test_api_server_runs.py::TestStopRun::test_stop_requires_auth tests/gateway/test_api_server_runs.py::TestStopRun::test_stop_running_agent tests/gateway/test_api_server_runs.py::TestStopRun::test_stop_sends_sentinel_to_events_stream tests/gateway/test_api_server_toolset.py::TestApiServerAdapterToolset::test_create_agent_reads_config_toolsets tests/gateway/test_api_server_toolset.py::TestApiServerAdapterToolset::test_create_agent_respects_config_override tests/gateway/test_api_server_toolset.py::TestApiServerPlatformConfig::test_platforms_dict_includes_api_server tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_excludes_clarify tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_excludes_send_message tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_excludes_text_to_speech tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_exists tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_includes_browser_tools tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_includes_core_tools tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_includes_homeassistant_tools tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_includes_web_tools tests/gateway/test_api_server_toolset.py::TestHermesApiServerToolset::test_toolset_validates tests/gateway/test_approve_deny_commands.py::TestApproveCommand::test_approve_all_resolves_multiple tests/gateway/test_approve_deny_commands.py::TestApproveCommand::test_approve_all_session tests/gateway/test_approve_deny_commands.py::TestApproveCommand::test_approve_no_pending tests/gateway/test_approve_deny_commands.py::TestApproveCommand::test_approve_resolves_blocking_approval tests/gateway/test_approve_deny_commands.py::TestApproveCommand::test_approve_stale_old_style_pending tests/gateway/test_approve_deny_commands.py::TestBareTextNoLongerApproves::test_yes_does_not_execute_pending_command tests/gateway/test_approve_deny_commands.py::TestBlockingApprovalE2E::test_blocking_approval_approve_once tests/gateway/test_approve_deny_commands.py::TestBlockingApprovalE2E::test_blocking_approval_deny tests/gateway/test_approve_deny_commands.py::TestBlockingApprovalE2E::test_blocking_approval_timeout tests/gateway/test_approve_deny_commands.py::TestBlockingApprovalE2E::test_parallel_mixed_approve_deny tests/gateway/test_approve_deny_commands.py::TestBlockingApprovalE2E::test_parallel_subagent_approvals tests/gateway/test_approve_deny_commands.py::TestBlockingGatewayApproval::test_clear_session_denies_and_signals_all_entries tests/gateway/test_approve_deny_commands.py::TestBlockingGatewayApproval::test_register_and_resolve_unblocks_entry tests/gateway/test_approve_deny_commands.py::TestBlockingGatewayApproval::test_resolve_all_unblocks_multiple_entries tests/gateway/test_approve_deny_commands.py::TestBlockingGatewayApproval::test_resolve_returns_zero_when_no_pending tests/gateway/test_approve_deny_commands.py::TestBlockingGatewayApproval::test_resolve_single_pops_oldest_fifo tests/gateway/test_approve_deny_commands.py::TestBlockingGatewayApproval::test_unregister_signals_all_entries tests/gateway/test_approve_deny_commands.py::TestDenyCommand::test_deny_all_resolves_all tests/gateway/test_approve_deny_commands.py::TestDenyCommand::test_deny_no_pending tests/gateway/test_approve_deny_commands.py::TestDenyCommand::test_deny_resolves_blocking_approval tests/gateway/test_approve_deny_commands.py::TestFallbackNoCallback::test_no_callback_returns_approval_required tests/gateway/test_auth_fallback.py::TestResolveRuntimeAgentKwargsAuthFallback::test_auth_error_no_fallback_raises tests/gateway/test_auth_fallback.py::TestResolveRuntimeAgentKwargsAuthFallback::test_auth_error_tries_fallback tests/gateway/test_auth_fallback.py::TestResolveRuntimeAgentKwargsAuthFallback::test_legacy_fallback_is_appended_after_fallback_providers tests/gateway/test_auto_continue.py::TestAutoDetection::test_empty_history_no_note tests/gateway/test_auto_continue.py::TestAutoDetection::test_multiple_tool_results_still_triggers tests/gateway/test_auto_continue.py::TestAutoDetection::test_original_message_preserved_after_note tests/gateway/test_auto_continue.py::TestAutoDetection::test_trailing_assistant_message_no_note tests/gateway/test_auto_continue.py::TestAutoDetection::test_trailing_tool_result_triggers_note tests/gateway/test_auto_continue.py::TestAutoDetection::test_trailing_user_message_no_note tests/gateway/test_auto_continue.py::TestInterruptedReplayFiltering::test_dangling_tail_after_completed_pair_is_removed_only_at_tail tests/gateway/test_auto_continue.py::TestInterruptedReplayFiltering::test_dangling_unanswered_tool_call_tail_is_removed tests/gateway/test_auto_continue.py::TestInterruptedReplayFiltering::test_interrupted_tool_tail_is_removed_from_agent_history tests/gateway/test_auto_continue.py::TestInterruptedReplayFiltering::test_mixed_tail_with_one_interrupted_result_is_removed tests/gateway/test_auto_continue.py::TestInterruptedReplayFiltering::test_persisted_auto_continue_note_is_not_replayed tests/gateway/test_auto_continue.py::TestInterruptedReplayFiltering::test_successful_tool_tail_is_preserved tests/gateway/test_auto_voice_reply_format.py::TestAutoVoiceReplyFormat::test_non_telegram_auto_voice_reply_keeps_mp3_default tests/gateway/test_auto_voice_reply_format.py::TestAutoVoiceReplyFormat::test_telegram_auto_voice_reply_requests_ogg_for_native_voice_bubble tests/gateway/test_background_command.py::TestBackgroundInCLICommands::test_background_autocompletes tests/gateway/test_background_command.py::TestBackgroundInCLICommands::test_background_in_commands_dict tests/gateway/test_background_command.py::TestBackgroundInCLICommands::test_background_in_session_category tests/gateway/test_background_command.py::TestBackgroundInCLICommands::test_bg_alias_in_commands_dict tests/gateway/test_background_command.py::TestBackgroundInHelp::test_background_in_help_output tests/gateway/test_background_command.py::TestBackgroundInHelp::test_background_is_known_command tests/gateway/test_background_command.py::TestBackgroundInHelp::test_bg_alias_is_known_command tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_bg_alias_no_prompt_shows_usage tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_empty_prompt_shows_usage tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_no_prompt_shows_usage tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_prompt_truncated_in_preview tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_task_id_is_unique tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_telegram_dm_topic_passes_trigger_anchor_to_task tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_valid_prompt_starts_task tests/gateway/test_background_command.py::TestHandleBackgroundCommand::test_works_across_platforms tests/gateway/test_background_command.py::TestRunBackgroundTask::test_agent_cleanup_runs_when_background_agent_raises tests/gateway/test_background_command.py::TestRunBackgroundTask::test_exception_sends_error_message tests/gateway/test_background_command.py::TestRunBackgroundTask::test_media_files_routed_by_type tests/gateway/test_background_command.py::TestRunBackgroundTask::test_no_adapter_returns_silently tests/gateway/test_background_command.py::TestRunBackgroundTask::test_no_credentials_sends_error tests/gateway/test_background_command.py::TestRunBackgroundTask::test_successful_task_sends_result tests/gateway/test_background_command.py::TestRunBackgroundTask::test_telegram_dm_topic_completion_preserves_reply_anchor_metadata tests/gateway/test_background_process_notifications.py::TestLoadBackgroundNotificationsMode::test_defaults_to_all tests/gateway/test_background_process_notifications.py::TestLoadBackgroundNotificationsMode::test_env_var_overrides_config tests/gateway/test_background_process_notifications.py::TestLoadBackgroundNotificationsMode::test_false_value_maps_to_off tests/gateway/test_background_process_notifications.py::TestLoadBackgroundNotificationsMode::test_invalid_value_defaults_to_all tests/gateway/test_background_process_notifications.py::TestLoadBackgroundNotificationsMode::test_reads_config_yaml tests/gateway/test_background_process_notifications.py::test_agent_notification_carries_message_id_reply_anchor tests/gateway/test_background_process_notifications.py::test_agent_notification_no_message_id_is_tolerated tests/gateway/test_background_process_notifications.py::test_build_process_event_source_falls_back_to_session_key_chat_type tests/gateway/test_background_process_notifications.py::test_build_process_event_source_returns_none_for_empty_evt tests/gateway/test_background_process_notifications.py::test_build_process_event_source_returns_none_for_invalid_platform tests/gateway/test_background_process_notifications.py::test_build_process_event_source_returns_none_for_short_session_key tests/gateway/test_background_process_notifications.py::test_build_process_event_source_uses_cached_live_source_before_session_key_parse tests/gateway/test_background_process_notifications.py::test_inject_watch_notification_carries_message_id_reply_anchor tests/gateway/test_background_process_notifications.py::test_inject_watch_notification_ignores_foreground_event_source tests/gateway/test_background_process_notifications.py::test_inject_watch_notification_routes_from_session_store_origin tests/gateway/test_background_process_notifications.py::test_no_thread_id_sends_no_metadata tests/gateway/test_background_process_notifications.py::test_parse_session_key_dm_with_thread tests/gateway/test_background_process_notifications.py::test_parse_session_key_thread_chat_type tests/gateway/test_background_process_notifications.py::test_parse_session_key_too_short tests/gateway/test_background_process_notifications.py::test_parse_session_key_valid tests/gateway/test_background_process_notifications.py::test_parse_session_key_with_extra_parts tests/gateway/test_background_process_notifications.py::test_parse_session_key_with_user_id_part tests/gateway/test_background_process_notifications.py::test_parse_session_key_wrong_prefix tests/gateway/test_background_process_notifications.py::test_run_process_watcher_respects_notification_mode[all-sessions0-1-is still running] tests/gateway/test_background_process_notifications.py::test_run_process_watcher_respects_notification_mode[all-sessions6-1-finished with exit code 0] tests/gateway/test_background_process_notifications.py::test_run_process_watcher_respects_notification_mode[error-sessions4-0-None] tests/gateway/test_background_process_notifications.py::test_run_process_watcher_respects_notification_mode[error-sessions5-1-finished with exit code 1] tests/gateway/test_background_process_notifications.py::test_run_process_watcher_respects_notification_mode[off-sessions2-0-None] tests/gateway/test_background_process_notifications.py::test_run_process_watcher_respects_notification_mode[result-sessions1-0-None] tests/gateway/test_background_process_notifications.py::test_run_process_watcher_respects_notification_mode[result-sessions3-1-finished with exit code 0] tests/gateway/test_background_process_notifications.py::test_thread_id_passed_to_send tests/gateway/test_base_topic_sessions.py::TestBasePlatformTopicSessions::test_cancel_background_tasks_marks_expected_cancellation_cancelled tests/gateway/test_base_topic_sessions.py::TestBasePlatformTopicSessions::test_handle_message_does_not_interrupt_different_topic tests/gateway/test_base_topic_sessions.py::TestBasePlatformTopicSessions::test_handle_message_interrupts_same_topic tests/gateway/test_base_topic_sessions.py::TestBasePlatformTopicSessions::test_process_message_background_marks_cancellation_unsuccessful tests/gateway/test_base_topic_sessions.py::TestBasePlatformTopicSessions::test_process_message_background_marks_exception_unsuccessful tests/gateway/test_base_topic_sessions.py::TestBasePlatformTopicSessions::test_process_message_background_marks_total_send_failure_unsuccessful tests/gateway/test_base_topic_sessions.py::TestBasePlatformTopicSessions::test_process_message_background_replies_in_same_topic tests/gateway/test_base_topic_sessions.py::TestTelegramAutoTtsCaptionDelivery::test_long_telegram_auto_tts_keeps_followup_text_when_caption_would_truncate tests/gateway/test_base_topic_sessions.py::TestTelegramAutoTtsCaptionDelivery::test_short_telegram_auto_tts_uses_caption_without_followup_text tests/gateway/test_base_topic_sessions.py::TestTelegramAutoTtsCaptionDelivery::test_telegram_auto_tts_send_failure_keeps_followup_text tests/gateway/test_bluebubbles.py::TestBlueBubblesAttachmentDownload::test_download_audio_uses_audio_cache tests/gateway/test_bluebubbles.py::TestBlueBubblesAttachmentDownload::test_download_document_uses_document_cache tests/gateway/test_bluebubbles.py::TestBlueBubblesAttachmentDownload::test_download_image_uses_image_cache tests/gateway/test_bluebubbles.py::TestBlueBubblesAttachmentDownload::test_download_returns_none_without_client tests/gateway/test_bluebubbles.py::TestBlueBubblesConfigLoading::test_apply_env_overrides_bluebubbles tests/gateway/test_bluebubbles.py::TestBlueBubblesConfigLoading::test_home_channel_set_from_env tests/gateway/test_bluebubbles.py::TestBlueBubblesConfigLoading::test_not_connected_without_password tests/gateway/test_bluebubbles.py::TestBlueBubblesGuidResolution::test_empty_target_returns_none tests/gateway/test_bluebubbles.py::TestBlueBubblesGuidResolution::test_raw_guid_returned_as_is tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_check_requirements tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_clean_mention_text_strips_leading_wake_word tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_custom_mention_patterns_override_defaults tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_default_mention_patterns_match_hermes_variants tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_format_message_preserves_underscores_in_identifiers tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_format_message_strips_markdown tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_init_normalizes_webhook_path tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_init_preserves_leading_slash tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_send_splits_paragraphs_into_multiple_bubbles tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_server_url_adds_scheme tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_server_url_normalized tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_strip_markdown_headers tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_strip_markdown_links tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_supports_message_editing_is_false tests/gateway/test_bluebubbles.py::TestBlueBubblesHelpers::test_truncate_message_omits_pagination_suffixes tests/gateway/test_bluebubbles.py::TestBlueBubblesMentionGating::test_dm_message_does_not_require_mention tests/gateway/test_bluebubbles.py::TestBlueBubblesMentionGating::test_group_message_with_default_mention_is_dispatched_cleaned tests/gateway/test_bluebubbles.py::TestBlueBubblesMentionGating::test_group_message_without_mention_is_acknowledged_and_skipped tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookParsing::test_extract_payload_record_accepts_list_data tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookParsing::test_extract_payload_record_dict_data tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookParsing::test_extract_payload_record_fallback_to_message tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookParsing::test_webhook_can_fall_back_to_sender_when_chat_fields_missing tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookParsing::test_webhook_extracts_chat_guid_from_chats_array_dm tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookParsing::test_webhook_extracts_chat_guid_from_chats_array_group tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookParsing::test_webhook_prefers_chat_guid_over_message_guid tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_find_registered_webhooks_empty_when_none tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_find_registered_webhooks_handles_api_error tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_find_registered_webhooks_returns_matches tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_register_accepts_201 tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_register_fresh tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_register_returns_false_on_server_error tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_register_returns_false_without_client tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_register_reuses_existing tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_unregister_handles_api_failure_gracefully tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_unregister_removes_all_duplicates tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_unregister_removes_matching tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookRegistration::test_unregister_returns_false_without_client tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_custom_host_preserved tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_default_host tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_local_hosts_normalized[0.0.0.0] tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_local_hosts_normalized[127.0.0.1] tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_local_hosts_normalized[::] tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_local_hosts_normalized[localhost] tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_register_url_embeds_password tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_register_url_for_log_masks_password tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_register_url_omits_query_when_no_password tests/gateway/test_bluebubbles.py::TestBlueBubblesWebhookUrl::test_register_url_url_encodes_password tests/gateway/test_bundles_command.py::TestBundleResolutionPriority::test_bundle_resolves tests/gateway/test_bundles_command.py::TestBundleResolutionPriority::test_underscore_alias tests/gateway/test_bundles_command.py::TestHandleBundlesCommand::test_empty tests/gateway/test_bundles_command.py::TestHandleBundlesCommand::test_with_bundles tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_ack_after_cooldown_expires tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_busy_text_mode_queue_delegates_to_adapter_handle_message tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_debounce_suppresses_rapid_acks tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_draining_still_works tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_handle_message_queue_mode_queues_without_interrupt tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_includes_status_detail_when_opted_in tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_no_adapter_falls_through tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_pending_sentinel_no_interrupt tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_queue_mode_suppresses_interrupt_and_updates_ack tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_sends_ack_when_agent_running tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_steer_mode_calls_agent_steer_no_interrupt_no_queue tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_steer_mode_falls_back_to_queue_when_agent_pending tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_steer_mode_falls_back_to_queue_when_agent_rejects tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_telegram_grace_followups_respect_queue_fifo tests/gateway/test_busy_session_ack.py::TestBusySessionAck::test_telegram_omits_status_detail_by_default tests/gateway/test_busy_session_ack.py::TestBusySessionOnboardingHint::test_first_busy_ack_appends_interrupt_hint tests/gateway/test_busy_session_ack.py::TestBusySessionOnboardingHint::test_queue_mode_hint_points_to_interrupt tests/gateway/test_busy_session_ack.py::TestBusySessionOnboardingHint::test_second_busy_ack_omits_hint tests/gateway/test_busy_session_auth_bypass.py::TestBusySessionAuthBypass::test_authorized_user_still_processed_in_busy_path tests/gateway/test_busy_session_auth_bypass.py::TestBusySessionAuthBypass::test_unauthorized_user_cannot_steer_active_agent tests/gateway/test_busy_session_auth_bypass.py::TestBusySessionAuthBypass::test_unauthorized_user_dropped_in_busy_path tests/gateway/test_busy_session_auth_bypass.py::TestBusySessionAuthBypass::test_unauthorized_user_during_drain_still_blocked tests/gateway/test_cached_agent_max_iterations.py::test_init_cached_agent_for_turn_does_not_touch_max_iterations tests/gateway/test_cached_agent_max_iterations.py::test_init_cached_agent_preserves_max_iterations_on_interrupt_depth tests/gateway/test_cached_agent_max_iterations.py::test_refreshed_max_iterations_propagates_to_turn_budget tests/gateway/test_cancel_background_drain.py::test_cancel_background_tasks_bounded_rounds tests/gateway/test_cancel_background_drain.py::test_cancel_background_tasks_drains_late_arrivals tests/gateway/test_cancel_background_drain.py::test_cancel_background_tasks_handles_no_tasks tests/gateway/test_channel_directory.py::TestBuildChannelDirectoryWrites::test_failed_write_preserves_previous_cache tests/gateway/test_channel_directory.py::TestBuildFromSessions::test_builds_from_sessions_json tests/gateway/test_channel_directory.py::TestBuildFromSessions::test_deduplication_by_chat_id tests/gateway/test_channel_directory.py::TestBuildFromSessions::test_keeps_distinct_topics_with_same_chat_id tests/gateway/test_channel_directory.py::TestBuildFromSessions::test_missing_sessions_file tests/gateway/test_channel_directory.py::TestBuildSlack::test_lists_channels_from_users_conversations tests/gateway/test_channel_directory.py::TestBuildSlack::test_no_team_clients_falls_back_to_sessions tests/gateway/test_channel_directory.py::TestBuildSlack::test_paginates_via_response_metadata_cursor tests/gateway/test_channel_directory.py::TestBuildSlack::test_per_workspace_error_does_not_block_others tests/gateway/test_channel_directory.py::TestBuildSlack::test_response_not_ok_breaks_pagination_for_that_workspace tests/gateway/test_channel_directory.py::TestBuildSlack::test_session_dms_merged_when_not_in_api_results tests/gateway/test_channel_directory.py::TestBuildSlack::test_skips_channels_with_no_id_or_name tests/gateway/test_channel_directory.py::TestChannelAliases::test_alias_injects_undiscovered_group tests/gateway/test_channel_directory.py::TestChannelAliases::test_alias_persists_through_rebuild tests/gateway/test_channel_directory.py::TestChannelAliases::test_alias_renames_existing_entry_on_load tests/gateway/test_channel_directory.py::TestChannelAliases::test_apply_aliases_handles_malformed_map tests/gateway/test_channel_directory.py::TestChannelAliases::test_corrupt_alias_file_is_ignored tests/gateway/test_channel_directory.py::TestChannelAliases::test_no_alias_file_is_noop tests/gateway/test_channel_directory.py::TestFormatDirectoryForDisplay::test_discord_grouped_by_guild tests/gateway/test_channel_directory.py::TestFormatDirectoryForDisplay::test_empty_directory tests/gateway/test_channel_directory.py::TestFormatDirectoryForDisplay::test_telegram_display tests/gateway/test_channel_directory.py::TestLoadDirectory::test_corrupt_file tests/gateway/test_channel_directory.py::TestLoadDirectory::test_missing_file tests/gateway/test_channel_directory.py::TestLoadDirectory::test_valid_file tests/gateway/test_channel_directory.py::TestLookupChannelType::test_channel_without_type_key_returns_none tests/gateway/test_channel_directory.py::TestLookupChannelType::test_forum_channel tests/gateway/test_channel_directory.py::TestLookupChannelType::test_regular_channel tests/gateway/test_channel_directory.py::TestLookupChannelType::test_unknown_chat_id_returns_none tests/gateway/test_channel_directory.py::TestLookupChannelType::test_unknown_platform_returns_none tests/gateway/test_channel_directory.py::TestResolveChannelName::test_case_insensitive tests/gateway/test_channel_directory.py::TestResolveChannelName::test_display_label_with_type_suffix_resolves tests/gateway/test_channel_directory.py::TestResolveChannelName::test_exact_match tests/gateway/test_channel_directory.py::TestResolveChannelName::test_guild_qualified_match tests/gateway/test_channel_directory.py::TestResolveChannelName::test_id_match_takes_precedence_over_name tests/gateway/test_channel_directory.py::TestResolveChannelName::test_no_channels_returns_none tests/gateway/test_channel_directory.py::TestResolveChannelName::test_no_match_returns_none tests/gateway/test_channel_directory.py::TestResolveChannelName::test_prefix_match_ambiguous_returns_none tests/gateway/test_channel_directory.py::TestResolveChannelName::test_prefix_match_unambiguous tests/gateway/test_channel_directory.py::TestResolveChannelName::test_topic_name_resolves_to_composite_id tests/gateway/test_clean_shutdown_marker.py::TestCleanShutdownMarker::test_marker_skips_suspension_on_startup tests/gateway/test_clean_shutdown_marker.py::TestCleanShutdownMarker::test_marker_written_on_graceful_stop tests/gateway/test_clean_shutdown_marker.py::TestCleanShutdownMarker::test_marker_written_on_restart_stop tests/gateway/test_clean_shutdown_marker.py::TestCleanShutdownMarker::test_no_marker_triggers_suspension tests/gateway/test_clean_shutdown_marker.py::TestSuspendRecentlyActive::test_already_resume_pending_not_double_counted tests/gateway/test_clean_shutdown_marker.py::TestSuspendRecentlyActive::test_does_not_suspend_old_sessions tests/gateway/test_clean_shutdown_marker.py::TestSuspendRecentlyActive::test_suspends_recently_active_sessions tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/compress-compress] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/insights 7-insights] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/model claude-sonnet-4-model] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/model-model] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/personality default-personality] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/reasoning high-reasoning] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/reload-mcp-reload-mcp] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/resume yesterday-resume] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/retry-retry] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/sethome-sethome] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/title my session-title] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/undo-undo] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/usage-usage] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_command_bypasses_guard[/voice on-voice] tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_should_bypass_returns_false_for_unknown tests/gateway/test_command_bypass_active_session.py::TestAllResolvableCommandsBypassGuard::test_should_bypass_returns_true_for_every_registered_command tests/gateway/test_command_bypass_active_session.py::TestBypassWithBotnameSuffix::test_new_with_botname tests/gateway/test_command_bypass_active_session.py::TestBypassWithBotnameSuffix::test_stop_with_botname tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_agents_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_approve_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_background_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_deny_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_help_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_new_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_queue_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_reset_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_status_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_steer_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_stop_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_tasks_alias_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestCommandBypassActiveSession::test_update_bypasses_guard tests/gateway/test_command_bypass_active_session.py::TestNoActiveSessionNormalDispatch::test_stop_when_no_session_active tests/gateway/test_command_bypass_active_session.py::TestNonBypassStillQueued::test_file_path_not_treated_as_command tests/gateway/test_command_bypass_active_session.py::TestNonBypassStillQueued::test_regular_text_queued tests/gateway/test_command_bypass_active_session.py::TestNonBypassStillQueued::test_unknown_command_queued tests/gateway/test_command_bypass_active_session.py::TestPendingCommandSafetyNet::test_file_path_not_detected_as_command tests/gateway/test_command_bypass_active_session.py::TestPendingCommandSafetyNet::test_new_command_detected tests/gateway/test_command_bypass_active_session.py::TestPendingCommandSafetyNet::test_reset_alias_detected tests/gateway/test_command_bypass_active_session.py::TestPendingCommandSafetyNet::test_stop_command_detected tests/gateway/test_command_bypass_active_session.py::TestPendingCommandSafetyNet::test_unknown_command_not_detected tests/gateway/test_complete_path_at_filter.py::test_at_file_bare_without_colon_lists_files tests/gateway/test_complete_path_at_filter.py::test_at_file_colon_only_files tests/gateway/test_complete_path_at_filter.py::test_at_folder_bare_without_colon_lists_dirs tests/gateway/test_complete_path_at_filter.py::test_at_folder_colon_only_dirs tests/gateway/test_complete_path_at_filter.py::test_bare_at_still_shows_static_refs tests/gateway/test_complete_path_at_filter.py::test_fuzzy_at_file_prefix_preserved tests/gateway/test_complete_path_at_filter.py::test_fuzzy_at_finds_file_without_directory_prefix tests/gateway/test_complete_path_at_filter.py::test_fuzzy_camelcase_word_boundary tests/gateway/test_complete_path_at_filter.py::test_fuzzy_caps_results tests/gateway/test_complete_path_at_filter.py::test_fuzzy_hides_dotfiles_unless_asked tests/gateway/test_complete_path_at_filter.py::test_fuzzy_paths_relative_to_cwd_inside_subdir tests/gateway/test_complete_path_at_filter.py::test_fuzzy_ranks_exact_before_prefix_before_subseq tests/gateway/test_complete_path_at_filter.py::test_fuzzy_skipped_when_folder_tag tests/gateway/test_complete_path_at_filter.py::test_fuzzy_skipped_when_path_has_slash tests/gateway/test_complete_path_at_filter.py::test_fuzzy_subsequence_catches_sparse_queries tests/gateway/test_compress_command.py::test_compress_command_appends_warning_when_compression_aborts tests/gateway/test_compress_command.py::test_compress_command_explains_when_token_estimate_rises tests/gateway/test_compress_command.py::test_compress_command_reports_noop_without_success_banner tests/gateway/test_compress_command.py::test_compress_command_surfaces_aux_model_failure_even_when_recovered tests/gateway/test_compress_focus.py::test_compress_focus_topic_passed_to_agent tests/gateway/test_compress_focus.py::test_compress_no_focus_passes_none tests/gateway/test_compress_plugin_engine.py::test_compress_respects_plugin_has_content_to_compress_false tests/gateway/test_compress_plugin_engine.py::test_compress_works_with_plugin_context_engine tests/gateway/test_compression_concurrent_sessions.py::test_concurrent_compressions_do_not_alias_sessions tests/gateway/test_compression_concurrent_sessions.py::test_concurrent_compressions_same_session_serialize tests/gateway/test_compression_failure_session_sync.py::test_failed_turn_still_syncs_compression_session_split tests/gateway/test_compression_session_id_persistence.py::TestCompressionSessionPropagation::test_contextvar_and_session_entry_agree_after_compression tests/gateway/test_compression_session_id_persistence.py::TestCompressionSessionPropagation::test_gateway_session_entry_follows_compression_rotation tests/gateway/test_compression_session_id_persistence.py::TestCompressionSessionPropagation::test_no_update_when_session_id_unchanged tests/gateway/test_compression_session_id_persistence.py::test_every_post_compression_session_id_assignment_persists tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_from_dict_coerces_quoted_false_always_log_local tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_full_roundtrip tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_get_notice_delivery_defaults_to_public tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_get_notice_delivery_honors_platform_override tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_max_concurrent_sessions_from_dict_accepts_nested_fallback tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_max_concurrent_sessions_from_dict_accepts_positive_integer tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_max_concurrent_sessions_from_dict_ignores_invalid_values tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_max_concurrent_sessions_from_dict_normalizes_disabled_values tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_max_concurrent_sessions_top_level_overrides_nested tests/gateway/test_config.py::TestGatewayConfigRoundtrip::test_roundtrip_preserves_unauthorized_dm_behavior tests/gateway/test_config.py::TestGetConnectedPlatforms::test_dingtalk_disabled_not_connected tests/gateway/test_config.py::TestGetConnectedPlatforms::test_dingtalk_missing_creds_not_connected tests/gateway/test_config.py::TestGetConnectedPlatforms::test_dingtalk_recognised_via_env_vars tests/gateway/test_config.py::TestGetConnectedPlatforms::test_dingtalk_recognised_via_extras tests/gateway/test_config.py::TestGetConnectedPlatforms::test_empty_platforms tests/gateway/test_config.py::TestGetConnectedPlatforms::test_returns_enabled_with_token tests/gateway/test_config.py::TestHomeChannelEnvOverrides::test_existing_platform_configs_accept_home_channel_env_overrides tests/gateway/test_config.py::TestHomeChannelRoundtrip::test_to_dict_from_dict tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_discord_allow_from_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_discord_channel_prompts_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_discord_history_backfill_settings_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_discord_platform_extra_allow_from_to_env tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_discord_thread_require_mention_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_feishu_allow_bots_from_config_yaml_to_env tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_group_sessions_per_user_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_nested_gateway_platforms_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_nested_max_concurrent_sessions_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_notice_delivery_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_quick_commands_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_quoted_false_always_log_local_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_quoted_false_platform_enabled_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_quoted_false_session_notify_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_slack_channel_prompts_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_telegram_channel_prompts_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_telegram_disable_link_previews_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_telegram_extra_base_url_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_telegram_proxy_url_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_thread_sessions_per_user_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_top_level_max_concurrent_sessions_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_bridges_unauthorized_dm_behavior_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_feishu_allow_bots_env_takes_precedence_over_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_invalid_quick_commands_in_config_yaml_are_ignored tests/gateway/test_config.py::TestLoadGatewayConfig::test_load_config_default_enables_telegram_rich_messages tests/gateway/test_config.py::TestLoadGatewayConfig::test_loads_telegram_rich_messages_from_gateway_platform_extra tests/gateway/test_config.py::TestLoadGatewayConfig::test_relay_platform_absent_when_url_unset tests/gateway/test_config.py::TestLoadGatewayConfig::test_relay_platform_enabled_from_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_relay_platform_enabled_from_env_url tests/gateway/test_config.py::TestLoadGatewayConfig::test_shared_key_loop_bridges_allow_from_from_nested_gateway_platforms tests/gateway/test_config.py::TestLoadGatewayConfig::test_shared_key_loop_bridges_allow_from_from_nested_platforms tests/gateway/test_config.py::TestLoadGatewayConfig::test_telegram_proxy_env_takes_precedence_over_config tests/gateway/test_config.py::TestLoadGatewayConfig::test_thread_require_mention_yaml_does_not_overwrite_env tests/gateway/test_config.py::TestLoadGatewayConfig::test_thread_sessions_per_user_defaults_to_false tests/gateway/test_config.py::TestLoadGatewayConfig::test_top_level_max_concurrent_sessions_overrides_nested_config_yaml tests/gateway/test_config.py::TestLoadGatewayConfig::test_top_level_platforms_override_nested_gateway_platforms tests/gateway/test_config.py::TestPlatformConfigRoundtrip::test_disabled_no_token tests/gateway/test_config.py::TestPlatformConfigRoundtrip::test_from_dict_coerces_quoted_false_enabled tests/gateway/test_config.py::TestPlatformConfigRoundtrip::test_gateway_restart_notification_coerces_quoted_false tests/gateway/test_config.py::TestPlatformConfigRoundtrip::test_gateway_restart_notification_defaults_true tests/gateway/test_config.py::TestPlatformConfigRoundtrip::test_gateway_restart_notification_roundtrip_false tests/gateway/test_config.py::TestPlatformConfigRoundtrip::test_to_dict_from_dict tests/gateway/test_config.py::TestSessionResetPolicy::test_defaults tests/gateway/test_config.py::TestSessionResetPolicy::test_from_dict_coerces_quoted_false_notify tests/gateway/test_config.py::TestSessionResetPolicy::test_from_dict_treats_null_values_as_defaults tests/gateway/test_config.py::TestSessionResetPolicy::test_roundtrip tests/gateway/test_config.py::TestStreamingConfig::test_defaults_to_auto_transport tests/gateway/test_config.py::TestStreamingConfig::test_from_dict_coerces_quoted_false_enabled tests/gateway/test_config.py::TestStreamingConfig::test_from_dict_malformed_numeric_values_fall_back_to_defaults tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_non_cwd_terminal_keys_still_bridge tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_terminal_auto_cwd_does_not_clobber_env tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_terminal_cwd_keyword_does_not_clobber_env tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_terminal_dot_cwd_and_messaging_cwd_both_set tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_terminal_dot_cwd_does_not_clobber_env tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_terminal_dot_cwd_falls_back_to_messaging_cwd tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_terminal_explicit_cwd_does_override tests/gateway/test_config_cwd_bridge.py::TestNestedTerminalCwdPlaceholderSkip::test_terminal_home_mode_bridges_to_env tests/gateway/test_config_cwd_bridge.py::TestTildeExpansion::test_terminal_cwd_tilde_expanded tests/gateway/test_config_cwd_bridge.py::TestTildeExpansion::test_tilde_with_nested_precedence tests/gateway/test_config_cwd_bridge.py::TestTildeExpansion::test_top_level_cwd_tilde_expanded tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_auto_cwd_triggers_messaging_fallback tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_dot_cwd_triggers_messaging_fallback tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_empty_cwd_ignored tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_messaging_cwd_env_var_works tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_nested_terminal_backend_takes_precedence tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_nested_terminal_takes_precedence_over_top_level tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_no_cwd_falls_back_to_messaging_cwd tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_no_cwd_no_messaging_cwd_falls_back_to_home tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_top_level_backend_sets_terminal_env tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_top_level_cwd_and_backend tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_top_level_cwd_beats_messaging_cwd tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_top_level_cwd_sets_terminal_cwd tests/gateway/test_config_cwd_bridge.py::TestTopLevelCwdAlias::test_whitespace_only_cwd_ignored tests/gateway/test_config_driven_access_policy.py::test_base_adapter_defaults_to_not_owning_access_policy tests/gateway/test_config_driven_access_policy.py::test_env_allowlist_still_takes_precedence_for_own_policy_platform tests/gateway/test_config_driven_access_policy.py::test_non_owning_platform_still_default_denies tests/gateway/test_config_driven_access_policy.py::test_own_policy_adapters_declare_the_flag[gateway.platforms.qqbot.adapter-QQAdapter] tests/gateway/test_config_driven_access_policy.py::test_own_policy_adapters_declare_the_flag[gateway.platforms.wecom-WeComAdapter] tests/gateway/test_config_driven_access_policy.py::test_own_policy_adapters_declare_the_flag[gateway.platforms.weixin-WeixinAdapter] tests/gateway/test_config_driven_access_policy.py::test_own_policy_adapters_declare_the_flag[gateway.platforms.whatsapp-WhatsAppAdapter] tests/gateway/test_config_driven_access_policy.py::test_own_policy_adapters_declare_the_flag[gateway.platforms.yuanbao-YuanbaoAdapter] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_for_group_chat[Platform.QQBOT] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_for_group_chat[Platform.WECOM] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_for_group_chat[Platform.WEIXIN] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_for_group_chat[Platform.WHATSAPP] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_for_group_chat[Platform.YUANBAO] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_without_env_allowlist[Platform.QQBOT] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_without_env_allowlist[Platform.WECOM] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_without_env_allowlist[Platform.WEIXIN] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_without_env_allowlist[Platform.WHATSAPP] tests/gateway/test_config_driven_access_policy.py::test_own_policy_allowlist_authorized_without_env_allowlist[Platform.YUANBAO] tests/gateway/test_config_driven_access_policy.py::test_own_policy_default_open_dm_is_fail_closed[Platform.QQBOT] tests/gateway/test_config_driven_access_policy.py::test_own_policy_default_open_dm_is_fail_closed[Platform.WECOM] tests/gateway/test_config_driven_access_policy.py::test_own_policy_default_open_dm_is_fail_closed[Platform.WEIXIN] tests/gateway/test_config_driven_access_policy.py::test_own_policy_default_open_dm_is_fail_closed[Platform.WHATSAPP] tests/gateway/test_config_driven_access_policy.py::test_own_policy_default_open_dm_is_fail_closed[Platform.YUANBAO] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_dm_not_authorized_without_allowlist[Platform.QQBOT] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_dm_not_authorized_without_allowlist[Platform.WECOM] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_dm_not_authorized_without_allowlist[Platform.WEIXIN] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_dm_not_authorized_without_allowlist[Platform.WHATSAPP] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_dm_not_authorized_without_allowlist[Platform.YUANBAO] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_group_not_authorized_without_allowlist[Platform.QQBOT] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_group_not_authorized_without_allowlist[Platform.WECOM] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_group_not_authorized_without_allowlist[Platform.WEIXIN] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_group_not_authorized_without_allowlist[Platform.WHATSAPP] tests/gateway/test_config_driven_access_policy.py::test_own_policy_open_group_not_authorized_without_allowlist[Platform.YUANBAO] tests/gateway/test_config_driven_access_policy.py::test_pairing_carveout_reads_adapter_when_env_set tests/gateway/test_config_driven_access_policy.py::test_pairing_dm_policy_authorizes_paired_user tests/gateway/test_config_driven_access_policy.py::test_pairing_dm_policy_group_chat_still_trusted tests/gateway/test_config_driven_access_policy.py::test_pairing_dm_policy_not_blanket_authorized[Platform.WECOM] tests/gateway/test_config_driven_access_policy.py::test_pairing_dm_policy_not_blanket_authorized[Platform.WEIXIN] tests/gateway/test_config_driven_access_policy.py::test_unauthorized_dm_behavior_follows_config_dm_policy[allowlist-ignore] tests/gateway/test_config_driven_access_policy.py::test_unauthorized_dm_behavior_follows_config_dm_policy[disabled-ignore] tests/gateway/test_config_driven_access_policy.py::test_unauthorized_dm_behavior_follows_config_dm_policy[pairing-pair] tests/gateway/test_config_driven_access_policy.py::test_unauthorized_dm_behavior_open_policy_keeps_default tests/gateway/test_config_driven_access_policy.py::test_unknown_adapter_does_not_crash_trust_check tests/gateway/test_config_driven_access_policy.py::test_wecom_open_group_with_per_group_sender_allowlist_is_authorized tests/gateway/test_config_driven_access_policy.py::test_wecom_open_group_with_wildcard_sender_allowlist_is_authorized tests/gateway/test_config_env_bridge_authority.py::test_config_display_busy_input_mode_wins_over_stale_env tests/gateway/test_config_env_bridge_authority.py::test_config_display_busy_text_mode_wins_over_stale_env tests/gateway/test_config_env_bridge_authority.py::test_config_gateway_timeout_wins_over_stale_env tests/gateway/test_config_env_bridge_authority.py::test_config_max_turns_wins_over_stale_env tests/gateway/test_config_env_bridge_authority.py::test_config_timezone_wins_over_stale_env tests/gateway/test_config_env_bridge_authority.py::test_env_value_survives_when_config_omits_key tests/gateway/test_cron_fire_webhook.py::test_fire_does_not_require_api_server_key tests/gateway/test_cron_fire_webhook.py::test_invalid_token_401_and_no_fire tests/gateway/test_cron_fire_webhook.py::test_missing_job_id_400 tests/gateway/test_cron_fire_webhook.py::test_missing_token_401 tests/gateway/test_cron_fire_webhook.py::test_valid_token_accepts_and_fires tests/gateway/test_debug_command.py::TestHandleDebugCommand::test_debug_survives_sweep_failure tests/gateway/test_debug_command.py::TestHandleDebugCommand::test_debug_sweeps_expired_pastes_before_upload tests/gateway/test_delivery.py::TestCaseSensitiveChatIdParsing::test_matrix_room_id_preserved tests/gateway/test_delivery.py::TestCaseSensitiveChatIdParsing::test_mixed_case_chat_id_roundtrip tests/gateway/test_delivery.py::TestCaseSensitiveChatIdParsing::test_slack_chat_id_with_thread_preserved tests/gateway/test_delivery.py::TestCaseSensitiveChatIdParsing::test_slack_uppercase_chat_id_preserved tests/gateway/test_delivery.py::TestParseTargetPlatformChat::test_explicit_telegram_chat tests/gateway/test_delivery.py::TestParseTargetPlatformChat::test_local_target tests/gateway/test_delivery.py::TestParseTargetPlatformChat::test_origin_with_source tests/gateway/test_delivery.py::TestParseTargetPlatformChat::test_origin_without_source tests/gateway/test_delivery.py::TestParseTargetPlatformChat::test_platform_only_no_chat_id tests/gateway/test_delivery.py::TestParseTargetPlatformChat::test_unknown_platform tests/gateway/test_delivery.py::TestPlatformNameCaseInsensitivity::test_mixed_case_platform_name tests/gateway/test_delivery.py::TestPlatformNameCaseInsensitivity::test_uppercase_platform_name tests/gateway/test_delivery.py::TestTargetToStringRoundtrip::test_explicit_chat_roundtrip tests/gateway/test_delivery.py::TestTargetToStringRoundtrip::test_local_roundtrip tests/gateway/test_delivery.py::TestTargetToStringRoundtrip::test_origin_roundtrip tests/gateway/test_delivery.py::TestTargetToStringRoundtrip::test_platform_only_roundtrip tests/gateway/test_delivery.py::test_explicit_telegram_direct_messages_topic_metadata_is_respected tests/gateway/test_delivery.py::test_explicit_telegram_group_thread_does_not_mark_dm_fallback tests/gateway/test_delivery.py::test_explicit_telegram_private_thread_requires_reply_anchor tests/gateway/test_delivery.py::test_explicit_telegram_private_thread_uses_reply_fallback_with_anchor tests/gateway/test_delivery.py::test_named_telegram_private_topic_is_created_before_delivery tests/gateway/test_delivery.py::test_named_telegram_private_topic_refreshes_stale_thread_id tests/gateway/test_delivery.py::test_platform_send_failure_raises_for_delivery_result tests/gateway/test_delivery_silence_filter.py::test_config_flag_defaults_true tests/gateway/test_delivery_silence_filter.py::test_config_from_dict_parses_flag tests/gateway/test_delivery_silence_filter.py::test_config_opt_out_lets_silence_through tests/gateway/test_delivery_silence_filter.py::test_config_to_dict_roundtrip tests/gateway/test_delivery_silence_filter.py::test_env_override_disables_filter tests/gateway/test_delivery_silence_filter.py::test_env_override_enables_filter_over_config tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[ ] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[Here is the result:\n\n- item one\n- item two] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[I have nothing to add, but here is why: the build is green.] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[Silence is golden \u2014 here is the plan...] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[Silent install completed] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[The deployment ran silently in the background] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[\U0001f44d] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[no responses were collected from the survey] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[ok] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[silent xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_negative[silently] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_none_safe tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[ *(silent)* ] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[(silent)] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[*(silent)*] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[*Silence.*] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[...] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[.] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[No Reply.] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[Silence] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[\U0001f507] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[\u2026] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[_silent_] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[`silent`] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[no response] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[silent] tests/gateway/test_delivery_silence_filter.py::test_is_silence_narration_positive[~silent~] tests/gateway/test_delivery_silence_filter.py::test_length_guard_rejects_long_strings tests/gateway/test_delivery_silence_filter.py::test_local_delivery_not_filtered tests/gateway/test_delivery_silence_filter.py::test_real_message_is_delivered tests/gateway/test_delivery_silence_filter.py::test_silence_narration_dropped_pre_send tests/gateway/test_destructive_slash_confirm.py::test_gate_off_runs_execute_immediately tests/gateway/test_destructive_slash_confirm.py::test_gate_on_pending_confirm_registered tests/gateway/test_destructive_slash_confirm.py::test_gate_on_text_fallback_returns_prompt_without_executing tests/gateway/test_destructive_slash_confirm.py::test_resolve_always_persists_opt_out_and_runs_execute tests/gateway/test_destructive_slash_confirm.py::test_resolve_cancel_does_not_run_execute tests/gateway/test_destructive_slash_confirm.py::test_resolve_once_runs_execute_and_returns_result tests/gateway/test_diagnostic_isolation.py::test_activated_coordinator_constructor_is_sealed_before_inputs tests/gateway/test_diagnostic_isolation.py::test_activation_derives_customer_and_trainer_routes_from_registered_runtime tests/gateway/test_diagnostic_isolation.py::test_activation_pin_body_destination_mutation_after_activation_has_zero_provider_and_rows[body] tests/gateway/test_diagnostic_isolation.py::test_activation_pin_body_destination_mutation_after_activation_has_zero_provider_and_rows[destination] tests/gateway/test_diagnostic_isolation.py::test_activation_pin_body_destination_mutation_after_activation_has_zero_provider_and_rows[pin] tests/gateway/test_diagnostic_isolation.py::test_activation_record_replacement_after_activation_has_zero_provider_and_rows tests/gateway/test_diagnostic_isolation.py::test_activation_rejects_caller_supplied_routes_before_rows_or_provider tests/gateway/test_diagnostic_isolation.py::test_active_host_rejects_post_activation_route_injection tests/gateway/test_diagnostic_isolation.py::test_audit_pending_duplicate_mapping_and_reconcile_are_exact_after_restart tests/gateway/test_diagnostic_isolation.py::test_authenticated_activation_is_one_use_and_reaches_provider tests/gateway/test_diagnostic_isolation.py::test_bootstrap_control_must_match_registered_owner_before_activation[7--100-60] tests/gateway/test_diagnostic_isolation.py::test_bootstrap_control_must_match_registered_owner_before_activation[7--101-59] tests/gateway/test_diagnostic_isolation.py::test_bootstrap_control_must_match_registered_owner_before_activation[8--100-59] tests/gateway/test_diagnostic_isolation.py::test_bootstrap_is_dormant_and_does_not_read_activation tests/gateway/test_diagnostic_isolation.py::test_cancellation_persists_one_unknown_terminal_and_reraises tests/gateway/test_diagnostic_isolation.py::test_candidate_provenance_requires_the_activated_child_instance tests/gateway/test_diagnostic_isolation.py::test_close_first_admission_race_has_zero_reservation_and_provider_calls[close] tests/gateway/test_diagnostic_isolation.py::test_close_first_admission_race_has_zero_reservation_and_provider_calls[expire] tests/gateway/test_diagnostic_isolation.py::test_close_first_admission_race_has_zero_reservation_and_provider_calls[stop] tests/gateway/test_diagnostic_isolation.py::test_detach_fence_failure_revokes_local_routes_and_provider[close] tests/gateway/test_diagnostic_isolation.py::test_detach_fence_failure_revokes_local_routes_and_provider[expire] tests/gateway/test_diagnostic_isolation.py::test_detach_fence_failure_revokes_local_routes_and_provider[stop] tests/gateway/test_diagnostic_isolation.py::test_detached_diagnostic_spaces_never_fall_through_to_generic_ingress[callback] tests/gateway/test_diagnostic_isolation.py::test_detached_diagnostic_spaces_never_fall_through_to_generic_ingress[message] tests/gateway/test_diagnostic_isolation.py::test_diagnostic_controller_and_host_constructors_require_factory_tokens tests/gateway/test_diagnostic_isolation.py::test_diagnostic_process_fence_blocks_lazy_generic_coordinator tests/gateway/test_diagnostic_isolation.py::test_durable_detach_revokes_cached_routes_before_ingress tests/gateway/test_diagnostic_isolation.py::test_malformed_or_missing_message_id_is_unknown_and_never_resends[blank] tests/gateway/test_diagnostic_isolation.py::test_malformed_or_missing_message_id_is_unknown_and_never_resends[boolean] tests/gateway/test_diagnostic_isolation.py::test_malformed_or_missing_message_id_is_unknown_and_never_resends[missing] tests/gateway/test_diagnostic_isolation.py::test_malformed_or_missing_message_id_is_unknown_and_never_resends[none] tests/gateway/test_diagnostic_isolation.py::test_pre_activation_delivery_fails_without_rows_or_provider tests/gateway/test_diagnostic_isolation.py::test_private_test_adapter_and_bootstrap_require_exact_token_and_type tests/gateway/test_diagnostic_isolation.py::test_production_binding_rejects_untrusted_adapter_before_activation[exact_adapter_fake_bot] tests/gateway/test_diagnostic_isolation.py::test_production_binding_rejects_untrusted_adapter_before_activation[none] tests/gateway/test_diagnostic_isolation.py::test_production_binding_rejects_untrusted_adapter_before_activation[simple_namespace] tests/gateway/test_diagnostic_isolation.py::test_production_binding_rejects_untrusted_adapter_before_activation[subclass] tests/gateway/test_diagnostic_isolation.py::test_production_bootstrap_rejects_sealed_test_adapter tests/gateway/test_diagnostic_isolation.py::test_provider_first_admission_race_terminalizes_before_detach[close] tests/gateway/test_diagnostic_isolation.py::test_provider_first_admission_race_terminalizes_before_detach[expire] tests/gateway/test_diagnostic_isolation.py::test_provider_first_admission_race_terminalizes_before_detach[stop] tests/gateway/test_diagnostic_isolation.py::test_public_generic_delivery_is_rejected_without_lifecycle tests/gateway/test_diagnostic_isolation.py::test_restart_generation_cannot_activate_again tests/gateway/test_diagnostic_isolation.py::test_role_route_rejects_every_wrong_identity_component[chat_id] tests/gateway/test_diagnostic_isolation.py::test_role_route_rejects_every_wrong_identity_component[generation] tests/gateway/test_diagnostic_isolation.py::test_role_route_rejects_every_wrong_identity_component[topic_id] tests/gateway/test_diagnostic_isolation.py::test_role_route_rejects_every_wrong_identity_component[user_id] tests/gateway/test_diagnostic_isolation.py::test_sealed_activation_delivery_records_exact_terminal_destination_and_body tests/gateway/test_diagnostic_isolation.py::test_sent_audited_duplicate_mapping_is_exact_in_process_and_after_restart tests/gateway/test_diagnostic_isolation.py::test_spec_less_authority_is_rejected tests/gateway/test_diagnostic_isolation.py::test_test_host_constructor_is_private_and_token_sealed tests/gateway/test_diagnostic_isolation.py::test_timeout_persists_one_unknown_terminal_and_reraises tests/gateway/test_diagnostic_isolation.py::test_transport_constructor_requires_factory_token_before_activation tests/gateway/test_diagnostic_isolation.py::test_transport_mutation_before_provider_is_terminal_unknown_and_provider_zero[adapter] tests/gateway/test_diagnostic_isolation.py::test_transport_mutation_before_provider_is_terminal_unknown_and_provider_zero[binding] tests/gateway/test_diagnostic_isolation.py::test_transport_mutation_before_provider_is_terminal_unknown_and_provider_zero[bot] tests/gateway/test_diagnostic_isolation.py::test_transport_mutation_before_provider_is_terminal_unknown_and_provider_zero[destination] tests/gateway/test_diagnostic_isolation.py::test_transport_mutation_before_provider_is_terminal_unknown_and_provider_zero[object] tests/gateway/test_diagnostic_isolation.py::test_unknown_duplicate_mapping_is_exact_in_process_and_after_restart tests/gateway/test_diagnostic_isolation.py::test_untrusted_activate_argument_has_zero_routes_reservations_and_provider tests/gateway/test_diagnostic_isolation.py::test_wrong_user_and_stale_generation_are_rejected_before_loader tests/gateway/test_diagnostic_isolation.py::test_wrong_user_message_and_callback_ingress_have_zero_downstream[callback] tests/gateway/test_diagnostic_isolation.py::test_wrong_user_message_and_callback_ingress_have_zero_downstream[message] tests/gateway/test_dingtalk.py::TestAllowedUsersGate::test_empty_allowlist_allows_everyone tests/gateway/test_dingtalk.py::TestAllowedUsersGate::test_env_var_csv_populates_allowlist tests/gateway/test_dingtalk.py::TestAllowedUsersGate::test_matches_sender_id_case_insensitive tests/gateway/test_dingtalk.py::TestAllowedUsersGate::test_matches_staff_id tests/gateway/test_dingtalk.py::TestAllowedUsersGate::test_rejects_unknown_user tests/gateway/test_dingtalk.py::TestAllowedUsersGate::test_wildcard_allowlist_allows_everyone tests/gateway/test_dingtalk.py::TestCardLifecycle::test_done_fires_only_when_reply_to_is_set tests/gateway/test_dingtalk.py::TestCardLifecycle::test_edit_message_finalize_false_tracks_sibling tests/gateway/test_dingtalk.py::TestCardLifecycle::test_edit_message_finalize_fires_done tests/gateway/test_dingtalk.py::TestCardLifecycle::test_edit_message_requires_message_id tests/gateway/test_dingtalk.py::TestCardLifecycle::test_final_reply_finalizes_card tests/gateway/test_dingtalk.py::TestCardLifecycle::test_fire_done_reaction_is_idempotent tests/gateway/test_dingtalk.py::TestCardLifecycle::test_intermediate_send_stays_streaming tests/gateway/test_dingtalk.py::TestCardLifecycle::test_next_send_auto_closes_sibling_streaming_cards tests/gateway/test_dingtalk.py::TestConnect::test_connect_fails_without_credentials tests/gateway/test_dingtalk.py::TestConnect::test_connect_fails_without_sdk tests/gateway/test_dingtalk.py::TestConnect::test_disconnect_cleans_up tests/gateway/test_dingtalk.py::TestConnect::test_disconnect_closes_session_websocket tests/gateway/test_dingtalk.py::TestConnect::test_disconnect_finalizes_open_streaming_cards tests/gateway/test_dingtalk.py::TestDeduplication::test_cache_cleanup_on_overflow tests/gateway/test_dingtalk.py::TestDeduplication::test_different_messages_not_duplicate tests/gateway/test_dingtalk.py::TestDeduplication::test_first_message_not_duplicate tests/gateway/test_dingtalk.py::TestDeduplication::test_second_same_message_is_duplicate tests/gateway/test_dingtalk.py::TestDingTalkAdapterAICards::test_send_uses_ai_card_if_configured tests/gateway/test_dingtalk.py::TestDingTalkAdapterInit::test_falls_back_to_env_vars tests/gateway/test_dingtalk.py::TestDingTalkAdapterInit::test_reads_config_from_extra tests/gateway/test_dingtalk.py::TestDingTalkRequirements::test_returns_false_when_env_vars_missing tests/gateway/test_dingtalk.py::TestDingTalkRequirements::test_returns_false_when_sdk_missing tests/gateway/test_dingtalk.py::TestDingTalkRequirements::test_returns_true_when_all_available tests/gateway/test_dingtalk.py::TestExtractMedia::test_audio_rich_text_item_stays_audio tests/gateway/test_dingtalk.py::TestExtractMedia::test_voice_rich_text_item_classified_as_voice tests/gateway/test_dingtalk.py::TestExtractText::test_empty_message tests/gateway/test_dingtalk.py::TestExtractText::test_rich_text_content_new_shape tests/gateway/test_dingtalk.py::TestExtractText::test_rich_text_legacy_shape tests/gateway/test_dingtalk.py::TestExtractText::test_text_as_dict_legacy tests/gateway/test_dingtalk.py::TestExtractText::test_text_as_textcontent_object tests/gateway/test_dingtalk.py::TestExtractText::test_text_content_attr_with_empty_string tests/gateway/test_dingtalk.py::TestExtractTextMentions::test_dingtalk_in_platform_enum tests/gateway/test_dingtalk.py::TestExtractTextMentions::test_preserves_at_mentions_in_text tests/gateway/test_dingtalk.py::TestHandlerProcessIsAsync::test_process_is_coroutine_function tests/gateway/test_dingtalk.py::TestIncomingHandlerProcess::test_process_extracts_session_webhook tests/gateway/test_dingtalk.py::TestIncomingHandlerProcess::test_process_fallback_session_webhook_when_from_dict_misses_it tests/gateway/test_dingtalk.py::TestIncomingHandlerProcess::test_process_returns_ack_immediately tests/gateway/test_dingtalk.py::TestMentionPatterns::test_empty_patterns_list tests/gateway/test_dingtalk.py::TestMentionPatterns::test_env_var_json_populates_patterns tests/gateway/test_dingtalk.py::TestMentionPatterns::test_env_var_newline_fallback_when_not_json tests/gateway/test_dingtalk.py::TestMentionPatterns::test_invalid_regex_is_skipped_not_raised tests/gateway/test_dingtalk.py::TestMentionPatterns::test_pattern_is_case_insensitive tests/gateway/test_dingtalk.py::TestMentionPatterns::test_pattern_matches_text tests/gateway/test_dingtalk.py::TestMessageContextIsolation::test_contexts_keyed_by_chat_id tests/gateway/test_dingtalk.py::TestSend::test_send_document_returns_explicit_unsupported_error tests/gateway/test_dingtalk.py::TestSend::test_send_fails_without_webhook tests/gateway/test_dingtalk.py::TestSend::test_send_handles_http_error tests/gateway/test_dingtalk.py::TestSend::test_send_image_file_returns_explicit_unsupported_error tests/gateway/test_dingtalk.py::TestSend::test_send_image_renders_markdown_image tests/gateway/test_dingtalk.py::TestSend::test_send_posts_to_webhook tests/gateway/test_dingtalk.py::TestSend::test_send_uses_cached_webhook tests/gateway/test_dingtalk.py::TestShouldProcessMessage::test_dm_always_accepted tests/gateway/test_dingtalk.py::TestShouldProcessMessage::test_group_accepted_when_bot_is_mentioned tests/gateway/test_dingtalk.py::TestShouldProcessMessage::test_group_accepted_when_chat_in_free_response_list tests/gateway/test_dingtalk.py::TestShouldProcessMessage::test_group_accepted_when_require_mention_disabled tests/gateway/test_dingtalk.py::TestShouldProcessMessage::test_group_accepted_when_text_matches_wake_word tests/gateway/test_dingtalk.py::TestShouldProcessMessage::test_group_rejected_when_require_mention_and_no_trigger tests/gateway/test_dingtalk.py::TestWebhookDomainAllowlist::test_api_domain_accepted tests/gateway/test_dingtalk.py::TestWebhookDomainAllowlist::test_http_rejected tests/gateway/test_dingtalk.py::TestWebhookDomainAllowlist::test_oapi_domain_accepted tests/gateway/test_dingtalk.py::TestWebhookDomainAllowlist::test_suffix_attack_rejected tests/gateway/test_dingtalk.py::TestWebhookDomainAllowlist::test_unsanctioned_subdomain_rejected tests/gateway/test_discord_allowed_channels.py::TestDiscordAllowedChannelsWildcard::test_empty_allowlist_allows_all tests/gateway/test_discord_allowed_channels.py::TestDiscordAllowedChannelsWildcard::test_exact_match_allowed tests/gateway/test_discord_allowed_channels.py::TestDiscordAllowedChannelsWildcard::test_non_matching_channel_blocked tests/gateway/test_discord_allowed_channels.py::TestDiscordAllowedChannelsWildcard::test_whitespace_only_entry_ignored tests/gateway/test_discord_allowed_channels.py::TestDiscordAllowedChannelsWildcard::test_wildcard_allows_any_channel tests/gateway/test_discord_allowed_channels.py::TestDiscordAllowedChannelsWildcard::test_wildcard_in_list_allows_any_channel tests/gateway/test_discord_allowed_channels.py::TestDiscordFreeResponseChannelsWildcard::test_empty_list_no_free_response tests/gateway/test_discord_allowed_channels.py::TestDiscordFreeResponseChannelsWildcard::test_exact_match_is_free_response tests/gateway/test_discord_allowed_channels.py::TestDiscordFreeResponseChannelsWildcard::test_non_match_not_free_response tests/gateway/test_discord_allowed_channels.py::TestDiscordFreeResponseChannelsWildcard::test_wildcard_in_list_applies_everywhere tests/gateway/test_discord_allowed_channels.py::TestDiscordFreeResponseChannelsWildcard::test_wildcard_makes_every_channel_free_response tests/gateway/test_discord_allowed_channels.py::TestDiscordIgnoredChannelsWildcard::test_empty_ignored_list_silences_nothing tests/gateway/test_discord_allowed_channels.py::TestDiscordIgnoredChannelsWildcard::test_exact_match_is_ignored tests/gateway/test_discord_allowed_channels.py::TestDiscordIgnoredChannelsWildcard::test_non_match_not_ignored tests/gateway/test_discord_allowed_channels.py::TestDiscordIgnoredChannelsWildcard::test_wildcard_silences_every_channel tests/gateway/test_discord_allowed_mentions.py::test_all_four_knobs_together tests/gateway/test_discord_allowed_mentions.py::test_env_var_can_disable_users tests/gateway/test_discord_allowed_mentions.py::test_env_var_opts_back_into_everyone tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[ true -True] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[-False] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[0-False] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[1-True] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[False-False] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[TRUE-True] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[True-True] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[YES-True] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[false-False] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[garbage-False] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[no-False] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[off-False] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[on-True] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[true-True] tests/gateway/test_discord_allowed_mentions.py::test_everyone_boolean_parsing[yes-True] tests/gateway/test_discord_allowed_mentions.py::test_safe_defaults_block_everyone_and_roles tests/gateway/test_discord_attachment_download.py::TestCacheDiscordAudio::test_falls_back_to_url_when_no_read tests/gateway/test_discord_attachment_download.py::TestCacheDiscordAudio::test_prefers_att_read_over_url tests/gateway/test_discord_attachment_download.py::TestCacheDiscordDocument::test_fallback_aiohttp_when_safe_url tests/gateway/test_discord_attachment_download.py::TestCacheDiscordDocument::test_fallback_blocked_by_ssrf_guard tests/gateway/test_discord_attachment_download.py::TestCacheDiscordDocument::test_prefers_att_read_returns_bytes_directly tests/gateway/test_discord_attachment_download.py::TestCacheDiscordImage::test_falls_back_to_url_when_bytes_validator_rejects tests/gateway/test_discord_attachment_download.py::TestCacheDiscordImage::test_falls_back_to_url_when_no_read tests/gateway/test_discord_attachment_download.py::TestCacheDiscordImage::test_prefers_att_read_over_url tests/gateway/test_discord_attachment_download.py::TestHandleMessageUsesAuthenticatedRead::test_image_downloads_via_att_read_not_url tests/gateway/test_discord_attachment_download.py::TestHandleMessageUsesAuthenticatedRead::test_native_voice_note_is_classified_as_voice tests/gateway/test_discord_attachment_download.py::TestHandleMessageUsesAuthenticatedRead::test_plain_audio_attachment_stays_audio tests/gateway/test_discord_attachment_download.py::TestReadAttachmentBytes::test_returns_bytes_on_successful_read tests/gateway/test_discord_attachment_download.py::TestReadAttachmentBytes::test_returns_none_when_read_missing tests/gateway/test_discord_attachment_download.py::TestReadAttachmentBytes::test_returns_none_when_read_raises tests/gateway/test_discord_bot_auth_bypass.py::test_bot_bypass_does_not_leak_to_other_platforms tests/gateway/test_discord_bot_auth_bypass.py::test_discord_bot_NOT_authorized_when_allow_bots_none tests/gateway/test_discord_bot_auth_bypass.py::test_discord_bot_NOT_authorized_when_allow_bots_unset tests/gateway/test_discord_bot_auth_bypass.py::test_discord_bot_authorized_when_allow_bots_all tests/gateway/test_discord_bot_auth_bypass.py::test_discord_bot_authorized_when_allow_bots_mentions tests/gateway/test_discord_bot_auth_bypass.py::test_discord_human_still_checked_against_allowlist_when_bot_policy_set tests/gateway/test_discord_bot_auth_bypass.py::test_discord_role_config_does_not_bypass_gateway_allowlist tests/gateway/test_discord_bot_auth_bypass.py::test_discord_role_config_does_not_leak_to_other_platforms tests/gateway/test_discord_bot_auth_bypass.py::test_discord_user_allowlist_still_authorizes_when_role_is_also_configured tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_allow_bots_all_accepts_bots tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_allow_bots_mentions_accepts_with_mention tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_allow_bots_mentions_rejects_without_mention tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_allow_bots_none_rejects_bots tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_case_insensitive tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_default_is_none tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_human_messages_always_accepted tests/gateway/test_discord_bot_filter.py::TestDiscordBotFilter::test_own_messages_always_ignored tests/gateway/test_discord_channel_controls.py::test_config_bridges_ignored_channels tests/gateway/test_discord_channel_controls.py::test_config_bridges_no_thread_channels tests/gateway/test_discord_channel_controls.py::test_config_env_var_takes_precedence tests/gateway/test_discord_channel_controls.py::test_dms_unaffected_by_ignored_channels tests/gateway/test_discord_channel_controls.py::test_ignored_channel_blocks_even_with_mention tests/gateway/test_discord_channel_controls.py::test_ignored_channel_blocks_message tests/gateway/test_discord_channel_controls.py::test_ignored_channel_thread_parent_match tests/gateway/test_discord_channel_controls.py::test_ignored_channels_csv_parsing tests/gateway/test_discord_channel_controls.py::test_ignored_channels_empty_string_ignores_nothing tests/gateway/test_discord_channel_controls.py::test_no_thread_channel_skips_auto_thread tests/gateway/test_discord_channel_controls.py::test_no_thread_channels_csv_parsing tests/gateway/test_discord_channel_controls.py::test_no_thread_with_auto_thread_disabled_is_noop tests/gateway/test_discord_channel_controls.py::test_non_ignored_channel_processes_normally tests/gateway/test_discord_channel_controls.py::test_normal_channel_still_auto_threads tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_blank_prompts_are_ignored tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_build_message_event_sets_channel_prompt tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_dispatch_thread_session_inherits_parent_channel_prompt tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_exact_channel_overrides_parent tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_match_by_channel_id tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_match_by_parent_id tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_no_prompt_returns_none tests/gateway/test_discord_channel_prompts.py::TestResolveChannelPrompts::test_numeric_yaml_keys_normalized_at_config_load tests/gateway/test_discord_channel_prompts.py::test_retry_preserves_channel_prompt tests/gateway/test_discord_channel_prompts.py::test_run_agent_appends_channel_prompt_to_ephemeral_system_prompt tests/gateway/test_discord_channel_skills.py::TestResolveChannelSkills::test_dedup_preserves_order tests/gateway/test_discord_channel_skills.py::TestResolveChannelSkills::test_match_by_channel_id tests/gateway/test_discord_channel_skills.py::TestResolveChannelSkills::test_match_by_parent_id tests/gateway/test_discord_channel_skills.py::TestResolveChannelSkills::test_no_bindings_returns_none tests/gateway/test_discord_channel_skills.py::TestResolveChannelSkills::test_no_match_returns_none tests/gateway/test_discord_channel_skills.py::TestResolveChannelSkills::test_single_skill_string tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceResolve::test_already_resolved_sends_ephemeral_reply tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceResolve::test_choice_falls_back_to_label_text_when_entry_missing tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceResolve::test_choice_resolves_with_canonical_choice_text tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceResolve::test_unauthorized_user_rejected tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceViewConstruction::test_caps_at_24_choices_plus_other tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceViewConstruction::test_renders_n_choice_buttons_plus_other tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceViewConstruction::test_truncates_long_choice_label tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceViewConstruction::test_truncates_long_choice_label_breaks_on_word_boundary tests/gateway/test_discord_clarify_buttons.py::TestClarifyChoiceViewConstruction::test_truncates_long_no_space_choice_on_soft_boundary tests/gateway/test_discord_clarify_buttons.py::TestClarifyOtherButton::test_other_flips_entry_to_awaiting_text tests/gateway/test_discord_clarify_buttons.py::TestClarifyOtherButton::test_other_unauthorized_user_rejected tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_filters_empty_and_whitespace_choices tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_multi_choice_attaches_view tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_not_connected_returns_failure tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_open_ended_omits_view tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_routes_to_thread_when_metadata_thread_id_set tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_unwrap_does_not_pick_value_or_name_alone tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_unwrap_prefers_description_over_name_in_multi_key_dict tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_unwrap_prefers_label_over_description tests/gateway/test_discord_clarify_buttons.py::TestDiscordSendClarify::test_unwraps_dict_choices_to_description tests/gateway/test_discord_component_auth.py::test_clarify_choice_view_accepts_role_allowlist tests/gateway/test_discord_component_auth.py::test_component_check_accepts_role_allowlist_sequences tests/gateway/test_discord_component_auth.py::test_component_check_empty_allowlists_rejects_by_default tests/gateway/test_discord_component_auth.py::test_component_check_explicit_allow_all_passes[DISCORD_ALLOW_ALL_USERS-true] tests/gateway/test_discord_component_auth.py::test_component_check_explicit_allow_all_passes[GATEWAY_ALLOW_ALL_USERS-yes] tests/gateway/test_discord_component_auth.py::test_component_check_global_allowlist_without_match_rejects tests/gateway/test_discord_component_auth.py::test_component_check_missing_user_with_allowlist_rejects tests/gateway/test_discord_component_auth.py::test_component_check_role_only_user_with_matching_role_passes tests/gateway/test_discord_component_auth.py::test_component_check_role_only_user_without_matching_role_rejected tests/gateway/test_discord_component_auth.py::test_component_check_role_policy_with_no_roles_attr_rejects tests/gateway/test_discord_component_auth.py::test_component_check_user_in_global_allowlist_passes tests/gateway/test_discord_component_auth.py::test_component_check_user_in_user_allowlist_passes tests/gateway/test_discord_component_auth.py::test_component_check_user_not_in_user_allowlist_rejected tests/gateway/test_discord_component_auth.py::test_component_check_user_or_role_neither_match tests/gateway/test_discord_component_auth.py::test_component_check_user_or_role_role_match tests/gateway/test_discord_component_auth.py::test_component_check_user_or_role_user_match tests/gateway/test_discord_component_auth.py::test_component_check_wildcard_user_allowlist_passes tests/gateway/test_discord_component_auth.py::test_exec_approval_view_accepts_role_allowlist tests/gateway/test_discord_component_auth.py::test_exec_approval_view_role_default_is_empty_set tests/gateway/test_discord_component_auth.py::test_model_picker_view_accepts_role_allowlist tests/gateway/test_discord_component_auth.py::test_model_picker_view_empty_allowlists_reject_by_default tests/gateway/test_discord_component_auth.py::test_slash_confirm_view_accepts_role_allowlist tests/gateway/test_discord_component_auth.py::test_update_prompt_view_accepts_role_allowlist tests/gateway/test_discord_component_auth.py::test_view_empty_allowlists_allow_with_explicit_allow_all tests/gateway/test_discord_component_auth.py::test_views_empty_allowlists_reject_by_default[0] tests/gateway/test_discord_component_auth.py::test_views_empty_allowlists_reject_by_default[1] tests/gateway/test_discord_component_auth.py::test_views_empty_allowlists_reject_by_default[2] tests/gateway/test_discord_component_auth.py::test_views_empty_allowlists_reject_by_default[3] tests/gateway/test_discord_connect.py::test_connect_does_not_wait_for_slash_sync tests/gateway/test_discord_connect.py::test_connect_only_requests_members_intent_when_needed[769524422783664158,abhey-gupta-True] tests/gateway/test_discord_connect.py::test_connect_only_requests_members_intent_when_needed[769524422783664158-False] tests/gateway/test_discord_connect.py::test_connect_only_requests_members_intent_when_needed[abhey-gupta-True] tests/gateway/test_discord_connect.py::test_connect_releases_token_lock_on_timeout tests/gateway/test_discord_connect.py::test_connect_respects_slash_commands_opt_out tests/gateway/test_discord_connect.py::test_connect_timeout_cancels_bot_task tests/gateway/test_discord_connect.py::test_disconnect_cancels_running_bot_task tests/gateway/test_discord_connect.py::test_post_connect_initialization_reraises_non_rate_limit_exceptions tests/gateway/test_discord_connect.py::test_post_connect_initialization_respects_discord_retry_after tests/gateway/test_discord_connect.py::test_post_connect_initialization_skips_same_fingerprint_after_success tests/gateway/test_discord_connect.py::test_post_connect_initialization_skips_sync_when_policy_off tests/gateway/test_discord_connect.py::test_reconnect_closes_previous_client_to_prevent_zombie_websocket tests/gateway/test_discord_connect.py::test_safe_sync_detects_contexts_drift tests/gateway/test_discord_connect.py::test_safe_sync_reads_permission_attrs_from_existing_command tests/gateway/test_discord_connect.py::test_safe_sync_slash_commands_only_mutates_diffs tests/gateway/test_discord_connect.py::test_safe_sync_slash_commands_paces_mutation_writes tests/gateway/test_discord_connect.py::test_safe_sync_slash_commands_recreates_metadata_only_diffs tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_allowlisted_doc_unchanged_when_flag_on tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_helper_config_overrides_env tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_helper_reads_env_fallback tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_max_attachment_bytes_caps_uploads tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_max_attachment_bytes_zero_means_unlimited tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_max_bytes_helper_invalid_value_falls_back tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_unknown_type_cached_when_flag_on tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_unknown_type_no_content_type_becomes_octet_stream tests/gateway/test_discord_document_handling.py::TestAllowAnyAttachment::test_unknown_type_skipped_by_default tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_download_error_handled tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_image_attachment_unaffected tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_large_txt_cached_not_injected tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_log_content_injected tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_md_content_injected tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_mid_sized_zip_under_32mb_is_cached tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_multiple_text_files_both_injected tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_oversized_document_skipped tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_pdf_document_cached tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_txt_content_injected tests/gateway/test_discord_document_handling.py::TestIncomingDocumentHandling::test_zip_document_cached tests/gateway/test_discord_free_response.py::test_discord_accepts_and_strips_bot_mentions_when_required tests/gateway/test_discord_free_response.py::test_discord_auto_thread_can_be_disabled tests/gateway/test_discord_free_response.py::test_discord_auto_thread_enabled_by_default tests/gateway/test_discord_free_response.py::test_discord_auto_thread_skips_backfill tests/gateway/test_discord_free_response.py::test_discord_auto_thread_tracks_participation tests/gateway/test_discord_free_response.py::test_discord_bot_thread_skips_mention_requirement tests/gateway/test_discord_free_response.py::test_discord_can_still_require_mentions_when_enabled tests/gateway/test_discord_free_response.py::test_discord_defaults_to_require_mention tests/gateway/test_discord_free_response.py::test_discord_dm_does_not_backfill tests/gateway/test_discord_free_response.py::test_discord_dms_ignore_mention_requirement tests/gateway/test_discord_free_response.py::test_discord_forum_parent_in_free_response_list_allows_forum_thread tests/gateway/test_discord_free_response.py::test_discord_forum_threads_are_handled_as_threads tests/gateway/test_discord_free_response.py::test_discord_free_response_channel_can_come_from_config_extra tests/gateway/test_discord_free_response.py::test_discord_free_response_channel_overrides_mention_requirement tests/gateway/test_discord_free_response.py::test_discord_free_response_channel_skips_auto_thread tests/gateway/test_discord_free_response.py::test_discord_free_response_channels_bare_int tests/gateway/test_discord_free_response.py::test_discord_free_response_channels_int_list tests/gateway/test_discord_free_response.py::test_discord_free_response_in_server_channels tests/gateway/test_discord_free_response.py::test_discord_free_response_in_threads tests/gateway/test_discord_free_response.py::test_discord_non_reply_free_channel_skips_backfill tests/gateway/test_discord_free_response.py::test_discord_participated_thread_backfills_without_mention tests/gateway/test_discord_free_response.py::test_discord_per_user_channel_backfills_too tests/gateway/test_discord_free_response.py::test_discord_reply_in_free_channel_triggers_backfill tests/gateway/test_discord_free_response.py::test_discord_reply_message_skips_auto_thread tests/gateway/test_discord_free_response.py::test_discord_send_does_not_cache_nonconversational_status_as_history_boundary tests/gateway/test_discord_free_response.py::test_discord_shared_channel_backfill_prepends_context tests/gateway/test_discord_free_response.py::test_discord_thread_default_keeps_responding_after_participation tests/gateway/test_discord_free_response.py::test_discord_thread_participation_tracked_on_dispatch tests/gateway/test_discord_free_response.py::test_discord_thread_require_mention_gates_followups tests/gateway/test_discord_free_response.py::test_discord_thread_require_mention_still_responds_when_mentioned tests/gateway/test_discord_free_response.py::test_discord_thread_require_mention_via_config_extra tests/gateway/test_discord_free_response.py::test_discord_unknown_thread_still_requires_mention tests/gateway/test_discord_free_response.py::test_discord_voice_linked_channel_skips_mention_requirement_and_auto_thread tests/gateway/test_discord_free_response.py::test_discord_voice_linked_parent_thread_still_requires_mention tests/gateway/test_discord_free_response.py::test_fetch_channel_context_cache_uses_latest_window_when_after_set tests/gateway/test_discord_free_response.py::test_fetch_channel_context_hydrates_around_reply_target tests/gateway/test_discord_free_response.py::test_fetch_channel_context_ignores_stale_cache tests/gateway/test_discord_free_response.py::test_fetch_channel_context_reply_target_in_primary_window_not_duplicated tests/gateway/test_discord_free_response.py::test_fetch_channel_context_skips_other_bots_when_allow_bots_none tests/gateway/test_discord_free_response.py::test_fetch_channel_context_skips_self_improvement_boundary_message tests/gateway/test_discord_free_response.py::test_fetch_channel_context_stops_at_self_message_and_reverses_to_chronological_order tests/gateway/test_discord_free_response.py::test_fetch_channel_context_uses_cache_to_narrow_window tests/gateway/test_discord_free_response.py::test_nonconversational_fallback_requires_self_improvement_emoji tests/gateway/test_discord_imports.py::TestDiscordImportSafety::test_module_imports_even_when_discord_dependency_is_missing tests/gateway/test_discord_lazy_install_views.py::TestDefineDiscordViewClasses::test_check_discord_requirements_calls_define_on_lazy_install tests/gateway/test_discord_lazy_install_views.py::TestDefineDiscordViewClasses::test_registers_all_five_view_classes tests/gateway/test_discord_media_metadata.py::test_discord_media_methods_accept_metadata_kwarg tests/gateway/test_discord_model_picker.py::test_expensive_model_requires_confirmation tests/gateway/test_discord_model_picker.py::test_model_picker_clears_controls_before_running_switch_callback tests/gateway/test_discord_opus.py::TestOpusFindLibrary::test_homebrew_fallback_is_conditional tests/gateway/test_discord_opus.py::TestOpusFindLibrary::test_opus_decode_error_logged tests/gateway/test_discord_opus.py::TestOpusFindLibrary::test_uses_find_library_first tests/gateway/test_discord_opus.py::TestOpusFindLibrary::test_windows_bundled_discord_opus_dll_is_discovered tests/gateway/test_discord_race_polish.py::test_concurrent_joins_do_not_double_connect tests/gateway/test_discord_reactions.py::test_interaction_backed_events_do_not_attempt_reactions tests/gateway/test_discord_reactions.py::test_on_processing_complete_cancelled_removes_eyes_without_terminal_reaction tests/gateway/test_discord_reactions.py::test_process_message_background_adds_and_swaps_reactions tests/gateway/test_discord_reactions.py::test_reaction_helper_failures_do_not_break_message_flow tests/gateway/test_discord_reactions.py::test_reactions_disabled_via_env tests/gateway/test_discord_reactions.py::test_reactions_disabled_via_env_zero tests/gateway/test_discord_reactions.py::test_reactions_enabled_by_default tests/gateway/test_discord_reply_mode.py::TestConfigSerialization::test_from_dict_defaults_to_first tests/gateway/test_discord_reply_mode.py::TestConfigSerialization::test_from_dict_loads_reply_to_mode tests/gateway/test_discord_reply_mode.py::TestConfigSerialization::test_to_dict_includes_reply_to_mode tests/gateway/test_discord_reply_mode.py::TestEnvVarOverride::test_env_var_case_insensitive tests/gateway/test_discord_reply_mode.py::TestEnvVarOverride::test_env_var_creates_platform_config_if_missing tests/gateway/test_discord_reply_mode.py::TestEnvVarOverride::test_env_var_empty_value_ignored tests/gateway/test_discord_reply_mode.py::TestEnvVarOverride::test_env_var_invalid_value_ignored tests/gateway/test_discord_reply_mode.py::TestEnvVarOverride::test_env_var_sets_all_mode tests/gateway/test_discord_reply_mode.py::TestEnvVarOverride::test_env_var_sets_off_mode tests/gateway/test_discord_reply_mode.py::TestReplyToModeConfig::test_all_mode tests/gateway/test_discord_reply_mode.py::TestReplyToModeConfig::test_default_mode_is_first tests/gateway/test_discord_reply_mode.py::TestReplyToModeConfig::test_empty_string_mode_defaults_to_first tests/gateway/test_discord_reply_mode.py::TestReplyToModeConfig::test_first_mode tests/gateway/test_discord_reply_mode.py::TestReplyToModeConfig::test_invalid_mode_stored_as_is tests/gateway/test_discord_reply_mode.py::TestReplyToModeConfig::test_none_mode_defaults_to_first tests/gateway/test_discord_reply_mode.py::TestReplyToModeConfig::test_off_mode tests/gateway/test_discord_reply_mode.py::TestReplyToText::test_no_reference_both_none tests/gateway/test_discord_reply_mode.py::TestReplyToText::test_reference_with_deleted_message tests/gateway/test_discord_reply_mode.py::TestReplyToText::test_reference_with_empty_resolved_content tests/gateway/test_discord_reply_mode.py::TestReplyToText::test_reference_with_resolved_content tests/gateway/test_discord_reply_mode.py::TestReplyToText::test_reference_without_resolved tests/gateway/test_discord_reply_mode.py::TestSendWithReplyToMode::test_all_mode_all_chunks_reference tests/gateway/test_discord_reply_mode.py::TestSendWithReplyToMode::test_first_mode_only_first_chunk_references tests/gateway/test_discord_reply_mode.py::TestSendWithReplyToMode::test_invalid_mode_falls_back_to_first_behavior tests/gateway/test_discord_reply_mode.py::TestSendWithReplyToMode::test_no_reply_to_param_no_reference tests/gateway/test_discord_reply_mode.py::TestSendWithReplyToMode::test_off_mode_no_reply_reference tests/gateway/test_discord_reply_mode.py::TestSendWithReplyToMode::test_single_chunk_off_mode tests/gateway/test_discord_reply_mode.py::TestSendWithReplyToMode::test_single_chunk_respects_first_mode tests/gateway/test_discord_reply_mode.py::TestYamlConfigLoading::test_env_var_takes_precedence_over_yaml tests/gateway/test_discord_reply_mode.py::TestYamlConfigLoading::test_extra_reply_to_mode_off tests/gateway/test_discord_reply_mode.py::TestYamlConfigLoading::test_top_level_reply_to_mode_all tests/gateway/test_discord_reply_mode.py::TestYamlConfigLoading::test_top_level_reply_to_mode_off tests/gateway/test_discord_reply_mode.py::TestYamlConfigLoading::test_top_level_takes_precedence_over_extra tests/gateway/test_discord_roles_dm_scope.py::test_dm_rejects_role_held_in_other_guild tests/gateway/test_discord_roles_dm_scope.py::test_dm_role_auth_optin_rejects_when_not_member tests/gateway/test_discord_roles_dm_scope.py::test_dm_role_auth_requires_explicit_guild_optin tests/gateway/test_discord_roles_dm_scope.py::test_empty_allowlists_allow_everyone tests/gateway/test_discord_roles_dm_scope.py::test_guild_message_rejects_author_roles_from_different_guild tests/gateway/test_discord_roles_dm_scope.py::test_guild_message_role_check_allows_when_role_in_same_guild tests/gateway/test_discord_roles_dm_scope.py::test_guild_message_role_check_scoped_to_originating_guild tests/gateway/test_discord_roles_dm_scope.py::test_slash_authorization_allows_in_scope_guild_role tests/gateway/test_discord_roles_dm_scope.py::test_slash_authorization_rejects_cross_guild_role_dm tests/gateway/test_discord_roles_dm_scope.py::test_slash_authorization_rejects_cross_guild_role_in_guild tests/gateway/test_discord_roles_dm_scope.py::test_user_id_allowlist_works_in_dm tests/gateway/test_discord_roles_dm_scope.py::test_user_id_allowlist_works_in_guild tests/gateway/test_discord_send.py::TestIsForumParent::test_forum_channel_class_instance tests/gateway/test_discord_send.py::TestIsForumParent::test_none_returns_false tests/gateway/test_discord_send.py::TestIsForumParent::test_regular_channel_returns_false tests/gateway/test_discord_send.py::TestIsForumParent::test_thread_returns_false tests/gateway/test_discord_send.py::TestIsForumParent::test_type_value_15 tests/gateway/test_discord_send.py::test_forum_post_file_creates_thread_with_attachment tests/gateway/test_discord_send.py::test_forum_post_file_creation_failure tests/gateway/test_discord_send.py::test_forum_post_file_uses_filename_when_no_content tests/gateway/test_discord_send.py::test_send_does_not_retry_on_unrelated_errors tests/gateway/test_discord_send.py::test_send_retries_without_reference_when_reply_target_is_deleted tests/gateway/test_discord_send.py::test_send_retries_without_reference_when_reply_target_is_system_message tests/gateway/test_discord_send.py::test_send_to_forum_create_thread_failure tests/gateway/test_discord_send.py::test_send_to_forum_creates_thread_post tests/gateway/test_discord_send.py::test_send_to_forum_follow_up_chunk_failures_collected_as_warnings tests/gateway/test_discord_send.py::test_send_to_forum_sends_remaining_chunks tests/gateway/test_discord_send.py::test_typing_restartable_after_error tests/gateway/test_discord_send.py::test_typing_stop_cleans_up tests/gateway/test_discord_send.py::test_typing_task_removed_after_api_error tests/gateway/test_discord_slash_auth.py::test_allowed_user_passes tests/gateway/test_discord_slash_auth.py::test_channel_allowlist_does_not_apply_to_dms tests/gateway/test_discord_slash_auth.py::test_channel_allowlist_wildcard_passes tests/gateway/test_discord_slash_auth.py::test_channel_in_allowlist_passes tests/gateway/test_discord_slash_auth.py::test_channel_not_in_allowlist_rejected tests/gateway/test_discord_slash_auth.py::test_disallowed_user_rejected_with_ephemeral tests/gateway/test_discord_slash_auth.py::test_ignored_beats_allowed tests/gateway/test_discord_slash_auth.py::test_ignored_channel_rejected tests/gateway/test_discord_slash_auth.py::test_ignored_channel_wildcard_blocks_all tests/gateway/test_discord_slash_auth.py::test_missing_channel_id_allowed_when_no_channel_policy tests/gateway/test_discord_slash_auth.py::test_missing_channel_id_rejected_when_channel_policy_configured tests/gateway/test_discord_slash_auth.py::test_missing_user_allowed_when_no_allowlist_configured tests/gateway/test_discord_slash_auth.py::test_missing_user_rejected_when_allowlist_configured tests/gateway/test_discord_slash_auth.py::test_no_allowlist_allows_everyone tests/gateway/test_discord_slash_auth.py::test_no_allowlist_dm_also_allowed tests/gateway/test_discord_slash_auth.py::test_notify_falls_back_to_slack_if_no_telegram tests/gateway/test_discord_slash_auth.py::test_notify_falls_back_to_slack_on_telegram_soft_fail tests/gateway/test_discord_slash_auth.py::test_notify_returns_on_telegram_truthy_success tests/gateway/test_discord_slash_auth.py::test_notify_silently_no_ops_without_runner tests/gateway/test_discord_slash_auth.py::test_role_member_passes tests/gateway/test_discord_slash_auth.py::test_role_non_member_rejected tests/gateway/test_discord_slash_auth.py::test_skill_autocomplete_returns_choices_for_authorized tests/gateway/test_discord_slash_auth.py::test_skill_autocomplete_returns_empty_for_unauthorized tests/gateway/test_discord_slash_auth.py::test_skill_handler_dispatches_for_authorized tests/gateway/test_discord_slash_auth.py::test_skill_handler_known_and_unknown_produce_same_rejection tests/gateway/test_discord_slash_auth.py::test_skill_handler_rejects_before_dispatch_for_unauthorized tests/gateway/test_discord_slash_auth.py::test_thread_parent_in_allowlist_passes tests/gateway/test_discord_slash_auth.py::test_thread_parent_in_ignorelist_rejects tests/gateway/test_discord_slash_auth.py::test_unauthorized_attempt_notifies_telegram tests/gateway/test_discord_slash_auth.py::test_visibility_hide_helper_zeroes_perms tests/gateway/test_discord_slash_auth.py::test_visibility_hide_off_by_default_is_noop tests/gateway/test_discord_slash_auth.py::test_visibility_hide_tolerates_unsetable_command tests/gateway/test_discord_slash_commands.py::test_auto_create_thread_falls_back_to_hermes_when_only_mentions tests/gateway/test_discord_slash_commands.py::test_auto_create_thread_falls_back_to_seed_message tests/gateway/test_discord_slash_commands.py::test_auto_create_thread_returns_none_when_direct_and_fallback_fail tests/gateway/test_discord_slash_commands.py::test_auto_create_thread_strips_mention_syntax_from_name tests/gateway/test_discord_slash_commands.py::test_auto_create_thread_truncates_long_names tests/gateway/test_discord_slash_commands.py::test_auto_create_thread_uses_message_content_as_name tests/gateway/test_discord_slash_commands.py::test_auto_registered_command_dispatches_correctly tests/gateway/test_discord_slash_commands.py::test_auto_registered_command_with_args tests/gateway/test_discord_slash_commands.py::test_auto_registered_plugin_command_without_args_hint tests/gateway/test_discord_slash_commands.py::test_auto_registers_missing_gateway_commands tests/gateway/test_discord_slash_commands.py::test_auto_registers_plugin_commands_for_discord tests/gateway/test_discord_slash_commands.py::test_auto_thread_can_be_disabled tests/gateway/test_discord_slash_commands.py::test_auto_thread_creates_thread_and_redirects tests/gateway/test_discord_slash_commands.py::test_auto_thread_enabled_by_default_slash_commands tests/gateway/test_discord_slash_commands.py::test_auto_thread_skips_threads_and_dms tests/gateway/test_discord_slash_commands.py::test_build_slash_event_preserves_thread_context tests/gateway/test_discord_slash_commands.py::test_build_slash_event_uses_group_context_for_channels tests/gateway/test_discord_slash_commands.py::test_discord_auto_thread_config_bridge tests/gateway/test_discord_slash_commands.py::test_dispatch_thread_session_builds_thread_event tests/gateway/test_discord_slash_commands.py::test_handle_thread_create_slash_dispatches_session_when_message_provided tests/gateway/test_discord_slash_commands.py::test_handle_thread_create_slash_falls_back_to_seed_message tests/gateway/test_discord_slash_commands.py::test_handle_thread_create_slash_no_dispatch_without_message tests/gateway/test_discord_slash_commands.py::test_handle_thread_create_slash_reports_failure tests/gateway/test_discord_slash_commands.py::test_handle_thread_create_slash_reports_success tests/gateway/test_discord_slash_commands.py::test_plugin_command_name_conflict_skipped tests/gateway/test_discord_slash_commands.py::test_register_skill_command_autocomplete_filters_by_name_and_description tests/gateway/test_discord_slash_commands.py::test_register_skill_command_callback_dispatches_by_name tests/gateway/test_discord_slash_commands.py::test_register_skill_command_empty_skills_no_command tests/gateway/test_discord_slash_commands.py::test_register_skill_command_handles_unknown_skill_gracefully tests/gateway/test_discord_slash_commands.py::test_register_skill_command_is_flat_not_nested tests/gateway/test_discord_slash_commands.py::test_register_skill_command_payload_fits_discord_8kb_limit tests/gateway/test_discord_slash_commands.py::test_registers_native_restart_slash_command tests/gateway/test_discord_slash_commands.py::test_registers_native_thread_slash_command tests/gateway/test_discord_slash_commands.py::test_slash_command_registration_stays_under_discord_limit tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_default_messages_accepted tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_new_member_ignored tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_own_default_messages_still_ignored tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_pins_add_ignored tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_premium_guild_subscription_ignored tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_recipient_add_ignored tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_reply_messages_accepted tests/gateway/test_discord_system_messages.py::TestDiscordSystemMessageFilter::test_thread_rename_ignored tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_capacity_keeps_newest_thread_when_existing_state_is_full tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_caps_at_max_tracked_threads tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_corrupted_state_file_falls_back_to_empty tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_duplicate_track_does_not_double_save tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_missing_hermes_home_does_not_crash tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_starts_empty_when_no_state_file tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_threads_survive_restart tests/gateway/test_discord_thread_persistence.py::TestDiscordThreadPersistence::test_track_thread_persists_to_disk tests/gateway/test_display_config.py::TestBackwardCompat::test_legacy_overrides_only_for_tool_progress tests/gateway/test_display_config.py::TestBackwardCompat::test_legacy_overrides_read tests/gateway/test_display_config.py::TestBackwardCompat::test_new_platforms_takes_precedence_over_legacy tests/gateway/test_display_config.py::TestCleanupProgress::test_default_off_for_all_platforms tests/gateway/test_display_config.py::TestCleanupProgress::test_global_true_applies_to_all_platforms tests/gateway/test_display_config.py::TestCleanupProgress::test_per_platform_override_wins tests/gateway/test_display_config.py::TestCleanupProgress::test_yaml_off_string_normalises_to_false tests/gateway/test_display_config.py::TestCleanupProgress::test_yaml_true_string_normalises_to_true tests/gateway/test_display_config.py::TestConfigMigration::test_migration_creates_platforms_entries tests/gateway/test_display_config.py::TestConfigMigration::test_migration_preserves_existing_platforms_entries tests/gateway/test_display_config.py::TestPlatformDefaults::test_high_tier_platforms tests/gateway/test_display_config.py::TestPlatformDefaults::test_high_tier_streaming_defaults_to_none tests/gateway/test_display_config.py::TestPlatformDefaults::test_low_tier_platforms tests/gateway/test_display_config.py::TestPlatformDefaults::test_low_tier_streaming_defaults_to_false tests/gateway/test_display_config.py::TestPlatformDefaults::test_medium_tier_platforms tests/gateway/test_display_config.py::TestPlatformDefaults::test_minimal_tier_platforms tests/gateway/test_display_config.py::TestPlatformDefaults::test_slack_defaults_tool_progress_off tests/gateway/test_display_config.py::TestPlatformDefaults::test_telegram_mobile_chatter_can_opt_in tests/gateway/test_display_config.py::TestPlatformDefaults::test_telegram_mobile_chatter_defaults tests/gateway/test_display_config.py::TestPlatformDefaults::test_whatsapp_cloud_locked_to_low_tier_until_edit_message_lands tests/gateway/test_display_config.py::TestResolveDisplaySetting::test_explicit_platform_override_wins tests/gateway/test_display_config.py::TestResolveDisplaySetting::test_fallback_parameter_used_last tests/gateway/test_display_config.py::TestResolveDisplaySetting::test_global_default_for_unknown_platform tests/gateway/test_display_config.py::TestResolveDisplaySetting::test_global_setting_when_no_platform_override tests/gateway/test_display_config.py::TestResolveDisplaySetting::test_platform_default_when_no_user_config tests/gateway/test_display_config.py::TestResolveDisplaySetting::test_platform_override_only_affects_that_platform tests/gateway/test_display_config.py::TestStreamingPerPlatform::test_explicit_false_disables tests/gateway/test_display_config.py::TestStreamingPerPlatform::test_explicit_true_enables tests/gateway/test_display_config.py::TestStreamingPerPlatform::test_global_display_streaming_is_cli_only tests/gateway/test_display_config.py::TestStreamingPerPlatform::test_none_means_follow_global tests/gateway/test_display_config.py::TestToolProgressGrouping::test_case_insensitive tests/gateway/test_display_config.py::TestToolProgressGrouping::test_default_is_accumulate tests/gateway/test_display_config.py::TestToolProgressGrouping::test_global_separate tests/gateway/test_display_config.py::TestToolProgressGrouping::test_invalid_value_falls_back_to_accumulate tests/gateway/test_display_config.py::TestToolProgressGrouping::test_platform_override_wins tests/gateway/test_display_config.py::TestYAMLNormalisation::test_platform_override_false_tool_progress tests/gateway/test_display_config.py::TestYAMLNormalisation::test_show_reasoning_string_true tests/gateway/test_display_config.py::TestYAMLNormalisation::test_tool_preview_length_string tests/gateway/test_display_config.py::TestYAMLNormalisation::test_tool_progress_false_normalised_to_off tests/gateway/test_display_config.py::TestYAMLNormalisation::test_tool_progress_true_normalised_to_all tests/gateway/test_dm_topics.py::test_build_message_event_dm_from_user_none_falls_back_to_chat_id tests/gateway/test_dm_topics.py::test_build_message_event_dm_from_user_present_uses_user tests/gateway/test_dm_topics.py::test_build_message_event_filters_non_topic_dm_thread_id tests/gateway/test_dm_topics.py::test_build_message_event_group_from_user_none_stays_none tests/gateway/test_dm_topics.py::test_build_message_event_no_auto_skill_without_binding tests/gateway/test_dm_topics.py::test_build_message_event_no_auto_skill_without_thread tests/gateway/test_dm_topics.py::test_build_message_event_preserves_true_dm_topic_thread_id tests/gateway/test_dm_topics.py::test_build_message_event_sets_auto_skill tests/gateway/test_dm_topics.py::test_cache_dm_topic_from_message tests/gateway/test_dm_topics.py::test_cache_dm_topic_from_message_no_overwrite tests/gateway/test_dm_topics.py::test_create_dm_topic_handles_duplicate_error tests/gateway/test_dm_topics.py::test_create_dm_topic_handles_generic_error tests/gateway/test_dm_topics.py::test_create_dm_topic_returns_none_without_bot tests/gateway/test_dm_topics.py::test_ensure_dm_topic_creates_on_demand_and_persists tests/gateway/test_dm_topics.py::test_ensure_dm_topic_force_create_replaces_persisted_thread_id tests/gateway/test_dm_topics.py::test_get_dm_topic_info_finds_cached_topic tests/gateway/test_dm_topics.py::test_get_dm_topic_info_hot_reloads_from_config tests/gateway/test_dm_topics.py::test_get_dm_topic_info_returns_none_for_none_thread tests/gateway/test_dm_topics.py::test_get_dm_topic_info_returns_none_for_unknown tests/gateway/test_dm_topics.py::test_get_dm_topic_info_returns_none_without_config tests/gateway/test_dm_topics.py::test_group_topic_chat_id_int_string_coercion tests/gateway/test_dm_topics.py::test_group_topic_no_config tests/gateway/test_dm_topics.py::test_group_topic_no_skill_binding tests/gateway/test_dm_topics.py::test_group_topic_skill_binding tests/gateway/test_dm_topics.py::test_group_topic_skill_binding_second_topic tests/gateway/test_dm_topics.py::test_group_topic_unmapped_chat_id tests/gateway/test_dm_topics.py::test_group_topic_unmapped_thread_id tests/gateway/test_dm_topics.py::test_persist_dm_topic_thread_id_preserves_config_on_write_failure tests/gateway/test_dm_topics.py::test_persist_dm_topic_thread_id_replaces_existing_when_requested tests/gateway/test_dm_topics.py::test_persist_dm_topic_thread_id_skips_if_already_set tests/gateway/test_dm_topics.py::test_persist_dm_topic_thread_id_writes_config tests/gateway/test_dm_topics.py::test_setup_dm_topics_creates_when_no_thread_id tests/gateway/test_dm_topics.py::test_setup_dm_topics_loads_persisted_thread_ids tests/gateway/test_dm_topics.py::test_setup_dm_topics_mixed_persisted_and_new tests/gateway/test_dm_topics.py::test_setup_dm_topics_no_config tests/gateway/test_dm_topics.py::test_setup_dm_topics_skips_empty_config tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_basic_caching tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_dot_dot_filename_handled tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_empty_filename_uses_fallback tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_filename_preserved_in_path tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_none_filename_uses_fallback tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_null_bytes_stripped tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_path_traversal_blocked tests/gateway/test_document_cache.py::TestCacheDocumentFromBytes::test_unique_filenames tests/gateway/test_document_cache.py::TestCacheMediaBytes::test_invalid_image_returns_none tests/gateway/test_document_cache.py::TestCacheMediaBytes::test_mime_only_resolves_extension tests/gateway/test_document_cache.py::TestCacheMediaBytes::test_mp4_routes_to_video tests/gateway/test_document_cache.py::TestCacheMediaBytes::test_native_photo_without_filename_uses_default_kind tests/gateway/test_document_cache.py::TestCacheMediaBytes::test_pdf_routes_to_document tests/gateway/test_document_cache.py::TestCacheMediaBytes::test_png_routes_to_image tests/gateway/test_document_cache.py::TestCacheMediaBytes::test_unsupported_document_returns_none tests/gateway/test_document_cache.py::TestCleanupDocumentCache::test_empty_cache_dir tests/gateway/test_document_cache.py::TestCleanupDocumentCache::test_keeps_recent_files tests/gateway/test_document_cache.py::TestCleanupDocumentCache::test_removes_old_files tests/gateway/test_document_cache.py::TestCleanupDocumentCache::test_returns_removed_count tests/gateway/test_document_cache.py::TestGetDocumentCacheDir::test_creates_directory tests/gateway/test_document_cache.py::TestGetDocumentCacheDir::test_returns_existing_directory tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_all_extensions_have_mime_types tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.doc] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.docx] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.md] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.pdf] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.ppt] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.pptx] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.txt] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.xls] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.xlsx] tests/gateway/test_document_cache.py::TestSupportedDocumentTypes::test_expected_extensions_present[.zip] tests/gateway/test_document_context_note.py::TestBinaryDocumentNote::test_binary_note_distinct_from_text_note tests/gateway/test_document_context_note.py::TestBinaryDocumentNote::test_binary_note_guides_extraction[application/octet-stream] tests/gateway/test_document_context_note.py::TestBinaryDocumentNote::test_binary_note_guides_extraction[application/pdf] tests/gateway/test_document_context_note.py::TestBinaryDocumentNote::test_binary_note_guides_extraction[application/vnd.openxmlformats-officedocument.spreadsheetml.sheet] tests/gateway/test_document_context_note.py::TestBinaryDocumentNote::test_binary_note_guides_extraction[application/vnd.openxmlformats-officedocument.wordprocessingml.document] tests/gateway/test_document_context_note.py::TestTextDocumentNote::test_text_note_mentions_included_content_and_path[text/csv] tests/gateway/test_document_context_note.py::TestTextDocumentNote::test_text_note_mentions_included_content_and_path[text/markdown] tests/gateway/test_document_context_note.py::TestTextDocumentNote::test_text_note_mentions_included_content_and_path[text/plain] tests/gateway/test_duplicate_reply_suppression.py::TestBaseInterruptSuppression::test_response_not_suppressed_with_interrupt_but_no_pending tests/gateway/test_duplicate_reply_suppression.py::TestBaseInterruptSuppression::test_response_not_suppressed_without_interrupt tests/gateway/test_duplicate_reply_suppression.py::TestBaseInterruptSuppression::test_stale_response_suppressed_when_interrupted tests/gateway/test_duplicate_reply_suppression.py::TestCancellationHandlerDeliveryConfirmation::test_best_effort_fails_stays_false tests/gateway/test_duplicate_reply_suppression.py::TestCancellationHandlerDeliveryConfirmation::test_best_effort_succeeds_sets_true tests/gateway/test_duplicate_reply_suppression.py::TestCancellationHandlerDeliveryConfirmation::test_old_behavior_would_have_promoted_partial tests/gateway/test_duplicate_reply_suppression.py::TestCancellationHandlerDeliveryConfirmation::test_partial_only_no_accumulated_stays_false tests/gateway/test_duplicate_reply_suppression.py::TestCancellationHandlerDeliveryConfirmation::test_preserves_existing_true tests/gateway/test_duplicate_reply_suppression.py::TestEmptyResponseNotSuppressed::test_empty_sentinel_not_suppressed_with_already_sent tests/gateway/test_duplicate_reply_suppression.py::TestEmptyResponseNotSuppressed::test_empty_string_not_suppressed_with_already_sent tests/gateway/test_duplicate_reply_suppression.py::TestEmptyResponseNotSuppressed::test_failed_empty_response_never_suppressed tests/gateway/test_duplicate_reply_suppression.py::TestEmptyResponseNotSuppressed::test_none_response_not_suppressed_with_already_sent tests/gateway/test_duplicate_reply_suppression.py::TestEmptyResponseNotSuppressed::test_real_response_still_suppressed_only_when_final_delivery_confirmed tests/gateway/test_duplicate_reply_suppression.py::TestFinalContentDeliveredSuppression::test_content_delivered_but_final_edit_failed_suppresses tests/gateway/test_duplicate_reply_suppression.py::TestFinalContentDeliveredSuppression::test_intermediate_text_only_does_not_suppress tests/gateway/test_duplicate_reply_suppression.py::TestOnlyFinalStreamDeliverySuppressesFinalSend::test_already_sent_not_set_on_failed_response tests/gateway/test_duplicate_reply_suppression.py::TestOnlyFinalStreamDeliverySuppressesFinalSend::test_already_sent_not_set_when_nothing_sent tests/gateway/test_duplicate_reply_suppression.py::TestOnlyFinalStreamDeliverySuppressesFinalSend::test_already_sent_set_on_final_response_sent tests/gateway/test_duplicate_reply_suppression.py::TestOnlyFinalStreamDeliverySuppressesFinalSend::test_partial_stream_output_does_not_set_already_sent tests/gateway/test_duplicate_reply_suppression.py::TestQueuedMessageAlreadyStreamed::test_queued_path_detects_confirmed_final_stream_delivery tests/gateway/test_duplicate_reply_suppression.py::TestQueuedMessageAlreadyStreamed::test_queued_path_detects_previewed_response_delivery tests/gateway/test_duplicate_reply_suppression.py::TestQueuedMessageAlreadyStreamed::test_queued_path_only_skips_send_when_final_response_was_streamed tests/gateway/test_duplicate_reply_suppression.py::TestQueuedMessageAlreadyStreamed::test_queued_path_sends_when_not_streamed tests/gateway/test_duplicate_reply_suppression.py::TestQueuedMessageAlreadyStreamed::test_queued_path_with_no_stream_consumer tests/gateway/test_email.py::TestCheckRequirements::test_requirements_empty_env tests/gateway/test_email.py::TestCheckRequirements::test_requirements_met tests/gateway/test_email.py::TestCheckRequirements::test_requirements_not_met tests/gateway/test_email.py::TestConfigEnvOverrides::test_email_config_loaded_from_env tests/gateway/test_email.py::TestConfigEnvOverrides::test_email_home_channel_loaded tests/gateway/test_email.py::TestConfigEnvOverrides::test_email_not_loaded_without_env tests/gateway/test_email.py::TestConnectDisconnect::test_connect_imap_failure tests/gateway/test_email.py::TestConnectDisconnect::test_connect_smtp_failure tests/gateway/test_email.py::TestConnectDisconnect::test_connect_success tests/gateway/test_email.py::TestConnectDisconnect::test_disconnect_cancels_poll tests/gateway/test_email.py::TestConnectSmtp::test_ipv4_connection_does_not_mutate_global_resolver tests/gateway/test_email.py::TestConnectSmtp::test_ipv6_timeout_falls_back_to_ipv4 tests/gateway/test_email.py::TestConnectSmtp::test_port_465_ipv6_fallback tests/gateway/test_email.py::TestConnectSmtp::test_port_465_uses_smtp_ssl tests/gateway/test_email.py::TestConnectSmtp::test_port_587_uses_smtp_with_starttls tests/gateway/test_email.py::TestConnectSmtp::test_tls_verification_error_does_not_retry_ipv4 tests/gateway/test_email.py::TestDispatchMessage::test_allowlisted_sender_proceeds tests/gateway/test_email.py::TestDispatchMessage::test_document_attachment_sets_document_type tests/gateway/test_email.py::TestDispatchMessage::test_empty_allowlist_allows_all tests/gateway/test_email.py::TestDispatchMessage::test_empty_body_handled tests/gateway/test_email.py::TestDispatchMessage::test_image_attachment_sets_photo_type tests/gateway/test_email.py::TestDispatchMessage::test_mixed_image_and_document_prefers_document tests/gateway/test_email.py::TestDispatchMessage::test_non_allowlisted_sender_dropped tests/gateway/test_email.py::TestDispatchMessage::test_reply_subject_not_duplicated tests/gateway/test_email.py::TestDispatchMessage::test_self_message_filtered tests/gateway/test_email.py::TestDispatchMessage::test_source_built_correctly tests/gateway/test_email.py::TestDispatchMessage::test_subject_included_in_text tests/gateway/test_email.py::TestExtractAttachments::test_document_attachment tests/gateway/test_email.py::TestExtractAttachments::test_image_attachment tests/gateway/test_email.py::TestExtractAttachments::test_no_attachments tests/gateway/test_email.py::TestExtractTextBody::test_empty_body tests/gateway/test_email.py::TestExtractTextBody::test_html_body_fallback tests/gateway/test_email.py::TestExtractTextBody::test_multipart_html_only tests/gateway/test_email.py::TestExtractTextBody::test_multipart_prefers_plain tests/gateway/test_email.py::TestExtractTextBody::test_plain_text_body tests/gateway/test_email.py::TestFetchNewMessages::test_fetch_extracts_sender_name tests/gateway/test_email.py::TestFetchNewMessages::test_fetch_handles_imap_error tests/gateway/test_email.py::TestFetchNewMessages::test_fetch_no_unseen_messages tests/gateway/test_email.py::TestFetchNewMessages::test_fetch_skips_seen_uids tests/gateway/test_email.py::TestHelperFunctions::test_decode_header_encoded tests/gateway/test_email.py::TestHelperFunctions::test_decode_header_plain tests/gateway/test_email.py::TestHelperFunctions::test_extract_email_address_bare tests/gateway/test_email.py::TestHelperFunctions::test_extract_email_address_uppercase tests/gateway/test_email.py::TestHelperFunctions::test_extract_email_address_with_name tests/gateway/test_email.py::TestHelperFunctions::test_strip_html_basic tests/gateway/test_email.py::TestHelperFunctions::test_strip_html_br_tags tests/gateway/test_email.py::TestHelperFunctions::test_strip_html_entities tests/gateway/test_email.py::TestImapConnectionCleanup::test_imap_logout_called_on_early_return tests/gateway/test_email.py::TestImapConnectionCleanup::test_imap_logout_called_on_uid_fetch_failure tests/gateway/test_email.py::TestImapIdExtensionForNetEase::test_connect_sends_imap_id_after_login tests/gateway/test_email.py::TestImapIdExtensionForNetEase::test_fetch_new_messages_sends_imap_id_after_login tests/gateway/test_email.py::TestImapIdExtensionForNetEase::test_send_imap_id_swallows_errors_for_non_supporting_servers tests/gateway/test_email.py::TestPollLoop::test_check_inbox_dispatches_messages tests/gateway/test_email.py::TestSendEmailStandalone::test_send_email_tool_failure tests/gateway/test_email.py::TestSendEmailStandalone::test_send_email_tool_not_configured tests/gateway/test_email.py::TestSendEmailStandalone::test_send_email_tool_success tests/gateway/test_email.py::TestSendMethods::test_get_chat_info tests/gateway/test_email.py::TestSendMethods::test_send_calls_smtp tests/gateway/test_email.py::TestSendMethods::test_send_document_with_attachment tests/gateway/test_email.py::TestSendMethods::test_send_failure_returns_error tests/gateway/test_email.py::TestSendMethods::test_send_image_includes_url tests/gateway/test_email.py::TestSendMethods::test_send_typing_is_noop tests/gateway/test_email.py::TestSmtpConnectionCleanup::test_smtp_close_called_when_quit_also_fails tests/gateway/test_email.py::TestSmtpConnectionCleanup::test_smtp_quit_called_on_send_message_failure tests/gateway/test_email.py::TestThreadContext::test_no_thread_context_uses_default_subject tests/gateway/test_email.py::TestThreadContext::test_reply_does_not_double_re tests/gateway/test_email.py::TestThreadContext::test_reply_uses_re_prefix tests/gateway/test_email.py::TestThreadContext::test_thread_context_stored_after_dispatch tests/gateway/test_empty_model_recovery.py::test_bare_runner_without_cache_attr_does_not_crash tests/gateway/test_empty_model_recovery.py::test_cold_start_empty_model_does_not_crash tests/gateway/test_empty_model_recovery.py::test_empty_model_new_session_recovers_global_last_good tests/gateway/test_empty_model_recovery.py::test_empty_model_recovers_session_last_good tests/gateway/test_empty_model_recovery.py::test_has_pending_fallback_empty_chain tests/gateway/test_empty_model_recovery.py::test_has_pending_fallback_exhausted_chain tests/gateway/test_empty_model_recovery.py::test_has_pending_fallback_missing_attrs tests/gateway/test_empty_model_recovery.py::test_has_pending_fallback_with_chain tests/gateway/test_empty_model_recovery.py::test_normal_turn_caches_last_resolved_model tests/gateway/test_ephemeral_reply.py::test_process_message_ephemeral_reply_does_not_auto_upload_bare_paths tests/gateway/test_ephemeral_reply.py::test_process_message_incapable_platform_does_not_schedule_delete tests/gateway/test_ephemeral_reply.py::test_process_message_plain_string_behaves_unchanged tests/gateway/test_ephemeral_reply.py::test_process_message_unwraps_ephemeral_before_send tests/gateway/test_ephemeral_reply.py::test_schedule_ephemeral_delete_calls_delete_after_ttl tests/gateway/test_ephemeral_reply.py::test_schedule_ephemeral_delete_outside_event_loop_is_noop tests/gateway/test_ephemeral_reply.py::test_schedule_ephemeral_delete_swallows_errors tests/gateway/test_ephemeral_reply.py::test_unwrap_ephemeral_default_ttl_from_config tests/gateway/test_ephemeral_reply.py::test_unwrap_ephemeral_default_ttl_zero_disables tests/gateway/test_ephemeral_reply.py::test_unwrap_ephemeral_explicit_ttl_on_capable_adapter tests/gateway/test_ephemeral_reply.py::test_unwrap_ephemeral_handles_unreadable_config tests/gateway/test_ephemeral_reply.py::test_unwrap_ephemeral_zeros_ttl_on_incapable_adapter tests/gateway/test_ephemeral_reply.py::test_unwrap_none_is_passthrough tests/gateway/test_ephemeral_reply.py::test_unwrap_plain_string_is_passthrough tests/gateway/test_extract_local_files.py::TestBasicDetection::test_absolute_path_image tests/gateway/test_extract_local_files.py::TestBasicDetection::test_archive_extensions tests/gateway/test_extract_local_files.py::TestBasicDetection::test_audio_extensions tests/gateway/test_extract_local_files.py::TestBasicDetection::test_case_insensitive_extension tests/gateway/test_extract_local_files.py::TestBasicDetection::test_chart_pdf_path tests/gateway/test_extract_local_files.py::TestBasicDetection::test_document_extensions tests/gateway/test_extract_local_files.py::TestBasicDetection::test_html_extension tests/gateway/test_extract_local_files.py::TestBasicDetection::test_image_extensions tests/gateway/test_extract_local_files.py::TestBasicDetection::test_multiple_paths tests/gateway/test_extract_local_files.py::TestBasicDetection::test_path_at_end_of_line tests/gateway/test_extract_local_files.py::TestBasicDetection::test_path_at_line_start tests/gateway/test_extract_local_files.py::TestBasicDetection::test_path_with_dots_in_directory tests/gateway/test_extract_local_files.py::TestBasicDetection::test_path_with_hyphens tests/gateway/test_extract_local_files.py::TestBasicDetection::test_presentation_extensions tests/gateway/test_extract_local_files.py::TestBasicDetection::test_spreadsheet_and_data_extensions tests/gateway/test_extract_local_files.py::TestBasicDetection::test_tilde_path_image tests/gateway/test_extract_local_files.py::TestBasicDetection::test_video_extensions tests/gateway/test_extract_local_files.py::TestCodeBlockExclusion::test_fenced_code_block_skipped tests/gateway/test_extract_local_files.py::TestCodeBlockExclusion::test_inline_code_skipped tests/gateway/test_extract_local_files.py::TestCodeBlockExclusion::test_mixed_inline_code_and_bare_path tests/gateway/test_extract_local_files.py::TestCodeBlockExclusion::test_multiline_fenced_block tests/gateway/test_extract_local_files.py::TestCodeBlockExclusion::test_path_outside_code_block_still_matched tests/gateway/test_extract_local_files.py::TestDeduplication::test_duplicate_paths_deduplicated tests/gateway/test_extract_local_files.py::TestDeduplication::test_tilde_and_expanded_same_file tests/gateway/test_extract_local_files.py::TestEdgeCases::test_bare_filename_not_matched tests/gateway/test_extract_local_files.py::TestEdgeCases::test_deep_nested_path tests/gateway/test_extract_local_files.py::TestEdgeCases::test_empty_string tests/gateway/test_extract_local_files.py::TestEdgeCases::test_no_media_extensions tests/gateway/test_extract_local_files.py::TestEdgeCases::test_path_followed_by_punctuation tests/gateway/test_extract_local_files.py::TestEdgeCases::test_path_in_parentheses tests/gateway/test_extract_local_files.py::TestEdgeCases::test_path_in_quotes tests/gateway/test_extract_local_files.py::TestEdgeCases::test_path_with_spaces_not_matched tests/gateway/test_extract_local_files.py::TestEdgeCases::test_relative_path_not_matched tests/gateway/test_extract_local_files.py::TestEdgeCases::test_relative_windows_path_not_matched tests/gateway/test_extract_local_files.py::TestEdgeCases::test_windows_drive_letter_paths_matched[Path e:/audio/track.mp3 done-e:/audio/track.mp3] tests/gateway/test_extract_local_files.py::TestEdgeCases::test_windows_drive_letter_paths_matched[See C:/Users/test/image.png here-C:/Users/test/image.png] tests/gateway/test_extract_local_files.py::TestEdgeCases::test_windows_drive_letter_paths_matched[See C:\\Users\\test\\image.png here-C:\\Users\\test\\image.png] tests/gateway/test_extract_local_files.py::TestEdgeCases::test_windows_drive_letter_paths_matched[Video at D:/data/clip.mp4 ready-D:/data/clip.mp4] tests/gateway/test_extract_local_files.py::TestIsfileGuard::test_nonexistent_path_skipped tests/gateway/test_extract_local_files.py::TestIsfileGuard::test_only_existing_paths_extracted tests/gateway/test_extract_local_files.py::TestTextCleanup::test_excessive_blank_lines_collapsed tests/gateway/test_extract_local_files.py::TestTextCleanup::test_no_paths_text_unchanged tests/gateway/test_extract_local_files.py::TestTextCleanup::test_only_path_in_text tests/gateway/test_extract_local_files.py::TestTextCleanup::test_path_removed_from_text tests/gateway/test_extract_local_files.py::TestTextCleanup::test_tilde_form_cleaned_from_text tests/gateway/test_extract_local_files.py::TestURLRejection::test_file_url_not_matched tests/gateway/test_extract_local_files.py::TestURLRejection::test_http_url_not_matched tests/gateway/test_extract_local_files.py::TestURLRejection::test_https_url_not_matched tests/gateway/test_fallback_eviction.py::TestFallbackEvictionGating::test_failed_run_does_not_evict_cached_agent tests/gateway/test_fallback_eviction.py::TestFallbackEvictionGating::test_missing_failed_key_treated_as_not_failed tests/gateway/test_fallback_eviction.py::TestFallbackEvictionGating::test_none_result_treated_as_not_failed tests/gateway/test_fallback_eviction.py::TestFallbackEvictionGating::test_successful_run_allows_eviction tests/gateway/test_fast_command.py::test_handle_fast_command_persists_config tests/gateway/test_fast_command.py::test_run_agent_passes_priority_processing_to_gateway_agent tests/gateway/test_fast_command.py::test_turn_route_injects_priority_processing_without_changing_runtime tests/gateway/test_fast_command.py::test_turn_route_skips_priority_processing_for_unsupported_models tests/gateway/test_feishu.py::TestAdapterBehavior::test_bot_origin_reactions_are_dropped_to_avoid_feedback_loops tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_event_handler_registers_reaction_and_card_processors tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_extracts_title_and_links tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_keeps_fence_like_code_lines_inside_code_block tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_keeps_full_markdown_text tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_preserves_trailing_spaces_in_code_block tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_splits_multiple_fenced_code_blocks tests/gateway/test_feishu.py::TestAdapterBehavior::test_build_post_payload_wraps_markdown_in_md_tag tests/gateway/test_feishu.py::TestAdapterBehavior::test_dedup_state_persists_across_adapter_restart tests/gateway/test_feishu.py::TestAdapterBehavior::test_default_group_policy_fallback_for_chats_without_explicit_rule tests/gateway/test_feishu.py::TestAdapterBehavior::test_download_remote_document_reads_response_before_httpx_client_closes tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_audio_message_downloads_and_caches tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_file_message_downloads_and_caches tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_image_message_downloads_and_caches tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_interactive_message_as_text_summary tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_media_message_with_image_mime_becomes_photo tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_media_message_with_video_mime_becomes_video tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_merge_forward_message_as_text_summary tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_as_text tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_downloads_embedded_resources tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_uses_first_available_language_block tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_post_message_with_rich_elements_does_not_drop_content tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_share_chat_message_as_text_summary tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_text_file_injects_content tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_text_from_raw_content_uses_relation_message_fallbacks tests/gateway/test_feishu.py::TestAdapterBehavior::test_extract_text_message_starting_with_slash_becomes_command tests/gateway/test_feishu.py::TestAdapterBehavior::test_global_admins_bypass_all_group_rules tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_allowlist_and_mention_both_required tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_matches_bot_name_when_only_name_available tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_matches_bot_open_id_when_configured tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_requires_mentions_even_when_policy_open tests/gateway/test_feishu.py::TestAdapterBehavior::test_group_message_with_other_user_mention_is_rejected_when_bot_identity_unknown tests/gateway/test_feishu.py::TestAdapterBehavior::test_media_batch_merges_rapid_photo_messages tests/gateway/test_feishu.py::TestAdapterBehavior::test_message_event_submits_to_adapter_loop tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_admin_only_policy_requires_admin tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_allowlist_policy_gates_by_sender tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_blacklist_policy_blocks_specific_users tests/gateway/test_feishu.py::TestAdapterBehavior::test_per_group_disabled_policy_blocks_all tests/gateway/test_feishu.py::TestAdapterBehavior::test_process_inbound_group_message_keeps_group_type_when_chat_lookup_falls_back tests/gateway/test_feishu.py::TestAdapterBehavior::test_process_inbound_message_fetches_reply_to_text tests/gateway/test_feishu.py::TestAdapterBehavior::test_process_inbound_message_uses_event_sender_identity_only tests/gateway/test_feishu.py::TestAdapterBehavior::test_reaction_on_our_own_bot_message_is_routed tests/gateway/test_feishu.py::TestAdapterBehavior::test_reaction_on_peer_bot_message_is_not_routed tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_animation_degrades_to_document_send tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_document_reply_uses_thread_flag tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_document_uploads_file_and_sends_file_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_document_with_caption_uses_single_post_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_does_not_retry_deterministic_api_failure tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_falls_back_to_text_when_post_payload_is_rejected tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_falls_back_to_text_when_post_response_is_unsuccessful tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_image_downloads_then_uses_native_image_send tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_image_file_uploads_image_and_sends_image_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_image_file_with_caption_uses_single_post_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_replies_in_thread_when_thread_metadata_present tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_retries_transient_failure tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_splits_fenced_code_blocks_into_separate_post_rows tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_uses_metadata_reply_target_for_threaded_feishu_topic tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_uses_post_for_advanced_markdown_lines tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_uses_post_for_inline_markdown tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_video_uploads_file_and_sends_media_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_send_voice_uploads_opus_and_sends_audio_message tests/gateway/test_feishu.py::TestAdapterBehavior::test_text_batch_flushes_when_message_count_limit_is_hit tests/gateway/test_feishu.py::TestAdapterBehavior::test_text_batch_merges_rapid_messages_into_single_event tests/gateway/test_feishu.py::TestAdapterBehavior::test_url_verification_requires_configured_verification_token tests/gateway/test_feishu.py::TestAdapterBehavior::test_user_reaction_with_managed_emoji_is_still_routed tests/gateway/test_feishu.py::TestAdapterBehavior::test_webhook_request_uses_same_message_dispatch_path tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_accepts_custom_ws_ping_values tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_accepts_custom_ws_reconnect_values tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_ignores_invalid_ws_ping_values tests/gateway/test_feishu.py::TestAdapterModule::test_load_settings_uses_sdk_defaults_for_invalid_ws_reconnect_values tests/gateway/test_feishu.py::TestAdapterModule::test_runtime_ws_overrides_reapply_after_sdk_configure tests/gateway/test_feishu.py::TestBotNameResolution::test_api_failure_returns_none_and_does_not_poison_cache tests/gateway/test_feishu.py::TestBotNameResolution::test_bot_absent_from_response_is_not_cached tests/gateway/test_feishu.py::TestBotNameResolution::test_empty_name_in_response_is_negative_cached tests/gateway/test_feishu.py::TestBotNameResolution::test_fetches_and_caches_bot_name tests/gateway/test_feishu.py::TestBotNameResolution::test_non_zero_code_returns_none tests/gateway/test_feishu.py::TestBotNameResolution::test_returns_cached_bot_name_without_api_call tests/gateway/test_feishu.py::TestChatLockEviction::test_chat_locks_is_ordered_dict tests/gateway/test_feishu.py::TestChatLockEviction::test_eviction_skips_held_locks tests/gateway/test_feishu.py::TestChatLockEviction::test_lru_eviction_respects_recent_access tests/gateway/test_feishu.py::TestChatLockEviction::test_same_id_returns_same_lock_and_stays_bounded tests/gateway/test_feishu.py::TestConfigEnvOverrides::test_feishu_config_loaded_from_env tests/gateway/test_feishu.py::TestConfigEnvOverrides::test_feishu_home_channel_loaded tests/gateway/test_feishu.py::TestConfigEnvOverrides::test_feishu_in_connected_platforms tests/gateway/test_feishu.py::TestDedupTTL::test_duplicate_within_ttl_is_rejected tests/gateway/test_feishu.py::TestDedupTTL::test_expired_entry_is_not_considered_duplicate tests/gateway/test_feishu.py::TestDedupTTL::test_load_backward_compat_list_format tests/gateway/test_feishu.py::TestDedupTTL::test_load_tolerates_malformed_timestamp_values tests/gateway/test_feishu.py::TestDedupTTL::test_persist_saves_timestamps_as_dict tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_acquires_scoped_lock_and_disconnect_releases_it tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_rejects_existing_app_lock tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_retries_transient_startup_failure tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_connect_webhook_mode_starts_local_server tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_edit_message_falls_back_to_text_when_post_update_is_rejected tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_edit_message_updates_existing_feishu_message tests/gateway/test_feishu.py::TestFeishuAdapterMessaging::test_get_chat_info_uses_real_feishu_chat_api tests/gateway/test_feishu.py::TestFeishuExtractMessageContent::test_returns_empty_mentions_when_missing tests/gateway/test_feishu.py::TestFeishuExtractMessageContent::test_returns_five_tuple_with_mentions tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_build_mentions_map_string_id_shape tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_extract_text_from_raw_content_accepts_mentions_kwarg tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_fetch_message_text_marks_is_self_via_string_id_shape tests/gateway/test_feishu.py::TestFeishuFetchMessageText::test_fetch_message_text_renders_mentions_without_hint_prefix tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_at_all_announcement tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_bot_plus_alice_plus_bob_build_group tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_mid_text_self_mention_preserved tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_no_mentions_zero_regression tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_post_at_alice_exposes_open_id tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_post_bot_plus_alice_filters_self_from_hint tests/gateway/test_feishu.py::TestFeishuMentionEndToEnd::test_scenario_trailing_self_mention_stripped tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_at_all tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_dedupes_repeated_at_all tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_dedupes_repeated_user tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_falls_back_when_open_id_missing tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_filters_self_mentions tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_multiple_users tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_returns_empty_for_no_refs tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_returns_empty_when_only_self tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_single_user tests/gateway/test_feishu.py::TestFeishuMentionHint::test_hint_uses_unknown_placeholder_when_name_missing tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_falls_back_to_name_when_bot_open_id_not_hydrated tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_handles_at_all tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_marks_self_by_name_fallback tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_marks_self_by_open_id tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_name_match_does_not_override_mismatching_open_id tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_non_self_user tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_returns_empty_for_none_input tests/gateway/test_feishu.py::TestFeishuMentionMap::test_build_mentions_map_tolerates_missing_id_object tests/gateway/test_feishu.py::TestFeishuMessageNormalization::test_normalize_interactive_card_preserves_title_body_and_actions tests/gateway/test_feishu.py::TestFeishuMessageNormalization::test_normalize_merge_forward_preserves_summary_lines tests/gateway/test_feishu.py::TestFeishuMessageNormalization::test_normalize_share_chat_exposes_summary_and_metadata tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_at_all_rendered_as_english_literal tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_backward_compatible_without_map tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_mention_for_missing_map_entry_degrades_to_space tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_renders_mention_with_display_name tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_renders_self_mention_with_name tests/gateway/test_feishu.py::TestFeishuNormalizeText::test_unknown_placeholder_degrades_to_space tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_post_message_marks_self_via_mentions_map_lookup tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_at_all_in_text_without_mentions_payload tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_at_all_not_synthesized_if_absent_from_text tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_at_all_surfaces_ref tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_marks_bot_self_mention tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_renders_mention_by_name tests/gateway/test_feishu.py::TestFeishuNormalizeWithMentions::test_text_message_without_mentions_param_is_backward_compatible tests/gateway/test_feishu.py::TestFeishuPostMentionParsing::test_post_at_all_tag_renders_as_at_all tests/gateway/test_feishu.py::TestFeishuPostMentionParsing::test_post_at_tag_falls_back_to_inline_user_name_when_map_misses tests/gateway/test_feishu.py::TestFeishuPostMentionParsing::test_post_at_tag_renders_via_mentions_map tests/gateway/test_feishu.py::TestFeishuPostMentionsBot::test_post_mentions_bot_empty_returns_false tests/gateway/test_feishu.py::TestFeishuPostMentionsBot::test_post_mentions_bot_uses_is_self_flag tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_command_message_never_injects_hint tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_leading_self_mention_stripped_for_command tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_mid_text_self_mention_preserved tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_non_command_message_with_mentions_injects_hint tests/gateway/test_feishu.py::TestFeishuProcessInboundMessage::test_pure_self_mention_message_is_ignored tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_preserves_mid_text_self tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_preserves_trailing_self_before_non_terminal_char tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_returns_input_when_no_self_refs tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_returns_input_when_refs_empty tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_stops_at_first_non_self_token tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_consecutive_leading_self tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_leading_self tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_trailing_self_at_end_of_text tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_strips_trailing_self_with_terminal_punct tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_uses_open_id_fallback_when_name_missing tests/gateway/test_feishu.py::TestFeishuStripLeadingSelf::test_word_boundary_prevents_prefix_collision tests/gateway/test_feishu.py::TestGroupMentionAtAll::test_at_all_in_content_accepts_without_explicit_bot_mention tests/gateway/test_feishu.py::TestGroupMentionAtAll::test_at_all_still_requires_policy_gate tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_overwrites_stale_env_open_id tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_populates_open_id_from_bot_info tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_preserves_env_values_when_bot_info_probe_fails tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_refreshes_env_values_when_bot_info_available tests/gateway/test_feishu.py::TestHydrateBotIdentity::test_hydration_tolerates_probe_failure_and_falls_back_to_app_info tests/gateway/test_feishu.py::TestPendingInboundQueue::test_drainer_drops_queue_when_adapter_shuts_down tests/gateway/test_feishu.py::TestPendingInboundQueue::test_drainer_replays_queued_events_when_loop_becomes_ready tests/gateway/test_feishu.py::TestPendingInboundQueue::test_event_queued_when_loop_not_ready tests/gateway/test_feishu.py::TestPendingInboundQueue::test_normal_path_unchanged_when_loop_ready tests/gateway/test_feishu.py::TestPendingInboundQueue::test_queue_cap_evicts_oldest_beyond_max_depth tests/gateway/test_feishu.py::TestProcessingReactions::test_cache_evicts_oldest_entry_beyond_size_limit tests/gateway/test_feishu.py::TestProcessingReactions::test_cancelled_removes_typing_and_adds_nothing tests/gateway/test_feishu.py::TestProcessingReactions::test_delete_failure_on_failure_outcome_skips_cross_mark tests/gateway/test_feishu.py::TestProcessingReactions::test_delete_failure_on_success_outcome_retains_handle tests/gateway/test_feishu.py::TestProcessingReactions::test_env_disable_short_circuits_both_hooks tests/gateway/test_feishu.py::TestProcessingReactions::test_failure_removes_typing_then_adds_cross_mark tests/gateway/test_feishu.py::TestProcessingReactions::test_failure_without_preceding_start_still_adds_cross_mark tests/gateway/test_feishu.py::TestProcessingReactions::test_start_adds_typing_and_caches_reaction_id tests/gateway/test_feishu.py::TestProcessingReactions::test_start_does_not_cache_when_create_fails tests/gateway/test_feishu.py::TestProcessingReactions::test_start_is_idempotent_for_same_message_id tests/gateway/test_feishu.py::TestProcessingReactions::test_success_removes_typing_and_adds_nothing tests/gateway/test_feishu.py::TestProcessingReactions::test_success_without_preceding_start_is_full_noop tests/gateway/test_feishu.py::TestSenderNameResolution::test_api_failure_returns_none_without_raising tests/gateway/test_feishu.py::TestSenderNameResolution::test_expired_cache_triggers_new_api_call tests/gateway/test_feishu.py::TestSenderNameResolution::test_fetches_and_caches_name_from_api tests/gateway/test_feishu.py::TestSenderNameResolution::test_returns_cached_name_within_ttl tests/gateway/test_feishu.py::TestSenderNameResolution::test_returns_none_when_client_is_none tests/gateway/test_feishu.py::TestWebhookSecurity::test_rate_limit_allows_requests_within_window tests/gateway/test_feishu.py::TestWebhookSecurity::test_rate_limit_blocks_after_exceeding_max tests/gateway/test_feishu.py::TestWebhookSecurity::test_rate_limit_resets_after_window_expires tests/gateway/test_feishu.py::TestWebhookSecurity::test_signature_invalid_rejected tests/gateway/test_feishu.py::TestWebhookSecurity::test_signature_missing_headers_rejected tests/gateway/test_feishu.py::TestWebhookSecurity::test_signature_valid_passes tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_connect_requires_inbound_auth_secret tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_loads_auth_secrets_from_platform_extra tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_request_rejects_bad_signature tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_request_rejects_invalid_json tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_request_rejects_oversized_body tests/gateway/test_feishu.py::TestWebhookSecurity::test_webhook_url_verification_challenge_passes_without_signature tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_already_resolved_update_prompt_returns_no_card tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_drops_action_when_loop_not_ready tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_falls_back_to_open_id_when_name_not_cached tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_ignores_expired_cached_name tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_ignores_missing_approval_id tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_ignores_missing_update_prompt_id tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_no_card_for_non_approval_action tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_rejects_approval_click_from_unauthorized_user tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_rejects_approval_click_when_callback_chat_mismatches tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_returns_card_for_approve_action tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_returns_card_for_deny_action tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_returns_card_for_update_prompt_no tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_returns_card_for_update_prompt_yes tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_update_prompt_chat_mismatch_returns_no_card tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_update_prompt_empty_allowlists_fail_closed tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_update_prompt_schedule_failure_returns_no_card tests/gateway/test_feishu_approval_buttons.py::TestCardActionCallbackResponse::test_update_prompt_unauthorized_operator_returns_no_card tests/gateway/test_feishu_approval_buttons.py::TestFeishuExecApproval::test_multiple_approvals_get_unique_ids tests/gateway/test_feishu_approval_buttons.py::TestFeishuExecApproval::test_not_connected tests/gateway/test_feishu_approval_buttons.py::TestFeishuExecApproval::test_sends_interactive_card tests/gateway/test_feishu_approval_buttons.py::TestFeishuExecApproval::test_stores_approval_state tests/gateway/test_feishu_approval_buttons.py::TestFeishuExecApproval::test_truncates_long_command tests/gateway/test_feishu_approval_buttons.py::TestFeishuUpdatePrompt::test_not_connected tests/gateway/test_feishu_approval_buttons.py::TestFeishuUpdatePrompt::test_send_failure_returns_error tests/gateway/test_feishu_approval_buttons.py::TestFeishuUpdatePrompt::test_sends_interactive_card tests/gateway/test_feishu_approval_buttons.py::TestFeishuUpdatePrompt::test_stores_prompt_state tests/gateway/test_feishu_approval_buttons.py::TestNonApprovalCardAction::test_routes_as_synthetic_command tests/gateway/test_feishu_approval_buttons.py::TestResolveApproval::test_already_resolved_drops_silently tests/gateway/test_feishu_approval_buttons.py::TestResolveApproval::test_chat_mismatch_does_not_resolve tests/gateway/test_feishu_approval_buttons.py::TestResolveApproval::test_resolves_always tests/gateway/test_feishu_approval_buttons.py::TestResolveApproval::test_resolves_deny tests/gateway/test_feishu_approval_buttons.py::TestResolveApproval::test_resolves_once tests/gateway/test_feishu_approval_buttons.py::TestResolveApproval::test_resolves_session tests/gateway/test_feishu_approval_buttons.py::TestResolveApproval::test_unauthorized_click_does_not_resolve tests/gateway/test_feishu_approval_buttons.py::TestResolveUpdatePrompt::test_chat_mismatch_does_not_write_response_file tests/gateway/test_feishu_approval_buttons.py::TestResolveUpdatePrompt::test_overwrites_existing_response_file tests/gateway/test_feishu_approval_buttons.py::TestResolveUpdatePrompt::test_unknown_prompt_id_drops_silently tests/gateway/test_feishu_approval_buttons.py::TestResolveUpdatePrompt::test_writes_response_file tests/gateway/test_feishu_bot_admission.py::test_admit_accepts_realistic_bot_at_bot_group_event tests/gateway/test_feishu_bot_admission.py::test_admit_group_mention_checked_once_per_call tests/gateway/test_feishu_bot_admission.py::test_admit_per_group_require_mention_overrides_global tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[all_mode:mentioned_dm] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[all_mode:not_mentioned_dm] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[bots_disabled:mode_empty] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[bots_disabled:mode_none] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[bots_disabled:mode_unknown_value] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[bots_disabled:wins_over_self_ids_unknown] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[human:dm_admitted_regardless_of_allow_bots] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[human:p2p_admitted] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[mentions_mode:mentioned_dm] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[mentions_mode:not_mentioned_dm] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[require_mention_false:group_bot_all_mode_admitted] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[require_mention_false:group_bot_mentions_mode_still_gated] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[require_mention_false:group_human_no_mention_admitted] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[self_echo:mixed_ids] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[self_echo:open_id_under_all_mode] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[self_echo:user_id_only] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[self_echo:user_id_when_bot_user_id_set] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[self_ids_unknown:app_sender_no_self_ids] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[self_ids_unknown:bot_sender_no_self_ids] tests/gateway/test_feishu_bot_admission.py::test_admit_pipeline[self_ids_unknown:no_sender_ids] tests/gateway/test_feishu_bot_admission.py::test_admit_skips_mention_check_under_all_mode tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_blacklist_is_human_scope_only[app] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_blacklist_is_human_scope_only[bot] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_channel_locks_apply_to_bots[app:admin_only_policy_blocks_non_admin] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_channel_locks_apply_to_bots[app:disabled_policy_blocks_even_with_bypass] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_channel_locks_apply_to_bots[bot:admin_only_policy_blocks_non_admin] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_channel_locks_apply_to_bots[bot:disabled_policy_blocks_even_with_bypass] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_matrix[app:allowlist_skipped] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_matrix[bot:admin_short_circuit] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_matrix[bot:allowlist_skipped] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_matrix[bot:bypasses_default_allowlist] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_matrix[human:admin_via_user_id] tests/gateway/test_feishu_bot_admission.py::test_allow_group_message_matrix[human:gated_by_default_allowlist] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_allow_bots_defaults_to_none tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_falls_back_to_env_when_extra_missing tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_ignores_extra_allow_bots tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_parses_per_group_require_mention tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_populates_allow_bots[ Mentions -mentions] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_populates_allow_bots[all-all] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_populates_allow_bots[mentions-mentions] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_populates_allow_bots[none-none] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_require_mention[None-extra0-True] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_require_mention[false-extra1-False] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_require_mention[true-extra2-True] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_require_mention[true-extra3-False] tests/gateway/test_feishu_bot_admission.py::test_feishu_load_settings_warns_on_unknown_allow_bots tests/gateway/test_feishu_bot_admission.py::test_handle_message_event_data_drops_bot_sender_by_default tests/gateway/test_feishu_bot_admission.py::test_handle_message_event_data_forwards_sender_when_admitted tests/gateway/test_feishu_bot_admission.py::test_hydrate_bot_identity_populates_self_ids_from_bot_v3_info tests/gateway/test_feishu_bot_admission.py::test_is_bot_sender_rejects_non_bot_origin[None] tests/gateway/test_feishu_bot_admission.py::test_is_bot_sender_rejects_non_bot_origin[] tests/gateway/test_feishu_bot_admission.py::test_is_bot_sender_rejects_non_bot_origin[user] tests/gateway/test_feishu_bot_admission.py::test_is_bot_sender_treats_bot_and_app_as_bot_origin[app] tests/gateway/test_feishu_bot_admission.py::test_is_bot_sender_treats_bot_and_app_as_bot_origin[bot] tests/gateway/test_feishu_bot_admission.py::test_resolve_sender_profile_uses_open_id_for_bot_name_lookup tests/gateway/test_feishu_bot_admission.py::test_sender_identity_collects_every_non_empty_id_variant tests/gateway/test_feishu_bot_admission.py::test_sender_identity_handles_missing_sender_id tests/gateway/test_feishu_bot_auth_bypass.py::test_feishu_bot_NOT_authorized_when_allow_bots_none tests/gateway/test_feishu_bot_auth_bypass.py::test_feishu_bot_NOT_authorized_when_allow_bots_unset tests/gateway/test_feishu_bot_auth_bypass.py::test_feishu_bot_authorized_when_allow_bots_all tests/gateway/test_feishu_bot_auth_bypass.py::test_feishu_bot_authorized_when_allow_bots_mentions tests/gateway/test_feishu_bot_auth_bypass.py::test_feishu_bot_bypass_does_not_leak_to_other_platforms tests/gateway/test_feishu_bot_auth_bypass.py::test_feishu_human_still_checked_against_allowlist_when_bot_policy_set tests/gateway/test_feishu_comment.py::TestAccessControlIntegration::test_denied_user_no_side_effects tests/gateway/test_feishu_comment.py::TestAccessControlIntegration::test_disabled_comment_skipped tests/gateway/test_feishu_comment.py::TestEventFiltering::test_allowed_notice_types tests/gateway/test_feishu_comment.py::TestEventFiltering::test_empty_to_open_id_filtered tests/gateway/test_feishu_comment.py::TestEventFiltering::test_invalid_notice_type_filtered tests/gateway/test_feishu_comment.py::TestEventFiltering::test_self_reply_filtered tests/gateway/test_feishu_comment.py::TestEventFiltering::test_wrong_receiver_filtered tests/gateway/test_feishu_comment.py::TestParseEvent::test_parse_missing_event_attr tests/gateway/test_feishu_comment.py::TestParseEvent::test_parse_none_event tests/gateway/test_feishu_comment.py::TestParseEvent::test_parse_valid_event tests/gateway/test_feishu_comment.py::TestSanitizeCommentText::test_ampersand_escaped_first tests/gateway/test_feishu_comment.py::TestSanitizeCommentText::test_ampersand_not_double_escaped tests/gateway/test_feishu_comment.py::TestSanitizeCommentText::test_angle_brackets_escaped tests/gateway/test_feishu_comment.py::TestSanitizeCommentText::test_code_snippet tests/gateway/test_feishu_comment.py::TestSanitizeCommentText::test_empty_string tests/gateway/test_feishu_comment.py::TestSanitizeCommentText::test_plain_text_unchanged tests/gateway/test_feishu_comment.py::TestWikiReverseLookup::test_reverse_lookup_not_wiki tests/gateway/test_feishu_comment.py::TestWikiReverseLookup::test_reverse_lookup_service_error tests/gateway/test_feishu_comment.py::TestWikiReverseLookup::test_reverse_lookup_success tests/gateway/test_feishu_comment.py::TestWikiReverseLookup::test_wiki_lookup_triggered_when_no_exact_match tests/gateway/test_feishu_comment_rules.py::TestCommentDocumentRuleParsing::test_invalid_policy_ignored tests/gateway/test_feishu_comment_rules.py::TestCommentDocumentRuleParsing::test_parse_empty_rule tests/gateway/test_feishu_comment_rules.py::TestCommentDocumentRuleParsing::test_parse_full_rule tests/gateway/test_feishu_comment_rules.py::TestCommentDocumentRuleParsing::test_parse_partial_rule tests/gateway/test_feishu_comment_rules.py::TestHasWikiKeys::test_empty_documents tests/gateway/test_feishu_comment_rules.py::TestHasWikiKeys::test_has_wiki_keys tests/gateway/test_feishu_comment_rules.py::TestHasWikiKeys::test_no_wiki_keys tests/gateway/test_feishu_comment_rules.py::TestIsUserAllowed::test_allowlist_allows_listed tests/gateway/test_feishu_comment_rules.py::TestIsUserAllowed::test_allowlist_denies_unlisted tests/gateway/test_feishu_comment_rules.py::TestIsUserAllowed::test_allowlist_empty_denies_all tests/gateway/test_feishu_comment_rules.py::TestIsUserAllowed::test_pairing_allows_in_allow_from tests/gateway/test_feishu_comment_rules.py::TestIsUserAllowed::test_pairing_checks_store tests/gateway/test_feishu_comment_rules.py::TestLoadConfig::test_load_missing_file_returns_defaults tests/gateway/test_feishu_comment_rules.py::TestLoadConfig::test_load_with_documents tests/gateway/test_feishu_comment_rules.py::TestMtimeCache::test_reads_file_and_caches tests/gateway/test_feishu_comment_rules.py::TestMtimeCache::test_reloads_on_mtime_change tests/gateway/test_feishu_comment_rules.py::TestMtimeCache::test_returns_empty_dict_for_missing_file tests/gateway/test_feishu_comment_rules.py::TestPairingStore::test_add_and_list tests/gateway/test_feishu_comment_rules.py::TestPairingStore::test_add_duplicate tests/gateway/test_feishu_comment_rules.py::TestPairingStore::test_remove tests/gateway/test_feishu_comment_rules.py::TestPairingStore::test_remove_nonexistent tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_default_config tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_exact_match tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_exact_overrides_wildcard tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_exact_takes_priority_over_wiki tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_explicit_empty_allow_from_does_not_fall_through tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_field_by_field_fallback tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_top_level_fallback tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_wiki_token_match tests/gateway/test_feishu_comment_rules.py::TestResolveRule::test_wildcard_match tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteHandler::test_duplicate_event_is_dropped tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteHandler::test_inviter_without_open_id_is_dropped tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteHandler::test_routes_as_synthetic_message_to_inviter_open_id tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteParsing::test_parse_actual_payload_string_int64_fields tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteParsing::test_parse_body_content_payload tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteParsing::test_parse_requires_inviter tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteParsing::test_parse_requires_meeting_no tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteParsing::test_prompt_contains_meeting_and_inviter_context tests/gateway/test_feishu_meeting_invite.py::TestMeetingInviteSendRouting::test_feishu_user_id_prefix_sends_with_user_id_receive_type tests/gateway/test_feishu_onboard.py::TestBeginRegistration::test_begin_returns_device_code_and_qr_url tests/gateway/test_feishu_onboard.py::TestBeginRegistration::test_begin_sends_correct_archetype tests/gateway/test_feishu_onboard.py::TestInitRegistration::test_init_raises_when_client_secret_not_supported tests/gateway/test_feishu_onboard.py::TestInitRegistration::test_init_succeeds_when_client_secret_supported tests/gateway/test_feishu_onboard.py::TestInitRegistration::test_init_uses_lark_url_for_lark_domain tests/gateway/test_feishu_onboard.py::TestPollRegistration::test_poll_returns_credentials_on_success tests/gateway/test_feishu_onboard.py::TestPollRegistration::test_poll_returns_none_on_access_denied tests/gateway/test_feishu_onboard.py::TestPollRegistration::test_poll_returns_none_on_timeout tests/gateway/test_feishu_onboard.py::TestPollRegistration::test_poll_success_with_lark_brand_in_same_response tests/gateway/test_feishu_onboard.py::TestPollRegistration::test_poll_switches_domain_on_lark_tenant_brand tests/gateway/test_feishu_onboard.py::TestPollRegistration::test_poll_timeout_uses_monotonic_clock tests/gateway/test_feishu_onboard.py::TestPostRegistration::test_post_registration_returns_parsed_json tests/gateway/test_feishu_onboard.py::TestPostRegistration::test_post_registration_sends_form_encoded_body tests/gateway/test_feishu_onboard.py::TestProbeBot::test_http_fallback_returns_none_on_network_error tests/gateway/test_feishu_onboard.py::TestProbeBot::test_http_fallback_when_sdk_unavailable tests/gateway/test_feishu_onboard.py::TestProbeBot::test_probe_returns_bot_info_on_success tests/gateway/test_feishu_onboard.py::TestProbeBot::test_probe_returns_none_on_failure tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_propagates_unexpected_errors tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_returns_none_on_init_failure tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_returns_none_on_json_error tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_returns_none_on_network_error tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_returns_none_on_poll_failure tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_returns_none_when_begin_missing_device_code tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_succeeds_even_when_probe_fails tests/gateway/test_feishu_onboard.py::TestQrRegister::test_qr_register_success_flow tests/gateway/test_feishu_onboard.py::TestRenderQr::test_render_qr_returns_false_when_qrcode_missing tests/gateway/test_feishu_onboard.py::TestRenderQr::test_render_qr_returns_true_on_success tests/gateway/test_fresh_reset_skill_injection.py::TestIsNewSessionSurvivesUpdatedAtBump::test_flag_consumed_after_first_read tests/gateway/test_fresh_reset_skill_injection.py::TestIsNewSessionSurvivesUpdatedAtBump::test_is_new_session_true_after_reset_then_next_message tests/gateway/test_fresh_reset_skill_injection.py::TestPersistence::test_default_false_when_missing_from_dict tests/gateway/test_fresh_reset_skill_injection.py::TestPersistence::test_is_fresh_reset_survives_to_dict_from_dict tests/gateway/test_fresh_reset_skill_injection.py::TestResetSessionStampsFreshReset::test_fresh_session_does_not_have_is_fresh_reset tests/gateway/test_fresh_reset_skill_injection.py::TestResetSessionStampsFreshReset::test_reset_session_sets_is_fresh_reset_true tests/gateway/test_fresh_reset_skill_injection.py::TestResetSessionStampsFreshReset::test_reset_session_unknown_key_returns_none tests/gateway/test_fresh_reset_skill_injection.py::TestVanillaBehaviorUnaffected::test_idle_auto_reset_does_not_set_is_fresh_reset tests/gateway/test_fresh_reset_skill_injection.py::TestVanillaBehaviorUnaffected::test_ongoing_session_not_flagged_as_new tests/gateway/test_gateway_command_help.py::test_commands_sanitizes_slash_command_mentions_for_telegram tests/gateway/test_gateway_command_help.py::test_help_keeps_non_telegram_slash_command_mentions_unchanged tests/gateway/test_gateway_command_help.py::test_help_sanitizes_slash_command_mentions_for_telegram tests/gateway/test_gateway_command_help.py::test_start_is_known_gateway_command tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run["C:\\Program Files\\Hermes\\gateway\\run.py" run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run["C:\\Program Files\\Hermes\\hermes-gateway.exe"] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run["C:\\Program Files\\Py\\pythonw.exe" -m hermes_cli.main gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[C:\\Users\\me\\hermes\\venv\\Scripts\\pythonw.exe -m hermes_cli.main gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[hermes -p gateway gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[hermes gateway --profile work run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[hermes gateway --profile=work run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[hermes gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[hermes gateway] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[hermes-gateway.exe] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[python -m hermes_cli.main --profile gateway gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[python -m hermes_cli.main --profile work gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[python -m hermes_cli.main gateway -p work run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[python -m hermes_cli.main gateway run --replace] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[python -m hermes_cli/main.py gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[python gateway/run.py] tests/gateway/test_gateway_command_line_matcher.py::test_accepts_real_gateway_run[pythonw.exe -m hermes_cli.main gateway run] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[None] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[python -m hermes_cli.main --profile x dashboard] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[python -m hermes_cli.main gateway restart] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[python -m hermes_cli.main gateway status] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[python -m hermes_cli.main gateway stop] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[python -m tui_gateway] tests/gateway/test_gateway_command_line_matcher.py::test_rejects_non_gateway_run[some random python -m mygateway thing] tests/gateway/test_gateway_inactivity_timeout.py::TestStagedInactivityWarning::test_full_timeout_still_fires_after_warning tests/gateway/test_gateway_inactivity_timeout.py::TestStagedInactivityWarning::test_unlimited_timeout_no_warning tests/gateway/test_gateway_inactivity_timeout.py::TestStagedInactivityWarning::test_warning_disabled_when_zero tests/gateway/test_gateway_inactivity_timeout.py::TestStagedInactivityWarning::test_warning_env_var_respected tests/gateway/test_gateway_inactivity_timeout.py::TestStagedInactivityWarning::test_warning_fires_once_before_timeout tests/gateway/test_gateway_inactivity_timeout.py::TestStagedInactivityWarning::test_warning_fires_only_once tests/gateway/test_gateway_inactivity_timeout.py::TestStagedInactivityWarning::test_warning_zero_means_disabled tests/gateway/test_gateway_inactivity_timeout.py::TestWarningThresholdBelowTimeout::test_warning_at_half_timeout tests/gateway/test_gateway_shutdown.py::test_cancel_background_tasks_cancels_inflight_message_processing tests/gateway/test_gateway_shutdown.py::test_cleanup_agent_resources_reaps_stale_aux_clients tests/gateway/test_gateway_shutdown.py::test_drain_active_agents_throttles_status_updates tests/gateway/test_gateway_shutdown.py::test_gateway_stop_drains_running_agents_before_disconnect tests/gateway/test_gateway_shutdown.py::test_gateway_stop_interrupts_after_drain_timeout tests/gateway/test_gateway_shutdown.py::test_gateway_stop_interrupts_running_agents_and_cancels_adapter_tasks tests/gateway/test_gateway_shutdown.py::test_gateway_stop_kills_tool_subprocesses_before_adapter_disconnect_on_timeout tests/gateway/test_gateway_shutdown.py::test_gateway_stop_kills_tool_subprocesses_on_graceful_path tests/gateway/test_gateway_shutdown.py::test_gateway_stop_launchd_service_restart_keeps_nonzero_exit tests/gateway/test_gateway_shutdown.py::test_gateway_stop_systemd_service_restart_exits_cleanly tests/gateway/test_gateway_shutdown.py::test_idle_in_chat_restart_does_not_send_interruption_warning tests/gateway/test_gateway_shutdown.py::test_in_chat_restart_does_not_write_home_startup_marker tests/gateway/test_gateway_shutdown.py::test_in_chat_restart_skips_home_shutdown_even_with_active_session tests/gateway/test_gateway_shutdown.py::test_operator_initiated_stop_persists_stopped tests/gateway/test_gateway_shutdown.py::test_restart_shutdown_warning_uses_restart_command_reply_anchor_for_active_session tests/gateway/test_gateway_shutdown.py::test_signal_initiated_restart_still_persists_stopped tests/gateway/test_gateway_shutdown.py::test_signal_initiated_shutdown_persists_running_not_stopped tests/gateway/test_gateway_silence_tokens.py::test_blank_and_prose_mentions_are_not_silence tests/gateway/test_gateway_silence_tokens.py::test_empty_success_still_gets_empty_response_warning tests/gateway/test_gateway_silence_tokens.py::test_exact_silence_tokens_are_intentional_silence tests/gateway/test_gateway_silence_tokens.py::test_failed_agent_result_never_counts_as_intentional_silence tests/gateway/test_gateway_silence_tokens.py::test_prose_mentioning_silence_token_is_delivered tests/gateway/test_gateway_silence_tokens.py::test_silence_token_suppresses_delivery_but_preserves_transcript tests/gateway/test_goal_max_turns_config.py::test_gateway_goal_uses_goals_max_turns_from_full_config tests/gateway/test_goal_status_notice.py::test_clear_goal_pending_continuations_removes_slot_and_overflow_only tests/gateway/test_goal_status_notice.py::test_goal_status_notice_defers_until_post_delivery_callback tests/gateway/test_goal_status_notice.py::test_goal_status_notice_uses_adapter_send_with_thread_metadata tests/gateway/test_goal_verdict_send.py::test_goal_verdict_budget_exhausted_sends_pause tests/gateway/test_goal_verdict_send.py::test_goal_verdict_continue_enqueues_continuation tests/gateway/test_goal_verdict_send.py::test_goal_verdict_done_sent_via_adapter_send tests/gateway/test_goal_verdict_send.py::test_goal_verdict_skipped_when_no_active_goal tests/gateway/test_goal_verdict_send.py::test_goal_verdict_survives_adapter_without_send tests/gateway/test_google_chat.py::TestADCFallback::test_load_credentials_raises_when_no_sa_and_adc_unavailable tests/gateway/test_google_chat.py::TestADCFallback::test_load_credentials_uses_adc_when_no_sa_path tests/gateway/test_google_chat.py::TestAttachmentSSRFGuard::test_drive_file_with_resource_name_uses_bot_path tests/gateway/test_google_chat.py::TestAttachmentSSRFGuard::test_drive_picker_only_skipped_when_no_resource_name tests/gateway/test_google_chat.py::TestAttachmentSSRFGuard::test_rejects_metadata_endpoint tests/gateway/test_google_chat.py::TestAttachmentSSRFGuard::test_rejects_non_google_host tests/gateway/test_google_chat.py::TestAuthorizationEmailMatch::test_allowlist_denies_wrong_email tests/gateway/test_google_chat.py::TestAuthorizationEmailMatch::test_allowlist_falls_back_to_resource_name_when_no_email tests/gateway/test_google_chat.py::TestAuthorizationEmailMatch::test_allowlist_matches_when_user_id_is_email tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_attachment_image_triggers_download tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_dm_different_top_level_threads_share_session tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_dm_first_message_in_thread_is_main_flow tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_dm_main_flow_after_side_thread_clears_cache tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_dm_second_message_in_same_thread_is_side_thread tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_dm_side_thread_caches_thread_for_outbound tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_group_keeps_thread_id_on_source tests/gateway/test_google_chat.py::TestBuildMessageEvent::test_slash_command_yields_command_type tests/gateway/test_google_chat.py::TestChunkText::test_empty_returns_empty_list tests/gateway/test_google_chat.py::TestChunkText::test_long_splits_into_multiple tests/gateway/test_google_chat.py::TestChunkText::test_short_returns_single_chunk tests/gateway/test_google_chat.py::TestChunkText::test_splits_on_newline_near_boundary tests/gateway/test_google_chat.py::TestCronSchedulerRegistry::test_google_chat_home_env_var_resolves tests/gateway/test_google_chat.py::TestCronSchedulerRegistry::test_google_chat_is_known_delivery_platform tests/gateway/test_google_chat.py::TestDeleteMessage::test_delete_message_calls_api tests/gateway/test_google_chat.py::TestDeleteMessage::test_delete_message_missing_id_returns_false tests/gateway/test_google_chat.py::TestDeleteMessage::test_delete_message_swallows_404 tests/gateway/test_google_chat.py::TestEditMessage::test_edit_message_429_increments_rate_limit_counter tests/gateway/test_google_chat.py::TestEditMessage::test_edit_message_missing_id_returns_failure tests/gateway/test_google_chat.py::TestEditMessage::test_edit_message_overrides_base_so_progress_pipeline_runs tests/gateway/test_google_chat.py::TestEditMessage::test_edit_message_patches_via_messages_patch tests/gateway/test_google_chat.py::TestEditMessage::test_edit_message_truncates_overlong_text tests/gateway/test_google_chat.py::TestEnvConfigLoading::test_missing_project_does_not_enable tests/gateway/test_google_chat.py::TestEnvConfigLoading::test_missing_subscription_does_not_enable tests/gateway/test_google_chat.py::TestExtractMessagePayload::test_native_chat_api_format_drops_non_message_events tests/gateway/test_google_chat.py::TestExtractMessagePayload::test_native_chat_api_format_extracts_msg_and_space tests/gateway/test_google_chat.py::TestExtractMessagePayload::test_relay_flat_coerces_unknown_sender_type_to_human tests/gateway/test_google_chat.py::TestExtractMessagePayload::test_relay_flat_defaults_sender_type_human_when_absent tests/gateway/test_google_chat.py::TestExtractMessagePayload::test_relay_flat_format_synthesizes_chat_api_shape tests/gateway/test_google_chat.py::TestExtractMessagePayload::test_relay_flat_honors_declared_sender_type_bot tests/gateway/test_google_chat.py::TestExtractMessagePayload::test_unrecognized_envelope_returns_none tests/gateway/test_google_chat.py::TestFormatMessage::test_bold_double_asterisk_to_single tests/gateway/test_google_chat.py::TestFormatMessage::test_bold_italic_combo_to_chat_dialect tests/gateway/test_google_chat.py::TestFormatMessage::test_empty_and_none_safe tests/gateway/test_google_chat.py::TestFormatMessage::test_fenced_code_block_protected tests/gateway/test_google_chat.py::TestFormatMessage::test_header_to_bold_at_line_start_only tests/gateway/test_google_chat.py::TestFormatMessage::test_inline_code_protected tests/gateway/test_google_chat.py::TestFormatMessage::test_markdown_link_to_chat_anglebracket tests/gateway/test_google_chat.py::TestFormatMessage::test_mixed_bold_italic_orderings tests/gateway/test_google_chat.py::TestFormatMessage::test_strips_bom_and_bidi_marks tests/gateway/test_google_chat.py::TestFormatMessage::test_strips_zwj_and_variation_selector tests/gateway/test_google_chat.py::TestFormatMessage::test_unmatched_asterisks_left_alone tests/gateway/test_google_chat.py::TestFormatMessage::test_url_with_parens_in_path tests/gateway/test_google_chat.py::TestGoogleChatInteractiveSetup::test_interactive_setup_uses_shared_cli_prompt_helpers tests/gateway/test_google_chat.py::TestGoogleChatStandaloneSend::test_standalone_send_propagates_api_failure tests/gateway/test_google_chat.py::TestGoogleChatStandaloneSend::test_standalone_send_refreshes_token_and_posts_message tests/gateway/test_google_chat.py::TestGoogleChatStandaloneSend::test_standalone_send_rejects_chat_id_with_path_traversal tests/gateway/test_google_chat.py::TestGoogleChatStandaloneSend::test_standalone_send_returns_error_on_invalid_chat_id tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_accepts_google_hosts[https://chat.googleapis.com/v1/x] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_accepts_google_hosts[https://drive.google.com/file/d/abc] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_accepts_google_hosts[https://lh3.googleusercontent.com/photo.jpg] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_accepts_google_hosts[https://www.googleapis.com/upload/chat/v1/x] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_rejects_non_google_or_insecure[ftp://drive.google.com/x] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_rejects_non_google_or_insecure[http://chat.googleapis.com/] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_rejects_non_google_or_insecure[https://169.254.169.254/latest/meta-data/] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_rejects_non_google_or_insecure[https://chat.google.com.attacker.example/] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_rejects_non_google_or_insecure[https://evil.com/foo] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_rejects_non_google_or_insecure[https://metadata.internal/computeMetadata/v1/] tests/gateway/test_google_chat.py::TestGoogleOwnedHost::test_rejects_non_google_or_insecure[not a url] tests/gateway/test_google_chat.py::TestHelpers::test_mime_audio_maps_to_audio tests/gateway/test_google_chat.py::TestHelpers::test_mime_empty_maps_to_document tests/gateway/test_google_chat.py::TestHelpers::test_mime_image_maps_to_photo tests/gateway/test_google_chat.py::TestHelpers::test_mime_other_maps_to_document tests/gateway/test_google_chat.py::TestHelpers::test_mime_video_maps_to_video tests/gateway/test_google_chat.py::TestMediaDelegation::test_send_animation_delegates_to_image tests/gateway/test_google_chat.py::TestMediaDelegation::test_send_file_missing_path_returns_error tests/gateway/test_google_chat.py::TestMediaDelegation::test_send_video_delegates_with_video_mime tests/gateway/test_google_chat.py::TestMediaDelegation::test_send_voice_delegates_to_document_with_audio_mime tests/gateway/test_google_chat.py::TestNativeAttachmentDelivery::test_send_file_falls_back_to_notice_on_401 tests/gateway/test_google_chat.py::TestNativeAttachmentDelivery::test_send_file_posts_setup_notice_when_no_user_oauth tests/gateway/test_google_chat.py::TestNativeAttachmentDelivery::test_send_file_returns_error_on_unrelated_http_error tests/gateway/test_google_chat.py::TestNativeAttachmentDelivery::test_send_file_two_step_native_upload_when_user_oauth_ready tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_bot_sender_is_filtered tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_callback_exception_does_not_escape tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_duplicate_message_dropped tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_malformed_json_acks_without_dispatch tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_membership_created_caches_bot_user_id tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_membership_deleted_acks_no_dispatch tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_relay_flat_bot_sender_is_filtered_end_to_end tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_relay_flat_human_sender_dispatches tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_shutting_down_nacks tests/gateway/test_google_chat.py::TestOnPubsubMessage::test_text_message_submits_to_loop tests/gateway/test_google_chat.py::TestOutboundRetry::test_does_not_retry_on_400 tests/gateway/test_google_chat.py::TestOutboundRetry::test_gives_up_after_max_attempts tests/gateway/test_google_chat.py::TestOutboundRetry::test_is_retryable_error_classifier tests/gateway/test_google_chat.py::TestOutboundRetry::test_retries_on_503_then_succeeds tests/gateway/test_google_chat.py::TestOutboundThreadRouting::test_resolve_falls_back_to_cached_thread_for_dm tests/gateway/test_google_chat.py::TestOutboundThreadRouting::test_resolve_metadata_overrides_cache tests/gateway/test_google_chat.py::TestOutboundThreadRouting::test_resolve_returns_none_when_no_inputs tests/gateway/test_google_chat.py::TestOutboundThreadRouting::test_resolve_uses_metadata_thread_id tests/gateway/test_google_chat.py::TestPerUserAttachmentRouting::test_build_message_event_caches_sender_email tests/gateway/test_google_chat.py::TestPerUserAttachmentRouting::test_send_file_falls_back_to_legacy_when_per_user_missing tests/gateway/test_google_chat.py::TestPerUserAttachmentRouting::test_send_file_no_creds_anywhere_posts_setup_notice tests/gateway/test_google_chat.py::TestPerUserAttachmentRouting::test_send_file_per_user_401_evicts_only_that_user tests/gateway/test_google_chat.py::TestPerUserAttachmentRouting::test_send_file_uses_per_user_token_when_sender_known tests/gateway/test_google_chat.py::TestPerUserAttachmentRouting::test_setup_files_revoke_drops_only_that_user tests/gateway/test_google_chat.py::TestPerUserAttachmentRouting::test_setup_files_writes_to_per_user_path tests/gateway/test_google_chat.py::TestPlatformRegistration::test_enum_value tests/gateway/test_google_chat.py::TestPlatformRegistration::test_requirements_check_returns_true_when_available tests/gateway/test_google_chat.py::TestRedactSensitive::test_empty_text_passes_through tests/gateway/test_google_chat.py::TestRedactSensitive::test_redacts_service_account_email tests/gateway/test_google_chat.py::TestRedactSensitive::test_redacts_subscription_path tests/gateway/test_google_chat.py::TestRedactSensitive::test_redacts_topic_path tests/gateway/test_google_chat.py::TestSend::test_403_sets_fatal_error tests/gateway/test_google_chat.py::TestSend::test_404_returns_target_not_found tests/gateway/test_google_chat.py::TestSend::test_429_increments_rate_limit_counter_and_raises tests/gateway/test_google_chat.py::TestSend::test_create_message_omits_messageReplyOption_when_no_thread tests/gateway/test_google_chat.py::TestSend::test_create_message_passes_messageReplyOption_when_thread_set tests/gateway/test_google_chat.py::TestSend::test_long_text_splits_and_sends_multiple tests/gateway/test_google_chat.py::TestSend::test_text_send_creates_message tests/gateway/test_google_chat.py::TestSend::test_with_typing_card_patches_instead_of_creating tests/gateway/test_google_chat.py::TestSetupFilesSlashCommand::test_no_arg_status_when_unconfigured tests/gateway/test_google_chat.py::TestSetupFilesSlashCommand::test_revoke_clears_in_memory_creds tests/gateway/test_google_chat.py::TestSetupFilesSlashCommand::test_slash_command_intercepted_before_agent tests/gateway/test_google_chat.py::TestSupervisorReconnect::test_fatal_after_max_retries tests/gateway/test_google_chat.py::TestThreadCountStore::test_corrupt_json_treated_as_empty tests/gateway/test_google_chat.py::TestThreadCountStore::test_incr_returns_pre_increment_value tests/gateway/test_google_chat.py::TestThreadCountStore::test_invalid_shape_dropped_silently tests/gateway/test_google_chat.py::TestThreadCountStore::test_missing_file_returns_zero_counts tests/gateway/test_google_chat.py::TestThreadCountStore::test_outbound_thread_tracked_for_user_reply_in_bot_thread tests/gateway/test_google_chat.py::TestThreadCountStore::test_round_trip_persists_across_load tests/gateway/test_google_chat.py::TestThreadCountStore::test_side_thread_detection_survives_restart tests/gateway/test_google_chat.py::TestTypingLifecycle::test_on_processing_complete_patches_stranded_card tests/gateway/test_google_chat.py::TestTypingLifecycle::test_on_processing_complete_pops_sentinel_on_success tests/gateway/test_google_chat.py::TestTypingLifecycle::test_orphan_typing_cards_reaped_on_completion tests/gateway/test_google_chat.py::TestTypingLifecycle::test_send_typing_concurrent_calls_create_only_one_card tests/gateway/test_google_chat.py::TestTypingLifecycle::test_send_typing_inherits_inbound_thread tests/gateway/test_google_chat.py::TestTypingLifecycle::test_send_typing_no_thread_when_cache_empty tests/gateway/test_google_chat.py::TestTypingLifecycle::test_send_typing_posts_and_tracks tests/gateway/test_google_chat.py::TestTypingLifecycle::test_send_typing_skips_when_already_tracking tests/gateway/test_google_chat.py::TestTypingLifecycle::test_send_typing_survives_caller_cancellation tests/gateway/test_google_chat.py::TestTypingLifecycle::test_stop_typing_is_noop_for_live_card tests/gateway/test_google_chat.py::TestTypingLifecycle::test_stop_typing_noop_when_nothing_tracked tests/gateway/test_google_chat.py::TestTypingLifecycle::test_stop_typing_pops_sentinel tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_list_authorized_emails_empty_when_dir_missing tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_list_authorized_emails_lists_per_user_files tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_load_user_credentials_per_email_returns_none_when_missing tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_load_user_credentials_returns_none_on_corrupt_token tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_load_user_credentials_returns_none_when_no_token tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_pending_auth_path_is_per_user_when_email_given tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_per_user_token_path_isolated_from_legacy tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_persist_credentials_writes_private_json tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_sanitize_email_lowercases_and_replaces_unsafe_chars tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_save_pending_auth_writes_private_json tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_scopes_are_minimal tests/gateway/test_google_chat.py::TestUserOAuthHelper::test_store_client_secret_writes_private_json tests/gateway/test_google_chat.py::TestValidateConfig::test_missing_project_raises tests/gateway/test_google_chat.py::TestValidateConfig::test_missing_subscription_raises tests/gateway/test_google_chat.py::TestValidateConfig::test_subscription_format_rejected tests/gateway/test_google_chat.py::TestValidateConfig::test_subscription_project_mismatch_rejected tests/gateway/test_google_chat.py::TestValidateConfig::test_validate_config_happy tests/gateway/test_home_target_env_var.py::test_case_insensitive_platform_name tests/gateway/test_home_target_env_var.py::test_discord_home_target_env_var_uses_home_channel tests/gateway/test_home_target_env_var.py::test_email_home_target_env_var_uses_home_address tests/gateway/test_home_target_env_var.py::test_home_thread_env_var_uses_home_target_name_plus_thread_id tests/gateway/test_home_target_env_var.py::test_matrix_home_target_env_var_uses_home_room tests/gateway/test_home_target_env_var.py::test_telegram_home_target_env_var_uses_home_channel tests/gateway/test_home_target_env_var.py::test_unknown_platform_home_target_env_var_falls_back_to_home_channel tests/gateway/test_homeassistant.py::TestAdapterInit::test_defaults_when_no_extra tests/gateway/test_homeassistant.py::TestAdapterInit::test_trailing_slash_stripped tests/gateway/test_homeassistant.py::TestAdapterInit::test_url_and_token_from_config_extra tests/gateway/test_homeassistant.py::TestAdapterInit::test_url_fallback_to_env tests/gateway/test_homeassistant.py::TestAdapterInit::test_watch_all_parsed tests/gateway/test_homeassistant.py::TestAdapterInit::test_watch_filters_parsed tests/gateway/test_homeassistant.py::TestCheckRequirements::test_returns_false_without_aiohttp tests/gateway/test_homeassistant.py::TestCheckRequirements::test_returns_false_without_token tests/gateway/test_homeassistant.py::TestCheckRequirements::test_returns_true_with_token tests/gateway/test_homeassistant.py::TestConfigIntegration::test_config_roundtrip_preserves_extra tests/gateway/test_homeassistant.py::TestConfigIntegration::test_env_override_creates_ha_platform tests/gateway/test_homeassistant.py::TestConfigIntegration::test_no_env_no_platform tests/gateway/test_homeassistant.py::TestCooldown::test_cooldown_blocks_rapid_events tests/gateway/test_homeassistant.py::TestCooldown::test_cooldown_expires tests/gateway/test_homeassistant.py::TestCooldown::test_different_entities_independent_cooldowns tests/gateway/test_homeassistant.py::TestCooldown::test_zero_cooldown_passes_all tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_empty_entity_id_skipped tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_ignored_entity_not_forwarded tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_message_event_has_correct_source tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_no_filters_blocks_everything tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_same_state_not_forwarded tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_unwatched_domain_not_forwarded tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_watch_all_passes_everything tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_watched_domain_forwarded tests/gateway/test_homeassistant.py::TestEventFilteringPipeline::test_watched_entity_forwarded tests/gateway/test_homeassistant.py::TestFormatStateChange::test_alarm_panel tests/gateway/test_homeassistant.py::TestFormatStateChange::test_binary_sensor_off tests/gateway/test_homeassistant.py::TestFormatStateChange::test_binary_sensor_on tests/gateway/test_homeassistant.py::TestFormatStateChange::test_climate_includes_temperatures tests/gateway/test_homeassistant.py::TestFormatStateChange::test_empty_new_state_returns_none tests/gateway/test_homeassistant.py::TestFormatStateChange::test_fan_domain_uses_light_switch_branch tests/gateway/test_homeassistant.py::TestFormatStateChange::test_generic_domain_includes_entity_id tests/gateway/test_homeassistant.py::TestFormatStateChange::test_light_turned_on tests/gateway/test_homeassistant.py::TestFormatStateChange::test_no_old_state_uses_unknown tests/gateway/test_homeassistant.py::TestFormatStateChange::test_same_state_returns_none tests/gateway/test_homeassistant.py::TestFormatStateChange::test_sensor_includes_unit tests/gateway/test_homeassistant.py::TestFormatStateChange::test_sensor_without_unit tests/gateway/test_homeassistant.py::TestFormatStateChange::test_switch_turned_off tests/gateway/test_homeassistant.py::TestFormatStateChange::test_uses_entity_id_when_no_friendly_name tests/gateway/test_homeassistant.py::TestSendViaRestApi::test_send_does_not_use_websocket tests/gateway/test_homeassistant.py::TestSendViaRestApi::test_send_http_error tests/gateway/test_homeassistant.py::TestSendViaRestApi::test_send_success tests/gateway/test_homeassistant.py::TestSendViaRestApi::test_send_truncates_long_message tests/gateway/test_homeassistant.py::TestWsUrlConstruction::test_http_to_ws tests/gateway/test_homeassistant.py::TestWsUrlConstruction::test_https_to_wss tests/gateway/test_hooks.py::TestDiscoverAndLoad::test_loads_valid_hook tests/gateway/test_hooks.py::TestDiscoverAndLoad::test_multiple_hooks tests/gateway/test_hooks.py::TestDiscoverAndLoad::test_nonexistent_hooks_dir tests/gateway/test_hooks.py::TestDiscoverAndLoad::test_skips_missing_handler_py tests/gateway/test_hooks.py::TestDiscoverAndLoad::test_skips_missing_hook_yaml tests/gateway/test_hooks.py::TestDiscoverAndLoad::test_skips_no_events tests/gateway/test_hooks.py::TestDiscoverAndLoad::test_skips_no_handle_function tests/gateway/test_hooks.py::TestEmit::test_emit_calls_async_handler tests/gateway/test_hooks.py::TestEmit::test_emit_calls_sync_handler tests/gateway/test_hooks.py::TestEmit::test_emit_default_context tests/gateway/test_hooks.py::TestEmit::test_handler_error_does_not_propagate tests/gateway/test_hooks.py::TestEmit::test_no_handlers_for_event tests/gateway/test_hooks.py::TestEmit::test_wildcard_matching tests/gateway/test_hooks.py::TestEmitCollect::test_collects_async_return_values tests/gateway/test_hooks.py::TestEmitCollect::test_collects_sync_return_values tests/gateway/test_hooks.py::TestEmitCollect::test_default_context tests/gateway/test_hooks.py::TestEmitCollect::test_drops_none_return_values tests/gateway/test_hooks.py::TestEmitCollect::test_handler_exception_does_not_abort_chain tests/gateway/test_hooks.py::TestEmitCollect::test_no_handlers_returns_empty_list tests/gateway/test_hooks.py::TestEmitCollect::test_wildcard_match_also_collected tests/gateway/test_hooks.py::TestHookRegistryInit::test_empty_registry tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_bare_number_still_works tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_no_flags_unchanged tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_regular_hyphens_unaffected tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[--days 7---days 7] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[--source telegram---source telegram] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[\u2012days 7---days 7] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[\u2013days 7---days 7] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[\u2013source telegram---source telegram] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[\u2014days 30 \u2014source cli---days 30 --source cli] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[\u2014days 7---days 7] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[\u2014source telegram---source telegram] tests/gateway/test_insights_unicode_flags.py::TestInsightsUnicodeDashFlags::test_unicode_dash_normalized[\u2015days 7---days 7] tests/gateway/test_internal_event_bypass_pairing.py::test_internal_event_bypasses_authorization tests/gateway/test_internal_event_bypass_pairing.py::test_internal_event_does_not_trigger_pairing tests/gateway/test_internal_event_bypass_pairing.py::test_non_internal_event_without_user_triggers_pairing tests/gateway/test_internal_event_bypass_pairing.py::test_none_user_id_does_not_generate_pairing_code tests/gateway/test_internal_event_bypass_pairing.py::test_none_user_id_skips_pairing tests/gateway/test_internal_event_bypass_pairing.py::test_notify_on_complete_preserves_user_identity tests/gateway/test_internal_event_bypass_pairing.py::test_notify_on_complete_sets_internal_flag tests/gateway/test_internal_event_bypass_pairing.py::test_notify_on_complete_uses_session_store_origin_for_group_topic tests/gateway/test_interrupt_key_match.py::TestInterruptKeyConsistency::test_get_pending_message_requires_session_key tests/gateway/test_interrupt_key_match.py::TestInterruptKeyConsistency::test_handle_message_stores_under_session_key tests/gateway/test_interrupt_key_match.py::TestInterruptKeyConsistency::test_has_pending_interrupt_requires_session_key tests/gateway/test_interrupt_key_match.py::TestInterruptKeyConsistency::test_photo_followup_is_queued_without_interrupt tests/gateway/test_interrupt_key_match.py::TestInterruptKeyConsistency::test_session_key_differs_from_chat_id_for_dm tests/gateway/test_interrupt_key_match.py::TestInterruptKeyConsistency::test_session_key_differs_from_chat_id_for_group tests/gateway/test_irc_adapter.py::TestIRCAdapterInit::test_env_overrides_config tests/gateway/test_irc_adapter.py::TestIRCAdapterInit::test_init_from_config_extra tests/gateway/test_irc_adapter.py::TestIRCAdapterInit::test_init_from_env tests/gateway/test_irc_adapter.py::TestIRCAdapterMarkdown::test_strip_bold tests/gateway/test_irc_adapter.py::TestIRCAdapterMarkdown::test_strip_code tests/gateway/test_irc_adapter.py::TestIRCAdapterMarkdown::test_strip_image tests/gateway/test_irc_adapter.py::TestIRCAdapterMarkdown::test_strip_italic tests/gateway/test_irc_adapter.py::TestIRCAdapterMarkdown::test_strip_link tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_allowed_users_case_insensitive tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_ctcp_action_converted tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_handle_addressed_channel_message tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_handle_dm tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_handle_nick_collision tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_handle_ping tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_handle_welcome tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_ignores_own_messages tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_ignores_unaddressed_channel_message tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_nick_collision_retry tests/gateway/test_irc_adapter.py::TestIRCAdapterMessageParsing::test_unauthorized_user_blocked tests/gateway/test_irc_adapter.py::TestIRCAdapterSend::test_send_not_connected tests/gateway/test_irc_adapter.py::TestIRCAdapterSend::test_send_splits_long_messages tests/gateway/test_irc_adapter.py::TestIRCAdapterSend::test_send_success tests/gateway/test_irc_adapter.py::TestIRCAdapterSplitting::test_split_prefers_word_boundary tests/gateway/test_irc_adapter.py::TestIRCAdapterSplitting::test_split_respects_byte_limit tests/gateway/test_irc_adapter.py::TestIRCPluginRegistration::test_register_adds_to_registry tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpers::test_extract_nick_bare tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpers::test_extract_nick_full_prefix tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpers::test_parse_nick_collision tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpers::test_parse_numeric_reply tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpers::test_parse_prefixed_message tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpers::test_parse_simple_command tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpersExtra::test_parse_empty tests/gateway/test_irc_adapter.py::TestIRCProtocolHelpersExtra::test_parse_malformed_no_space tests/gateway/test_irc_adapter.py::TestIRCRequirements::test_check_requirements_missing_channel tests/gateway/test_irc_adapter.py::TestIRCRequirements::test_check_requirements_missing_server tests/gateway/test_irc_adapter.py::TestIRCRequirements::test_check_requirements_with_env tests/gateway/test_irc_adapter.py::TestIRCRequirements::test_validate_config_from_extra tests/gateway/test_irc_adapter.py::TestIRCRequirements::test_validate_config_missing tests/gateway/test_irc_adapter.py::TestIRCStandaloneSend::test_standalone_send_completes_handshake_and_sends_privmsg tests/gateway/test_irc_adapter.py::TestIRCStandaloneSend::test_standalone_send_joins_channel_before_privmsg tests/gateway/test_irc_adapter.py::TestIRCStandaloneSend::test_standalone_send_rejects_crlf_in_chat_id tests/gateway/test_irc_adapter.py::TestIRCStandaloneSend::test_standalone_send_returns_error_on_registration_timeout tests/gateway/test_irc_adapter.py::TestIRCStandaloneSend::test_standalone_send_returns_error_when_unconfigured tests/gateway/test_irc_adapter.py::TestIRCStandaloneSend::test_standalone_send_strips_crlf_from_message_body tests/gateway/test_kanban_notifier.py::test_kanban_db_path_is_test_isolated_from_real_home tests/gateway/test_kanban_notifier.py::test_kanban_notifier_claim_prevents_second_watcher_send tests/gateway/test_kanban_notifier.py::test_kanban_notifier_dedupes_board_slugs_pointing_to_same_db tests/gateway/test_kanban_notifier.py::test_kanban_notifier_rewinds_claim_if_adapter_disconnects tests/gateway/test_kanban_notifier.py::test_kanban_notifier_rewinds_claim_on_send_exception tests/gateway/test_kanban_notifier.py::test_notifier_redelivers_same_kind_on_dispatch_cycle tests/gateway/test_kanban_notifier_watcher_dispatch_gate.py::test_notifier_watcher_env_override_disables tests/gateway/test_kanban_notifier_watcher_dispatch_gate.py::test_notifier_watcher_runs_when_dispatch_enabled tests/gateway/test_kanban_notifier_watcher_dispatch_gate.py::test_notifier_watcher_skips_when_dispatch_disabled tests/gateway/test_kanban_watchers_mixin.py::test_gateway_runner_inherits_mixin tests/gateway/test_kanban_watchers_mixin.py::test_mixin_defines_kanban_methods tests/gateway/test_kanban_watchers_mixin.py::test_singleton_dispatcher_lock_is_exclusive tests/gateway/test_kanban_watchers_mixin.py::test_watcher_loops_are_coroutines tests/gateway/test_keep_typing_timeout.py::TestKeepTypingTimeoutPerTick::test_fast_send_typing_still_gets_awaited tests/gateway/test_keep_typing_timeout.py::TestKeepTypingTimeoutPerTick::test_paused_chat_skips_send_typing tests/gateway/test_keep_typing_timeout.py::TestKeepTypingTimeoutPerTick::test_send_typing_exception_does_not_kill_loop tests/gateway/test_keep_typing_timeout.py::TestKeepTypingTimeoutPerTick::test_slow_send_typing_does_not_block_cadence tests/gateway/test_keep_typing_timeout.py::TestKeepTypingTimeoutPerTick::test_stop_typing_refresh_blocks_late_cancel_tick tests/gateway/test_korean_humanizer.py::test_adaptive_projection_allows_optional_averages_and_rate_to_be_none tests/gateway/test_korean_humanizer.py::test_adaptive_projection_rejects_forged_field_types_and_revision[updates0] tests/gateway/test_korean_humanizer.py::test_adaptive_projection_rejects_forged_field_types_and_revision[updates1] tests/gateway/test_korean_humanizer.py::test_adaptive_projection_rejects_forged_field_types_and_revision[updates2] tests/gateway/test_korean_humanizer.py::test_adaptive_projection_rejects_forged_field_types_and_revision[updates3] tests/gateway/test_korean_humanizer.py::test_adaptive_projection_rejects_forged_field_types_and_revision[updates4] tests/gateway/test_korean_humanizer.py::test_adaptive_projection_rejects_forged_field_types_and_revision[updates5] tests/gateway/test_korean_humanizer.py::test_adaptive_projection_rejects_forged_field_types_and_revision[updates6] tests/gateway/test_korean_humanizer.py::test_adaptive_projection_requires_the_exact_frozen_class_identity tests/gateway/test_korean_humanizer.py::test_adaptive_rewrites_review_copy_but_not_decision_or_delivery_state tests/gateway/test_korean_humanizer.py::test_daily_accepts_natural_prose_and_preserves_locked_copy tests/gateway/test_korean_humanizer.py::test_external_revision_binding_is_explicit_and_exact[1] tests/gateway/test_korean_humanizer.py::test_external_revision_binding_is_explicit_and_exact[None] tests/gateway/test_korean_humanizer.py::test_external_revision_binding_is_explicit_and_exact[] tests/gateway/test_korean_humanizer.py::test_external_revision_binding_is_explicit_and_exact[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] tests/gateway/test_korean_humanizer.py::test_external_revision_binding_is_explicit_and_exact[external_binding2] tests/gateway/test_korean_humanizer.py::test_extra_stage_slot_is_rejected tests/gateway/test_korean_humanizer.py::test_finite_pipeline_allows_three_to_five_approved_principles[3] tests/gateway/test_korean_humanizer.py::test_finite_pipeline_allows_three_to_five_approved_principles[4] tests/gateway/test_korean_humanizer.py::test_finite_pipeline_allows_three_to_five_approved_principles[5] tests/gateway/test_korean_humanizer.py::test_finite_pipeline_rejects_principle_counts_outside_bounds[2] tests/gateway/test_korean_humanizer.py::test_finite_pipeline_rejects_principle_counts_outside_bounds[6] tests/gateway/test_korean_humanizer.py::test_forged_finite_ids_fail_closed_without_retry[coach-atom_ids] tests/gateway/test_korean_humanizer.py::test_forged_finite_ids_fail_closed_without_retry[coach-principle_ids] tests/gateway/test_korean_humanizer.py::test_forged_finite_ids_fail_closed_without_retry[polish-variant_id] tests/gateway/test_korean_humanizer.py::test_humanize_makes_one_request_and_provider_failure_is_canonical tests/gateway/test_korean_humanizer.py::test_invalid_surface_or_canonical_is_canonical_with_zero_calls[None-\uc624\ub298 \uccb4\ud06c\uc778 \uc644\ub8cc\n\n- \uccb4\uc911: 78.10kg\n- \uc12d\ucde8: 2,310kcal\n\n\uc800\uc7a5\ub41c \uc624\ub298 \uae30\ub85d\uc744 \ud655\uc778\ud588\uc2b5\ub2c8\ub2e4.\n\n\uc624\ub298 \ud560 \uc77c\n\n- \ud604\uc7ac \uc2dd\uc0ac\ub7c9 \uc720\uc9c0] tests/gateway/test_korean_humanizer.py::test_invalid_surface_or_canonical_is_canonical_with_zero_calls[daily-None] tests/gateway/test_korean_humanizer.py::test_invalid_surface_or_canonical_is_canonical_with_zero_calls[daily-canonical2] tests/gateway/test_korean_humanizer.py::test_invalid_surface_or_canonical_is_canonical_with_zero_calls[unknown-\uc624\ub298 \uccb4\ud06c\uc778 \uc644\ub8cc\n\n- \uccb4\uc911: 78.10kg\n- \uc12d\ucde8: 2,310kcal\n\n\uc800\uc7a5\ub41c \uc624\ub298 \uae30\ub85d\uc744 \ud655\uc778\ud588\uc2b5\ub2c8\ub2e4.\n\n\uc624\ub298 \ud560 \uc77c\n\n- \ud604\uc7ac \uc2dd\uc0ac\ub7c9 \uc720\uc9c0] tests/gateway/test_korean_humanizer.py::test_malformed_grounding_fields_fail_closed_without_hashing_or_calls[approved_principles-None] tests/gateway/test_korean_humanizer.py::test_malformed_grounding_fields_fail_closed_without_hashing_or_calls[decision_id-customer_001] tests/gateway/test_korean_humanizer.py::test_malformed_grounding_fields_fail_closed_without_hashing_or_calls[excluded_risk_ids-None] tests/gateway/test_korean_humanizer.py::test_malformed_grounding_fields_fail_closed_without_hashing_or_calls[playbook_id-None] tests/gateway/test_korean_humanizer.py::test_malformed_grounding_fields_fail_closed_without_hashing_or_calls[revision_binding_digest-None] tests/gateway/test_korean_humanizer.py::test_malformed_grounding_fields_fail_closed_without_hashing_or_calls[source_cluster_ids-value2] tests/gateway/test_korean_humanizer.py::test_malformed_grounding_fields_fail_closed_without_hashing_or_calls[verified_memory-None] tests/gateway/test_korean_humanizer.py::test_malformed_or_partial_response_falls_back_exactly tests/gateway/test_korean_humanizer.py::test_malformed_surrogate_response_falls_back_without_raising tests/gateway/test_korean_humanizer.py::test_mismatched_playbook_or_revision_is_zero_call_canonical[revision] tests/gateway/test_korean_humanizer.py::test_mismatched_playbook_or_revision_is_zero_call_canonical[surface] tests/gateway/test_korean_humanizer.py::test_new_number_or_internal_code_rejects_the_whole_response tests/gateway/test_korean_humanizer.py::test_oversized_stage_json_fails_closed[coach] tests/gateway/test_korean_humanizer.py::test_oversized_stage_json_fails_closed[polish] tests/gateway/test_korean_humanizer.py::test_pipeline_receipt_contains_only_opaque_ids_and_digests tests/gateway/test_korean_humanizer.py::test_processing_gate_revocation_before_final_output_returns_canonical tests/gateway/test_korean_humanizer.py::test_processing_gate_revocation_between_stages_returns_canonical tests/gateway/test_korean_humanizer.py::test_stage_one_exception_returns_canonical_without_retry tests/gateway/test_korean_humanizer.py::test_stage_one_requires_exact_hard_identity_field[alias] tests/gateway/test_korean_humanizer.py::test_stage_one_requires_exact_hard_identity_field[missing] tests/gateway/test_korean_humanizer.py::test_stage_one_response_template_requires_exact_hard_identity_copy tests/gateway/test_korean_humanizer.py::test_stage_two_exception_rechecks_final_processing_gate tests/gateway/test_korean_humanizer.py::test_stage_two_exception_returns_validated_coach_without_retry tests/gateway/test_korean_humanizer.py::test_unbounded_receipt_ids_fail_before_model_calls tests/gateway/test_korean_humanizer.py::test_verified_memory_temporal_grammar_requires_real_iso_values[memory0] tests/gateway/test_korean_humanizer.py::test_verified_memory_temporal_grammar_requires_real_iso_values[memory1] tests/gateway/test_korean_humanizer.py::test_verified_memory_temporal_grammar_requires_real_iso_values[memory2] tests/gateway/test_korean_humanizer.py::test_verified_memory_temporal_grammar_requires_real_iso_values[memory3] tests/gateway/test_korean_humanizer.py::test_verified_memory_temporal_grammar_requires_real_iso_values[memory4] tests/gateway/test_korean_humanizer.py::test_weekly_rewrites_only_interpretation_and_rationale tests/gateway/test_line_plugin.py::TestAdapterInit::test_csv_allowlist_parsed tests/gateway/test_line_plugin.py::TestAdapterInit::test_env_overrides_extra tests/gateway/test_line_plugin.py::TestAdapterInit::test_get_chat_info_infers_type_from_prefix tests/gateway/test_line_plugin.py::TestAdapterInit::test_init_from_config_extra tests/gateway/test_line_plugin.py::TestAllowlist::test_allow_all_short_circuits tests/gateway/test_line_plugin.py::TestAllowlist::test_group_uses_group_list_not_user_list tests/gateway/test_line_plugin.py::TestAllowlist::test_room_uses_room_list tests/gateway/test_line_plugin.py::TestAllowlist::test_unknown_type_rejected tests/gateway/test_line_plugin.py::TestAllowlist::test_user_in_allowlist_passes tests/gateway/test_line_plugin.py::TestAllowlist::test_user_not_in_allowlist_rejected tests/gateway/test_line_plugin.py::TestCheckRequirements::test_rejects_without_secret tests/gateway/test_line_plugin.py::TestCheckRequirements::test_rejects_without_token tests/gateway/test_line_plugin.py::TestDedup::test_blank_id_not_treated_as_duplicate tests/gateway/test_line_plugin.py::TestDedup::test_first_event_not_duplicate tests/gateway/test_line_plugin.py::TestDedup::test_lru_eviction_under_pressure tests/gateway/test_line_plugin.py::TestDedup::test_repeat_event_marked_duplicate tests/gateway/test_line_plugin.py::TestEnvEnablement::test_returns_dict_with_credentials tests/gateway/test_line_plugin.py::TestEnvEnablement::test_returns_none_without_credentials tests/gateway/test_line_plugin.py::TestEnvEnablement::test_seeds_port_from_env tests/gateway/test_line_plugin.py::TestEnvEnablement::test_seeds_public_url tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_bold_stripped tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_bullet_marker_replaced tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_code_fence_content_kept tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_heading_prefix_stripped tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_inline_code_unfenced tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_italic_stripped tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_link_preserved_with_url tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_split_caps_at_five_chunks tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_split_long_chunks_at_paragraph_boundary tests/gateway/test_line_plugin.py::TestMarkdownAndChunking::test_split_short_returns_single_chunk tests/gateway/test_line_plugin.py::TestMessageTypeMapping::test_every_line_type_maps_to_correct_enum tests/gateway/test_line_plugin.py::TestMessageTypeMapping::test_image_event_not_attributeerror_regression tests/gateway/test_line_plugin.py::TestMessageTypeMapping::test_unknown_type_falls_back_to_text tests/gateway/test_line_plugin.py::TestPostbackButtonShape::test_alt_text_truncated_to_400 tests/gateway/test_line_plugin.py::TestPostbackButtonShape::test_template_buttons_structure tests/gateway/test_line_plugin.py::TestPostbackButtonShape::test_text_truncated_to_160 tests/gateway/test_line_plugin.py::TestRegister::test_max_message_length_below_line_per_bubble_limit tests/gateway/test_line_plugin.py::TestRegister::test_register_advertises_required_env tests/gateway/test_line_plugin.py::TestRegister::test_register_calls_register_platform tests/gateway/test_line_plugin.py::TestRegister::test_register_factory_yields_line_adapter tests/gateway/test_line_plugin.py::TestRegister::test_register_provides_env_enablement tests/gateway/test_line_plugin.py::TestRegister::test_register_provides_standalone_sender tests/gateway/test_line_plugin.py::TestRegister::test_register_wires_allowlist_envs tests/gateway/test_line_plugin.py::TestRegister::test_register_wires_cron_home_channel tests/gateway/test_line_plugin.py::TestRequestCache::test_find_pending_for_chat tests/gateway/test_line_plugin.py::TestRequestCache::test_mark_delivered_from_error tests/gateway/test_line_plugin.py::TestRequestCache::test_mark_delivered_from_ready tests/gateway/test_line_plugin.py::TestRequestCache::test_register_pending_is_pending tests/gateway/test_line_plugin.py::TestRequestCache::test_set_error_transitions tests/gateway/test_line_plugin.py::TestRequestCache::test_set_ready_on_delivered_is_noop tests/gateway/test_line_plugin.py::TestRequestCache::test_set_ready_transitions tests/gateway/test_line_plugin.py::TestSendRouting::test_format_message_strips_markdown tests/gateway/test_line_plugin.py::TestSendRouting::test_send_caps_messages_per_call_at_five tests/gateway/test_line_plugin.py::TestSendRouting::test_send_falls_back_to_push_when_no_token tests/gateway/test_line_plugin.py::TestSendRouting::test_send_falls_back_to_push_when_reply_fails tests/gateway/test_line_plugin.py::TestSendRouting::test_send_pending_button_caches_response tests/gateway/test_line_plugin.py::TestSendRouting::test_send_returns_failure_when_push_fails tests/gateway/test_line_plugin.py::TestSendRouting::test_send_system_bypass_skips_postback_cache tests/gateway/test_line_plugin.py::TestSendRouting::test_send_uses_reply_when_token_present tests/gateway/test_line_plugin.py::TestSendRouting::test_system_bypass_recognized tests/gateway/test_line_plugin.py::TestSignature::test_empty_secret_rejected tests/gateway/test_line_plugin.py::TestSignature::test_empty_signature_rejected tests/gateway/test_line_plugin.py::TestSignature::test_garbage_signature_rejected tests/gateway/test_line_plugin.py::TestSignature::test_tampered_body_rejected tests/gateway/test_line_plugin.py::TestSignature::test_valid_signature_passes tests/gateway/test_line_plugin.py::TestSignature::test_wrong_secret_rejected tests/gateway/test_line_plugin.py::TestSourceResolution::test_empty_source tests/gateway/test_line_plugin.py::TestSourceResolution::test_group_source tests/gateway/test_line_plugin.py::TestSourceResolution::test_room_source tests/gateway/test_line_plugin.py::TestSourceResolution::test_unknown_source_falls_back_to_dm tests/gateway/test_line_plugin.py::TestSourceResolution::test_user_source tests/gateway/test_line_plugin.py::TestStandaloneSend::test_missing_chat_id_returns_error tests/gateway/test_line_plugin.py::TestStandaloneSend::test_missing_token_returns_error tests/gateway/test_line_plugin.py::TestStandaloneSend::test_pushes_via_client_when_credentials_present tests/gateway/test_line_plugin.py::TestValidateConfig::test_rejects_empty_config tests/gateway/test_line_plugin.py::TestValidateConfig::test_validates_from_extra tests/gateway/test_load_transcript_db_only.py::test_load_transcript_returns_db_messages_when_no_jsonl tests/gateway/test_loop_exception_handler.py::test_handler_delegates_unknown_errors_to_default tests/gateway/test_loop_exception_handler.py::test_handler_swallows_transient_error_and_logs_warning tests/gateway/test_loop_exception_handler.py::test_handler_tolerates_missing_exception_key tests/gateway/test_loop_exception_handler.py::test_transient_classifier_does_not_infinite_loop_on_cyclic_cause tests/gateway/test_loop_exception_handler.py::test_transient_classifier_matches_known_network_errors[ClientConnectorError] tests/gateway/test_loop_exception_handler.py::test_transient_classifier_matches_known_network_errors[ConnectError] tests/gateway/test_loop_exception_handler.py::test_transient_classifier_matches_known_network_errors[NetworkError] tests/gateway/test_loop_exception_handler.py::test_transient_classifier_matches_known_network_errors[PoolTimeout] tests/gateway/test_loop_exception_handler.py::test_transient_classifier_matches_known_network_errors[ReadTimeout] tests/gateway/test_loop_exception_handler.py::test_transient_classifier_matches_known_network_errors[TimedOut] tests/gateway/test_loop_exception_handler.py::test_transient_classifier_rejects_unrelated_errors tests/gateway/test_loop_exception_handler.py::test_transient_classifier_unwraps_cause_chain tests/gateway/test_loop_exception_handler.py::test_transient_classifier_unwraps_context_chain tests/gateway/test_loop_exception_handler.py::test_unhandled_transient_error_in_task_does_not_propagate_to_loop tests/gateway/test_matrix.py::TestCreateMatrixSession::test_http_proxy_sets_default_proxy tests/gateway/test_matrix.py::TestCreateMatrixSession::test_no_proxy_returns_trust_env_session tests/gateway/test_matrix.py::TestCreateMatrixSession::test_socks_proxy_uses_connector tests/gateway/test_matrix.py::TestDeviceKeyReVerification::test_verify_fails_when_server_keys_mismatch_after_upload tests/gateway/test_matrix.py::TestJoinedRoomsReference::test_joined_rooms_reference_preserved_after_reassignment tests/gateway/test_matrix.py::TestMatrixAccessTokenAuth::test_connect_with_access_token_and_encryption tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_bang_alias_underscore_resolves_to_hyphen_form tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_bang_command_bypasses_room_mention_requirement tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_bang_command_in_quoted_reply_normalizes tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_bang_model_reaches_gateway_as_slash_command tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_bang_queue_preserves_arguments tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_bang_skill_command_normalizes tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_known_bang_command_normalizes_to_slash_command tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_slash_command_bypasses_room_mention_requirement tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_slash_command_in_quoted_reply_normalizes tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_unknown_bang_text_does_not_bypass_room_mention_requirement tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_unknown_bang_text_is_not_treated_as_command tests/gateway/test_matrix.py::TestMatrixBangCommandAlias::test_unknown_bang_text_stays_normal_text tests/gateway/test_matrix.py::TestMatrixClockSkewWarning::test_fewer_than_three_late_drops_do_not_warn tests/gateway/test_matrix.py::TestMatrixClockSkewWarning::test_initial_sync_drops_do_not_warn tests/gateway/test_matrix.py::TestMatrixClockSkewWarning::test_late_drops_emit_one_shot_clock_skew_warning tests/gateway/test_matrix.py::TestMatrixClockSkewWarning::test_state_reset_allows_warning_to_fire_again tests/gateway/test_matrix.py::TestMatrixClockSkewWarning::test_varied_backfill_skews_do_not_warn tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_apply_env_overrides_with_access_token tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_apply_env_overrides_with_password tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_matrix_e2ee_mode_optional_sets_config tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_matrix_encryption_default_off tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_matrix_encryption_flag tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_matrix_home_room tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_matrix_not_loaded_without_creds tests/gateway/test_matrix.py::TestMatrixConfigLoading::test_matrix_user_id_stored_in_extra tests/gateway/test_matrix.py::TestMatrixDeviceId::test_connect_uses_configured_device_id_over_whoami tests/gateway/test_matrix.py::TestMatrixDeviceId::test_device_id_config_takes_precedence_over_env tests/gateway/test_matrix.py::TestMatrixDeviceId::test_device_id_from_config_extra tests/gateway/test_matrix.py::TestMatrixDeviceId::test_device_id_from_env tests/gateway/test_matrix.py::TestMatrixDeviceIdConfig::test_device_id_in_config_extra tests/gateway/test_matrix.py::TestMatrixDeviceIdConfig::test_device_id_not_set_when_env_empty tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_capability_matrix_is_declared_for_docs tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_diagnostics_redacts_credentials_and_reports_status tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_matrix_capability_claims_match_adapter_surfaces tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_matrix_diagnostics_redacts_recovery_key tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_matrix_docs_capability_table_matches_declaration tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_matrix_recovery_key_bootstrap_skips_existing_output_file tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_matrix_recovery_key_bootstrap_skips_without_output_file tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_matrix_recovery_key_is_never_logged tests/gateway/test_matrix.py::TestMatrixDiagnostics::test_matrix_recovery_key_output_file_is_0600 tests/gateway/test_matrix.py::TestMatrixDisconnect::test_disconnect_closes_api_session tests/gateway/test_matrix.py::TestMatrixDisconnect::test_disconnect_handles_session_close_failure tests/gateway/test_matrix.py::TestMatrixDisconnect::test_disconnect_without_client tests/gateway/test_matrix.py::TestMatrixDisplayName::test_get_display_name_fallback_to_localpart tests/gateway/test_matrix.py::TestMatrixDisplayName::test_get_display_name_from_state_store tests/gateway/test_matrix.py::TestMatrixDisplayName::test_get_display_name_no_client tests/gateway/test_matrix.py::TestMatrixDmAutoThread::test_dm_auto_thread_disabled_no_thread tests/gateway/test_matrix.py::TestMatrixDmAutoThread::test_dm_auto_thread_enabled_creates_thread tests/gateway/test_matrix.py::TestMatrixDmDetection::test_canonical_alias_used_when_name_missing tests/gateway/test_matrix.py::TestMatrixDmDetection::test_m_direct_room_is_dm tests/gateway/test_matrix.py::TestMatrixDmDetection::test_named_room_overrides_stale_dm_cache tests/gateway/test_matrix.py::TestMatrixDmDetection::test_named_two_member_room_is_not_dm tests/gateway/test_matrix.py::TestMatrixDmDetection::test_non_string_m_direct_entries_ignored tests/gateway/test_matrix.py::TestMatrixDmDetection::test_refresh_dm_cache_with_m_direct tests/gateway/test_matrix.py::TestMatrixDmDetection::test_room_in_m_direct_is_dm tests/gateway/test_matrix.py::TestMatrixDmDetection::test_unknown_room_not_in_cache tests/gateway/test_matrix.py::TestMatrixE2EEHardFail::test_connect_continues_when_e2ee_optional_but_no_deps tests/gateway/test_matrix.py::TestMatrixE2EEHardFail::test_connect_fails_when_crypto_setup_raises tests/gateway/test_matrix.py::TestMatrixE2EEHardFail::test_connect_fails_when_encryption_true_but_no_e2ee_deps tests/gateway/test_matrix.py::TestMatrixEncryptedEventHandler::test_connect_fails_on_stale_otk_conflict tests/gateway/test_matrix.py::TestMatrixEncryptedEventHandler::test_connect_registers_encrypted_event_handler_when_encryption_on tests/gateway/test_matrix.py::TestMatrixEncryptedSendFallback::test_send_retries_after_e2ee_error tests/gateway/test_matrix.py::TestMatrixFormatMessage::test_image_markdown_stripped tests/gateway/test_matrix.py::TestMatrixFormatMessage::test_multiple_images_stripped tests/gateway/test_matrix.py::TestMatrixFormatMessage::test_plain_text_unchanged tests/gateway/test_matrix.py::TestMatrixFormatMessage::test_regular_markdown_preserved tests/gateway/test_matrix.py::TestMatrixFreeResponsePolicy::test_free_response_room_allows_unmentioned_message tests/gateway/test_matrix.py::TestMatrixFreeResponsePolicy::test_non_free_room_requires_mention tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_external_media_download_rejects_non_image_content_type tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_external_media_download_rejects_oversized_content_length tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_external_media_download_rejects_oversized_stream tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_external_media_download_rejects_unsafe_initial_url tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_external_media_download_rejects_unsafe_redirect tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_image_caption_text_is_preserved tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_image_only_filename_body_is_not_forwarded_as_text tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_inbound_encrypted_non_mxc_media_url_is_rejected tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_inbound_non_mxc_media_url_is_rejected tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_inbound_oversized_media_is_rejected tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_send_image_failure_log_redacts_signed_url tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_send_image_failure_log_still_redacts_signed_url tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_send_image_failure_response_does_not_expose_signed_url_fragment tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_send_image_failure_response_does_not_expose_signed_url_query tests/gateway/test_matrix.py::TestMatrixImageOnlyMediaNormalization::test_send_image_failure_response_preserves_caption tests/gateway/test_matrix.py::TestMatrixLinkSanitization::test_data_blocked tests/gateway/test_matrix.py::TestMatrixLinkSanitization::test_javascript_blocked tests/gateway/test_matrix.py::TestMatrixLinkSanitization::test_quotes_escaped tests/gateway/test_matrix.py::TestMatrixLinkSanitization::test_safe_https_url tests/gateway/test_matrix.py::TestMatrixLinkSanitization::test_vbscript_blocked tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_blockquote tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_code_block_html_escaped tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_complex_mixed_document tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_fenced_code_block tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_fenced_code_block_no_lang tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_headers tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_horizontal_rule tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_links_preserved tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_ordered_list tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_strikethrough tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlFormatting::test_unordered_list tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_data_uri_blocked tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_html_injection_in_bold tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_html_injection_in_italic tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_img_onerror_in_blockquote tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_javascript_uri_blocked tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_link_href_attribute_breakout tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_link_text_html_injection tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_script_in_list_item tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_script_in_ordered_list tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_script_injection_in_header tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_script_injection_in_plain_text tests/gateway/test_matrix.py::TestMatrixMarkdownHtmlSecurity::test_vbscript_uri_blocked tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_bold_conversion tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_inline_code tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_italic_conversion tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_preserves_code_fences tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_preserves_table_structure tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_rejects_blob_links tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_rejects_file_links tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_rejects_ftp_links tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_rejects_javascript_links tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_rejects_obfuscated_javascript_links tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_strips_inline_event_handlers tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_matrix_markdown_strips_script_tag tests/gateway/test_matrix.py::TestMatrixMarkdownToHtml::test_plain_text_returns_html tests/gateway/test_matrix.py::TestMatrixModuleImport::test_module_importable_without_mautrix tests/gateway/test_matrix.py::TestMatrixMxcToHttp::test_basic_mxc_conversion tests/gateway/test_matrix.py::TestMatrixMxcToHttp::test_mxc_uses_client_v1_endpoint tests/gateway/test_matrix.py::TestMatrixMxcToHttp::test_mxc_with_different_server tests/gateway/test_matrix.py::TestMatrixMxcToHttp::test_non_mxc_url_passthrough tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_authorized_user_reaches_text_handler tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_bridge_sender_dropped_before_pairing tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_configured_bridge_pattern_is_dropped tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_dm_room_bypasses_allowed_room_gate tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_duplicate_event_id_dropped tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_empty_sender_dropped tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_notice_message_can_be_enabled tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_notice_message_is_dropped_by_default tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_old_startup_event_dropped tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_own_sender_case_insensitive_dropped tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_regular_user_reaches_text_handler tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_seconds_timestamp_reaches_text_handler tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_self_with_unresolved_user_id_dropped tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_unauthorized_room_is_dropped tests/gateway/test_matrix.py::TestMatrixOnRoomMessageFilter::test_unauthorized_user_reaches_text_handler tests/gateway/test_matrix.py::TestMatrixPasswordLoginDeviceId::test_password_login_uses_device_id tests/gateway/test_matrix.py::TestMatrixPresence::test_set_presence_invalid_state tests/gateway/test_matrix.py::TestMatrixPresence::test_set_presence_no_client tests/gateway/test_matrix.py::TestMatrixPresence::test_set_presence_valid tests/gateway/test_matrix.py::TestMatrixProxyConfig::test_generic_proxy_fallback tests/gateway/test_matrix.py::TestMatrixProxyConfig::test_matrix_proxy_env_var tests/gateway/test_matrix.py::TestMatrixProxyConfig::test_matrix_proxy_takes_priority tests/gateway/test_matrix.py::TestMatrixProxyConfig::test_no_proxy_by_default tests/gateway/test_matrix.py::TestMatrixReactions::test_approval_reaction_cleanup_is_delayed tests/gateway/test_matrix.py::TestMatrixReactions::test_on_processing_complete_cancelled_sends_no_terminal_reaction tests/gateway/test_matrix.py::TestMatrixReactions::test_on_processing_complete_no_pending_reaction tests/gateway/test_matrix.py::TestMatrixReactions::test_on_processing_complete_sends_check tests/gateway/test_matrix.py::TestMatrixReactions::test_on_processing_complete_sends_cross_on_failure tests/gateway/test_matrix.py::TestMatrixReactions::test_on_processing_start_sends_eyes tests/gateway/test_matrix.py::TestMatrixReactions::test_reactions_disabled tests/gateway/test_matrix.py::TestMatrixReactions::test_send_reaction tests/gateway/test_matrix.py::TestMatrixReactions::test_send_reaction_no_client tests/gateway/test_matrix.py::TestMatrixReadReceipts::test_accepted_message_schedules_read_receipt tests/gateway/test_matrix.py::TestMatrixReadReceipts::test_read_receipt_no_client tests/gateway/test_matrix.py::TestMatrixReadReceipts::test_send_read_receipt tests/gateway/test_matrix.py::TestMatrixReadReceipts::test_send_read_receipt_falls_back_to_receipt_only tests/gateway/test_matrix.py::TestMatrixRedaction::test_redact_message tests/gateway/test_matrix.py::TestMatrixRedaction::test_redact_no_client tests/gateway/test_matrix.py::TestMatrixRenderingPayloads::test_edit_payload_uses_m_replace tests/gateway/test_matrix.py::TestMatrixRenderingPayloads::test_long_response_split_preserves_thread_context tests/gateway/test_matrix.py::TestMatrixRenderingPayloads::test_render_plain_and_html_body tests/gateway/test_matrix.py::TestMatrixRenderingPayloads::test_thread_payload_preserves_explicit_reply_target tests/gateway/test_matrix.py::TestMatrixRenderingPayloads::test_thread_payload_uses_m_thread_with_reply_fallback tests/gateway/test_matrix.py::TestMatrixReplyFallbackStripping::test_empty_fallback_separator tests/gateway/test_matrix.py::TestMatrixReplyFallbackStripping::test_multiline_reply_fallback tests/gateway/test_matrix.py::TestMatrixReplyFallbackStripping::test_multiline_response_after_fallback tests/gateway/test_matrix.py::TestMatrixReplyFallbackStripping::test_no_reply_fallback_preserved tests/gateway/test_matrix.py::TestMatrixReplyFallbackStripping::test_quote_without_reply_preserved tests/gateway/test_matrix.py::TestMatrixReplyFallbackStripping::test_simple_reply_fallback tests/gateway/test_matrix.py::TestMatrixRequireMention::test_require_mention_config_takes_precedence_over_env tests/gateway/test_matrix.py::TestMatrixRequireMention::test_require_mention_false_allows_unmentioned_group_message tests/gateway/test_matrix.py::TestMatrixRequireMention::test_require_mention_from_config_extra_false tests/gateway/test_matrix.py::TestMatrixRequireMention::test_require_mention_from_env_when_extra_unset tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_e2ee_deps_requires_aiosqlite tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_e2ee_deps_requires_asyncpg tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_e2ee_optional_no_deps_ok tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_encryption_false_no_e2ee_deps_ok tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_encryption_true_no_e2ee_deps tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_encryption_true_with_e2ee_deps tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_runs_lazy_install_when_partial tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_with_token tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_without_creds tests/gateway/test_matrix.py::TestMatrixRequirements::test_check_requirements_without_homeserver tests/gateway/test_matrix.py::TestMatrixRoomManagement::test_create_room tests/gateway/test_matrix.py::TestMatrixRoomManagement::test_create_room_no_client tests/gateway/test_matrix.py::TestMatrixRoomManagement::test_invite_user tests/gateway/test_matrix.py::TestMatrixSelfSenderFilter::test_case_insensitive_match_is_self tests/gateway/test_matrix.py::TestMatrixSelfSenderFilter::test_different_user_is_not_self tests/gateway/test_matrix.py::TestMatrixSelfSenderFilter::test_empty_user_id_is_treated_as_self tests/gateway/test_matrix.py::TestMatrixSelfSenderFilter::test_exact_match_is_self tests/gateway/test_matrix.py::TestMatrixSelfSenderFilter::test_whitespace_trimmed tests/gateway/test_matrix.py::TestMatrixSyncLoop::test_connect_receives_dm_from_initial_sync_dispatch tests/gateway/test_matrix.py::TestMatrixSyncLoop::test_dispatch_sync_accepts_async_handle_sync tests/gateway/test_matrix.py::TestMatrixSyncLoop::test_room_message_after_invite_join_is_received tests/gateway/test_matrix.py::TestMatrixSyncLoop::test_seconds_timestamp_is_not_treated_as_milliseconds tests/gateway/test_matrix.py::TestMatrixSyncLoop::test_sync_loop_dispatches_events_and_stores_token tests/gateway/test_matrix.py::TestMatrixSyncLoop::test_sync_loop_dispatches_registered_room_message_handler tests/gateway/test_matrix.py::TestMatrixSyncLoop::test_sync_loop_reconciles_pending_invites tests/gateway/test_matrix.py::TestMatrixSystemBridgeFilter::test_appservice_underscore_prefix_is_bridge tests/gateway/test_matrix.py::TestMatrixSystemBridgeFilter::test_bot_account_is_not_bridge tests/gateway/test_matrix.py::TestMatrixSystemBridgeFilter::test_empty_localpart_is_system tests/gateway/test_matrix.py::TestMatrixSystemBridgeFilter::test_empty_sender_is_system tests/gateway/test_matrix.py::TestMatrixSystemBridgeFilter::test_regular_user_is_not_bridge tests/gateway/test_matrix.py::TestMatrixThreadDetection::test_empty_relates_to tests/gateway/test_matrix.py::TestMatrixThreadDetection::test_no_thread_for_edit tests/gateway/test_matrix.py::TestMatrixThreadDetection::test_no_thread_for_reply tests/gateway/test_matrix.py::TestMatrixThreadDetection::test_thread_id_from_m_relates_to tests/gateway/test_matrix.py::TestMatrixTypingIndicator::test_stop_typing_clears_matrix_typing_state tests/gateway/test_matrix.py::TestMatrixTypingIndicator::test_stop_typing_no_client_is_noop tests/gateway/test_matrix.py::TestMatrixTypingIndicator::test_stop_typing_suppresses_exceptions tests/gateway/test_matrix.py::TestMatrixUploadAndSend::test_media_preserves_caption_and_thread tests/gateway/test_matrix.py::TestMatrixUploadAndSend::test_send_multiple_images_preserves_logical_batch_order_and_thread tests/gateway/test_matrix.py::TestMatrixUploadAndSend::test_upload_encrypted_room_uses_file_payload tests/gateway/test_matrix.py::TestMatrixUploadAndSend::test_upload_rejects_oversized_file tests/gateway/test_matrix.py::TestMatrixUploadAndSend::test_upload_unencrypted_room_uses_plain_url tests/gateway/test_matrix_approval_reaction_fail_closed.py::TestApprovalReactionFailClosed::test_listed_sender_permits tests/gateway/test_matrix_approval_reaction_fail_closed.py::TestApprovalReactionFailClosed::test_no_allowlist_allow_all_permits tests/gateway/test_matrix_approval_reaction_fail_closed.py::TestApprovalReactionFailClosed::test_no_allowlist_no_allow_all_denies tests/gateway/test_matrix_approval_reaction_fail_closed.py::TestApprovalReactionFailClosed::test_unlisted_sender_denies tests/gateway/test_matrix_exec_approval.py::TestMatrixExecApprovalReactions::test_reaction_resolves_pending_approval tests/gateway/test_matrix_exec_approval.py::TestMatrixExecApprovalReactions::test_send_exec_approval_registers_prompt_and_seeds_reactions tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_empty_body tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_full_user_id_in_body tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_localpart_case_insensitive tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_localpart_in_body tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_m_mentions_user_ids_authoritative tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_m_mentions_user_ids_empty_list tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_m_mentions_user_ids_none tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_m_mentions_user_ids_other_user_only tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_m_mentions_user_ids_with_body_mention tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_matrix_pill_in_formatted_body tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_no_mention tests/gateway/test_matrix_mention.py::TestIsBotMentioned::test_partial_localpart_no_match tests/gateway/test_matrix_mention.py::TestMatrixConfigBridge::test_env_vars_take_precedence_over_yaml tests/gateway/test_matrix_mention.py::TestMatrixConfigBridge::test_yaml_bridge_sets_dm_mention_threads tests/gateway/test_matrix_mention.py::TestMatrixConfigBridge::test_yaml_bridge_sets_env_vars tests/gateway/test_matrix_mention.py::TestOutboundMentions::test_edit_message_preserves_mentions tests/gateway/test_matrix_mention.py::TestOutboundMentions::test_send_adds_matrix_mentions_and_formatted_body tests/gateway/test_matrix_mention.py::TestOutboundMentions::test_send_dedupes_mentions_and_ignores_code_spans tests/gateway/test_matrix_mention.py::TestOutboundMentions::test_send_simple_notice_adds_mentions tests/gateway/test_matrix_mention.py::TestStripMention::test_does_not_strip_bare_localpart_word tests/gateway/test_matrix_mention.py::TestStripMention::test_localpart_in_path_preserved tests/gateway/test_matrix_mention.py::TestStripMention::test_localpart_preserved tests/gateway/test_matrix_mention.py::TestStripMention::test_strip_full_user_id tests/gateway/test_matrix_mention.py::TestStripMention::test_strip_localpart_when_explicit_at_mention tests/gateway/test_matrix_mention.py::TestStripMention::test_strip_returns_empty_for_mention_only tests/gateway/test_matrix_mention.py::TestThreadPersistence::test_cap_max_tracked_threads tests/gateway/test_matrix_mention.py::TestThreadPersistence::test_empty_state_file tests/gateway/test_matrix_mention.py::TestThreadPersistence::test_threads_survive_reload tests/gateway/test_matrix_mention.py::TestThreadPersistence::test_track_thread_persists tests/gateway/test_matrix_mention.py::test_auto_thread_default_creates_thread tests/gateway/test_matrix_mention.py::test_auto_thread_disabled tests/gateway/test_matrix_mention.py::test_auto_thread_preserves_existing_thread tests/gateway/test_matrix_mention.py::test_auto_thread_skips_dm tests/gateway/test_matrix_mention.py::test_auto_thread_tracks_participation tests/gateway/test_matrix_mention.py::test_bare_mention_passes_empty_string tests/gateway/test_matrix_mention.py::test_dm_mention_thread_creates_thread tests/gateway/test_matrix_mention.py::test_dm_mention_thread_disabled_by_default tests/gateway/test_matrix_mention.py::test_dm_mention_thread_no_mention_no_thread tests/gateway/test_matrix_mention.py::test_dm_mention_thread_preserves_existing_thread tests/gateway/test_matrix_mention.py::test_dm_mention_thread_tracks_participation tests/gateway/test_matrix_mention.py::test_dm_preserves_localpart_in_body tests/gateway/test_matrix_mention.py::test_dm_strips_full_mxid tests/gateway/test_matrix_mention.py::test_require_mention_bot_participated_thread tests/gateway/test_matrix_mention.py::test_require_mention_default_ignores_unmentioned tests/gateway/test_matrix_mention.py::test_require_mention_default_processes_mentioned tests/gateway/test_matrix_mention.py::test_require_mention_disabled tests/gateway/test_matrix_mention.py::test_require_mention_disabled_skips_stripping tests/gateway/test_matrix_mention.py::test_require_mention_dm_always_responds tests/gateway/test_matrix_mention.py::test_require_mention_free_response_room tests/gateway/test_matrix_mention.py::test_require_mention_html_pill tests/gateway/test_matrix_mention.py::test_require_mention_m_mentions_other_user_ignored tests/gateway/test_matrix_mention.py::test_require_mention_m_mentions_user_ids tests/gateway/test_matrix_project_context_isolation.py::test_matrix_inbound_handler_emits_project_b_metadata_not_project_a tests/gateway/test_matrix_project_context_isolation.py::test_matrix_inbound_handler_keeps_project_a_and_b_distinct tests/gateway/test_matrix_project_context_isolation.py::test_matrix_project_a_and_project_b_have_distinct_session_keys tests/gateway/test_matrix_project_context_isolation.py::test_matrix_project_b_prompt_contains_project_b_not_project_a tests/gateway/test_matrix_project_context_isolation.py::test_matrix_project_context_survives_concurrent_messages tests/gateway/test_matrix_project_context_isolation.py::test_matrix_project_context_survives_sequential_messages tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_all_lists_room_names tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_allows_same_room_session tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_cross_room_requires_explicit_flag_and_warns tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_does_not_cross_rooms_by_default tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_lists_only_current_room_by_default tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_malformed_quote_returns_helpful_error tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_quoted_title_cross_room_blocked tests/gateway/test_matrix_project_context_isolation.py::test_matrix_resume_quoted_title_same_room tests/gateway/test_matrix_project_context_isolation.py::test_matrix_room_scope_group_sessions_per_user_false_shares_room tests/gateway/test_matrix_project_context_isolation.py::test_matrix_room_scope_group_sessions_per_user_true_separates_users tests/gateway/test_matrix_project_context_isolation.py::test_matrix_session_scope_auto_and_thread_preserve_synthetic_threads tests/gateway/test_matrix_project_context_isolation.py::test_matrix_source_includes_room_name_topic_and_message_id tests/gateway/test_matrix_project_context_isolation.py::test_matrix_status_reports_current_matrix_room_scope tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_apply_env_overrides_mattermost tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_mattermost_home_channel tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_mattermost_not_loaded_without_token tests/gateway/test_mattermost.py::TestMattermostConfigLoading::test_mattermost_url_warning_without_url tests/gateway/test_mattermost.py::TestMattermostDedup::test_different_post_ids_both_processed tests/gateway/test_mattermost.py::TestMattermostDedup::test_duplicate_post_ignored tests/gateway/test_mattermost.py::TestMattermostDedup::test_prune_seen_clears_expired tests/gateway/test_mattermost.py::TestMattermostDedup::test_seen_cache_tracks_post_ids tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_global_thinking_progress_still_applies_to_other_platforms tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_platform_opt_in_can_enable_interim_assistant_messages tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_platform_opt_in_can_enable_show_reasoning tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_requires_platform_opt_in_for_interim_assistant_messages tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_requires_platform_opt_in_for_show_reasoning tests/gateway/test_mattermost.py::TestMattermostDisplayHygiene::test_mattermost_requires_platform_opt_in_for_thinking_progress tests/gateway/test_mattermost.py::TestMattermostFileUpload::test_send_image_downloads_and_uploads tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_image_markdown_strips_alt_text tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_image_markdown_to_url tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_multiple_images tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_plain_text_unchanged tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_regular_links_preserved tests/gateway/test_mattermost.py::TestMattermostFormatMessage::test_regular_markdown_preserved tests/gateway/test_mattermost.py::TestMattermostMediaTypes::test_audio_media_type_is_full_mime tests/gateway/test_mattermost.py::TestMattermostMediaTypes::test_document_media_type_is_full_mime tests/gateway/test_mattermost.py::TestMattermostMediaTypes::test_image_media_type_is_full_mime tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_dm_always_responds tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_free_response_channel_responds_without_mention tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_mention_stripped_from_text tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_non_free_channel_still_requires_mention tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_require_mention_false_responds_to_all tests/gateway/test_mattermost.py::TestMattermostMentionBehavior::test_require_mention_true_skips_without_mention tests/gateway/test_mattermost.py::TestMattermostProgressThreadRouting::test_telegram_progress_does_not_use_message_id_as_thread_id tests/gateway/test_mattermost.py::TestMattermostProgressThreadRouting::test_threaded_mattermost_progress_prefers_existing_thread_root tests/gateway/test_mattermost.py::TestMattermostProgressThreadRouting::test_top_level_mattermost_progress_uses_event_message_id tests/gateway/test_mattermost.py::TestMattermostRequirements::test_check_requirements_with_token_and_url tests/gateway/test_mattermost.py::TestMattermostRequirements::test_check_requirements_without_token tests/gateway/test_mattermost.py::TestMattermostRequirements::test_check_requirements_without_url tests/gateway/test_mattermost.py::TestMattermostSend::test_notify_send_with_invalid_thread_root_falls_back_flat_with_warning tests/gateway/test_mattermost.py::TestMattermostSend::test_notify_send_with_server_error_does_not_fall_back_flat tests/gateway/test_mattermost.py::TestMattermostSend::test_progress_send_with_invalid_thread_root_never_falls_back_flat tests/gateway/test_mattermost.py::TestMattermostSend::test_send_api_failure tests/gateway/test_mattermost.py::TestMattermostSend::test_send_calls_api_post tests/gateway/test_mattermost.py::TestMattermostSend::test_send_empty_content_succeeds tests/gateway/test_mattermost.py::TestMattermostSend::test_send_uses_metadata_thread_id_for_progress_messages tests/gateway/test_mattermost.py::TestMattermostSend::test_send_with_thread_reply tests/gateway/test_mattermost.py::TestMattermostSend::test_send_without_thread_no_root_id tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_custom_max_length tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_exactly_at_limit tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_long_message_splits tests/gateway/test_mattermost.py::TestMattermostTruncateMessage::test_short_message_single_chunk tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_channel_type_mapping tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_ignore_non_posted_events tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_ignore_own_messages tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_ignore_system_posts tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_invalid_post_json_ignored tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_parse_posted_event tests/gateway/test_mattermost.py::TestMattermostWebSocketParsing::test_thread_id_from_root_id tests/gateway/test_mattermost.py::test_mattermost_dm_post_does_not_seed_thread_root tests/gateway/test_mattermost.py::test_mattermost_top_level_channel_post_is_thread_root tests/gateway/test_max_concurrent_sessions.py::test_existing_active_session_uses_busy_handling_at_limit tests/gateway/test_max_concurrent_sessions.py::test_new_session_can_start_after_active_session_released tests/gateway/test_max_concurrent_sessions.py::test_new_session_gets_clean_error_at_active_session_limit tests/gateway/test_max_concurrent_sessions.py::test_skill_command_that_would_start_agent_is_blocked_at_limit tests/gateway/test_max_concurrent_sessions.py::test_status_command_bypasses_active_session_limit tests/gateway/test_max_tokens_propagation.py::test_env_override_beats_everything tests/gateway/test_max_tokens_propagation.py::test_global_max_tokens_beats_per_provider tests/gateway/test_max_tokens_propagation.py::test_lift_helper_accepts_alias_and_rejects_garbage tests/gateway/test_max_tokens_propagation.py::test_no_config_leaves_max_tokens_none tests/gateway/test_max_tokens_propagation.py::test_per_provider_max_output_tokens_fallback tests/gateway/test_max_tokens_propagation.py::test_top_level_max_tokens_propagates tests/gateway/test_mcp_reload_refreshes_cached_agents.py::test_reload_mcp_handles_empty_agent_cache tests/gateway/test_mcp_reload_refreshes_cached_agents.py::test_reload_mcp_preserves_per_agent_toolset_overrides tests/gateway/test_mcp_reload_refreshes_cached_agents.py::test_reload_mcp_refreshes_cached_agent_tools tests/gateway/test_media_download_retry.py::TestCacheAudioFromUrl::test_non_retryable_4xx_raises_immediately tests/gateway/test_media_download_retry.py::TestCacheAudioFromUrl::test_raises_after_max_retries_exhausted tests/gateway/test_media_download_retry.py::TestCacheAudioFromUrl::test_retries_on_429_then_succeeds tests/gateway/test_media_download_retry.py::TestCacheAudioFromUrl::test_retries_on_500_then_succeeds tests/gateway/test_media_download_retry.py::TestCacheAudioFromUrl::test_retries_on_timeout_then_succeeds tests/gateway/test_media_download_retry.py::TestCacheAudioFromUrl::test_success_on_first_attempt tests/gateway/test_media_download_retry.py::TestCacheImageFromBytes::test_caches_valid_jpeg tests/gateway/test_media_download_retry.py::TestCacheImageFromBytes::test_caches_valid_png tests/gateway/test_media_download_retry.py::TestCacheImageFromBytes::test_rejects_empty_data tests/gateway/test_media_download_retry.py::TestCacheImageFromBytes::test_rejects_html_content tests/gateway/test_media_download_retry.py::TestCacheImageFromBytes::test_rejects_plain_text tests/gateway/test_media_download_retry.py::TestCacheImageFromUrl::test_non_retryable_4xx_raises_immediately tests/gateway/test_media_download_retry.py::TestCacheImageFromUrl::test_raises_after_max_retries_exhausted tests/gateway/test_media_download_retry.py::TestCacheImageFromUrl::test_retries_on_429_then_succeeds tests/gateway/test_media_download_retry.py::TestCacheImageFromUrl::test_retries_on_timeout_then_succeeds tests/gateway/test_media_download_retry.py::TestCacheImageFromUrl::test_success_on_first_attempt tests/gateway/test_media_download_retry.py::TestMattermostSendUrlAsFile::test_falls_back_on_client_error tests/gateway/test_media_download_retry.py::TestMattermostSendUrlAsFile::test_falls_back_to_text_after_max_retries_on_5xx tests/gateway/test_media_download_retry.py::TestMattermostSendUrlAsFile::test_non_retryable_404_falls_back_immediately tests/gateway/test_media_download_retry.py::TestMattermostSendUrlAsFile::test_retries_on_429_then_succeeds tests/gateway/test_media_download_retry.py::TestMattermostSendUrlAsFile::test_retries_on_500_then_succeeds tests/gateway/test_media_download_retry.py::TestMattermostSendUrlAsFile::test_success_on_first_attempt tests/gateway/test_media_download_retry.py::TestSSRFRedirectGuard::test_audio_blocks_private_redirect tests/gateway/test_media_download_retry.py::TestSSRFRedirectGuard::test_image_blocks_private_redirect tests/gateway/test_media_download_retry.py::TestSSRFRedirectGuard::test_safe_redirect_allowed tests/gateway/test_media_download_retry.py::TestSlackAttachmentDiagnostics::test_download_failure_403_returns_permission_notice tests/gateway/test_media_download_retry.py::TestSlackAttachmentDiagnostics::test_missing_scope_error_returns_actionable_notice tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFile::test_non_retryable_403_raises_immediately tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFile::test_raises_after_max_retries tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFile::test_rejects_html_response tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFile::test_retries_on_timeout_then_succeeds tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFile::test_success_on_first_attempt tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFileBytes::test_raises_after_max_retries tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFileBytes::test_rejects_html_response tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFileBytes::test_retries_on_429_then_succeeds tests/gateway/test_media_download_retry.py::TestSlackDownloadSlackFileBytes::test_success_returns_bytes tests/gateway/test_media_extraction.py::TestMediaExtraction::test_deduplication_within_current_turn tests/gateway/test_media_extraction.py::TestMediaExtraction::test_gateway_auto_append_ignores_media_examples_in_skill_docs tests/gateway/test_media_extraction.py::TestMediaExtraction::test_gateway_auto_append_image_generate_dedupes_history tests/gateway/test_media_extraction.py::TestMediaExtraction::test_gateway_auto_append_image_generate_failure_and_url_ignored tests/gateway/test_media_extraction.py::TestMediaExtraction::test_gateway_auto_append_image_generate_json_path tests/gateway/test_media_extraction.py::TestMediaExtraction::test_gateway_auto_append_image_generate_prefers_host_path tests/gateway/test_media_extraction.py::TestMediaExtraction::test_gateway_auto_append_keeps_real_tts_media_tag tests/gateway/test_media_extraction.py::TestMediaExtraction::test_media_tags_extracted_from_current_turn tests/gateway/test_media_extraction.py::TestMediaExtraction::test_media_tags_not_extracted_from_history tests/gateway/test_media_extraction.py::TestMediaExtraction::test_multiple_tts_calls_in_history_not_accumulated tests/gateway/test_media_extraction.py::TestStaleToolMediaLeak::test_compression_shrink_falls_back_to_path_dedup tests/gateway/test_media_extraction.py::TestStaleToolMediaLeak::test_current_turn_media_still_attached_when_dedup_set_empty tests/gateway/test_media_extraction.py::TestStaleToolMediaLeak::test_stale_execute_code_media_not_attached_to_text_only_reply tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.bluebubbles-BlueBubblesAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.dingtalk-DingTalkAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.discord-DiscordAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.email-EmailAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.feishu-FeishuAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.matrix-MatrixAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.mattermost-MattermostAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.signal-SignalAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.slack-SlackAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.telegram-TelegramAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.wecom-WeComAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.weixin-WeixinAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.whatsapp-WhatsAppAdapter] tests/gateway/test_media_metadata_contract.py::test_all_adapters_send_image_metadata_sweep[gateway.platforms.yuanbao-YuanbaoAdapter] tests/gateway/test_media_metadata_contract.py::test_send_image_accepts_metadata[gateway.platforms.email-EmailAdapter] tests/gateway/test_media_metadata_contract.py::test_send_image_accepts_metadata[gateway.platforms.whatsapp-WhatsAppAdapter] tests/gateway/test_memory_monitor.py::test_double_start_is_noop tests/gateway/test_memory_monitor.py::test_log_memory_usage_emits_memory_line tests/gateway/test_memory_monitor.py::test_log_memory_usage_has_grep_friendly_format tests/gateway/test_memory_monitor.py::test_log_memory_usage_with_prefix tests/gateway/test_memory_monitor.py::test_periodic_timer_fires tests/gateway/test_memory_monitor.py::test_start_logs_baseline_and_returns_true tests/gateway/test_memory_monitor.py::test_stop_logs_shutdown_snapshot tests/gateway/test_memory_monitor.py::test_stop_without_start_is_noop tests/gateway/test_memory_monitor.py::test_thread_is_daemon tests/gateway/test_memory_monitor.py::test_unavailable_rss_warns_and_does_not_start tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_different_messages_not_confused tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_duplicate_within_ttl tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_empty_id_never_duplicate tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_expired_entry_gets_refreshed tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_max_size_eviction_caps_fresh_entries tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_max_size_eviction_prunes_expired tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_not_duplicate_after_ttl_expires tests/gateway/test_message_deduplicator.py::TestMessageDeduplicatorTTL::test_ttl_zero_means_no_dedup tests/gateway/test_message_timestamps.py::test_build_history_injects_only_when_enabled tests/gateway/test_message_timestamps.py::test_coerce_message_timestamp_accepts_datetime_and_epoch tests/gateway/test_message_timestamps.py::test_message_timestamps_enabled_defaults_off tests/gateway/test_message_timestamps.py::test_message_timestamps_enabled_when_opted_in tests/gateway/test_message_timestamps.py::test_persist_user_message_override_keeps_clean_content_and_timestamp_metadata tests/gateway/test_message_timestamps.py::test_render_user_content_adds_single_context_timestamp tests/gateway/test_message_timestamps.py::test_render_user_content_deduplicates_existing_timestamp_and_preserves_embedded_time tests/gateway/test_message_timestamps.py::test_strip_leading_message_timestamps_removes_multiple_prefixes_and_prefers_inner_time tests/gateway/test_mirror.py::TestAppendToSqlite::test_connection_closed_even_on_error tests/gateway/test_mirror.py::TestAppendToSqlite::test_connection_is_closed_after_use tests/gateway/test_mirror.py::TestFindSessionId::test_ambiguous_same_group_chat_without_user_id_returns_none tests/gateway/test_mirror.py::TestFindSessionId::test_finds_matching_session tests/gateway/test_mirror.py::TestFindSessionId::test_missing_sessions_file tests/gateway/test_mirror.py::TestFindSessionId::test_no_match_returns_none tests/gateway/test_mirror.py::TestFindSessionId::test_platform_case_insensitive tests/gateway/test_mirror.py::TestFindSessionId::test_returns_most_recent tests/gateway/test_mirror.py::TestFindSessionId::test_thread_id_disambiguates_same_chat tests/gateway/test_mirror.py::TestFindSessionId::test_user_id_disambiguates_same_group_chat tests/gateway/test_mirror.py::TestMirrorToSession::test_error_returns_false tests/gateway/test_mirror.py::TestMirrorToSession::test_no_matching_session tests/gateway/test_mirror.py::TestMirrorToSession::test_successful_mirror tests/gateway/test_mirror.py::TestMirrorToSession::test_successful_mirror_uses_thread_id tests/gateway/test_mirror.py::TestMirrorToSession::test_successful_mirror_uses_user_id_for_group_session tests/gateway/test_model_command_custom_providers.py::test_handle_model_command_lists_saved_custom_provider tests/gateway/test_model_command_expensive_confirm.py::test_typed_model_cheap_switches_without_prompt tests/gateway/test_model_command_expensive_confirm.py::test_typed_model_expensive_cancel_keeps_current_model tests/gateway/test_model_command_expensive_confirm.py::test_typed_model_expensive_confirm_once_applies_switch tests/gateway/test_model_command_expensive_confirm.py::test_typed_model_expensive_prompts_instead_of_switching tests/gateway/test_model_command_flat_string_config.py::test_model_global_persists_when_config_has_flat_string_model tests/gateway/test_model_command_flat_string_config.py::test_model_global_persists_when_config_has_missing_model tests/gateway/test_model_command_flat_string_config.py::test_model_global_persists_when_config_has_proper_dict_model tests/gateway/test_model_command_flat_string_config.py::test_model_no_flag_persists_by_default tests/gateway/test_model_command_flat_string_config.py::test_model_session_flag_does_not_persist tests/gateway/test_model_picker_persist.py::test_picker_tap_persists_by_default[flat-string] tests/gateway/test_model_picker_persist.py::test_picker_tap_persists_by_default[nested-dict] tests/gateway/test_model_picker_persist.py::test_picker_tap_session_flag_does_not_persist tests/gateway/test_model_switch_persistence.py::TestApplySessionModelOverride::test_different_session_key_not_affected tests/gateway/test_model_switch_persistence.py::TestApplySessionModelOverride::test_empty_string_overwrites tests/gateway/test_model_switch_persistence.py::TestApplySessionModelOverride::test_no_override_returns_originals tests/gateway/test_model_switch_persistence.py::TestApplySessionModelOverride::test_none_values_do_not_overwrite tests/gateway/test_model_switch_persistence.py::TestApplySessionModelOverride::test_override_replaces_all_fields tests/gateway/test_model_switch_persistence.py::TestIsIntentionalModelSwitch::test_different_model_returns_false tests/gateway/test_model_switch_persistence.py::TestIsIntentionalModelSwitch::test_matches_override tests/gateway/test_model_switch_persistence.py::TestIsIntentionalModelSwitch::test_no_override_returns_false tests/gateway/test_model_switch_persistence.py::TestIsIntentionalModelSwitch::test_wrong_session_key tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_bad_client_state_rejected_as_auth_failure[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_client_state_compare_is_timing_safe[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_duplicate_notification_deduped[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_malformed_body_returns_400[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_missing_client_state_is_auth_rejected[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_missing_value_array_returns_400[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_notifications_without_id_are_not_deduped[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_resource_not_in_allowlist_returns_400[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_resource_patterns_accept_leading_slash[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_seen_receipts_are_bounded[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphNotifications::test_valid_notification_accepted_and_scheduled[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_cidr_list_accepts_comma_string[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_health_endpoint_also_respects_allowlist[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_invalid_cidr_entries_are_ignored_at_init[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_loopback_bind_without_allowlist_still_accepts_local_requests[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_post_from_allowed_ip_accepted[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_post_from_disallowed_ip_rejected[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_public_bind_without_allowlist_fails_closed[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphSourceIPAllowlist::test_validation_handshake_also_respects_allowlist[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphValidationHandshake::test_bare_get_without_validation_token_rejected[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphValidationHandshake::test_connect_allows_loopback_without_source_allowlist[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphValidationHandshake::test_connect_requires_client_state[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphValidationHandshake::test_connect_requires_source_allowlist_on_public_bind[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphValidationHandshake::test_post_with_validation_token_still_echoes[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphValidationHandshake::test_validation_token_echo_on_get[asyncio] tests/gateway/test_msgraph_webhook.py::TestMSGraphWebhookConfig::test_env_overrides_apply_to_existing_msgraph_webhook_platform tests/gateway/test_msgraph_webhook.py::TestMSGraphWebhookConfig::test_gateway_config_accepts_msgraph_webhook_platform tests/gateway/test_multiplex_adapter_registry.py::TestCredentialFingerprint::test_distinct_tokens_distinct_fp tests/gateway/test_multiplex_adapter_registry.py::TestCredentialFingerprint::test_none_without_token tests/gateway/test_multiplex_adapter_registry.py::TestCredentialFingerprint::test_reads_alt_attrs tests/gateway/test_multiplex_adapter_registry.py::TestCredentialFingerprint::test_stable_and_log_safe tests/gateway/test_multiplex_adapter_registry.py::TestPortBindingHardError::test_port_binding_set_covers_known_listeners tests/gateway/test_multiplex_adapter_registry.py::TestPortBindingHardError::test_secondary_non_binding_platform_ok tests/gateway/test_multiplex_adapter_registry.py::TestPortBindingHardError::test_secondary_webhook_raises tests/gateway/test_multiplex_adapter_registry.py::TestProfileMessageHandler::test_does_not_override_existing_profile tests/gateway/test_multiplex_adapter_registry.py::TestProfileMessageHandler::test_stamps_profile_on_unstamped_source tests/gateway/test_multiplex_credential_isolation.py::TestMcpInterpolationUsesScope::test_interpolation_off_reads_environ tests/gateway/test_multiplex_credential_isolation.py::TestMcpInterpolationUsesScope::test_interpolation_reads_scope tests/gateway/test_multiplex_credential_isolation.py::TestMcpInterpolationUsesScope::test_interpolation_unset_keeps_placeholder tests/gateway/test_multiplex_credential_isolation.py::TestRuntimeProviderUsesScope::test_getenv_fails_closed_unscoped tests/gateway/test_multiplex_credential_isolation.py::TestRuntimeProviderUsesScope::test_getenv_global_var_still_reads_environ tests/gateway/test_multiplex_credential_isolation.py::TestRuntimeProviderUsesScope::test_getenv_reads_scope_under_multiplex tests/gateway/test_multiplex_credential_isolation.py::TestRuntimeProviderUsesScope::test_getenv_two_profiles_isolated tests/gateway/test_multiplex_http_routing.py::TestSessionSourceProfileField::test_profile_absent_not_serialized tests/gateway/test_multiplex_http_routing.py::TestSessionSourceProfileField::test_profile_roundtrips tests/gateway/test_multiplex_http_routing.py::TestSessionSourceProfileField::test_source_profile_drives_session_key_namespace tests/gateway/test_multiplex_http_routing.py::TestWebhookProfileResolution::test_known_profile_accepted tests/gateway/test_multiplex_http_routing.py::TestWebhookProfileResolution::test_no_prefix_returns_none tests/gateway/test_multiplex_http_routing.py::TestWebhookProfileResolution::test_prefix_ignored_when_multiplex_off tests/gateway/test_multiplex_http_routing.py::TestWebhookProfileResolution::test_unknown_profile_rejected tests/gateway/test_multiplex_lifecycle.py::TestNamedProfileMultiplexerGuard::test_force_bypasses tests/gateway/test_multiplex_lifecycle.py::TestNamedProfileMultiplexerGuard::test_inert_for_default_profile tests/gateway/test_multiplex_lifecycle.py::TestNamedProfileMultiplexerGuard::test_inert_when_no_default_gateway_running tests/gateway/test_multiplex_lifecycle.py::TestServedProfilesStatus::test_served_profiles_absent_by_default tests/gateway/test_multiplex_lifecycle.py::TestServedProfilesStatus::test_write_and_read_served_profiles tests/gateway/test_multiplex_phase0.py::TestMultiplexConfigFlag::test_default_is_false tests/gateway/test_multiplex_phase0.py::TestMultiplexConfigFlag::test_from_dict_coerces_truthy_string tests/gateway/test_multiplex_phase0.py::TestMultiplexConfigFlag::test_from_dict_nested_gateway tests/gateway/test_multiplex_phase0.py::TestMultiplexConfigFlag::test_from_dict_top_level tests/gateway/test_multiplex_phase0.py::TestMultiplexConfigFlag::test_roundtrip tests/gateway/test_multiplex_phase0.py::TestMultiplexConfigFlag::test_to_dict_includes_flag tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_dm_with_chat_id[None] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_dm_with_chat_id[default] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_dm_with_thread[None] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_dm_with_thread[default] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_dm_without_chat_id_falls_back_to_user[None] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_dm_without_chat_id_falls_back_to_user[default] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_group_per_user[None] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_group_per_user[default] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_group_shared_when_disabled[None] tests/gateway/test_multiplex_phase0.py::TestSessionKeyByteIdenticalWhenOff::test_group_shared_when_disabled[default] tests/gateway/test_multiplex_phase0.py::TestSessionKeyNamespacedWhenOn::test_default_namespace_layout_matches_named tests/gateway/test_multiplex_phase0.py::TestSessionKeyNamespacedWhenOn::test_named_profile_dm tests/gateway/test_multiplex_phase0.py::TestSessionKeyNamespacedWhenOn::test_named_profile_group_per_user tests/gateway/test_multiplex_phase0.py::TestSessionKeyNamespacedWhenOn::test_positional_layout_preserved_for_parsers tests/gateway/test_multiplex_phase0.py::TestSessionKeyNamespacedWhenOn::test_two_profiles_same_chat_do_not_collide tests/gateway/test_multiplex_phase0.py::TestSessionStoreProfileResolution::test_flag_off_resolve_profile_is_none tests/gateway/test_multiplex_phase0.py::TestSessionStoreProfileResolution::test_flag_off_uses_legacy_namespace tests/gateway/test_multiplex_phase0.py::TestSessionStoreProfileResolution::test_flag_on_default_profile_stays_legacy tests/gateway/test_multiplex_phase0.py::TestSessionStoreProfileResolution::test_flag_on_uses_active_profile_namespace tests/gateway/test_native_image_buffer_isolation.py::test_native_image_buffer_isolated_per_session tests/gateway/test_native_image_buffer_isolation.py::test_native_image_buffer_not_cleared_by_other_sessions_without_images tests/gateway/test_notice_delivery.py::test_deliver_platform_notice_falls_back_to_public_when_private_fails tests/gateway/test_notice_delivery.py::test_deliver_platform_notice_uses_private_delivery_when_configured tests/gateway/test_notice_delivery.py::test_deliver_platform_notice_uses_public_delivery_by_default tests/gateway/test_notice_rendering.py::TestDeliverNoticeLine::test_no_adapter_is_a_noop tests/gateway/test_notice_rendering.py::TestDeliverNoticeLine::test_private_delivery_prefers_private_notice tests/gateway/test_notice_rendering.py::TestDeliverNoticeLine::test_public_delivery_sends_rendered_line tests/gateway/test_notice_rendering.py::TestRenderNoticeLine::test_does_not_prepend_a_second_glyph tests/gateway/test_notice_rendering.py::TestRenderNoticeLine::test_empty_text_returns_empty_string tests/gateway/test_notice_rendering.py::TestRenderNoticeLine::test_malformed_notice_does_not_raise tests/gateway/test_notice_rendering.py::TestRenderNoticeLine::test_returns_text_verbatim_with_its_baked_glyph tests/gateway/test_notice_rendering.py::TestRenderNoticeLine::test_text_is_stripped tests/gateway/test_notice_rendering.py::test_real_policy_notices_render_without_doubling tests/gateway/test_ntfy_plugin.py::TestAuthHeaders::test_auth_header_key_is_authorization tests/gateway/test_ntfy_plugin.py::TestAuthHeaders::test_basic_auth_for_user_colon_password tests/gateway/test_ntfy_plugin.py::TestAuthHeaders::test_bearer_token_for_plain_token tests/gateway/test_ntfy_plugin.py::TestAuthHeaders::test_bearer_token_used_when_no_colon tests/gateway/test_ntfy_plugin.py::TestAuthHeaders::test_no_token_returns_empty_dict tests/gateway/test_ntfy_plugin.py::TestConnect::test_connect_fails_when_httpx_unavailable tests/gateway/test_ntfy_plugin.py::TestConnect::test_connect_fails_when_no_topic tests/gateway/test_ntfy_plugin.py::TestConnect::test_connect_starts_stream_task tests/gateway/test_ntfy_plugin.py::TestConnect::test_disconnect_cancels_stream_task tests/gateway/test_ntfy_plugin.py::TestConnect::test_disconnect_clears_state tests/gateway/test_ntfy_plugin.py::TestDeduplication::test_cache_pruned_on_overflow tests/gateway/test_ntfy_plugin.py::TestDeduplication::test_different_ids_not_duplicate tests/gateway/test_ntfy_plugin.py::TestDeduplication::test_expired_id_can_be_seen_again tests/gateway/test_ntfy_plugin.py::TestDeduplication::test_first_message_not_duplicate tests/gateway/test_ntfy_plugin.py::TestDeduplication::test_many_messages_recorded tests/gateway/test_ntfy_plugin.py::TestDeduplication::test_second_occurrence_is_duplicate tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_custom_server_url tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_home_channel_defaults_to_topic tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_home_channel_override tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_markdown_falsy_values tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_markdown_truthy_values tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_publish_topic_seeded tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_returns_none_without_topic tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_seeds_topic_and_server tests/gateway/test_ntfy_plugin.py::TestEnvEnablement::test_token_seeded tests/gateway/test_ntfy_plugin.py::TestFatalErrorPropagation::test_401_sets_fatal_unauthorized tests/gateway/test_ntfy_plugin.py::TestFatalErrorPropagation::test_404_sets_fatal_topic_not_found tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_default_server_url tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_initial_state tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_publish_topic_falls_back_to_topic tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_publish_topic_uses_extra_value tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_server_trailing_slash_stripped tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_token_read_from_env tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_token_read_from_extra tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_topic_read_from_env tests/gateway/test_ntfy_plugin.py::TestNtfyAdapterInit::test_topic_read_from_extra tests/gateway/test_ntfy_plugin.py::TestNtfyRequirements::test_is_connected_from_env tests/gateway/test_ntfy_plugin.py::TestNtfyRequirements::test_is_connected_from_extra tests/gateway/test_ntfy_plugin.py::TestNtfyRequirements::test_returns_false_when_httpx_unavailable tests/gateway/test_ntfy_plugin.py::TestNtfyRequirements::test_returns_false_when_topic_not_set tests/gateway/test_ntfy_plugin.py::TestNtfyRequirements::test_returns_true_when_topic_set_via_env tests/gateway/test_ntfy_plugin.py::TestNtfyRequirements::test_validate_config_requires_topic tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_duplicate_message_skipped tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_empty_message_skipped tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_message_dispatched_to_handler tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_message_id_set_from_event tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_message_with_other_tags_still_dispatched tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_own_tagged_message_skipped tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_source_chat_id_is_topic tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_timestamp_parsed_from_event tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_title_not_used_as_user_id tests/gateway/test_ntfy_plugin.py::TestOnMessage::test_unknown_publisher_cannot_impersonate_allowed_user tests/gateway/test_ntfy_plugin.py::TestSend::test_get_chat_info_returns_dict tests/gateway/test_ntfy_plugin.py::TestSend::test_send_emits_echo_tag_header tests/gateway/test_ntfy_plugin.py::TestSend::test_send_emits_markdown_header_when_enabled tests/gateway/test_ntfy_plugin.py::TestSend::test_send_fails_without_http_client tests/gateway/test_ntfy_plugin.py::TestSend::test_send_falls_back_to_subscribe_topic tests/gateway/test_ntfy_plugin.py::TestSend::test_send_handles_http_error_status tests/gateway/test_ntfy_plugin.py::TestSend::test_send_handles_timeout tests/gateway/test_ntfy_plugin.py::TestSend::test_send_includes_bearer_auth_header tests/gateway/test_ntfy_plugin.py::TestSend::test_send_omits_markdown_header_when_disabled tests/gateway/test_ntfy_plugin.py::TestSend::test_send_posts_to_publish_topic tests/gateway/test_ntfy_plugin.py::TestSend::test_send_truncates_to_max_length tests/gateway/test_ntfy_plugin.py::TestSend::test_send_typing_is_noop tests/gateway/test_ntfy_plugin.py::TestSend::test_send_uses_metadata_publish_topic tests/gateway/test_ntfy_plugin.py::TestStandaloneSend::test_basic_auth_when_token_has_colon tests/gateway/test_ntfy_plugin.py::TestStandaloneSend::test_emits_bearer_token_when_configured tests/gateway/test_ntfy_plugin.py::TestStandaloneSend::test_emits_echo_tag_header tests/gateway/test_ntfy_plugin.py::TestStandaloneSend::test_errors_without_topic tests/gateway/test_ntfy_plugin.py::TestStandaloneSend::test_posts_to_server tests/gateway/test_ntfy_plugin.py::TestStandaloneSend::test_returns_error_on_http_failure tests/gateway/test_ntfy_plugin.py::TestTokenHygiene::test_adapter_strips_token_via_helper tests/gateway/test_ntfy_plugin.py::TestTokenHygiene::test_basic_auth_token_also_stripped tests/gateway/test_ntfy_plugin.py::TestTokenHygiene::test_trailing_newline_stripped tests/gateway/test_ntfy_plugin.py::TestTokenHygiene::test_trailing_whitespace_stripped tests/gateway/test_ntfy_plugin.py::TestTokenHygiene::test_whitespace_only_returns_empty tests/gateway/test_ntfy_plugin.py::TestTruncateHelper::test_long_message_truncated tests/gateway/test_ntfy_plugin.py::TestTruncateHelper::test_short_message_passes_through tests/gateway/test_ntfy_plugin.py::TestTruncateHelper::test_unicode_message_encoded tests/gateway/test_ntfy_plugin.py::test_adapter_factory_returns_ntfy_adapter tests/gateway/test_ntfy_plugin.py::test_platform_enum_resolves_via_plugin_scan tests/gateway/test_ntfy_plugin.py::test_register_calls_register_platform tests/gateway/test_nutricoach_v140_disposable_e2e.py::test_weekly_operations_disposable_cli_drives_real_telegram_surface tests/gateway/test_nutricoach_v140_golden_path.py::test_seven_day_driver_emits_exact_receipt_when_network_is_disabled tests/gateway/test_nutricoach_v140_golden_path.py::test_seven_day_driver_rejects_network_enabled_surface tests/gateway/test_nutricoach_v140_golden_path.py::test_seven_day_receipt_is_byte_identical_across_clean_roots tests/gateway/test_nutricoach_v140_golden_path_r2.py::test_completed_artifact_verifier_rejects_each_tamper_class tests/gateway/test_nutricoach_v140_golden_path_r2.py::test_driver_has_no_test_imports_when_production_path_is_required tests/gateway/test_nutricoach_v140_golden_path_r2.py::test_driver_uses_production_tick_without_constructing_schedule_tasks tests/gateway/test_nutricoach_v140_golden_path_r2.py::test_fault_matrix_executes_every_observed_weekly_boundary tests/gateway/test_nutricoach_v140_golden_path_r2.py::test_receipt_records_observed_fresh_child_restarts tests/gateway/test_nutricoach_v140_golden_path_r3.py::test_fault_results_are_exhaustive_and_bind_authoritative_rows tests/gateway/test_nutricoach_v140_golden_path_r3.py::test_sentinel_render_produces_positive_scan_and_fails_artifact_verification tests/gateway/test_nutrition_coaching.py::test_adaptive_config_requires_explicit_schedule_confirmation_enablement tests/gateway/test_nutrition_coaching.py::test_approval_continuity_uses_authoritative_customer_body tests/gateway/test_nutrition_coaching.py::test_approve_and_send_uses_fresh_action_capabilities_and_stops_on_failure tests/gateway/test_nutrition_coaching.py::test_approved_edit_creates_child_revision_and_requires_reapproval tests/gateway/test_nutrition_coaching.py::test_approved_revision_and_canonical_evidence_are_required tests/gateway/test_nutrition_coaching.py::test_coaching_id_command_reports_only_the_callers_current_address tests/gateway/test_nutrition_coaching.py::test_completed_customer_day_is_terminal_without_new_session_or_event tests/gateway/test_nutrition_coaching.py::test_concurrent_delivery_reservation_allows_only_one_transport tests/gateway/test_nutrition_coaching.py::test_consent_revocation_is_rechecked_at_draft_lifecycle_boundaries tests/gateway/test_nutrition_coaching.py::test_console_transport_revalidates_after_reservation[consent-revoked] tests/gateway/test_nutrition_coaching.py::test_console_transport_revalidates_after_reservation[safety-held] tests/gateway/test_nutrition_coaching.py::test_corrupt_delivery_ledger_fails_closed_without_transport tests/gateway/test_nutrition_coaching.py::test_corrupt_draft_ledger_blocks_create_without_overwriting_the_file tests/gateway/test_nutrition_coaching.py::test_corrupt_request_ledger_blocks_delivery_preparation tests/gateway/test_nutrition_coaching.py::test_customer_route_requires_exact_submitter_chat_and_topic tests/gateway/test_nutrition_coaching.py::test_customer_space_is_reserved_even_for_an_unregistered_sender tests/gateway/test_nutrition_coaching.py::test_customer_start_callback_click_binds_clicked_card_and_resumes_open_draft tests/gateway/test_nutrition_coaching.py::test_customer_start_callback_is_stable_opaque_and_telegram_sized tests/gateway/test_nutrition_coaching.py::test_customer_start_callback_resolves_only_exact_live_customer_route tests/gateway/test_nutrition_coaching.py::test_daily_bodyweight_advances_when_onboarding_authority_is_stale tests/gateway/test_nutrition_coaching.py::test_delivered_receipt_retries_audit_without_duplicate_transport tests/gateway/test_nutrition_coaching.py::test_delivery_claim_defaults_to_injected_generation_clock tests/gateway/test_nutrition_coaching.py::test_delivery_intent_is_pending_before_transport_and_retry_never_resends tests/gateway/test_nutrition_coaching.py::test_disabled_customer_is_not_routable tests/gateway/test_nutrition_coaching.py::test_disposable_controller_issuance_enables_approved_transport tests/gateway/test_nutrition_coaching.py::test_dual_coach_review_cards_are_customer_local_and_deterministic tests/gateway/test_nutrition_coaching.py::test_dual_coach_review_journal_failure_returns_bounded_operator_diagnostic tests/gateway/test_nutrition_coaching.py::test_dual_coach_review_publication_claim_is_append_only_across_restart tests/gateway/test_nutrition_coaching.py::test_due_tick_sends_one_customer_launcher_and_claims_the_day tests/gateway/test_nutrition_coaching.py::test_due_tick_sends_weekly_summary_only_to_owner_during_pilot tests/gateway/test_nutrition_coaching.py::test_gateway_ac21_safety_matrix[SF-S1-C] tests/gateway/test_nutrition_coaching.py::test_gateway_ac21_safety_matrix[SF-S2-C] tests/gateway/test_nutrition_coaching.py::test_gateway_ac21_safety_matrix[SF-S3-C] tests/gateway/test_nutrition_coaching.py::test_gateway_ac21_safety_matrix[SF-S4-C] tests/gateway/test_nutrition_coaching.py::test_gateway_ac21_safety_matrix[SF-S5-C] tests/gateway/test_nutrition_coaching.py::test_gateway_ac21_safety_matrix[SF-S6-C] tests/gateway/test_nutrition_coaching.py::test_manual_customer_aliases_render_one_reusable_card_with_stable_callback tests/gateway/test_nutrition_coaching.py::test_nutrition_live_reload_keeps_disable_and_revoke_live tests/gateway/test_nutrition_coaching.py::test_nutrition_live_reload_rejects_manual_enable_without_committed_receipt tests/gateway/test_nutrition_coaching.py::test_nutrition_startup_accepts_committed_receipt_and_canonical_path tests/gateway/test_nutrition_coaching.py::test_nutrition_startup_rejects_manual_enable_without_committed_receipt tests/gateway/test_nutrition_coaching.py::test_owner_draft_lifecycle_is_canonical_and_preapproval_send_is_rejected tests/gateway/test_nutrition_coaching.py::test_pending_delivery_requires_explicit_receipt_reconciliation tests/gateway/test_nutrition_coaching.py::test_private_trainer_menu_uses_live_assignment_and_opaque_customer_callback tests/gateway/test_nutrition_coaching.py::test_private_trainer_selection_rejects_group_and_wrong_trainer tests/gateway/test_nutrition_coaching.py::test_production_console_factory_rejects_unpinned_approval_and_transport tests/gateway/test_nutrition_coaching.py::test_registry_trainer_bridge_opens_scoped_trainer_session tests/gateway/test_nutrition_coaching.py::test_safety_completion_is_sent_to_owner_without_draft_button tests/gateway/test_nutrition_coaching.py::test_safety_hold_on_existing_draft_blocks_delivery_reservation tests/gateway/test_nutrition_coaching.py::test_saved_customer_checkin_creates_owner_only_draft_request tests/gateway/test_nutrition_coaching.py::test_schedule_confirm_callback_claims_once_and_rejects_invalid_authority tests/gateway/test_nutrition_coaching.py::test_schedule_confirm_integration_gateway_request_replays_one_canonical_and_projection tests/gateway/test_nutrition_coaching.py::test_schedule_confirm_integration_rejects_stale_reference_and_wrong_review_authority tests/gateway/test_nutrition_coaching.py::test_schedule_confirm_replay_recovers_after_consume_before_confirm_crash tests/gateway/test_nutrition_coaching.py::test_scheduled_customer_card_reuses_stable_callback_without_opening_session tests/gateway/test_nutrition_coaching.py::test_sent_audit_write_failure_leaves_receipt_for_retry_without_resend tests/gateway/test_nutrition_coaching.py::test_telegram_utf16_limit_is_checked_before_coach_review[\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600-True] tests/gateway/test_nutrition_coaching.py::test_telegram_utf16_limit_is_checked_before_coach_review[\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600\U0001f600a-False] tests/gateway/test_nutrition_coaching.py::test_telegram_utf16_limit_is_checked_before_coach_review[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-True] tests/gateway/test_nutrition_coaching.py::test_telegram_utf16_limit_is_checked_before_coach_review[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-False] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[PT \uae30\ub85d \uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[\uace0\uac1d 001 \uae30\ub85d \uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[\uae30\ub85d \uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[\uc624\ub298 PT \uae30\ub85d] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[\uc6b4\ub3d9 \uae30\ub85d \uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[\ud2b8\ub808\uc774\ub108 \uae30\ub85d \uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[\ud2b8\ub808\uc774\ub108 \uc138\uc158 \uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[\ud2b8\ub808\uc774\ub108\uae30\ub85d\uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_launcher_accepts_human_friendly_commands_and_shows_customer_date[client_001 \uae30\ub85d \uc2dc\uc791] tests/gateway/test_nutrition_coaching.py::test_trainer_route_is_exactly_isolated_from_customer_and_reserved_spaces tests/gateway/test_nutrition_coaching.py::test_typed_weekly_source_reuses_owner_draft_lifecycle tests/gateway/test_nutrition_coaching.py::test_urgent_customer_note_notifies_owner_without_draft_token tests/gateway/test_nutrition_coaching.py::test_weekday_due_tick_sends_customer_launcher tests/gateway/test_nutrition_coaching.py::test_weekly_destination_pin_precedes_revision_authority_gate tests/gateway/test_nutrition_weekly_dispatcher.py::test_authorized_tick_dispatches_enabled_weekly_operations_before_generic_work tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_absent_schedule_policy_imports_zero_weekly_modules tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_absent_sunday_daily_task_retains_legacy_weekday_guard tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_feature_absent_authorized_host_is_inert tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_config_off_after_snapshot_blocks_provider tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_mutable_authority_drift_blocks_provider[authority_owner] tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_mutable_authority_drift_blocks_provider[candidate] tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_mutable_authority_drift_blocks_provider[config] tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_mutable_authority_drift_blocks_provider[consent] tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_mutable_authority_drift_blocks_provider[route] tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_provider_outcome_is_terminal_on_real_host_replay[ProviderMode.KNOWN] tests/gateway/test_nutrition_weekly_dispatcher_epoch2.py::test_reminder_provider_outcome_is_terminal_on_real_host_replay[ProviderMode.UNKNOWN] tests/gateway/test_nutrition_weekly_dispatcher_host_matrix.py::test_canonical_sidecar_disagreement_fails_with_exact_zero_new_counts tests/gateway/test_nutrition_weekly_dispatcher_host_matrix.py::test_corrupt_reminder_ledger_fails_before_every_provider_and_projection tests/gateway/test_nutrition_weekly_dispatcher_host_matrix.py::test_corrupt_topic59_ledger_retains_cutoff_but_blocks_card_provider tests/gateway/test_nutrition_weekly_dispatcher_host_matrix.py::test_monday_draft_is_owner_dm_only_and_topic59_has_no_approval_controls tests/gateway/test_nutrition_weekly_dispatcher_host_matrix.py::test_response_race_at_pre_io_rebind_makes_valid_status_win tests/gateway/test_nutrition_weekly_dispatcher_lifecycle.py::test_concurrent_ticks_share_one_topic59_provider_authority[asyncio] tests/gateway/test_nutrition_weekly_dispatcher_lifecycle.py::test_real_authorized_tick_projects_cutoff_once_across_restart tests/gateway/test_nutrition_weekly_dispatcher_lifecycle.py::test_toggle_off_after_snapshot_blocks_topic59_provider tests/gateway/test_nutrition_weekly_dispatcher_lifecycle.py::test_wrong_topic_fails_planning_without_sidecar_or_provider tests/gateway/test_nutrition_weekly_host_refactor.py::test_weekly_owner_host_module_owns_weekly_lifecycle tests/gateway/test_nutrition_weekly_operations.py::test_authority_integrity_digest_binds_registry_identity_stably tests/gateway/test_nutrition_weekly_operations.py::test_baseline_schedule_is_unchanged_when_weekly_operations_is_absent tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_fails_closed_for_every_binding[candidate_digest-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_fails_closed_for_every_binding[config_digest-dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_fails_closed_for_every_binding[consent_digest-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_fails_closed_for_every_binding[enabled_customer_keys-value2] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_fails_closed_for_every_binding[feature_epoch-weekly-operations-v2] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_fails_closed_for_every_binding[owner-value3] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_fails_closed_for_every_binding[owner-value4] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_rejects_missing_or_naive_issue_expiry tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_rejects_stale_and_expired_receipts[2026-08-23T23:00:00+09:00-2026-08-24T00:00:00+09:00] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_rejects_stale_and_expired_receipts[2026-08-24T00:45:00+09:00-2026-08-24T01:45:00+09:00] tests/gateway/test_nutrition_weekly_operations.py::test_config_authority_requires_compiled_configured_authorized_and_consented tests/gateway/test_nutrition_weekly_operations.py::test_config_binds_only_the_existing_topic_59_review_route tests/gateway/test_nutrition_weekly_operations.py::test_config_defaults_off_with_stable_kst_schedule_when_absent tests/gateway/test_nutrition_weekly_operations.py::test_config_rejects_missing_naive_and_absolute_recurring_times[missed_cutoff_time-2026-08-24T23:00:00+09:00] tests/gateway/test_nutrition_weekly_operations.py::test_config_rejects_missing_naive_and_absolute_recurring_times[reminder_time-20:00+00:00] tests/gateway/test_nutrition_weekly_operations.py::test_config_rejects_missing_naive_and_absolute_recurring_times[reminder_time-20:00] tests/gateway/test_nutrition_weekly_operations.py::test_config_rejects_missing_naive_and_absolute_recurring_times[reminder_time-None] tests/gateway/test_nutrition_weekly_operations.py::test_config_rejects_reminder_at_or_after_cutoff_and_wrong_route tests/gateway/test_nutrition_weekly_operations.py::test_enabled_authority_requires_sealed_registry_identity tests/gateway/test_nutrition_weekly_operations.py::test_enabled_config_requires_registry_identity_binding_digest tests/gateway/test_nutrition_weekly_operations_registry_identity_r7.py::test_gateway_registry_boundary_exposes_no_runtime_issuer tests/gateway/test_nutrition_weekly_operations_registry_identity_r7.py::test_identity_is_issued_from_exact_private_no_follow_inode tests/gateway/test_nutrition_weekly_operations_registry_identity_r7.py::test_identity_issuance_rejects_unsafe_registry_name[fifo] tests/gateway/test_nutrition_weekly_operations_registry_identity_r7.py::test_identity_issuance_rejects_unsafe_registry_name[hardlink] tests/gateway/test_nutrition_weekly_operations_registry_identity_r7.py::test_identity_issuance_rejects_unsafe_registry_name[mode] tests/gateway/test_nutrition_weekly_operations_registry_identity_r7.py::test_identity_issuance_rejects_unsafe_registry_name[symlink] tests/gateway/test_nutrition_weekly_operations_topic59.py::test_missed_to_late_submitted_edits_the_persisted_message tests/gateway/test_nutrition_weekly_operations_topic59.py::test_rendered_and_durable_payloads_match_the_machine_whitelist tests/gateway/test_nutrition_weekly_operations_topic59.py::test_restart_and_duplicate_tick_do_not_repeat_a_send tests/gateway/test_nutrition_weekly_operations_topic59.py::test_seven_kst_days_create_seven_logical_cards tests/gateway/test_nutrition_weekly_operations_topic59.py::test_sidecar_extra_health_fields_cannot_cross_the_topic59_whitelist tests/gateway/test_nutrition_weekly_operations_topic59.py::test_topic59_projector_exposes_one_customer_day_publication_binding tests/gateway/test_nutrition_weekly_operations_topic59_failures.py::test_corrupt_ledger_becomes_an_incident_without_a_provider_call tests/gateway/test_nutrition_weekly_operations_topic59_failures.py::test_malformed_sidecar_is_rejected_before_a_provider_call tests/gateway/test_nutrition_weekly_operations_topic59_failures.py::test_unknown_and_known_edit_outcomes_are_terminal_without_replacement tests/gateway/test_nutrition_weekly_operations_topic59_failures.py::test_unknown_and_known_send_outcomes_are_terminal_without_replacement tests/gateway/test_nutrition_weekly_operations_topic59_failures.py::test_unresolved_reservation_is_an_incident_not_a_blind_new_send tests/gateway/test_nutrition_weekly_operations_topic59_failures.py::test_wrong_topic_is_rejected_before_the_projector_can_call_a_provider tests/gateway/test_nutrition_weekly_operations_topic59_failures.py::test_wrong_user_chat_config_or_authority_make_zero_provider_calls tests/gateway/test_nutrition_weekly_operations_topic59_r2.py::test_all_raw_sidecar_sentinels_are_absent_from_every_topic59_surface tests/gateway/test_nutrition_weekly_operations_topic59_r2.py::test_opaque_ids_are_deterministic_nonreversible_and_value_validation_is_exhaustive tests/gateway/test_nutrition_weekly_operations_topic59_r2_slots.py::test_candidate_config_and_route_drift_are_terminal_slot_incidents tests/gateway/test_nutrition_weekly_operations_topic59_r2_slots.py::test_concurrent_differing_pins_preserve_one_slot_and_one_initial_send tests/gateway/test_nutrition_weekly_operations_topic59_r2_slots.py::test_malformed_stored_slot_is_an_incident_without_provider_replacement tests/gateway/test_nutrition_weekly_operations_topic59_telegram.py::test_real_adapter_uses_strict_topic59_send_then_edits_the_persisted_message tests/gateway/test_nutrition_weekly_owner_draft.py::test_concurrent_restart_owner_edit_and_approval_use_one_generation tests/gateway/test_nutrition_weekly_owner_draft.py::test_direct_tampered_source_fails_before_draft_mutation tests/gateway/test_nutrition_weekly_owner_draft_authority.py::test_wrong_authority_and_stale_grounding_fail_before_provider[candidate] tests/gateway/test_nutrition_weekly_owner_draft_authority.py::test_wrong_authority_and_stale_grounding_fail_before_provider[consent] tests/gateway/test_nutrition_weekly_owner_draft_authority.py::test_wrong_authority_and_stale_grounding_fail_before_provider[customer] tests/gateway/test_nutrition_weekly_owner_draft_authority.py::test_wrong_authority_and_stale_grounding_fail_before_provider[day] tests/gateway/test_nutrition_weekly_owner_draft_authority.py::test_wrong_authority_and_stale_grounding_fail_before_provider[owner] tests/gateway/test_nutrition_weekly_owner_draft_authority.py::test_wrong_authority_and_stale_grounding_fail_before_provider[stale] tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_interrupted_sending_is_terminal_fallback_without_provider_retry tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_invalid_first_uses_one_correction_and_never_a_third_call tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_outage_and_two_invalid_results_use_deterministic_fallback[outcome0] tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_outage_and_two_invalid_results_use_deterministic_fallback[outcome1] tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_outage_and_two_invalid_results_use_deterministic_fallback[outcome2] tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_outage_and_two_invalid_results_use_deterministic_fallback[outcome3] tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_outage_and_two_invalid_results_use_deterministic_fallback[outcome4] tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_provider_request_ledger_source_and_draft_exclude_all_sentinels tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_tampered_source_and_ledger_corruption_fail_closed tests/gateway/test_nutrition_weekly_owner_draft_model.py::test_valid_replay_has_one_total_provider_call_and_private_ledger tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_cross_root_request_and_inode_swap_fail_before_provider tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_current_todo7_authority_is_final_fenced_before_draft_persistence tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[CALORIE-RAW] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[CUSTOMER-KEY] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[CUSTOMER-NAME] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[DIGESTION-RAW] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[RAW-FREE-TEXT] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[RAW-HEALTH] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[RAW-MEAL] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[RAW-SYMPTOM] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[TELEGRAM-CHAT] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[TELEGRAM-USER] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_fact_model_copy_rejects_arbitrary_finite_field_even_with_digest[WEIGHT-RAW] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_self_hashed_forged_bound_row_is_typed_request_conflict[_forge_aggregate] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_self_hashed_forged_bound_row_is_typed_request_conflict[_forge_customer] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_self_hashed_forged_bound_row_is_typed_request_conflict[_forge_request] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_self_hashed_forged_bound_row_is_typed_request_conflict[_forge_route] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_self_hashed_forged_bound_row_is_typed_request_conflict[_forge_source] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_self_hashed_forged_bound_row_is_typed_request_conflict[_forge_week] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unknown_correction_is_terminal_without_third_call tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unknown_initial_is_terminal_across_restart_and_concurrency tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[CALORIE-RAW] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[CUSTOMER-KEY] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[CUSTOMER-NAME] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[DIGESTION-RAW] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[RAW-FREE-TEXT] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[RAW-HEALTH] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[RAW-MEAL] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[RAW-SYMPTOM] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[TELEGRAM-CHAT] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[TELEGRAM-USER] tests/gateway/test_nutrition_weekly_owner_draft_r3.py::test_unverified_direct_knowledge_never_reaches_provider_request[WEIGHT-RAW] tests/gateway/test_nutrition_weekly_reminder_allocation_r10.py::test_bootstrap_allocating_factories_require_registrar_and_no_post_return_adopt tests/gateway/test_nutrition_weekly_reminder_allocation_r10.py::test_every_executed_allocation_factory_line_unwinds_exactly tests/gateway/test_nutrition_weekly_reminder_allocation_r10.py::test_success_allocation_deltas_and_idempotent_reverse_close tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[directory] tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[fifo] tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[hardlink_replacement] tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[inode_identical] tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[link_count] tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[mode] tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[route_replacement] tests/gateway/test_nutrition_weekly_reminder_bootstrap_boundary_r7.py::test_default_bootstrap_rejects_unsealed_registry_attachment[symlink_identical] tests/gateway/test_nutrition_weekly_reminder_bootstrap_r6.py::test_default_adapter_bootstrap_fails_typed_before_provider_call[missing] tests/gateway/test_nutrition_weekly_reminder_bootstrap_r6.py::test_default_adapter_bootstrap_fails_typed_before_provider_call[stale] tests/gateway/test_nutrition_weekly_reminder_bootstrap_r6.py::test_default_adapter_bootstrap_opens_existing_capabilities_and_sends_once tests/gateway/test_nutrition_weekly_reminder_bootstrap_r6.py::test_default_adapter_off_is_inert_without_profile_root tests/gateway/test_nutrition_weekly_reminder_bootstrap_race_r7.py::test_registry_swap_during_bootstrap_fails_after_retained_fd_recheck[1] tests/gateway/test_nutrition_weekly_reminder_bootstrap_race_r7.py::test_registry_swap_during_bootstrap_fails_after_retained_fd_recheck[2] tests/gateway/test_nutrition_weekly_reminder_boundaries.py::test_enabled_missing_external_schedule_policy_is_typed_incident tests/gateway/test_nutrition_weekly_reminder_boundaries.py::test_invalid_owner_protocol_is_typed_before_provider tests/gateway/test_nutrition_weekly_reminder_close_r11.py::test_concurrent_registrar_close_cannot_hit_reused_descriptor tests/gateway/test_nutrition_weekly_reminder_close_r11.py::test_every_owned_fd_close_line_and_opcode_boundary_is_safe tests/gateway/test_nutrition_weekly_reminder_close_r11.py::test_repeated_interruptions_preserve_the_first_pending_exception tests/gateway/test_nutrition_weekly_reminder_ownership_r8.py::test_interruption_after_customer_construction_unwinds_exact_fds[KeyboardInterrupt] tests/gateway/test_nutrition_weekly_reminder_ownership_r8.py::test_interruption_after_customer_construction_unwinds_exact_fds[SystemExit] tests/gateway/test_nutrition_weekly_reminder_ownership_r8.py::test_owner_construction_failure_closes_transferred_capabilities tests/gateway/test_nutrition_weekly_reminder_ownership_r8.py::test_second_customer_failure_closes_every_partial_capability[1] tests/gateway/test_nutrition_weekly_reminder_ownership_r8.py::test_second_customer_failure_closes_every_partial_capability[2] tests/gateway/test_nutrition_weekly_reminder_ownership_r8.py::test_successful_adapter_close_restores_exact_fd_baseline tests/gateway/test_nutrition_weekly_reminder_runtime.py::test_merged_coordinator_constructs_reminder_owner_beside_todo8 tests/gateway/test_nutrition_weekly_reminder_runtime.py::test_merged_coordinator_off_remains_typed_and_inert tests/gateway/test_nutrition_weekly_reminder_runtime.py::test_merged_coordinator_rejects_missing_or_stale_owner_zero_call[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] tests/gateway/test_nutrition_weekly_reminder_runtime.py::test_merged_coordinator_rejects_missing_or_stale_owner_zero_call[ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff] tests/gateway/test_nutrition_weekly_reminder_runtime.py::test_registered_owner_drives_reminder_and_cutoff tests/gateway/test_nutrition_weekly_reminder_runtime.py::test_registry_route_drift_twice_is_zero_call_one_incident tests/gateway/test_nutrition_weekly_reminder_threat_boundary_r8.py::test_enabled_bootstrap_requires_operator_authority_source_before_profile_open tests/gateway/test_nutrition_weekly_reminder_threat_boundary_r8.py::test_operator_input_is_captured_once_and_candidate_fields_are_exact tests/gateway/test_nutrition_weekly_reminder_threat_boundary_r8.py::test_operator_snapshot_drift_after_customer_construction_closes_all_fds[1] tests/gateway/test_nutrition_weekly_reminder_threat_boundary_r8.py::test_operator_snapshot_drift_after_customer_construction_closes_all_fds[2] tests/gateway/test_nutrition_weekly_reminder_threat_boundary_r8.py::test_runtime_exposes_no_registry_or_receipt_issuer tests/gateway/test_nutrition_weekly_reminder_threat_boundary_r8.py::test_simultaneous_trusted_source_rewrite_is_explicitly_out_of_scope tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.after_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.after_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.after_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.before_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.before_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.caller_received_before_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.last_child_entered_inner_stack] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.owned_container_after_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.owned_container_before_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-KeyboardInterrupt-nutricoach.weekly_reminder.owned_container_return_boundary] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.after_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.after_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.after_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.before_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.before_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.caller_received_before_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.last_child_entered_inner_stack] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.owned_container_after_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.owned_container_before_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[1-SystemExit-nutricoach.weekly_reminder.owned_container_return_boundary] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.after_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.after_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.after_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.before_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.before_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.caller_received_before_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.last_child_entered_inner_stack] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.owned_container_after_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.owned_container_before_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-KeyboardInterrupt-nutricoach.weekly_reminder.owned_container_return_boundary] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.after_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.after_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.after_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.before_adapter_attribute_assignment] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.before_outer_pop] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.caller_received_before_outer_enter] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.last_child_entered_inner_stack] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.owned_container_after_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.owned_container_before_construction] tests/gateway/test_nutrition_weekly_reminder_transfer_r9.py::test_every_transfer_seam_unwinds_without_one_fd_leak[2-SystemExit-nutricoach.weekly_reminder.owned_container_return_boundary] tests/gateway/test_pairing.py::TestApprovalFlow::test_approve_case_insensitive tests/gateway/test_pairing.py::TestApprovalFlow::test_approve_removes_from_pending tests/gateway/test_pairing.py::TestApprovalFlow::test_approve_strips_whitespace tests/gateway/test_pairing.py::TestApprovalFlow::test_approve_valid_code tests/gateway/test_pairing.py::TestApprovalFlow::test_approved_user_is_approved tests/gateway/test_pairing.py::TestApprovalFlow::test_invalid_code_returns_none tests/gateway/test_pairing.py::TestApprovalFlow::test_unapproved_user_not_approved tests/gateway/test_pairing.py::TestApprovalFlow::test_whatsapp_approved_user_survives_alias_flip tests/gateway/test_pairing.py::TestApprovalFlow::test_whatsapp_legacy_raw_jid_approval_survives_alias_flip tests/gateway/test_pairing.py::TestCodeExpiry::test_expired_code_cannot_be_approved tests/gateway/test_pairing.py::TestCodeExpiry::test_expired_codes_cleaned_up tests/gateway/test_pairing.py::TestCodeGeneration::test_code_format tests/gateway/test_pairing.py::TestCodeGeneration::test_code_uniqueness tests/gateway/test_pairing.py::TestCodeGeneration::test_stores_pending_entry tests/gateway/test_pairing.py::TestHashedStorage::test_different_salts_per_entry tests/gateway/test_pairing.py::TestHashedStorage::test_hash_code_static_method tests/gateway/test_pairing.py::TestHashedStorage::test_invalid_code_rejected tests/gateway/test_pairing.py::TestHashedStorage::test_pending_file_contains_hash_and_salt tests/gateway/test_pairing.py::TestHashedStorage::test_plaintext_code_not_stored tests/gateway/test_pairing.py::TestHashedStorage::test_valid_code_verifies_against_hash tests/gateway/test_pairing.py::TestLegacyPendingFileCompat::test_approve_code_ignores_legacy_entries tests/gateway/test_pairing.py::TestLegacyPendingFileCompat::test_approve_code_skips_malformed_entries tests/gateway/test_pairing.py::TestLegacyPendingFileCompat::test_cleanup_expired_handles_malformed_entries tests/gateway/test_pairing.py::TestLegacyPendingFileCompat::test_cleanup_expired_removes_legacy_at_ttl tests/gateway/test_pairing.py::TestLegacyPendingFileCompat::test_list_pending_handles_legacy_entries tests/gateway/test_pairing.py::TestListAndClear::test_clear_pending tests/gateway/test_pairing.py::TestListAndClear::test_clear_pending_all_platforms tests/gateway/test_pairing.py::TestListAndClear::test_list_approved tests/gateway/test_pairing.py::TestListAndClear::test_list_approved_all_platforms tests/gateway/test_pairing.py::TestLockout::test_lockout_after_max_failures tests/gateway/test_pairing.py::TestLockout::test_lockout_blocks_code_approval tests/gateway/test_pairing.py::TestLockout::test_lockout_blocks_code_generation tests/gateway/test_pairing.py::TestLockout::test_lockout_expires tests/gateway/test_pairing.py::TestMaxPending::test_different_platforms_independent tests/gateway/test_pairing.py::TestMaxPending::test_max_pending_per_platform tests/gateway/test_pairing.py::TestRateLimiting::test_different_users_not_rate_limited tests/gateway/test_pairing.py::TestRateLimiting::test_rate_limit_expires tests/gateway/test_pairing.py::TestRateLimiting::test_same_user_rate_limited tests/gateway/test_pairing.py::TestRateLimiting::test_whatsapp_alias_flip_hits_same_rate_limit tests/gateway/test_pairing.py::TestRevoke::test_revoke_approved_user tests/gateway/test_pairing.py::TestRevoke::test_revoke_nonexistent_returns_false tests/gateway/test_pairing.py::TestSecureWrite::test_creates_parent_dirs tests/gateway/test_pairing.py::TestSecureWrite::test_sets_file_permissions tests/gateway/test_pending_drain_no_recursion.py::test_drain_task_cancellation_releases_session tests/gateway/test_pending_drain_no_recursion.py::test_in_band_drain_does_not_grow_stack tests/gateway/test_pending_drain_no_recursion.py::test_in_band_drain_preserves_active_session_guard tests/gateway/test_pending_drain_no_recursion.py::test_late_arrival_drain_still_fires_when_no_in_band_drain tests/gateway/test_pending_drain_no_recursion.py::test_normal_path_releases_session_guard tests/gateway/test_pending_drain_race.py::test_finally_cleanup_drains_late_arrival_pending tests/gateway/test_pending_drain_race.py::test_no_pending_cleans_up_normally tests/gateway/test_pending_drain_race.py::test_pending_drain_keeps_active_session_guard_live tests/gateway/test_pending_event_none.py::TestControlInterruptMessages::test_real_user_interrupt_message_still_requeues tests/gateway/test_pending_event_none.py::TestControlInterruptMessages::test_session_reset_requested_is_not_treated_as_pending_user_message tests/gateway/test_pending_event_none.py::TestControlInterruptMessages::test_stop_requested_is_not_treated_as_pending_user_message tests/gateway/test_pending_event_none.py::TestPendingEventNoneChannelPrompt::test_none_pending_event_returns_none_channel_prompt tests/gateway/test_pending_event_none.py::TestPendingEventNoneChannelPrompt::test_pending_event_with_channel_prompt_passes_through tests/gateway/test_pending_event_none.py::TestPendingEventNoneChannelPrompt::test_pending_event_without_channel_prompt_returns_none tests/gateway/test_per_platform_streaming_defaults.py::test_dashboard_schema_exposes_per_platform_streaming tests/gateway/test_per_platform_streaming_defaults.py::test_default_per_platform_streaming_flags tests/gateway/test_per_platform_streaming_defaults.py::test_resolver_telegram_on_discord_off_when_global_enabled tests/gateway/test_per_platform_streaming_defaults.py::test_user_override_wins_over_default tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_different_ids_produce_different_hashes tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_discord_ids_not_redacted_even_with_flag tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_home_channel_id_hashed tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_home_channel_id_preserved_without_redaction tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_no_redaction_by_default tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_redaction_is_deterministic tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_signal_ids_redacted tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_slack_ids_not_redacted tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_user_id_hashed_when_redact_pii tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_user_name_not_redacted tests/gateway/test_pii_redaction.py::TestBuildSessionContextPromptRedaction::test_whatsapp_ids_redacted tests/gateway/test_pii_redaction.py::TestHashHelpers::test_hash_chat_id_no_prefix tests/gateway/test_pii_redaction.py::TestHashHelpers::test_hash_chat_id_preserves_prefix tests/gateway/test_pii_redaction.py::TestHashHelpers::test_hash_id_12_hex_chars tests/gateway/test_pii_redaction.py::TestHashHelpers::test_hash_id_deterministic tests/gateway/test_pii_redaction.py::TestHashHelpers::test_hash_sender_id_prefix tests/gateway/test_planned_stop_watcher.py::test_planned_stop_marker_targets_self_drops_malformed tests/gateway/test_planned_stop_watcher.py::test_planned_stop_marker_targets_self_probe_is_non_destructive tests/gateway/test_planned_stop_watcher.py::test_watcher_cleans_up_stale_marker_and_keeps_running tests/gateway/test_planned_stop_watcher.py::test_watcher_does_not_fire_for_foreign_pid_marker tests/gateway/test_planned_stop_watcher.py::test_watcher_does_not_fire_when_marker_absent tests/gateway/test_planned_stop_watcher.py::test_watcher_fires_only_once_when_marker_persists tests/gateway/test_planned_stop_watcher.py::test_watcher_fires_shutdown_when_marker_appears tests/gateway/test_planned_stop_watcher.py::test_watcher_responds_to_stop_event_promptly tests/gateway/test_planned_stop_watcher.py::test_watcher_skips_when_runner_already_draining tests/gateway/test_planned_stop_watcher.py::test_watcher_skips_when_runner_not_started tests/gateway/test_planned_stop_watcher.py::test_watcher_tolerates_marker_path_resolution_errors tests/gateway/test_platform_base.py::TestExtractImages::test_cleaned_content_trims_excess_newlines tests/gateway/test_platform_base.py::TestExtractImages::test_fal_cdn_url tests/gateway/test_platform_base.py::TestExtractImages::test_fal_media_cdn tests/gateway/test_platform_base.py::TestExtractImages::test_html_img_self_closing tests/gateway/test_platform_base.py::TestExtractImages::test_html_img_tag tests/gateway/test_platform_base.py::TestExtractImages::test_html_img_with_closing_tag tests/gateway/test_platform_base.py::TestExtractImages::test_markdown_image_gif tests/gateway/test_platform_base.py::TestExtractImages::test_markdown_image_jpeg tests/gateway/test_platform_base.py::TestExtractImages::test_markdown_image_jpg tests/gateway/test_platform_base.py::TestExtractImages::test_markdown_image_webp tests/gateway/test_platform_base.py::TestExtractImages::test_markdown_image_with_image_ext tests/gateway/test_platform_base.py::TestExtractImages::test_mixed_markdown_and_html tests/gateway/test_platform_base.py::TestExtractImages::test_multiple_images tests/gateway/test_platform_base.py::TestExtractImages::test_no_images tests/gateway/test_platform_base.py::TestExtractImages::test_non_http_url_not_matched tests/gateway/test_platform_base.py::TestExtractImages::test_non_image_ext_not_extracted tests/gateway/test_platform_base.py::TestExtractImages::test_non_image_link_preserved_when_mixed_with_images tests/gateway/test_platform_base.py::TestExtractImages::test_replicate_delivery tests/gateway/test_platform_base.py::TestExtractMedia::test_as_document_directive_alone_does_not_attach_voice_flag tests/gateway/test_platform_base.py::TestExtractMedia::test_as_document_directive_stripped_from_cleaned_text tests/gateway/test_platform_base.py::TestExtractMedia::test_both_directives_can_coexist tests/gateway/test_platform_base.py::TestExtractMedia::test_cleaned_content_trims_excess_newlines tests/gateway/test_platform_base.py::TestExtractMedia::test_inline_code_survives_when_real_media_present tests/gateway/test_platform_base.py::TestExtractMedia::test_media_in_blockquote_ignored tests/gateway/test_platform_base.py::TestExtractMedia::test_media_in_fenced_code_block_ignored tests/gateway/test_platform_base.py::TestExtractMedia::test_media_in_inline_code_ignored tests/gateway/test_platform_base.py::TestExtractMedia::test_media_mixed_code_and_prose tests/gateway/test_platform_base.py::TestExtractMedia::test_media_outside_code_blocks_still_extracted tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_allows_optional_whitespace_after_colon tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_strips_wrapping_quotes_and_backticks tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_supports_quoted_paths_with_spaces tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_supports_unquoted_flac_paths_with_spaces tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_unix_paths_still_work tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_windows_backslash_path tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_windows_drive_root tests/gateway/test_platform_base.py::TestExtractMedia::test_media_tag_windows_forward_slash_path tests/gateway/test_platform_base.py::TestExtractMedia::test_media_with_text_before tests/gateway/test_platform_base.py::TestExtractMedia::test_media_with_voice_directive tests/gateway/test_platform_base.py::TestExtractMedia::test_multiple_media_tags tests/gateway/test_platform_base.py::TestExtractMedia::test_no_media tests/gateway/test_platform_base.py::TestExtractMedia::test_relative_path_still_ignored tests/gateway/test_platform_base.py::TestExtractMedia::test_single_media_tag tests/gateway/test_platform_base.py::TestExtractMedia::test_voice_directive_removed_from_content tests/gateway/test_platform_base.py::TestGetHumanDelay::test_custom_mode_tolerates_malformed_env_vars tests/gateway/test_platform_base.py::TestGetHumanDelay::test_custom_mode_uses_env_vars tests/gateway/test_platform_base.py::TestGetHumanDelay::test_default_is_off tests/gateway/test_platform_base.py::TestGetHumanDelay::test_natural_mode_ignores_malformed_custom_env_vars tests/gateway/test_platform_base.py::TestGetHumanDelay::test_natural_mode_range tests/gateway/test_platform_base.py::TestGetHumanDelay::test_off_mode tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_accepts_any_extension_not_on_denylist tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_accepts_stale_file_outside_allowlist tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_denylist_blocks_hermes_config_in_active_profile tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_denylist_blocks_hermes_credentials tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_denylist_blocks_shared_hermes_root_config_for_profiles tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_denylist_blocks_system_prefixes tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_denylist_still_blocks_credentials tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_filter_passes_default_files_through tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_other_users_home_still_blocked_for_nonroot tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_root_home_credential_subdir_still_blocked tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_root_home_deliverable_is_accepted tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_root_home_hermes_env_still_blocked tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_root_home_workdir_symlink_to_credential_blocked tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_strict_mode_envvar_restores_legacy_behavior tests/gateway/test_platform_base.py::TestMediaDeliveryDefaultMode::test_strict_mode_truthy_aliases tests/gateway/test_platform_base.py::TestMediaDeliveryDiagnosability::test_canonical_cache_roots_present tests/gateway/test_platform_base.py::TestMediaDeliveryDiagnosability::test_crafted_null_path_does_not_abort_batch tests/gateway/test_platform_base.py::TestMediaDeliveryDiagnosability::test_extract_media_tolerates_crafted_null_path tests/gateway/test_platform_base.py::TestMediaDeliveryDiagnosability::test_log_safe_path_neutralises_line_breaks tests/gateway/test_platform_base.py::TestMediaDeliveryDiagnosability::test_rejected_path_appears_in_log tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_allows_existing_file_inside_safe_root tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_allows_operator_configured_extra_root tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_filter_keeps_recently_produced_files tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_filter_keeps_safe_media_and_drops_unsafe tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_recency_trust_allows_freshly_produced_file tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_recency_trust_allows_pdf_in_project_dir tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_recency_trust_denies_system_paths_even_when_fresh tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_recency_trust_disabled_falls_back_to_pure_allowlist tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_recency_trust_rejects_old_file tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_rejects_existing_file_outside_safe_root tests/gateway/test_platform_base.py::TestMediaDeliveryPathValidation::test_rejects_symlink_escape_from_safe_root tests/gateway/test_platform_base.py::TestMediaExtensionAllowlistParity::test_extract_media_and_local_files_share_one_extension_set tests/gateway/test_platform_base.py::TestMediaExtensionAllowlistParity::test_known_extension_tag_is_stripped_from_body tests/gateway/test_platform_base.py::TestMediaExtensionAllowlistParity::test_previously_dropped_extensions_now_extract tests/gateway/test_platform_base.py::TestMediaExtensionAllowlistParity::test_unknown_extension_not_black_holed_by_cleanup tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_cleaned_text_after_directive_not_truncated tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_json_embedded_media_kept_verbatim_in_cleaned_text tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_after_prose_same_line_still_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_at_line_start_still_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_in_embedded_serialized_reply_not_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_in_json_array_not_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_in_json_value_not_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_in_nested_json_value_not_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_in_pretty_json_value_not_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_media_indented_still_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_quoted_path_media_still_extracted tests/gateway/test_platform_base.py::TestMediaInsideSerializedJson::test_tts_two_line_still_extracted tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_command_is_lowercased tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_command_mixed_case_with_at_botname tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_command_with_args tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_command_with_at_botname tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_command_with_at_botname_and_args tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_not_a_command tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_simple_command tests/gateway/test_platform_base.py::TestMessageEventGetCommand::test_slash_only_returns_empty tests/gateway/test_platform_base.py::TestMessageEventGetCommandArgs::test_command_with_args tests/gateway/test_platform_base.py::TestMessageEventGetCommandArgs::test_command_without_args tests/gateway/test_platform_base.py::TestMessageEventGetCommandArgs::test_not_a_command_returns_full_text tests/gateway/test_platform_base.py::TestMessageEventIsCommand::test_empty_text tests/gateway/test_platform_base.py::TestMessageEventIsCommand::test_regular_text tests/gateway/test_platform_base.py::TestMessageEventIsCommand::test_slash_command tests/gateway/test_platform_base.py::TestMessageEventIsCommand::test_slash_only tests/gateway/test_platform_base.py::TestPrefixWithinUtf16Limit::test_all_emoji tests/gateway/test_platform_base.py::TestPrefixWithinUtf16Limit::test_ascii_truncation tests/gateway/test_platform_base.py::TestPrefixWithinUtf16Limit::test_does_not_split_surrogate_pair tests/gateway/test_platform_base.py::TestPrefixWithinUtf16Limit::test_emoji_at_limit tests/gateway/test_platform_base.py::TestPrefixWithinUtf16Limit::test_empty tests/gateway/test_platform_base.py::TestPrefixWithinUtf16Limit::test_fits_entirely tests/gateway/test_platform_base.py::TestProxyKwargsForAiohttp::test_http_proxy_falls_back_without_aiohttp_socks tests/gateway/test_platform_base.py::TestProxyKwargsForAiohttp::test_http_proxy_uses_connector_when_aiohttp_socks_available tests/gateway/test_platform_base.py::TestProxyKwargsForAiohttp::test_none_returns_empty tests/gateway/test_platform_base.py::TestProxyKwargsForAiohttp::test_socks_proxy_uses_connector tests/gateway/test_platform_base.py::TestSafeUrlForLog::test_handles_small_and_non_positive_max_len tests/gateway/test_platform_base.py::TestSafeUrlForLog::test_strips_query_fragment_and_userinfo tests/gateway/test_platform_base.py::TestSafeUrlForLog::test_truncates_long_values tests/gateway/test_platform_base.py::TestSecretCaptureGuidance::test_gateway_secret_capture_message_points_to_local_setup tests/gateway/test_platform_base.py::TestShouldSendMediaAsAudio::test_accepts_platform_enum tests/gateway/test_platform_base.py::TestShouldSendMediaAsAudio::test_non_telegram_platforms_route_all_audio tests/gateway/test_platform_base.py::TestShouldSendMediaAsAudio::test_telegram_mp3_and_m4a_route_to_audio tests/gateway/test_platform_base.py::TestShouldSendMediaAsAudio::test_telegram_ogg_opus_only_when_voice_flagged tests/gateway/test_platform_base.py::TestShouldSendMediaAsAudio::test_telegram_wav_and_flac_fall_through_to_document tests/gateway/test_platform_base.py::TestShouldSendMediaAsAudio::test_unknown_extension_returns_false tests/gateway/test_platform_base.py::TestTruncateMessage::test_chunks_have_indicators tests/gateway/test_platform_base.py::TestTruncateMessage::test_code_block_first_chunk_closed tests/gateway/test_platform_base.py::TestTruncateMessage::test_code_block_language_tag_carried tests/gateway/test_platform_base.py::TestTruncateMessage::test_continuation_chunks_have_balanced_fences tests/gateway/test_platform_base.py::TestTruncateMessage::test_each_chunk_under_max_length tests/gateway/test_platform_base.py::TestTruncateMessage::test_exact_length_single_chunk tests/gateway/test_platform_base.py::TestTruncateMessage::test_long_message_splits tests/gateway/test_platform_base.py::TestTruncateMessage::test_short_message_single_chunk tests/gateway/test_platform_base.py::TestTruncateMessageUtf16::test_all_content_preserved tests/gateway/test_platform_base.py::TestTruncateMessageUtf16::test_code_blocks_preserved_with_utf16 tests/gateway/test_platform_base.py::TestTruncateMessageUtf16::test_each_utf16_chunk_within_limit tests/gateway/test_platform_base.py::TestTruncateMessageUtf16::test_emoji_near_limit_triggers_split tests/gateway/test_platform_base.py::TestTruncateMessageUtf16::test_short_emoji_message_no_split tests/gateway/test_platform_base.py::TestUtf16Len::test_ascii tests/gateway/test_platform_base.py::TestUtf16Len::test_bmp_cjk tests/gateway/test_platform_base.py::TestUtf16Len::test_emoji_surrogate_pair tests/gateway/test_platform_base.py::TestUtf16Len::test_empty tests/gateway/test_platform_base.py::TestUtf16Len::test_mixed tests/gateway/test_platform_base.py::TestUtf16Len::test_musical_symbol tests/gateway/test_platform_connected_checkers.py::test_all_builtins_have_checker_or_generic_token_path tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.API_SERVER-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.BLUEBUBBLES-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.DINGTALK-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.EMAIL-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.FEISHU-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.MSGRAPH_WEBHOOK-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.QQBOT-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.RELAY-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.SIGNAL-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.SMS-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.WEBHOOK-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.WECOM-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.WECOM_CALLBACK-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.WEIXIN-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.WHATSAPP-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.WHATSAPP_CLOUD-] tests/gateway/test_platform_connected_checkers.py::test_checker_handles_minimal_config[Platform.YUANBAO-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.API_SERVER-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.BLUEBUBBLES-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.DINGTALK-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.EMAIL-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.FEISHU-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.MSGRAPH_WEBHOOK-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.QQBOT-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.RELAY-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.SIGNAL-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.SMS-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.WEBHOOK-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.WECOM-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.WECOM_CALLBACK-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.WEIXIN-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.WHATSAPP-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.WHATSAPP_CLOUD-] tests/gateway/test_platform_connected_checkers.py::test_checker_returns_true_when_configured[Platform.YUANBAO-] tests/gateway/test_platform_http_client_limits.py::TestWhatsappTypingLeakFix::test_bare_await_removed tests/gateway/test_platform_http_client_limits.py::test_default_limits_tighten_keepalive_below_httpx_default tests/gateway/test_platform_http_client_limits.py::test_env_override_keepalive_expiry tests/gateway/test_platform_http_client_limits.py::test_env_override_max_keepalive tests/gateway/test_platform_http_client_limits.py::test_env_override_rejects_garbage tests/gateway/test_platform_http_client_limits.py::test_helper_is_importable_from_every_platform_that_uses_it tests/gateway/test_platform_http_client_limits.py::test_returns_none_when_httpx_unavailable tests/gateway/test_platform_reconnect.py::TestPauseResume::test_pause_is_idempotent tests/gateway/test_platform_reconnect.py::TestPauseResume::test_pause_marks_platform_paused tests/gateway/test_platform_reconnect.py::TestPauseResume::test_pause_no_op_when_platform_not_queued tests/gateway/test_platform_reconnect.py::TestPauseResume::test_resume_clears_paused_and_resets_attempts tests/gateway/test_platform_reconnect.py::TestPauseResume::test_resume_returns_false_when_not_paused tests/gateway/test_platform_reconnect.py::TestPauseResume::test_resume_returns_false_when_not_queued tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_adapter_create_returns_none tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_no_failed_platforms_watcher_idles tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_reconnect_never_auto_pauses_retryable_failures tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_reconnect_nonretryable_removed_from_queue tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_reconnect_retries_resume_pending_for_platform tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_reconnect_retryable_stays_in_queue tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_reconnect_skips_paused_platforms tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_reconnect_skips_when_not_time_yet tests/gateway/test_platform_reconnect.py::TestPlatformReconnectWatcher::test_reconnect_succeeds_on_retry tests/gateway/test_platform_reconnect.py::TestPlatformSlashCommand::test_bare_platform_shows_usage_with_list tests/gateway/test_platform_reconnect.py::TestPlatformSlashCommand::test_list_shows_connected_and_paused tests/gateway/test_platform_reconnect.py::TestPlatformSlashCommand::test_pause_command_pauses_queued_platform tests/gateway/test_platform_reconnect.py::TestPlatformSlashCommand::test_pause_rejects_unqueued_platform tests/gateway/test_platform_reconnect.py::TestPlatformSlashCommand::test_resume_command_resumes_paused_platform tests/gateway/test_platform_reconnect.py::TestPlatformSlashCommand::test_unknown_platform_name tests/gateway/test_platform_reconnect.py::TestRuntimeDisconnectQueuing::test_nonretryable_error_triggers_shutdown tests/gateway/test_platform_reconnect.py::TestRuntimeDisconnectQueuing::test_nonretryable_runtime_error_not_queued tests/gateway/test_platform_reconnect.py::TestRuntimeDisconnectQueuing::test_retryable_error_keeps_gateway_alive_when_all_down tests/gateway/test_platform_reconnect.py::TestRuntimeDisconnectQueuing::test_retryable_error_no_exit_when_other_adapters_still_connected tests/gateway/test_platform_reconnect.py::TestRuntimeDisconnectQueuing::test_retryable_runtime_error_queued_for_reconnect tests/gateway/test_platform_reconnect.py::TestStartupFailureQueuing::test_failed_platform_not_queued_for_nonretryable tests/gateway/test_platform_reconnect.py::TestStartupFailureQueuing::test_failed_platform_queued_on_connect_failure tests/gateway/test_platform_reconnect.py::TestStartupPlatformIsolation::test_connect_adapter_timeout_raises_retryable_exception tests/gateway/test_platform_reconnect.py::TestStartupPlatformIsolation::test_start_continues_after_platform_connect_timeout tests/gateway/test_platform_reconnect_fd_leak.py::TestAPIServerDisconnectClosesResponseStore::test_disconnect_closes_response_store tests/gateway/test_platform_reconnect_fd_leak.py::TestAPIServerDisconnectClosesResponseStore::test_disconnect_swallows_response_store_close_exception tests/gateway/test_platform_reconnect_fd_leak.py::TestReconnectFDLeakRegression::test_dispose_helper_handles_none tests/gateway/test_platform_reconnect_fd_leak.py::TestReconnectFDLeakRegression::test_dispose_helper_swallows_disconnect_exception tests/gateway/test_platform_reconnect_fd_leak.py::TestReconnectFDLeakRegression::test_exception_during_connect_disposes_unowned_adapter tests/gateway/test_platform_reconnect_fd_leak.py::TestReconnectFDLeakRegression::test_nonretryable_failure_disposes_unowned_adapter tests/gateway/test_platform_reconnect_fd_leak.py::TestReconnectFDLeakRegression::test_retryable_failure_disposes_unowned_adapter tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnDispatch::test_env_var_takes_precedence_when_hook_uses_getenv_guard tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnDispatch::test_hook_can_mutate_environ tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnDispatch::test_hook_exception_swallowed tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnDispatch::test_hook_receives_full_yaml_and_platform_subdict tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnDispatch::test_hook_returned_dict_merges_into_extra tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnDispatch::test_hook_skipped_when_platform_section_missing tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnDispatch::test_hook_skipped_when_platform_section_not_dict tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnField::test_accepts_callable tests/gateway/test_platform_registry.py::TestApplyYamlConfigFnField::test_default_is_none tests/gateway/test_platform_registry.py::TestCronPlatformResolution::test_builtin_platform_resolves tests/gateway/test_platform_registry.py::TestCronPlatformResolution::test_invalid_platform_type_rejected tests/gateway/test_platform_registry.py::TestCronPlatformResolution::test_plugin_platform_resolves tests/gateway/test_platform_registry.py::TestGatewayConfigPluginPlatform::test_from_dict_accepts_plugin_platform tests/gateway/test_platform_registry.py::TestGatewayConfigPluginPlatform::test_get_connected_platforms_excludes_invalid_config tests/gateway/test_platform_registry.py::TestGatewayConfigPluginPlatform::test_get_connected_platforms_excludes_unregistered_plugin tests/gateway/test_platform_registry.py::TestGatewayConfigPluginPlatform::test_get_connected_platforms_includes_registered_plugin tests/gateway/test_platform_registry.py::TestPlatformEntryExtendedFields::test_custom_auth_fields tests/gateway/test_platform_registry.py::TestPlatformEntryExtendedFields::test_default_field_values tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_builtin_members_still_work tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_case_normalised tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_created tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_identity_stable tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_rejects_empty tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_rejects_non_string tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_rejects_unregistered tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_rejects_whitespace_only tests/gateway/test_platform_registry.py::TestPlatformEnumDynamic::test_dynamic_member_with_hyphens tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_all_entries tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_create_adapter_check_fails tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_create_adapter_factory_exception tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_create_adapter_no_validate tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_create_adapter_success tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_create_adapter_unknown_name tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_create_adapter_validate_fails tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_get_unknown_returns_none tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_plugin_entries tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_re_register_replaces tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_register_and_get tests/gateway/test_platform_registry.py::TestPlatformRegistry::test_unregister tests/gateway/test_platform_registry.py::TestPlatformsMerge::test_get_all_platforms_includes_builtins tests/gateway/test_platform_registry.py::TestPlatformsMerge::test_get_all_platforms_includes_plugin tests/gateway/test_platform_registry.py::TestPlatformsMerge::test_platform_label_plugin_fallback tests/gateway/test_platform_registry.py::TestPluginEnablementGate::test_is_connected_failed_gate_does_not_leak_extras tests/gateway/test_platform_registry.py::TestPluginEnablementGate::test_is_connected_raises_does_not_enable tests/gateway/test_platform_registry.py::TestPluginEnablementGate::test_is_connected_sees_env_seeded_extras tests/gateway/test_platform_registry.py::TestPluginEnablementGate::test_plugin_with_is_connected_false_is_NOT_enabled tests/gateway/test_platform_registry.py::TestPluginEnablementGate::test_plugin_with_is_connected_true_is_enabled tests/gateway/test_platform_registry.py::TestPluginEnablementGate::test_plugin_without_is_connected_falls_back_to_check_fn tests/gateway/test_platform_registry.py::TestPluginEnablementGate::test_yaml_enabled_true_overrides_is_connected_false tests/gateway/test_platform_registry.py::TestPluginPlatformSharedKeyBridge::test_shared_keys_bridged_for_plugin_platform tests/gateway/test_plugin_platform_interface.py::test_adapter_factory_produces_valid_adapter[NOTSET] tests/gateway/test_plugin_platform_interface.py::test_check_fn_returns_bool[NOTSET] tests/gateway/test_plugin_platform_interface.py::test_is_connected_if_present[NOTSET] tests/gateway/test_plugin_platform_interface.py::test_platform_entry_has_required_fields[NOTSET] tests/gateway/test_plugin_platform_interface.py::test_plugin_exposes_register_function[NOTSET] tests/gateway/test_plugin_platform_interface.py::test_plugin_registers_valid_platform_entry[NOTSET] tests/gateway/test_plugin_platform_interface.py::test_validate_config_if_present[NOTSET] tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_empty_session_key_is_noop tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_exception_in_one_callback_does_not_block_next tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_non_callable_is_noop tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_pop_at_wrong_generation_returns_none tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_same_generation_chains tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_single_callback_fires tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_stale_generation_registration_rejected tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_three_callbacks_chain_in_order tests/gateway/test_post_delivery_callback_chaining.py::TestPostDeliveryCallbackChaining::test_two_callbacks_chain_in_order tests/gateway/test_pre_gateway_dispatch.py::test_hook_allow_falls_through_to_auth tests/gateway/test_pre_gateway_dispatch.py::test_hook_exception_does_not_break_dispatch tests/gateway/test_pre_gateway_dispatch.py::test_hook_rewrite_replaces_event_text tests/gateway/test_pre_gateway_dispatch.py::test_hook_skip_short_circuits_dispatch tests/gateway/test_pre_gateway_dispatch.py::test_internal_events_bypass_hook tests/gateway/test_proxy_mode.py::TestEnvVarRegistration::test_proxy_key_in_optional_env_vars tests/gateway/test_proxy_mode.py::TestEnvVarRegistration::test_proxy_url_in_optional_env_vars tests/gateway/test_proxy_mode.py::TestGetProxyUrl::test_empty_string_treated_as_unset tests/gateway/test_proxy_mode.py::TestGetProxyUrl::test_env_var_overrides_config tests/gateway/test_proxy_mode.py::TestGetProxyUrl::test_reads_from_config_yaml tests/gateway/test_proxy_mode.py::TestGetProxyUrl::test_reads_from_env_var tests/gateway/test_proxy_mode.py::TestGetProxyUrl::test_returns_none_when_not_configured tests/gateway/test_proxy_mode.py::TestGetProxyUrl::test_strips_trailing_slash tests/gateway/test_proxy_mode.py::TestResolveProxyUrl::test_no_proxy_bypasses_cidr_target tests/gateway/test_proxy_mode.py::TestResolveProxyUrl::test_no_proxy_bypasses_matching_host tests/gateway/test_proxy_mode.py::TestResolveProxyUrl::test_no_proxy_ignored_without_target tests/gateway/test_proxy_mode.py::TestResolveProxyUrl::test_normalizes_socks_alias_from_all_proxy tests/gateway/test_proxy_mode.py::TestRunAgentProxyDispatch::test_run_agent_delegates_to_proxy tests/gateway/test_proxy_mode.py::TestRunAgentProxyDispatch::test_run_agent_skips_proxy_when_not_configured tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_builds_correct_request tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_handles_connection_error tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_handles_http_error tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_no_auth_header_without_key tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_no_system_message_when_context_empty tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_proxy_stale_generation_returns_empty_result tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_result_shape_matches_run_agent tests/gateway/test_proxy_mode.py::TestRunAgentViaProxy::test_skips_tool_messages_in_history tests/gateway/test_qqbot.py::TestAdapterInteractionDispatch::test_callback_exception_does_not_propagate tests/gateway/test_qqbot.py::TestAdapterInteractionDispatch::test_callback_invoked_with_parsed_event tests/gateway/test_qqbot.py::TestAdapterInteractionDispatch::test_explicit_no_callback_is_harmless tests/gateway/test_qqbot.py::TestAdapterInteractionDispatch::test_missing_id_skips_ack tests/gateway/test_qqbot.py::TestApprovalButtonData::test_parse_allow_always tests/gateway/test_qqbot.py::TestApprovalButtonData::test_parse_allow_once tests/gateway/test_qqbot.py::TestApprovalButtonData::test_parse_deny tests/gateway/test_qqbot.py::TestApprovalButtonData::test_parse_empty_returns_none tests/gateway/test_qqbot.py::TestApprovalButtonData::test_parse_invalid_prefix_returns_none tests/gateway/test_qqbot.py::TestApprovalButtonData::test_parse_unknown_decision_returns_none tests/gateway/test_qqbot.py::TestBuildApprovalKeyboard::test_button_data_embeds_session_key tests/gateway/test_qqbot.py::TestBuildApprovalKeyboard::test_buttons_share_group_id_for_mutual_exclusion tests/gateway/test_qqbot.py::TestBuildApprovalKeyboard::test_round_trip_parse_matches_build tests/gateway/test_qqbot.py::TestBuildApprovalKeyboard::test_three_buttons_in_single_row tests/gateway/test_qqbot.py::TestBuildApprovalKeyboard::test_to_dict_has_expected_shape tests/gateway/test_qqbot.py::TestBuildApprovalText::test_exec_approval_includes_command_preview tests/gateway/test_qqbot.py::TestBuildApprovalText::test_plugin_approval_uses_severity_icon tests/gateway/test_qqbot.py::TestBuildApprovalText::test_truncates_long_commands tests/gateway/test_qqbot.py::TestBuildTextBody::test_empty_string tests/gateway/test_qqbot.py::TestBuildTextBody::test_markdown_text tests/gateway/test_qqbot.py::TestBuildTextBody::test_plain_text tests/gateway/test_qqbot.py::TestBuildTextBody::test_reply_to tests/gateway/test_qqbot.py::TestBuildTextBody::test_truncation tests/gateway/test_qqbot.py::TestBuildUpdatePromptKeyboard::test_button_data_shape tests/gateway/test_qqbot.py::TestBuildUpdatePromptKeyboard::test_two_buttons tests/gateway/test_qqbot.py::TestChunkedUploadErrors::test_daily_limit_has_human_size tests/gateway/test_qqbot.py::TestChunkedUploadErrors::test_too_large_includes_limit tests/gateway/test_qqbot.py::TestChunkedUploadErrors::test_too_large_unknown_limit tests/gateway/test_qqbot.py::TestChunkedUploadFormatSize::test_bytes tests/gateway/test_qqbot.py::TestChunkedUploadFormatSize::test_gigabytes tests/gateway/test_qqbot.py::TestChunkedUploadFormatSize::test_kilobytes tests/gateway/test_qqbot.py::TestChunkedUploadFormatSize::test_megabytes tests/gateway/test_qqbot.py::TestChunkedUploadHelpers::test_compute_hashes_large_file_has_distinct_md5_10m tests/gateway/test_qqbot.py::TestChunkedUploadHelpers::test_compute_hashes_small_file tests/gateway/test_qqbot.py::TestChunkedUploadHelpers::test_parse_prepare_response_missing_parts_raises tests/gateway/test_qqbot.py::TestChunkedUploadHelpers::test_parse_prepare_response_missing_upload_id_raises tests/gateway/test_qqbot.py::TestChunkedUploadHelpers::test_parse_prepare_response_wrapped_in_data tests/gateway/test_qqbot.py::TestChunkedUploadHelpers::test_read_chunk_exact_bytes tests/gateway/test_qqbot.py::TestChunkedUploadHelpers::test_read_chunk_short_read_raises tests/gateway/test_qqbot.py::TestChunkedUploaderFlow::test_daily_limit_raises_structured_error tests/gateway/test_qqbot.py::TestChunkedUploaderFlow::test_full_upload_two_parts_success tests/gateway/test_qqbot.py::TestChunkedUploaderFlow::test_group_paths tests/gateway/test_qqbot.py::TestChunkedUploaderFlow::test_part_finish_retries_on_40093001_then_succeeds tests/gateway/test_qqbot.py::TestChunkedUploaderFlow::test_put_retries_transient_failure tests/gateway/test_qqbot.py::TestCloseCodeClassification::test_4009_preserves_session tests/gateway/test_qqbot.py::TestCloseCodeClassification::test_fatal_codes_include_intent_errors tests/gateway/test_qqbot.py::TestCoerceList::test_empty_string tests/gateway/test_qqbot.py::TestCoerceList::test_list tests/gateway/test_qqbot.py::TestCoerceList::test_none tests/gateway/test_qqbot.py::TestCoerceList::test_single_item_string tests/gateway/test_qqbot.py::TestCoerceList::test_string tests/gateway/test_qqbot.py::TestCoerceList::test_tuple tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_approval_click_always_maps_to_always tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_approval_click_deny_maps_to_deny tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_approval_click_once_maps_to_once tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_approval_click_rejects_unauthorized_operator tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_default_callback_installed_on_init tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_empty_button_data_is_harmless tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_resolve_exception_is_swallowed tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_send_exec_approval_is_a_class_method tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_unknown_button_data_is_harmless tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_update_prompt_click_no_writes_n tests/gateway/test_qqbot.py::TestDefaultInteractionDispatch::test_update_prompt_click_writes_response_file tests/gateway/test_qqbot.py::TestDetectMessageType::test_image tests/gateway/test_qqbot.py::TestDetectMessageType::test_no_media tests/gateway/test_qqbot.py::TestDetectMessageType::test_video tests/gateway/test_qqbot.py::TestDetectMessageType::test_voice tests/gateway/test_qqbot.py::TestDispatchPayload::test_op10_updates_heartbeat_interval tests/gateway/test_qqbot.py::TestDispatchPayload::test_op11_heartbeat_ack tests/gateway/test_qqbot.py::TestDispatchPayload::test_seq_increments tests/gateway/test_qqbot.py::TestDispatchPayload::test_seq_tracking tests/gateway/test_qqbot.py::TestDispatchPayload::test_unknown_op tests/gateway/test_qqbot.py::TestDmAllowed::test_allowlist_match tests/gateway/test_qqbot.py::TestDmAllowed::test_allowlist_no_match tests/gateway/test_qqbot.py::TestDmAllowed::test_allowlist_wildcard tests/gateway/test_qqbot.py::TestDmAllowed::test_disabled_policy tests/gateway/test_qqbot.py::TestDmAllowed::test_open_policy tests/gateway/test_qqbot.py::TestGroupAllowed::test_allowlist_match tests/gateway/test_qqbot.py::TestGroupAllowed::test_allowlist_no_match tests/gateway/test_qqbot.py::TestGroupAllowed::test_open_policy tests/gateway/test_qqbot.py::TestIdentifyIntents::test_intents_include_interaction_bit tests/gateway/test_qqbot.py::TestInteractionEventParsing::test_parse_c2c_interaction tests/gateway/test_qqbot.py::TestInteractionEventParsing::test_parse_group_interaction tests/gateway/test_qqbot.py::TestInteractionEventParsing::test_parse_missing_data_gracefully tests/gateway/test_qqbot.py::TestIsVoiceContentType::test_audio_content_type tests/gateway/test_qqbot.py::TestIsVoiceContentType::test_audio_extension_amr tests/gateway/test_qqbot.py::TestIsVoiceContentType::test_non_voice tests/gateway/test_qqbot.py::TestIsVoiceContentType::test_voice_content_type tests/gateway/test_qqbot.py::TestIsVoiceContentType::test_voice_extension tests/gateway/test_qqbot.py::TestMergeQuoteInto::test_both_present_joined_with_blank_line tests/gateway/test_qqbot.py::TestMergeQuoteInto::test_empty_quote_returns_original tests/gateway/test_qqbot.py::TestMergeQuoteInto::test_empty_text_returns_only_quote tests/gateway/test_qqbot.py::TestOp7ServerReconnect::test_op7_close_task_executes tests/gateway/test_qqbot.py::TestOp7ServerReconnect::test_op7_closes_websocket tests/gateway/test_qqbot.py::TestOp9InvalidSession::test_op9_non_resumable_triggers_ws_close tests/gateway/test_qqbot.py::TestOp9InvalidSession::test_op9_not_resumable_clears_session tests/gateway/test_qqbot.py::TestOp9InvalidSession::test_op9_resumable_preserves_session tests/gateway/test_qqbot.py::TestParseJson::test_empty_dict tests/gateway/test_qqbot.py::TestParseJson::test_invalid_json tests/gateway/test_qqbot.py::TestParseJson::test_non_dict_json tests/gateway/test_qqbot.py::TestParseJson::test_none_input tests/gateway/test_qqbot.py::TestParseJson::test_valid_json tests/gateway/test_qqbot.py::TestProcessAttachmentsPathExposure::test_download_failure_produces_no_attachment_info tests/gateway/test_qqbot.py::TestProcessAttachmentsPathExposure::test_file_attachment_includes_path tests/gateway/test_qqbot.py::TestProcessAttachmentsPathExposure::test_quoted_file_includes_path_in_quote_block tests/gateway/test_qqbot.py::TestProcessAttachmentsPathExposure::test_quoted_video_includes_path_in_quote_block tests/gateway/test_qqbot.py::TestProcessAttachmentsPathExposure::test_video_attachment_includes_path tests/gateway/test_qqbot.py::TestProcessAttachmentsPathExposure::test_video_without_filename_falls_back_to_content_type tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_invalid_message_type_string_returns_empty tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_multiple_elements_concatenated tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_non_quote_message_returns_empty tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_quote_type_but_no_elements_returns_empty tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_quote_with_file_preserves_filename tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_quote_with_image_only_no_text tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_quote_with_image_returns_cached_paths tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_quote_with_text_only tests/gateway/test_qqbot.py::TestProcessQuotedContext::test_quote_with_voice_attachment_runs_stt tests/gateway/test_qqbot.py::TestQQAdapterInit::test_allow_from_default_empty tests/gateway/test_qqbot.py::TestQQAdapterInit::test_allow_from_parsing_list tests/gateway/test_qqbot.py::TestQQAdapterInit::test_allow_from_parsing_string tests/gateway/test_qqbot.py::TestQQAdapterInit::test_basic_attributes tests/gateway/test_qqbot.py::TestQQAdapterInit::test_dm_policy_default tests/gateway/test_qqbot.py::TestQQAdapterInit::test_dm_policy_explicit tests/gateway/test_qqbot.py::TestQQAdapterInit::test_env_fallback tests/gateway/test_qqbot.py::TestQQAdapterInit::test_env_fallback_extra_wins tests/gateway/test_qqbot.py::TestQQAdapterInit::test_group_allow_from tests/gateway/test_qqbot.py::TestQQAdapterInit::test_group_policy_default tests/gateway/test_qqbot.py::TestQQAdapterInit::test_markdown_support_default tests/gateway/test_qqbot.py::TestQQAdapterInit::test_markdown_support_false tests/gateway/test_qqbot.py::TestQQAdapterInit::test_name_property tests/gateway/test_qqbot.py::TestQQCloseError::test_attributes tests/gateway/test_qqbot.py::TestQQCloseError::test_code_none tests/gateway/test_qqbot.py::TestQQCloseError::test_message_format tests/gateway/test_qqbot.py::TestQQCloseError::test_string_to_int tests/gateway/test_qqbot.py::TestQQRequirements::test_returns_bool tests/gateway/test_qqbot.py::TestQQWebSocketProxy::test_open_ws_honors_proxy_env tests/gateway/test_qqbot.py::TestReadEventsClosedWsGuard::test_read_events_raises_when_ws_closed_on_entry tests/gateway/test_qqbot.py::TestReadEventsClosedWsGuard::test_read_events_raises_when_ws_none tests/gateway/test_qqbot.py::TestReadyHandling::test_ready_stores_session tests/gateway/test_qqbot.py::TestReadyHandling::test_resumed_preserves_session tests/gateway/test_qqbot.py::TestResolveSTTConfig::test_env_config tests/gateway/test_qqbot.py::TestResolveSTTConfig::test_extra_config tests/gateway/test_qqbot.py::TestResolveSTTConfig::test_no_config tests/gateway/test_qqbot.py::TestSendExecApproval::test_accepts_metadata_arg tests/gateway/test_qqbot.py::TestSendExecApproval::test_delegates_to_send_approval_request tests/gateway/test_qqbot.py::TestSendUpdatePrompt::test_delegates_to_send_with_keyboard tests/gateway/test_qqbot.py::TestSendUpdatePrompt::test_empty_default_has_no_hint tests/gateway/test_qqbot.py::TestStripAtMention::test_empty_string tests/gateway/test_qqbot.py::TestStripAtMention::test_no_mention tests/gateway/test_qqbot.py::TestStripAtMention::test_only_mention tests/gateway/test_qqbot.py::TestStripAtMention::test_removes_mention tests/gateway/test_qqbot.py::TestUpdatePromptButtonData::test_parse_no tests/gateway/test_qqbot.py::TestUpdatePromptButtonData::test_parse_unknown_returns_none tests/gateway/test_qqbot.py::TestUpdatePromptButtonData::test_parse_wrong_prefix tests/gateway/test_qqbot.py::TestUpdatePromptButtonData::test_parse_yes tests/gateway/test_qqbot.py::TestVoiceAttachmentSSRFProtection::test_connect_uses_redirect_guard_hook tests/gateway/test_qqbot.py::TestVoiceAttachmentSSRFProtection::test_stt_blocks_unsafe_download_url tests/gateway/test_qqbot.py::TestWaitForReconnection::test_send_media_waits_for_reconnect tests/gateway/test_qqbot.py::TestWaitForReconnection::test_send_returns_retryable_after_timeout tests/gateway/test_qqbot.py::TestWaitForReconnection::test_send_succeeds_immediately_when_connected tests/gateway/test_qqbot.py::TestWaitForReconnection::test_send_waits_and_succeeds_on_reconnect tests/gateway/test_queue_consumption.py::TestBusyInputModeQueueFifo::test_photo_burst_still_merges_in_head_slot tests/gateway/test_queue_consumption.py::TestBusyInputModeQueueFifo::test_queue_respects_bounded_cap tests/gateway/test_queue_consumption.py::TestBusyInputModeQueueFifo::test_rapid_text_followups_are_queued_in_fifo_order tests/gateway/test_queue_consumption.py::TestQueueConsumptionAfterCompletion::test_enqueue_preserves_text_no_merging tests/gateway/test_queue_consumption.py::TestQueueConsumptionAfterCompletion::test_multiple_queues_overflow_fifo tests/gateway/test_queue_consumption.py::TestQueueConsumptionAfterCompletion::test_pending_message_available_after_normal_completion tests/gateway/test_queue_consumption.py::TestQueueConsumptionAfterCompletion::test_promote_advances_queue_fifo tests/gateway/test_queue_consumption.py::TestQueueConsumptionAfterCompletion::test_promote_stages_overflow_when_slot_already_populated tests/gateway/test_queue_consumption.py::TestQueueConsumptionAfterCompletion::test_queue_depth_counts_slot_plus_overflow tests/gateway/test_queue_consumption.py::TestQueueMessageStorage::test_dequeue_pending_event_preserves_voice_media_metadata tests/gateway/test_queue_consumption.py::TestQueueMessageStorage::test_get_pending_message_consumes_and_clears tests/gateway/test_queue_consumption.py::TestQueueMessageStorage::test_queue_does_not_set_interrupt_event tests/gateway/test_queue_consumption.py::TestQueueMessageStorage::test_queue_stores_message_in_pending tests/gateway/test_queue_consumption.py::TestQueueMessageStorage::test_regular_message_sets_interrupt_event tests/gateway/test_raft_adapter.py::TestRaftActivityHttp::test_activity_endpoint_auth_validation_and_drain tests/gateway/test_raft_adapter.py::TestRaftActivityHttp::test_hook_mapping_reports_only_raft_context tests/gateway/test_raft_adapter.py::TestRaftActivityHttp::test_interrupted_turn_reports_error_stop tests/gateway/test_raft_adapter.py::TestRaftActivityHttp::test_session_start_registers_raft_profile_env_passthrough tests/gateway/test_raft_adapter.py::TestRaftConfig::test_env_enablement_auto_enables_with_raft_profile tests/gateway/test_raft_adapter.py::TestRaftConfig::test_env_enablement_returns_none_without_profile tests/gateway/test_raft_adapter.py::TestRaftConfig::test_is_connected_checks_bridge_token_or_enabled tests/gateway/test_raft_adapter.py::TestRaftConfig::test_register_calls_register_platform tests/gateway/test_raft_adapter.py::TestRaftWakeHttp::test_accepts_content_free_wake_as_internal_event[raft-channel-wake.v1] tests/gateway/test_raft_adapter.py::TestRaftWakeHttp::test_accepts_content_free_wake_as_internal_event[raft-channel-wake.v2] tests/gateway/test_raft_adapter.py::TestRaftWakeHttp::test_busy_session_queues_without_interrupt tests/gateway/test_raft_adapter.py::TestRaftWakeHttp::test_rejects_content_bearing_payload tests/gateway/test_raft_adapter.py::TestRaftWakeHttp::test_rejects_missing_bridge_token tests/gateway/test_raft_adapter.py::TestRaftWakeHttp::test_returns_not_ready_without_gateway_handler tests/gateway/test_raft_adapter.py::TestRaftWakeHttp::test_send_is_noop_success tests/gateway/test_raft_adapter.py::TestRaftWakePayload::test_detects_content_fields tests/gateway/test_reasoning_command.py::TestLoadShowReasoningCoercion::test_bare_true_is_true tests/gateway/test_reasoning_command.py::TestLoadShowReasoningCoercion::test_missing_is_false tests/gateway/test_reasoning_command.py::TestLoadShowReasoningCoercion::test_quoted_false_is_false tests/gateway/test_reasoning_command.py::TestLoadShowReasoningCoercion::test_quoted_off_is_false tests/gateway/test_reasoning_command.py::TestLoadShowReasoningCoercion::test_quoted_true_is_true tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_handle_reasoning_command_defaults_to_session_only tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_handle_reasoning_command_updates_config_and_cache tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_parse_reasoning_command_args_accepts_ascii_and_smart_global_flags tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_reasoning_command_reloads_current_state_from_config tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_reasoning_global_clears_existing_session_override tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_reasoning_in_help_output tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_reasoning_is_known_command tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_reasoning_reset_clears_session_override_without_config_write tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_resolve_session_reasoning_prefers_session_override tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_run_agent_homeassistant_uses_default_platform_toolset tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_run_agent_includes_enabled_mcp_servers_in_gateway_toolsets tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_run_agent_prefers_session_reasoning_override tests/gateway/test_reasoning_command.py::TestReasoningCommand::test_run_agent_reloads_reasoning_config_per_message tests/gateway/test_relay_capability_surface.py::test_abstract_methods_are_the_known_set tests/gateway/test_relay_capability_surface.py::test_message_len_fn_defaults_to_len tests/gateway/test_relay_capability_surface.py::test_stream_consumer_reads_max_message_length_by_attribute tests/gateway/test_relay_capability_surface.py::test_supports_draft_streaming_defaults_false tests/gateway/test_reload_skills_command.py::test_dispatcher_routes_reload_skills tests/gateway/test_reload_skills_command.py::test_reload_skills_handler_queues_note_on_diff tests/gateway/test_reload_skills_command.py::test_reload_skills_handler_reports_no_changes tests/gateway/test_reload_skills_command.py::test_underscored_alias_not_flagged_unknown tests/gateway/test_reload_skills_discord_resync.py::TestHandleReloadSkillsCallsRefreshSkillGroup::test_orchestrator_calls_refresh_skill_group_on_every_adapter tests/gateway/test_reload_skills_discord_resync.py::TestRefreshSkillGroup::test_refresh_handles_collector_exception_gracefully tests/gateway/test_reload_skills_discord_resync.py::TestRefreshSkillGroup::test_refresh_repopulates_entries_after_catalog_change tests/gateway/test_reload_skills_discord_resync.py::TestRefreshSkillGroup::test_refresh_sorts_entries_alphabetically tests/gateway/test_reload_skills_discord_resync.py::TestRegisterSkillGroupUsesInstanceState::test_refresh_catalog_state_populates_instance_attrs tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_does_not_invent_keys tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_drops_falsy_reasoning tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_drops_none_reasoning_content tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_minimal_has_only_role_and_content tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_all_six_fields_together tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_codex_message_items tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_codex_reasoning_items tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_empty_reasoning_content tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_finish_reason tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_reasoning tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_reasoning_content tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_assistant_preserves_reasoning_details tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_replay_fields_constant_is_stable tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_tool_message_has_only_role_and_content tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_unrelated_keys_are_ignored tests/gateway/test_replay_entry_fields.py::TestBuildReplayEntry::test_user_message_has_only_role_and_content tests/gateway/test_reply_to_injection.py::test_no_prefix_when_reply_to_text_is_empty tests/gateway/test_reply_to_injection.py::test_no_prefix_without_reply_context tests/gateway/test_reply_to_injection.py::test_own_message_reply_prefix_marks_assistant_message tests/gateway/test_reply_to_injection.py::test_reply_prefix_injected_when_text_absent_from_history tests/gateway/test_reply_to_injection.py::test_reply_prefix_still_injected_when_text_in_history tests/gateway/test_reply_to_injection.py::test_reply_snippet_truncated_to_500_chars tests/gateway/test_response_filters.py::test_blank_and_prose_mentions_are_not_silence tests/gateway/test_response_filters.py::test_exact_silence_tokens_are_intentional_silence tests/gateway/test_response_filters.py::test_failed_agent_result_never_counts_as_intentional_silence tests/gateway/test_restart_drain.py::test_drain_queue_mode_queues_follow_up_without_interrupt tests/gateway/test_restart_drain.py::test_draining_rejects_new_session_messages tests/gateway/test_restart_drain.py::test_launch_detached_restart_command_uses_setsid tests/gateway/test_restart_drain.py::test_load_busy_input_mode_prefers_env_then_config_then_default tests/gateway/test_restart_drain.py::test_load_busy_text_mode_follows_input_mode_and_honors_legacy tests/gateway/test_restart_drain.py::test_load_restart_drain_timeout_prefers_env_then_config_then_default tests/gateway/test_restart_drain.py::test_request_restart_is_idempotent tests/gateway/test_restart_drain.py::test_restart_command_while_busy_requests_drain_without_interrupt tests/gateway/test_restart_drain.py::test_shutdown_notification_deduplicates_per_chat tests/gateway/test_restart_drain.py::test_shutdown_notification_home_channel_suppressed_when_flag_disabled tests/gateway/test_restart_drain.py::test_shutdown_notification_ignores_pending_sentinels tests/gateway/test_restart_drain.py::test_shutdown_notification_says_restarting_when_restart_requested tests/gateway/test_restart_drain.py::test_shutdown_notification_send_failure_does_not_block tests/gateway/test_restart_drain.py::test_shutdown_notification_sent_to_active_sessions tests/gateway/test_restart_drain.py::test_shutdown_notification_skipped_when_no_active_agents tests/gateway/test_restart_drain.py::test_shutdown_notification_suppressed_when_flag_disabled tests/gateway/test_restart_drain.py::test_shutdown_notification_uses_persisted_origin_for_colon_ids tests/gateway/test_restart_drain.py::test_windows_detached_restart_scrubs_gateway_marker tests/gateway/test_restart_drain.py::test_windows_gateway_venv_imports_add_site_packages tests/gateway/test_restart_notification.py::test_planned_restart_notification_pending_roundtrip tests/gateway/test_restart_notification.py::test_restart_command_preserves_thread_id tests/gateway/test_restart_notification.py::test_restart_command_uses_atomic_json_writes_for_marker_files tests/gateway/test_restart_notification.py::test_restart_command_uses_detached_without_systemd tests/gateway/test_restart_notification.py::test_restart_command_uses_service_restart_under_systemd tests/gateway/test_restart_notification.py::test_restart_command_writes_notify_file tests/gateway/test_restart_notification.py::test_restart_notification_pending_false_without_marker tests/gateway/test_restart_notification.py::test_restart_notification_pending_true_with_marker tests/gateway/test_restart_notification.py::test_restart_shutdown_notification_anchors_telegram_dm_topic tests/gateway/test_restart_notification.py::test_send_home_channel_startup_notification_default_flag_true tests/gateway/test_restart_notification.py::test_send_home_channel_startup_notification_does_not_skip_different_thread tests/gateway/test_restart_notification.py::test_send_home_channel_startup_notification_ignores_false_send_result tests/gateway/test_restart_notification.py::test_send_home_channel_startup_notification_preserves_thread_metadata tests/gateway/test_restart_notification.py::test_send_home_channel_startup_notification_skipped_when_flag_disabled tests/gateway/test_restart_notification.py::test_send_home_channel_startup_notification_skips_restart_target tests/gateway/test_restart_notification.py::test_send_home_channel_startup_notification_to_configured_home tests/gateway/test_restart_notification.py::test_send_restart_notification_cleans_up_on_send_failure tests/gateway/test_restart_notification.py::test_send_restart_notification_delivers_and_cleans_up tests/gateway/test_restart_notification.py::test_send_restart_notification_logs_info_on_sendresult_success tests/gateway/test_restart_notification.py::test_send_restart_notification_logs_warning_on_sendresult_failure tests/gateway/test_restart_notification.py::test_send_restart_notification_noop_when_no_file tests/gateway/test_restart_notification.py::test_send_restart_notification_skipped_when_flag_disabled tests/gateway/test_restart_notification.py::test_send_restart_notification_skips_when_adapter_missing tests/gateway/test_restart_notification.py::test_send_restart_notification_with_thread tests/gateway/test_restart_notification.py::test_sethome_preserves_thread_target_for_same_process_restart tests/gateway/test_restart_notification.py::test_sethome_updates_running_config_for_same_process_restart tests/gateway/test_restart_notification.py::test_shutdown_notifications_use_cached_live_thread_source_when_origin_missing tests/gateway/test_restart_redelivery_dedup.py::test_corrupt_marker_file_is_treated_as_absent tests/gateway/test_restart_redelivery_dedup.py::test_different_platform_bypasses_dedup tests/gateway/test_restart_redelivery_dedup.py::test_event_without_update_id_bypasses_dedup tests/gateway/test_restart_redelivery_dedup.py::test_fresh_restart_with_higher_update_id_is_processed tests/gateway/test_restart_redelivery_dedup.py::test_no_marker_file_allows_restart tests/gateway/test_restart_redelivery_dedup.py::test_redelivered_restart_with_older_update_id_is_ignored tests/gateway/test_restart_redelivery_dedup.py::test_redelivered_restart_with_same_update_id_is_ignored tests/gateway/test_restart_redelivery_dedup.py::test_restart_handler_writes_dedup_marker_with_update_id tests/gateway/test_restart_redelivery_dedup.py::test_stale_marker_older_than_5min_does_not_block tests/gateway/test_restart_resume_pending.py::TestClearResumePending::test_clears_flag tests/gateway/test_restart_resume_pending.py::TestClearResumePending::test_returns_false_for_unknown_key tests/gateway/test_restart_resume_pending.py::TestClearResumePending::test_returns_false_when_not_pending tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_auto_continue_freshness_window_default_when_unset tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_auto_continue_freshness_window_empty_falls_back tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_auto_continue_freshness_window_malformed_falls_back tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_auto_continue_freshness_window_reads_env tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_coerce_datetime tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_coerce_epoch_milliseconds tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_coerce_epoch_seconds tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_coerce_iso_string tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_coerce_iso_string_with_z_suffix tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_coerce_numeric_string tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_coerce_rejects_garbage tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_is_fresh_unknown_is_fresh tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_is_fresh_window_bounds tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_is_fresh_zero_window_always_fresh tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_last_transcript_timestamp_empty tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_last_transcript_timestamp_row_without_timestamp tests/gateway/test_restart_resume_pending.py::TestFreshnessHelpers::test_last_transcript_timestamp_skips_meta tests/gateway/test_restart_resume_pending.py::TestGetOrCreateResumePending::test_resume_pending_preserves_session_id tests/gateway/test_restart_resume_pending.py::TestGetOrCreateResumePending::test_suspended_overrides_resume_pending tests/gateway/test_restart_resume_pending.py::TestGetOrCreateResumePending::test_suspended_still_creates_new_session tests/gateway/test_restart_resume_pending.py::TestMarkResumePending::test_custom_reason_persists tests/gateway/test_restart_resume_pending.py::TestMarkResumePending::test_does_not_override_suspended tests/gateway/test_restart_resume_pending.py::TestMarkResumePending::test_marks_existing_session tests/gateway/test_restart_resume_pending.py::TestMarkResumePending::test_returns_false_for_unknown_key tests/gateway/test_restart_resume_pending.py::TestMarkResumePending::test_survives_roundtrip_through_json tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_fresh_tool_tail_preserves_auto_continue_note tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_freshness_gate_disabled_via_zero_window tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_legacy_history_without_timestamps_still_injects tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_no_note_when_nothing_to_resume tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_no_resume_pending_preserves_tool_tail_note tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_resume_pending_empty_message_reports_recovery tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_resume_pending_fires_without_tool_tail tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_resume_pending_note_warns_against_reexecuting_restart tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_resume_pending_restart_note_mentions_restart tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_resume_pending_shutdown_note_mentions_shutdown tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_resume_pending_subsumes_tool_tail_note tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_stale_resume_pending_does_not_inject_restart_note tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_stale_tool_tail_does_not_inject_auto_continue_note tests/gateway/test_restart_resume_pending.py::TestResumePendingSystemNote::test_stale_tool_tail_with_production_data_shape tests/gateway/test_restart_resume_pending.py::TestSessionEntryResumeFields::test_defaults tests/gateway/test_restart_resume_pending.py::TestSessionEntryResumeFields::test_from_dict_legacy_without_resume_fields tests/gateway/test_restart_resume_pending.py::TestSessionEntryResumeFields::test_malformed_timestamp_is_tolerated tests/gateway/test_restart_resume_pending.py::TestSessionEntryResumeFields::test_roundtrip_with_resume_fields tests/gateway/test_restart_resume_pending.py::TestStuckLoopEscalation::test_clear_restart_failure_count_uses_atomic_json_write_when_entries_remain tests/gateway/test_restart_resume_pending.py::TestStuckLoopEscalation::test_escalation_via_stuck_loop_counter_overrides_resume_pending tests/gateway/test_restart_resume_pending.py::TestStuckLoopEscalation::test_increment_restart_failure_counts_uses_atomic_json_write tests/gateway/test_restart_resume_pending.py::TestStuckLoopEscalation::test_successful_turn_flow_clears_both_counter_and_resume_pending tests/gateway/test_restart_resume_pending.py::TestSuspendRecentlyActiveSkipsResumePending::test_non_resume_pending_gets_resume_pending tests/gateway/test_restart_resume_pending.py::TestSuspendRecentlyActiveSkipsResumePending::test_resume_pending_entries_not_suspended tests/gateway/test_restart_resume_pending.py::test_auto_resume_runs_agent_exactly_once_through_full_path tests/gateway/test_restart_resume_pending.py::test_auto_resume_sentinel_cleaned_on_task_failure tests/gateway/test_restart_resume_pending.py::test_auto_resume_sets_sentinel_before_task_execution tests/gateway/test_restart_resume_pending.py::test_auto_resume_skips_sessions_with_running_agent tests/gateway/test_restart_resume_pending.py::test_drain_timeout_marks_resume_pending tests/gateway/test_restart_resume_pending.py::test_drain_timeout_skips_pending_sentinel_sessions tests/gateway/test_restart_resume_pending.py::test_drain_timeout_uses_restart_reason_when_restarting tests/gateway/test_restart_resume_pending.py::test_reconnect_reschedule_is_platform_scoped tests/gateway/test_restart_resume_pending.py::test_reconnect_reschedules_pending_after_late_platform_connect tests/gateway/test_restart_resume_pending.py::test_restart_banner_uses_try_to_resume_wording tests/gateway/test_restart_resume_pending.py::test_restart_home_channel_notification_dedupes_active_chat tests/gateway/test_restart_resume_pending.py::test_restart_home_channel_notification_ignores_false_send_result tests/gateway/test_restart_resume_pending.py::test_restart_home_channel_notification_not_deduped_across_threads tests/gateway/test_restart_resume_pending.py::test_restart_notifies_home_channel_even_without_active_sessions tests/gateway/test_restart_resume_pending.py::test_resume_pending_is_cleared_only_after_successful_turn tests/gateway/test_restart_resume_pending.py::test_startup_auto_resume_includes_crash_recovery tests/gateway/test_restart_resume_pending.py::test_startup_auto_resume_schedules_fresh_pending_sessions tests/gateway/test_restart_resume_pending.py::test_startup_auto_resume_skips_disallowed_reasons tests/gateway/test_restart_resume_pending.py::test_startup_auto_resume_skips_stale_entries tests/gateway/test_restart_resume_pending.py::test_startup_auto_resume_skips_suspended_and_originless tests/gateway/test_restart_resume_pending.py::test_startup_auto_resume_skips_when_adapter_unavailable tests/gateway/test_restart_resume_pending.py::test_startup_restore_gate_queues_real_inbound_messages tests/gateway/test_restart_resume_pending.py::test_startup_restore_waits_for_resume_before_draining_inbound tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_list_named_sessions_when_no_arg tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_list_shows_usage_when_no_titled tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_no_session_db tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_already_on_session tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_auto_lineage tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_by_index tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_by_name tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_clears_running_agent tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_evicts_cached_agent tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_follows_compression_continuation tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_index_out_of_range tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_nonexistent_name tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_resolves_by_session_id tests/gateway/test_resume_command.py::TestHandleResumeCommand::test_resume_strips_outer_brackets tests/gateway/test_resume_command.py::TestHandleSessionsCommand::test_gateway_dispatches_sessions_command tests/gateway/test_resume_command.py::TestHandleSessionsCommand::test_sessions_all_full_lists_cross_platform_unnamed_sessions tests/gateway/test_resume_command.py::TestHandleSessionsCommand::test_sessions_command_lists_current_platform_sessions tests/gateway/test_retry_replacement.py::test_gateway_retry_replaces_last_user_turn_in_transcript tests/gateway/test_retry_replacement.py::test_gateway_retry_replays_original_text_not_retry_command tests/gateway/test_retry_response.py::test_retry_no_previous_message tests/gateway/test_retry_response.py::test_retry_returns_response_not_none tests/gateway/test_run_cleanup_progress.py::test_cleanup_chains_with_existing_callback tests/gateway/test_run_cleanup_progress.py::test_cleanup_noop_on_adapter_without_delete_support tests/gateway/test_run_cleanup_progress.py::test_cleanup_off_by_default_leaves_bubbles tests/gateway/test_run_cleanup_progress.py::test_cleanup_registers_callback_and_deletes_on_success tests/gateway/test_run_cleanup_progress.py::test_cleanup_skipped_on_failed_run tests/gateway/test_run_progress_interrupt.py::test_baseline_non_interrupted_agent_renders_progress tests/gateway/test_run_progress_interrupt.py::test_progress_suppressed_when_agent_is_interrupted tests/gateway/test_run_progress_topics.py::test_all_mode_default_truncation_40_chars tests/gateway/test_run_progress_topics.py::test_all_mode_no_truncation_when_preview_fits tests/gateway/test_run_progress_topics.py::test_all_mode_respects_custom_preview_length tests/gateway/test_run_progress_topics.py::test_base_processing_releases_post_delivery_callback_after_main_send tests/gateway/test_run_progress_topics.py::test_base_processing_stops_typing_before_hung_post_delivery_callback tests/gateway/test_run_progress_topics.py::test_consecutive_terminal_progress_collapses_headers tests/gateway/test_run_progress_topics.py::test_display_streaming_does_not_enable_gateway_streaming tests/gateway/test_run_progress_topics.py::test_keep_typing_stops_immediately_when_interrupt_event_is_set tests/gateway/test_run_progress_topics.py::test_run_agent_bluebubbles_uses_commentary_send_path_for_quick_replies tests/gateway/test_run_progress_topics.py::test_run_agent_defers_background_review_notification_until_release tests/gateway/test_run_progress_topics.py::test_run_agent_drops_interim_commentary_after_generation_invalidation tests/gateway/test_run_progress_topics.py::test_run_agent_drops_tool_progress_after_generation_invalidation tests/gateway/test_run_progress_topics.py::test_run_agent_feishu_progress_replies_inside_existing_thread tests/gateway/test_run_progress_topics.py::test_run_agent_interim_commentary_works_with_tool_progress_off tests/gateway/test_run_progress_topics.py::test_run_agent_matrix_streaming_omits_cursor tests/gateway/test_run_progress_topics.py::test_run_agent_previewed_final_marks_already_sent tests/gateway/test_run_progress_topics.py::test_run_agent_progress_does_not_use_event_message_id_for_telegram_dm tests/gateway/test_run_progress_topics.py::test_run_agent_progress_edits_keep_originating_topic_metadata tests/gateway/test_run_progress_topics.py::test_run_agent_progress_stays_in_originating_topic tests/gateway/test_run_progress_topics.py::test_run_agent_progress_uses_event_message_id_for_slack_dm tests/gateway/test_run_progress_topics.py::test_run_agent_queued_message_does_not_treat_commentary_as_final tests/gateway/test_run_progress_topics.py::test_run_agent_rolls_progress_bubble_before_platform_limit tests/gateway/test_run_progress_topics.py::test_run_agent_streaming_does_not_enable_completed_interim_commentary tests/gateway/test_run_progress_topics.py::test_run_agent_suppresses_interim_commentary_when_disabled tests/gateway/test_run_progress_topics.py::test_run_agent_surfaces_interim_commentary_by_default tests/gateway/test_run_progress_topics.py::test_run_agent_surfaces_real_interim_commentary tests/gateway/test_run_progress_topics.py::test_run_agent_tool_progress_does_not_control_interim_commentary tests/gateway/test_run_progress_topics.py::test_terminal_progress_no_bash_block_in_verbose_mode tests/gateway/test_run_progress_topics.py::test_terminal_progress_renders_fenced_code_block tests/gateway/test_run_progress_topics.py::test_terminal_progress_verbose_shows_full_command tests/gateway/test_run_progress_topics.py::test_transformed_response_edits_streamed_message_in_place tests/gateway/test_run_progress_topics.py::test_verbose_mode_does_not_truncate_args_by_default tests/gateway/test_run_progress_topics.py::test_verbose_mode_respects_explicit_tool_preview_length tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_case_insensitive_drive_letter tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_case_insensitive_extensions[MEDIA:C:\\path\\file.GIF] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_case_insensitive_extensions[MEDIA:C:\\path\\file.JPG] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_case_insensitive_extensions[MEDIA:C:\\path\\file.MP4] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_case_insensitive_extensions[MEDIA:C:\\path\\file.jpeg] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_invalid_paths_dont_match[MEDIA:/path/to/file.unknown] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_invalid_paths_dont_match[MEDIA:/path/to/file] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_invalid_paths_dont_match[MEDIA:C:file.png] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_invalid_paths_dont_match[MEDIA:] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_invalid_paths_dont_match[MEDIA:file.png] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_invalid_paths_dont_match[MEDIA:relative/path/file.png] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_invalid_paths_dont_match[No MEDIA tag here] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_multiple_media_tags_in_content tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_pre_fix_pattern_rejects_windows[MEDIA:C:\\Users\\test\\image.png] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_pre_fix_pattern_rejects_windows[MEDIA:C:\\path\\file.jpg] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_pre_fix_pattern_rejects_windows[MEDIA:D:/data/report.pdf] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_unix_paths_still_match[MEDIA:/home/user/docs/file.txt-/home/user/docs/file.txt] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_unix_paths_still_match[MEDIA:/tmp/output.png-/tmp/output.png] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_unix_paths_still_match[MEDIA:/var/log/report.pdf-/var/log/report.pdf] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_unix_paths_still_match[MEDIA:~/Documents/report.pdf-~/Documents/report.pdf] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_unix_paths_still_match[MEDIA:~/Downloads/image.jpg-~/Downloads/image.jpg] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:C:/Users/test/image.png-C:/Users/test/image.png] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:C:\\Users/test\\image.webp-C:\\Users/test\\image.webp] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:C:\\Users\\test\\image.png-C:\\Users\\test\\image.png] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:D:/data/report.pdf-D:/data/report.pdf] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:D:\\data\\report.pdf-D:\\data\\report.pdf] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:E:\\Photos\\vacation.jpg-E:\\Photos\\vacation.jpg] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:F:\\videos\\clip.mp4-F:\\videos\\clip.mp4] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:G:\\audio\\song.mp3-G:\\audio\\song.mp3] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:H:\\docs\\sheet.xlsx-H:\\docs\\sheet.xlsx] tests/gateway/test_run_tool_media_re.py::TestToolMediaReWindowsPaths::test_windows_paths_match[MEDIA:Z:\\archive\\backup.zip-Z:\\archive\\backup.zip] tests/gateway/test_runner_fatal_adapter.py::test_runner_queues_retryable_runtime_fatal_for_reconnection tests/gateway/test_runner_fatal_adapter.py::test_runner_requests_clean_exit_for_nonretryable_startup_conflict tests/gateway/test_runner_startup_failures.py::test_runner_allows_cron_only_mode_when_no_platforms_are_enabled tests/gateway/test_runner_startup_failures.py::test_runner_degrades_gracefully_when_all_adapters_missing tests/gateway/test_runner_startup_failures.py::test_runner_records_connected_platform_state_on_success tests/gateway/test_runner_startup_failures.py::test_runner_stays_alive_for_retryable_startup_errors tests/gateway/test_runner_startup_failures.py::test_runner_warns_when_docker_gateway_lacks_explicit_output_mount tests/gateway/test_runner_startup_failures.py::test_start_gateway_replace_aborts_when_force_killed_pid_still_alive tests/gateway/test_runner_startup_failures.py::test_start_gateway_replace_clears_marker_on_permission_denied tests/gateway/test_runner_startup_failures.py::test_start_gateway_replace_force_uses_terminate_pid tests/gateway/test_runner_startup_failures.py::test_start_gateway_replace_writes_takeover_marker_before_sigterm tests/gateway/test_runner_startup_failures.py::test_start_gateway_verbosity_imports_redacting_formatter tests/gateway/test_running_agent_session_toggles.py::test_btw_dispatches_mid_run tests/gateway/test_running_agent_session_toggles.py::test_fast_rejected_mid_run tests/gateway/test_running_agent_session_toggles.py::test_reasoning_rejected_mid_run tests/gateway/test_running_agent_session_toggles.py::test_verbose_dispatches_mid_run tests/gateway/test_running_agent_session_toggles.py::test_yolo_dispatches_mid_run tests/gateway/test_runtime_config_env_expansion.py::test_gateway_runtime_loaders_expand_env_var_templates[agent:\n reasoning_effort: ${REASONING_LEVEL}\n-REASONING_LEVEL-high-_load_reasoning_config-expected1] tests/gateway/test_runtime_config_env_expansion.py::test_gateway_runtime_loaders_expand_env_var_templates[agent:\n restart_drain_timeout: ${DRAIN_TIMEOUT}\n-DRAIN_TIMEOUT-12-_load_restart_drain_timeout-12.0] tests/gateway/test_runtime_config_env_expansion.py::test_gateway_runtime_loaders_expand_env_var_templates[agent:\n service_tier: ${SERVICE_TIER}\n-SERVICE_TIER-priority-_load_service_tier-priority] tests/gateway/test_runtime_config_env_expansion.py::test_gateway_runtime_loaders_expand_env_var_templates[agent:\n system_prompt: ${GW_PROMPT}\n-GW_PROMPT-expanded prompt-_load_ephemeral_system_prompt-expanded prompt] tests/gateway/test_runtime_config_env_expansion.py::test_gateway_runtime_loaders_expand_env_var_templates[display:\n background_process_notifications: ${BG_MODE}\n-BG_MODE-error-_load_background_notifications_mode-error] tests/gateway/test_runtime_config_env_expansion.py::test_gateway_runtime_loaders_expand_env_var_templates[display:\n busy_input_mode: ${BUSY_MODE}\n-BUSY_MODE-steer-_load_busy_input_mode-steer] tests/gateway/test_runtime_config_env_expansion.py::test_load_prefill_messages_accepts_legacy_agent_key tests/gateway/test_runtime_config_env_expansion.py::test_load_prefill_messages_expands_env_var_path tests/gateway/test_runtime_config_env_expansion.py::test_load_prefill_messages_prefers_top_level_over_legacy tests/gateway/test_runtime_env_reload_config_authority.py::test_current_max_iterations_reloads_before_reading tests/gateway/test_runtime_env_reload_config_authority.py::test_reload_runtime_env_keeps_env_max_iterations_when_config_omits_key tests/gateway/test_runtime_env_reload_config_authority.py::test_reload_runtime_env_preserves_config_max_turns tests/gateway/test_runtime_footer.py::test_build_footer_empty_when_disabled tests/gateway/test_runtime_footer.py::test_build_footer_no_data_returns_empty_even_when_enabled tests/gateway/test_runtime_footer.py::test_build_footer_per_platform_off_suppresses tests/gateway/test_runtime_footer.py::test_build_footer_returns_rendered_when_enabled tests/gateway/test_runtime_footer.py::test_format_footer_all_fields tests/gateway/test_runtime_footer.py::test_format_footer_context_pct_clamped_to_100 tests/gateway/test_runtime_footer.py::test_format_footer_context_pct_never_negative tests/gateway/test_runtime_footer.py::test_format_footer_custom_field_order tests/gateway/test_runtime_footer.py::test_format_footer_drops_cwd_when_empty tests/gateway/test_runtime_footer.py::test_format_footer_empty_fields_returns_empty tests/gateway/test_runtime_footer.py::test_format_footer_skips_missing_context_length tests/gateway/test_runtime_footer.py::test_format_footer_unknown_field_silently_ignored tests/gateway/test_runtime_footer.py::test_home_relative_cwd_collapses_home tests/gateway/test_runtime_footer.py::test_home_relative_cwd_empty_returns_empty tests/gateway/test_runtime_footer.py::test_home_relative_cwd_leaves_abs_path_alone tests/gateway/test_runtime_footer.py::test_model_short_drops_vendor_prefix[-] tests/gateway/test_runtime_footer.py::test_model_short_drops_vendor_prefix[None-] tests/gateway/test_runtime_footer.py::test_model_short_drops_vendor_prefix[anthropic/claude-sonnet-4.6-claude-sonnet-4.6] tests/gateway/test_runtime_footer.py::test_model_short_drops_vendor_prefix[gpt-5.4-gpt-5.4] tests/gateway/test_runtime_footer.py::test_model_short_drops_vendor_prefix[openai/gpt-5.4-gpt-5.4] tests/gateway/test_runtime_footer.py::test_resolve_defaults_off_empty_config tests/gateway/test_runtime_footer.py::test_resolve_global_enable tests/gateway/test_runtime_footer.py::test_resolve_ignores_malformed_config tests/gateway/test_runtime_footer.py::test_resolve_platform_can_add_fields_only tests/gateway/test_runtime_footer.py::test_resolve_platform_override_wins tests/gateway/test_safe_adapter_disconnect.py::test_safe_disconnect_calls_adapter_disconnect tests/gateway/test_safe_adapter_disconnect.py::test_safe_disconnect_handles_none_platform tests/gateway/test_safe_adapter_disconnect.py::test_safe_disconnect_swallows_exceptions tests/gateway/test_safe_adapter_disconnect.py::test_safe_disconnect_times_out_and_continues tests/gateway/test_send_image_file.py::TestDiscordSendImageFile::test_handles_missing_channel tests/gateway/test_send_image_file.py::TestDiscordSendImageFile::test_returns_error_when_file_missing tests/gateway/test_send_image_file.py::TestDiscordSendImageFile::test_returns_error_when_not_connected tests/gateway/test_send_image_file.py::TestDiscordSendImageFile::test_send_document_uploads_file_attachment tests/gateway/test_send_image_file.py::TestDiscordSendImageFile::test_send_video_uploads_file_attachment tests/gateway/test_send_image_file.py::TestDiscordSendImageFile::test_sends_local_image_as_attachment tests/gateway/test_send_image_file.py::TestExtractMediaImages::test_jpg_image_extracted tests/gateway/test_send_image_file.py::TestExtractMediaImages::test_mixed_audio_and_image tests/gateway/test_send_image_file.py::TestExtractMediaImages::test_png_image_extracted tests/gateway/test_send_image_file.py::TestExtractMediaImages::test_webp_image_extracted tests/gateway/test_send_image_file.py::TestScreenshotCleanup::test_cleanup_handles_empty_dir tests/gateway/test_send_image_file.py::TestScreenshotCleanup::test_cleanup_handles_nonexistent_dir tests/gateway/test_send_image_file.py::TestScreenshotCleanup::test_cleanup_ignores_non_screenshot_files tests/gateway/test_send_image_file.py::TestScreenshotCleanup::test_cleanup_is_throttled_per_directory tests/gateway/test_send_image_file.py::TestScreenshotCleanup::test_cleanup_removes_old_screenshots tests/gateway/test_send_image_file.py::TestSlackSendImageFile::test_returns_error_when_file_missing tests/gateway/test_send_image_file.py::TestSlackSendImageFile::test_returns_error_when_not_connected tests/gateway/test_send_image_file.py::TestSlackSendImageFile::test_sends_local_image_via_upload tests/gateway/test_send_image_file.py::TestTelegramSendImageFile::test_caption_truncated_to_1024 tests/gateway/test_send_image_file.py::TestTelegramSendImageFile::test_returns_error_when_file_missing tests/gateway/test_send_image_file.py::TestTelegramSendImageFile::test_returns_error_when_not_connected tests/gateway/test_send_image_file.py::TestTelegramSendImageFile::test_sends_local_image_as_photo tests/gateway/test_send_image_file.py::TestTelegramSendImageFile::test_thread_id_forwarded tests/gateway/test_send_multiple_images.py::TestBaseDefaultLoop::test_empty_batch_is_noop tests/gateway/test_send_multiple_images.py::TestBaseDefaultLoop::test_loops_per_image_by_default tests/gateway/test_send_multiple_images.py::TestDiscordMultiImage::test_batch_over_10_chunks_into_two_messages tests/gateway/test_send_multiple_images.py::TestDiscordMultiImage::test_empty_noop tests/gateway/test_send_multiple_images.py::TestDiscordMultiImage::test_single_batch_of_local_files_sends_once tests/gateway/test_send_multiple_images.py::TestEmailMultiImage::test_empty_noop tests/gateway/test_send_multiple_images.py::TestEmailMultiImage::test_local_files_attached_in_single_email tests/gateway/test_send_multiple_images.py::TestEmailMultiImage::test_remote_urls_linked_in_body tests/gateway/test_send_multiple_images.py::TestMattermostMultiImage::test_batch_over_5_chunks tests/gateway/test_send_multiple_images.py::TestMattermostMultiImage::test_empty_noop tests/gateway/test_send_multiple_images.py::TestMattermostMultiImage::test_local_files_uploaded_and_single_post tests/gateway/test_send_multiple_images.py::TestSlackMultiImage::test_batch_over_10_chunks tests/gateway/test_send_multiple_images.py::TestSlackMultiImage::test_empty_noop tests/gateway/test_send_multiple_images.py::TestSlackMultiImage::test_single_batch_of_local_files_sends_one_upload tests/gateway/test_send_multiple_images.py::TestTelegramMultiImage::test_animations_routed_to_send_animation tests/gateway/test_send_multiple_images.py::TestTelegramMultiImage::test_batch_over_10_chunks tests/gateway/test_send_multiple_images.py::TestTelegramMultiImage::test_empty_noop tests/gateway/test_send_multiple_images.py::TestTelegramMultiImage::test_fallback_to_per_image_on_send_media_group_failure tests/gateway/test_send_multiple_images.py::TestTelegramMultiImage::test_single_batch_under_10_calls_send_media_group_once tests/gateway/test_send_retry.py::TestIsRetryableError::test_bad_request_not_retryable tests/gateway/test_send_retry.py::TestIsRetryableError::test_case_insensitive tests/gateway/test_send_retry.py::TestIsRetryableError::test_connect_timeout_is_retryable tests/gateway/test_send_retry.py::TestIsRetryableError::test_empty_string_is_not_retryable tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[broken pipe] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[connecterror] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[connectionerror] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[connectionrefused] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[connectionreset] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[connecttimeout] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[eoferror] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[network] tests/gateway/test_send_retry.py::TestIsRetryableError::test_known_pattern_is_retryable[remotedisconnected] tests/gateway/test_send_retry.py::TestIsRetryableError::test_none_is_not_retryable tests/gateway/test_send_retry.py::TestIsRetryableError::test_permission_error_not_retryable tests/gateway/test_send_retry.py::TestIsRetryableError::test_timed_out_not_retryable tests/gateway/test_send_retry.py::TestIsRetryableError::test_timeout_not_retryable tests/gateway/test_send_retry.py::TestIsTimeoutError::test_connect_timeout_not_flagged tests/gateway/test_send_retry.py::TestIsTimeoutError::test_connection_error_not_timeout tests/gateway/test_send_retry.py::TestIsTimeoutError::test_empty_is_not_timeout tests/gateway/test_send_retry.py::TestIsTimeoutError::test_none_is_not_timeout tests/gateway/test_send_retry.py::TestIsTimeoutError::test_read_timeout tests/gateway/test_send_retry.py::TestIsTimeoutError::test_timed_out tests/gateway/test_send_retry.py::TestIsTimeoutError::test_write_timeout tests/gateway/test_send_retry.py::TestSendWithRetryExhausted::test_notice_send_exception_doesnt_propagate tests/gateway/test_send_retry.py::TestSendWithRetryExhausted::test_sends_user_notice_after_exhaustion tests/gateway/test_send_retry.py::TestSendWithRetryFallback::test_fallback_failure_logged_but_not_raised tests/gateway/test_send_retry.py::TestSendWithRetryFallback::test_non_network_error_falls_back_immediately tests/gateway/test_send_retry.py::TestSendWithRetryNetworkRetry::test_connect_timeout_still_retried tests/gateway/test_send_retry.py::TestSendWithRetryNetworkRetry::test_network_to_nonnetwork_transition_falls_back_to_plaintext tests/gateway/test_send_retry.py::TestSendWithRetryNetworkRetry::test_retries_on_connect_error_and_succeeds tests/gateway/test_send_retry.py::TestSendWithRetryNetworkRetry::test_retryable_flag_respected tests/gateway/test_send_retry.py::TestSendWithRetryNetworkRetry::test_timeout_not_retried_to_prevent_duplicates tests/gateway/test_send_retry.py::TestSendWithRetrySuccess::test_returns_message_id tests/gateway/test_send_retry.py::TestSendWithRetrySuccess::test_success_first_attempt tests/gateway/test_send_voice_reply_notify.py::test_voice_reply_marks_existing_thread_metadata_without_mutation tests/gateway/test_send_voice_reply_notify.py::test_voice_reply_marks_metadata_notify_true_for_dm tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_bluebubbles_prompt_mentions_short_conversational_i_message_format tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_discord_prompt tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_discord_prompt_with_channel_topic tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_dm_thread_shows_user_not_multi tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_local_delivery_path_uses_display_hermes_home tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_local_prompt_mentions_machine tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_multi_user_thread_prompt tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_non_thread_group_shows_user tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_prompt_omits_channel_topic_when_none tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_shared_non_thread_group_prompt_hides_single_user tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_slack_prompt_includes_platform_notes tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_telegram_prompt_contains_platform_and_chat tests/gateway/test_session.py::TestBuildSessionContextPrompt::test_whatsapp_prompt tests/gateway/test_session.py::TestHasAnySessions::test_fallback_without_database tests/gateway/test_session.py::TestHasAnySessions::test_first_session_ever_returns_false tests/gateway/test_session.py::TestHasAnySessions::test_uses_database_count_when_available tests/gateway/test_session.py::TestLastPromptTokens::test_session_entry_default tests/gateway/test_session.py::TestLastPromptTokens::test_session_entry_from_old_data tests/gateway/test_session.py::TestLastPromptTokens::test_session_entry_roundtrip tests/gateway/test_session.py::TestLastPromptTokens::test_update_session_none_does_not_change tests/gateway/test_session.py::TestLastPromptTokens::test_update_session_sets_last_prompt_tokens tests/gateway/test_session.py::TestLastPromptTokens::test_update_session_zero_resets tests/gateway/test_session.py::TestLoadTranscriptDBOnly::test_db_only_returns_empty_for_nonexistent tests/gateway/test_session.py::TestLoadTranscriptDBOnly::test_db_only_returns_messages tests/gateway/test_session.py::TestLocalCliFactory::test_local_cli_defaults tests/gateway/test_session.py::TestRewriteTranscriptPreservesReasoning::test_db_rewrite_is_atomic_on_insert_failure tests/gateway/test_session.py::TestRewriteTranscriptPreservesReasoning::test_reasoning_survives_rewrite tests/gateway/test_session.py::TestSenderPrefixWithBackfill::test_backfill_prefix_only_on_trigger tests/gateway/test_session.py::TestSenderPrefixWithBackfill::test_backfill_preserves_context_block tests/gateway/test_session.py::TestSenderPrefixWithBackfill::test_plain_message_gets_prefix tests/gateway/test_session.py::TestSessionSourceDescription::test_channel_type tests/gateway/test_session.py::TestSessionSourceDescription::test_dm_with_username tests/gateway/test_session.py::TestSessionSourceDescription::test_dm_without_username_falls_back_to_user_id tests/gateway/test_session.py::TestSessionSourceDescription::test_group_shows_chat_name tests/gateway/test_session.py::TestSessionSourceDescription::test_local_cli tests/gateway/test_session.py::TestSessionSourceDescription::test_thread_id_appended tests/gateway/test_session.py::TestSessionSourceDescription::test_unknown_chat_type_uses_name tests/gateway/test_session.py::TestSessionSourceRoundtrip::test_chat_id_coerced_to_string tests/gateway/test_session.py::TestSessionSourceRoundtrip::test_full_roundtrip tests/gateway/test_session.py::TestSessionSourceRoundtrip::test_full_roundtrip_with_chat_topic tests/gateway/test_session.py::TestSessionSourceRoundtrip::test_minimal_roundtrip tests/gateway/test_session.py::TestSessionSourceRoundtrip::test_missing_optional_fields tests/gateway/test_session.py::TestSessionSourceRoundtrip::test_unknown_platform_rejected_for_bad_names tests/gateway/test_session.py::TestSessionStoreEntriesAttribute::test_entries_attribute_exists tests/gateway/test_session.py::TestSessionStoreLookupBySessionId::test_returns_active_entry_for_persisted_session_id tests/gateway/test_session.py::TestSessionStoreRewriteTranscript::test_rewrite_replaces_transcript tests/gateway/test_session.py::TestSessionStoreRewriteTranscript::test_rewrite_with_empty_list tests/gateway/test_session.py::TestSessionStoreSwitchSession::test_switch_session_reopens_target_session_in_db tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_canonical_empty_input tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_canonical_walks_lid_mapping tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_canonical_without_mapping_returns_normalized tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_normalize_handles_bare_numeric tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_normalize_handles_empty_and_none tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_normalize_strips_device_suffix tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_normalize_strips_jid_suffix tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_normalize_strips_leading_plus tests/gateway/test_session.py::TestWhatsAppIdentifierPublicHelpers::test_normalize_strips_lid_suffix tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_discord_group_includes_chat_id tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_discord_thread_sessions_shared_by_default tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_distinct_dm_chat_ids_get_distinct_session_keys tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_dm_thread_sessions_not_affected tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_dm_without_chat_id_distinct_users_do_not_collide tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_dm_without_chat_id_falls_back_to_user_id tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_dm_without_chat_id_or_user_id_falls_back_to_thread_then_sink tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_dm_without_chat_id_prefers_user_id_alt tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_group_sessions_are_isolated_per_user_when_user_id_present tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_group_sessions_can_be_shared_when_isolation_disabled tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_group_thread_includes_thread_id tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_group_thread_sessions_are_shared_by_default tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_group_thread_sessions_can_be_isolated_per_user tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_non_thread_group_sessions_still_isolated_per_user tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_store_creates_distinct_group_sessions_per_user tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_store_delegates_to_build_session_key tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_store_shares_group_sessions_when_disabled_in_config tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_telegram_dm_includes_chat_id tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_whatsapp_dm_aliases_share_one_session_key tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_whatsapp_dm_uses_canonical_identifier tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_whatsapp_group_participant_aliases_share_session_key tests/gateway/test_session.py::TestWhatsAppSessionKeyConsistency::test_whatsapp_group_shared_sessions_untouched_by_canonicalisation tests/gateway/test_session_api.py::test_capabilities_advertises_session_control_surface tests/gateway/test_session_api.py::test_run_agent_binds_api_session_context_for_tool_env tests/gateway/test_session_api.py::test_session_chat_accepts_multimodal_message tests/gateway/test_session_api.py::test_session_chat_loads_history_and_preserves_session_headers tests/gateway/test_session_api.py::test_session_chat_stream_accepts_multimodal_message tests/gateway/test_session_api.py::test_session_chat_stream_emits_lifecycle_events_and_keepalive_safe_shape tests/gateway/test_session_api.py::test_session_chat_stream_run_completed_carries_turn_transcript tests/gateway/test_session_api.py::test_session_crud_and_message_history tests/gateway/test_session_api.py::test_session_endpoints_require_auth_when_key_configured tests/gateway/test_session_api.py::test_session_fork_uses_current_sessiondb_branch_primitives tests/gateway/test_session_api.py::test_session_header_rejected_without_api_key tests/gateway/test_session_api.py::test_session_messages_follow_compression_tip tests/gateway/test_session_boundary_hooks.py::test_finalize_before_reset tests/gateway/test_session_boundary_hooks.py::test_hook_error_does_not_break_reset tests/gateway/test_session_boundary_hooks.py::test_idle_expiry_fires_finalize_hook tests/gateway/test_session_boundary_hooks.py::test_reset_fires_finalize_hook tests/gateway/test_session_boundary_hooks.py::test_reset_fires_reset_hook tests/gateway/test_session_boundary_hooks.py::test_shutdown_fires_finalize_for_active_agents tests/gateway/test_session_boundary_security_state.py::test_branch_clears_session_scoped_approval_and_yolo_state tests/gateway/test_session_boundary_security_state.py::test_branch_preserves_persisted_assistant_metadata tests/gateway/test_session_boundary_security_state.py::test_clear_session_boundary_security_state_is_scoped tests/gateway/test_session_boundary_security_state.py::test_clear_session_boundary_security_state_wakes_blocked_approvals tests/gateway/test_session_boundary_security_state.py::test_resume_clears_session_scoped_approval_and_yolo_state tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolation::test_existing_thread_session_preserved tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolation::test_multiple_threads_are_independent tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolation::test_parent_transcript_unaffected_by_thread tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolation::test_thread_session_starts_empty tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolationCrossPlatform::test_thread_starts_empty_across_platforms[Platform.DISCORD] tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolationCrossPlatform::test_thread_starts_empty_across_platforms[Platform.SLACK] tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolationCrossPlatform::test_thread_starts_empty_across_platforms[Platform.TELEGRAM] tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolationEdgeCases::test_dm_without_thread_starts_empty tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolationEdgeCases::test_group_thread_starts_empty tests/gateway/test_session_dm_thread_seeding.py::TestDMThreadIsolationEdgeCases::test_thread_without_parent_session_starts_empty tests/gateway/test_session_env.py::test_clear_session_env_restores_previous_state tests/gateway/test_session_env.py::test_get_session_env_default_when_nothing_set tests/gateway/test_session_env.py::test_get_session_env_falls_back_to_os_environ tests/gateway/test_session_env.py::test_run_in_executor_with_context_forwards_args tests/gateway/test_session_env.py::test_run_in_executor_with_context_preserves_session_env tests/gateway/test_session_env.py::test_run_in_executor_with_context_propagates_exceptions tests/gateway/test_session_env.py::test_session_id_set_via_contextvars tests/gateway/test_session_env.py::test_session_key_falls_back_to_os_environ tests/gateway/test_session_env.py::test_session_key_no_race_condition_with_contextvars tests/gateway/test_session_env.py::test_session_key_set_via_contextvars tests/gateway/test_session_env.py::test_session_source_uses_contextvars tests/gateway/test_session_env.py::test_set_session_env_handles_missing_optional_fields tests/gateway/test_session_env.py::test_set_session_env_includes_session_key tests/gateway/test_session_env.py::test_set_session_env_sets_contextvars tests/gateway/test_session_hygiene.py::TestEstimatedTokenThreshold::test_no_multiplier_means_same_threshold_for_estimated_and_actual tests/gateway/test_session_hygiene.py::TestEstimatedTokenThreshold::test_overestimate_fires_early_but_safely tests/gateway/test_session_hygiene.py::TestEstimatedTokenThreshold::test_threshold_below_context_for_128k_model tests/gateway/test_session_hygiene.py::TestEstimatedTokenThreshold::test_threshold_below_context_for_200k_model tests/gateway/test_session_hygiene.py::TestEstimatedTokenThreshold::test_warn_threshold_below_context tests/gateway/test_session_hygiene.py::TestSessionHygieneThresholds::test_custom_threshold_percentage tests/gateway/test_session_hygiene.py::TestSessionHygieneThresholds::test_large_token_count_triggers tests/gateway/test_session_hygiene.py::TestSessionHygieneThresholds::test_message_count_alone_does_not_trigger tests/gateway/test_session_hygiene.py::TestSessionHygieneThresholds::test_minimum_message_guard tests/gateway/test_session_hygiene.py::TestSessionHygieneThresholds::test_small_session_below_thresholds tests/gateway/test_session_hygiene.py::TestSessionHygieneThresholds::test_threshold_scales_with_model tests/gateway/test_session_hygiene.py::TestSessionHygieneThresholds::test_under_threshold_no_trigger tests/gateway/test_session_hygiene.py::TestSessionHygieneWarnThreshold::test_no_warn_when_under tests/gateway/test_session_hygiene.py::TestSessionHygieneWarnThreshold::test_warn_when_still_large tests/gateway/test_session_hygiene.py::TestTokenEstimation::test_empty_history tests/gateway/test_session_hygiene.py::TestTokenEstimation::test_pathological_session_detected tests/gateway/test_session_hygiene.py::TestTokenEstimation::test_proportional_to_content tests/gateway/test_session_hygiene.py::TestTokenEstimation::test_proportional_to_count tests/gateway/test_session_hygiene.py::test_session_hygiene_default_hard_message_limit_does_not_fire_at_12_messages tests/gateway/test_session_hygiene.py::test_session_hygiene_honors_configurable_hard_message_limit tests/gateway/test_session_hygiene.py::test_session_hygiene_informs_user_when_aux_model_fails_but_recovers tests/gateway/test_session_hygiene.py::test_session_hygiene_messages_stay_in_originating_topic tests/gateway/test_session_hygiene.py::test_session_hygiene_warns_user_when_compression_aborts tests/gateway/test_session_info.py::TestFormatSessionInfo::test_cloud_endpoint_hidden tests/gateway/test_session_info.py::TestFormatSessionInfo::test_config_context_length tests/gateway/test_session_info.py::TestFormatSessionInfo::test_default_fallback_hint tests/gateway/test_session_info.py::TestFormatSessionInfo::test_includes_model_name tests/gateway/test_session_info.py::TestFormatSessionInfo::test_includes_provider tests/gateway/test_session_info.py::TestFormatSessionInfo::test_local_endpoint_shown tests/gateway/test_session_info.py::TestFormatSessionInfo::test_million_context_format tests/gateway/test_session_info.py::TestFormatSessionInfo::test_missing_config tests/gateway/test_session_info.py::TestFormatSessionInfo::test_runtime_resolution_failure_doesnt_crash tests/gateway/test_session_list_allowed_sources.py::test_session_list_default_limit_is_200 tests/gateway/test_session_list_allowed_sources.py::test_session_list_preserves_ordering_after_filter tests/gateway/test_session_list_allowed_sources.py::test_session_list_respects_explicit_limit tests/gateway/test_session_list_allowed_sources.py::test_session_list_surfaces_all_user_facing_sources tests/gateway/test_session_model_override_routing.py::test_background_task_prefers_session_override_over_global_runtime tests/gateway/test_session_model_override_routing.py::test_gateway_auth_fallback_resolves_key_env_for_custom_provider tests/gateway/test_session_model_override_routing.py::test_gateway_auth_fallback_uses_fallback_model_from_config tests/gateway/test_session_model_override_routing.py::test_run_agent_prefers_session_override_over_global_runtime tests/gateway/test_session_model_reset.py::test_new_command_clears_session_model_override tests/gateway/test_session_model_reset.py::test_new_command_no_override_is_noop tests/gateway/test_session_model_reset.py::test_new_command_only_clears_own_session tests/gateway/test_session_override_thread_recovery.py::test_normalize_passthrough_when_no_recovery tests/gateway/test_session_override_thread_recovery.py::test_normalize_rewrites_lobby_thread_to_bound_topic tests/gateway/test_session_override_thread_recovery.py::test_normalize_swallows_recovery_exceptions tests/gateway/test_session_override_thread_recovery.py::test_override_key_matches_message_turn_key_after_recovery tests/gateway/test_session_race_guard.py::test_active_session_bypass_commands_dispatch_without_interrupt[/commands-_handle_commands_command-Commands text] tests/gateway/test_session_race_guard.py::test_active_session_bypass_commands_dispatch_without_interrupt[/help-_handle_help_command-Help text] tests/gateway/test_session_race_guard.py::test_active_session_bypass_commands_dispatch_without_interrupt[/profile-_handle_profile_command-Profile text] tests/gateway/test_session_race_guard.py::test_active_session_bypass_commands_dispatch_without_interrupt[/update-_handle_update_command-Update text] tests/gateway/test_session_race_guard.py::test_command_messages_do_not_leave_sentinel tests/gateway/test_session_race_guard.py::test_merge_pending_message_event_merges_text_and_photo_followups tests/gateway/test_session_race_guard.py::test_merge_pending_message_event_promotes_document_followups_over_text tests/gateway/test_session_race_guard.py::test_recent_telegram_followups_append_in_pending_queue tests/gateway/test_session_race_guard.py::test_recent_telegram_text_followup_is_queued_without_interrupt tests/gateway/test_session_race_guard.py::test_second_message_during_sentinel_queued_not_duplicate tests/gateway/test_session_race_guard.py::test_sentinel_cleaned_up_after_handler_returns tests/gateway/test_session_race_guard.py::test_sentinel_cleaned_up_on_exception tests/gateway/test_session_race_guard.py::test_sentinel_placed_before_agent_setup tests/gateway/test_session_race_guard.py::test_shutdown_skips_sentinel tests/gateway/test_session_race_guard.py::test_start_command_is_noop_and_does_not_show_help tests/gateway/test_session_race_guard.py::test_start_command_is_noop_during_active_session tests/gateway/test_session_race_guard.py::test_stop_clears_pending_messages tests/gateway/test_session_race_guard.py::test_stop_during_sentinel_force_cleans_session tests/gateway/test_session_race_guard.py::test_stop_hard_kills_running_agent tests/gateway/test_session_reset_notify.py::TestResetPolicyNotify::test_from_dict_preserves_defaults_on_missing_keys tests/gateway/test_session_reset_notify.py::TestResetPolicyNotify::test_from_dict_with_custom_excludes tests/gateway/test_session_reset_notify.py::TestResetPolicyNotify::test_from_dict_with_notify_false tests/gateway/test_session_reset_notify.py::TestResetPolicyNotify::test_notify_defaults_true tests/gateway/test_session_reset_notify.py::TestResetPolicyNotify::test_notify_exclude_defaults tests/gateway/test_session_reset_notify.py::TestResetPolicyNotify::test_to_dict_roundtrip tests/gateway/test_session_reset_notify.py::TestSessionEntryAutoResetRoundtrip::test_auto_reset_reason_none_roundtrip tests/gateway/test_session_reset_notify.py::TestSessionEntryAutoResetRoundtrip::test_reset_had_activity_persists_across_roundtrip tests/gateway/test_session_reset_notify.py::TestSessionEntryAutoResetRoundtrip::test_was_auto_reset_persists_across_roundtrip tests/gateway/test_session_reset_notify.py::TestSessionEntryReason::test_auto_reset_reason_stored tests/gateway/test_session_reset_notify.py::TestSessionEntryReason::test_reset_had_activity_false_when_no_tokens tests/gateway/test_session_reset_notify.py::TestSessionEntryReason::test_reset_had_activity_true_when_tokens_used tests/gateway/test_session_reset_notify.py::TestShouldResetReason::test_returns_daily_when_daily_boundary_crossed tests/gateway/test_session_reset_notify.py::TestShouldResetReason::test_returns_idle_when_idle_expired tests/gateway/test_session_reset_notify.py::TestShouldResetReason::test_returns_none_when_mode_is_none tests/gateway/test_session_reset_notify.py::TestShouldResetReason::test_returns_none_when_not_expired tests/gateway/test_session_split_brain_11016.py::TestAdapterSessionCancellation::test_command_cancels_active_task_and_unblocks_follow_up[/new] tests/gateway/test_session_split_brain_11016.py::TestAdapterSessionCancellation::test_command_cancels_active_task_and_unblocks_follow_up[/reset] tests/gateway/test_session_split_brain_11016.py::TestAdapterSessionCancellation::test_command_cancels_active_task_and_unblocks_follow_up[/stop] tests/gateway/test_session_split_brain_11016.py::TestAdapterSessionCancellation::test_new_keeps_guard_until_command_finishes_then_runs_follow_up tests/gateway/test_session_split_brain_11016.py::TestOldTaskCannotClobberNewerGuard::test_release_session_guard_matches_on_event_identity tests/gateway/test_session_split_brain_11016.py::TestOldTaskCannotClobberNewerGuard::test_release_session_guard_without_guard_releases_unconditionally tests/gateway/test_session_split_brain_11016.py::TestRunnerSessionGenerationGuard::test_is_session_run_current_tracks_bumps tests/gateway/test_session_split_brain_11016.py::TestRunnerSessionGenerationGuard::test_release_with_current_generation_clears_slot tests/gateway/test_session_split_brain_11016.py::TestRunnerSessionGenerationGuard::test_release_with_stale_generation_blocks tests/gateway/test_session_split_brain_11016.py::TestRunnerSessionGenerationGuard::test_release_without_generation_behaves_as_before tests/gateway/test_session_split_brain_11016.py::TestStaleSessionLockSelfHeal::test_live_owner_task_is_not_stale tests/gateway/test_session_split_brain_11016.py::TestStaleSessionLockSelfHeal::test_no_owner_task_is_not_treated_as_stale tests/gateway/test_session_split_brain_11016.py::TestStaleSessionLockSelfHeal::test_stale_lock_with_done_task_is_healed_on_next_message tests/gateway/test_session_state_cleanup.py::TestNoMoreBareDeleteSites::test_no_bare_del_of_running_agents_in_gateway_run tests/gateway/test_session_state_cleanup.py::TestReleaseRunningAgentStateUnit::test_concurrent_release_is_safe tests/gateway/test_session_state_cleanup.py::TestReleaseRunningAgentStateUnit::test_handles_missing_busy_ack_attribute tests/gateway/test_session_state_cleanup.py::TestReleaseRunningAgentStateUnit::test_idempotent_on_missing_key tests/gateway/test_session_state_cleanup.py::TestReleaseRunningAgentStateUnit::test_noop_on_empty_session_key tests/gateway/test_session_state_cleanup.py::TestReleaseRunningAgentStateUnit::test_pops_all_three_dicts tests/gateway/test_session_state_cleanup.py::TestReleaseRunningAgentStateUnit::test_preserves_other_sessions tests/gateway/test_session_state_cleanup.py::TestSessionDbCloseOnShutdown::test_shutdown_tolerates_close_raising tests/gateway/test_session_state_cleanup.py::TestSessionDbCloseOnShutdown::test_shutdown_tolerates_missing_session_store tests/gateway/test_session_state_cleanup.py::TestSessionDbCloseOnShutdown::test_stop_impl_closes_both_session_dbs tests/gateway/test_session_state_cleanup.py::TestSessionResetZombieRace::test_generation_guard_blocks_then_unconditional_release_evicts tests/gateway/test_session_state_cleanup.py::TestSessionResetZombieRace::test_normal_completion_is_not_evicted_by_outer_release tests/gateway/test_session_store_prune.py::TestGatewayConfigSerialization::test_session_store_max_age_days_bad_type_falls_back tests/gateway/test_session_store_prune.py::TestGatewayConfigSerialization::test_session_store_max_age_days_defaults_to_90 tests/gateway/test_session_store_prune.py::TestGatewayConfigSerialization::test_session_store_max_age_days_missing_defaults_90 tests/gateway/test_session_store_prune.py::TestGatewayConfigSerialization::test_session_store_max_age_days_negative_coerced_to_zero tests/gateway/test_session_store_prune.py::TestGatewayConfigSerialization::test_session_store_max_age_days_roundtrips tests/gateway/test_session_store_prune.py::TestGatewayWatcherCallsPrune::test_prune_gate_fires_on_first_tick tests/gateway/test_session_store_prune.py::TestGatewayWatcherCallsPrune::test_prune_gate_suppresses_within_interval tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_active_check_uses_session_key_not_session_id tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_disabled_when_max_age_is_negative tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_disabled_when_max_age_is_zero tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_does_not_write_disk_when_no_removals tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_is_thread_safe tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_removes_entries_past_max_age tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_skips_entries_with_active_processes tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_skips_suspended_entries tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_uses_updated_at_not_created_at tests/gateway/test_session_store_prune.py::TestPruneBasics::test_prune_writes_disk_after_removal tests/gateway/test_session_store_prune.py::TestPrunePersistsToDisk::test_prune_rewrites_sessions_json tests/gateway/test_setup_feishu.py::TestSetupFeishuAdapterIntegration::test_group_open_env_sets_adapter_group_policy tests/gateway/test_setup_feishu.py::TestSetupFeishuAdapterIntegration::test_open_dm_env_sets_correct_adapter_state tests/gateway/test_setup_feishu.py::TestSetupFeishuAdapterIntegration::test_qr_env_produces_valid_adapter_settings tests/gateway/test_setup_feishu.py::TestSetupFeishuConnectionMode::test_manual_path_webhook tests/gateway/test_setup_feishu.py::TestSetupFeishuConnectionMode::test_manual_path_websocket tests/gateway/test_setup_feishu.py::TestSetupFeishuConnectionMode::test_qr_path_defaults_to_websocket tests/gateway/test_setup_feishu.py::TestSetupFeishuDmPolicy::test_allow_all_sets_feishu_allow_all_true tests/gateway/test_setup_feishu.py::TestSetupFeishuDmPolicy::test_allowlist_prepopulates_with_scan_owner_open_id tests/gateway/test_setup_feishu.py::TestSetupFeishuDmPolicy::test_allowlist_sets_feishu_allow_all_false_with_list tests/gateway/test_setup_feishu.py::TestSetupFeishuDmPolicy::test_pairing_sets_feishu_allow_all_false tests/gateway/test_setup_feishu.py::TestSetupFeishuGroupPolicy::test_disabled tests/gateway/test_setup_feishu.py::TestSetupFeishuGroupPolicy::test_open_with_mention tests/gateway/test_setup_feishu.py::TestSetupFeishuQrPath::test_qr_success_does_not_persist_bot_identity tests/gateway/test_setup_feishu.py::TestSetupFeishuQrPath::test_qr_success_saves_core_credentials tests/gateway/test_shared_group_sender_prefix.py::test_preprocess_keeps_plain_text_for_default_group_sessions tests/gateway/test_shared_group_sender_prefix.py::test_preprocess_prefixes_sender_for_shared_non_thread_group_session tests/gateway/test_shutdown_cache_cleanup.py::TestCachedAgentCleanupOnShutdown::test_cache_cleared_after_shutdown tests/gateway/test_shutdown_cache_cleanup.py::TestCachedAgentCleanupOnShutdown::test_cached_agent_memory_provider_shut_down tests/gateway/test_shutdown_cache_cleanup.py::TestCachedAgentCleanupOnShutdown::test_cleanup_survives_agent_exception tests/gateway/test_shutdown_cache_cleanup.py::TestCachedAgentCleanupOnShutdown::test_multiple_cached_agents_all_cleaned tests/gateway/test_shutdown_cache_cleanup.py::TestCachedAgentCleanupOnShutdown::test_no_cached_agents_no_error tests/gateway/test_shutdown_cache_cleanup.py::TestCachedAgentCleanupOnShutdown::test_none_entry_skipped tests/gateway/test_shutdown_cache_cleanup.py::TestCachedAgentCleanupOnShutdown::test_plain_agent_not_tuple tests/gateway/test_shutdown_cache_cleanup.py::TestRunningAgentsNotDoubleCleaned::test_running_and_cached_agent_cleaned_at_least_once tests/gateway/test_shutdown_forensics.py::TestCheckSystemdTimingAlignment::test_returns_none_when_not_under_systemd tests/gateway/test_shutdown_forensics.py::TestCheckSystemdTimingAlignment::test_returns_none_when_unit_undeterminable tests/gateway/test_shutdown_forensics.py::TestFormatters::test_context_as_json_handles_unserialisable_values tests/gateway/test_shutdown_forensics.py::TestFormatters::test_context_as_json_round_trips tests/gateway/test_shutdown_forensics.py::TestFormatters::test_format_context_for_log_includes_signal_and_parent tests/gateway/test_shutdown_forensics.py::TestParseSystemdDuration::test_combined_min_sec tests/gateway/test_shutdown_forensics.py::TestParseSystemdDuration::test_empty_returns_none tests/gateway/test_shutdown_forensics.py::TestParseSystemdDuration::test_hours tests/gateway/test_shutdown_forensics.py::TestParseSystemdDuration::test_milliseconds tests/gateway/test_shutdown_forensics.py::TestParseSystemdDuration::test_minutes tests/gateway/test_shutdown_forensics.py::TestParseSystemdDuration::test_seconds tests/gateway/test_shutdown_forensics.py::TestParseSystemdDuration::test_unknown_unit_returns_none tests/gateway/test_shutdown_forensics.py::TestSignalName::test_known_signals_resolve_to_names tests/gateway/test_shutdown_forensics.py::TestSignalName::test_non_integer_falls_back_to_str tests/gateway/test_shutdown_forensics.py::TestSignalName::test_none_returns_unknown tests/gateway/test_shutdown_forensics.py::TestSignalName::test_unknown_int_returns_signal_num_token tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_completes_quickly tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_detects_planned_stop_marker tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_detects_takeover_marker_for_other tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_detects_takeover_marker_for_self tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_handles_none_signal tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_includes_parent_summary_on_linux tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_includes_self_pid_and_signal tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_includes_timestamps tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_under_systemd_false_without_invocation_id_and_normal_ppid tests/gateway/test_shutdown_forensics.py::TestSnapshotShutdownContext::test_under_systemd_flag_uses_invocation_id tests/gateway/test_shutdown_forensics.py::TestSpawnAsyncDiagnostic::test_does_not_block_caller tests/gateway/test_shutdown_forensics.py::TestSpawnAsyncDiagnostic::test_handles_unwritable_log_path_gracefully tests/gateway/test_shutdown_forensics.py::TestSpawnAsyncDiagnostic::test_returns_none_on_windows tests/gateway/test_shutdown_forensics.py::TestSpawnAsyncDiagnostic::test_spawns_subprocess_and_writes_output tests/gateway/test_shutdown_memory_provider_messages.py::TestCleanupAgentResourcesPassesMessages::test_agent_without_shutdown_method_is_tolerated tests/gateway/test_shutdown_memory_provider_messages.py::TestCleanupAgentResourcesPassesMessages::test_empty_list_still_forwarded tests/gateway/test_shutdown_memory_provider_messages.py::TestCleanupAgentResourcesPassesMessages::test_missing_attribute_falls_back_to_no_arg tests/gateway/test_shutdown_memory_provider_messages.py::TestCleanupAgentResourcesPassesMessages::test_non_list_attribute_falls_back_to_no_arg tests/gateway/test_shutdown_memory_provider_messages.py::TestCleanupAgentResourcesPassesMessages::test_none_agent_is_noop tests/gateway/test_shutdown_memory_provider_messages.py::TestCleanupAgentResourcesPassesMessages::test_populated_messages_forwarded tests/gateway/test_shutdown_memory_provider_messages.py::TestCleanupAgentResourcesPassesMessages::test_provider_exception_is_swallowed tests/gateway/test_signal.py::TestSignalAdapterInit::test_init_empty_allowlist tests/gateway/test_signal.py::TestSignalAdapterInit::test_init_parses_config tests/gateway/test_signal.py::TestSignalAdapterInit::test_init_strips_trailing_slash tests/gateway/test_signal.py::TestSignalAdapterInit::test_self_message_filtering tests/gateway/test_signal.py::TestSignalAttachmentFetch::test_fetch_attachment_handles_dict_response tests/gateway/test_signal.py::TestSignalAttachmentFetch::test_fetch_attachment_returns_none_on_empty tests/gateway/test_signal.py::TestSignalAttachmentFetch::test_fetch_attachment_uses_id_parameter tests/gateway/test_signal.py::TestSignalAuthorization::test_signal_in_allowlist_maps tests/gateway/test_signal.py::TestSignalConfigLoading::test_apply_env_overrides_signal tests/gateway/test_signal.py::TestSignalConfigLoading::test_signal_not_loaded_without_both_vars tests/gateway/test_signal.py::TestSignalConnectCleanup::test_releases_lock_and_closes_client_on_healthcheck_failure tests/gateway/test_signal.py::TestSignalContentlessEnvelope::test_allows_message_with_attachment_no_text tests/gateway/test_signal.py::TestSignalContentlessEnvelope::test_allows_normal_text_message tests/gateway/test_signal.py::TestSignalContentlessEnvelope::test_skips_empty_message tests/gateway/test_signal.py::TestSignalContentlessEnvelope::test_skips_profile_key_update_no_message_field tests/gateway/test_signal.py::TestSignalContentlessEnvelope::test_skips_whitespace_only_message tests/gateway/test_signal.py::TestSignalHelpers::test_check_requirements tests/gateway/test_signal.py::TestSignalHelpers::test_check_requirements_missing tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_aac_adts_protected tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_aac_adts_unprotected tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_aac_routes_to_audio_cache tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_jpeg tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_mp3_mpeg1_layer3 tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_mp3_mpeg2_layer3 tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_mp4 tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_pdf tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_png tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_unknown tests/gateway/test_signal.py::TestSignalHelpers::test_guess_extension_zip tests/gateway/test_signal.py::TestSignalHelpers::test_is_audio_ext tests/gateway/test_signal.py::TestSignalHelpers::test_is_image_ext tests/gateway/test_signal.py::TestSignalHelpers::test_parse_comma_list tests/gateway/test_signal.py::TestSignalHelpers::test_redact_phone_empty tests/gateway/test_signal.py::TestSignalHelpers::test_redact_phone_long tests/gateway/test_signal.py::TestSignalHelpers::test_redact_phone_short tests/gateway/test_signal.py::TestSignalHelpers::test_remux_aac_to_m4a_handles_garbage tests/gateway/test_signal.py::TestSignalHelpers::test_remux_aac_to_m4a_round_trip tests/gateway/test_signal.py::TestSignalHelpers::test_render_mentions tests/gateway/test_signal.py::TestSignalHelpers::test_render_mentions_no_mentions tests/gateway/test_signal.py::TestSignalInboundMessageTypeClassification::test_pdf_attachment_sets_document_type tests/gateway/test_signal.py::TestSignalInboundMessageTypeClassification::test_text_html_attachment_sets_document_type tests/gateway/test_signal.py::TestSignalInboundMessageTypeClassification::test_text_plain_attachment_sets_document_type tests/gateway/test_signal.py::TestSignalInboundMessageTypeClassification::test_unknown_mime_attachment_falls_back_to_document tests/gateway/test_signal.py::TestSignalInboundMessageTypeClassification::test_video_attachment_sets_video_type tests/gateway/test_signal.py::TestSignalMediaExtraction::test_extract_media_finds_audio_tag tests/gateway/test_signal.py::TestSignalMediaExtraction::test_extract_media_finds_image_tag tests/gateway/test_signal.py::TestSignalMediaExtraction::test_signal_has_all_media_methods tests/gateway/test_signal.py::TestSignalPhoneRedaction::test_multiple_numbers tests/gateway/test_signal.py::TestSignalPhoneRedaction::test_short_number_not_matched tests/gateway/test_signal.py::TestSignalPhoneRedaction::test_uk_number tests/gateway/test_signal.py::TestSignalPhoneRedaction::test_us_number tests/gateway/test_signal.py::TestSignalQuoteExtraction::test_handle_envelope_marks_quote_to_own_account_author tests/gateway/test_signal.py::TestSignalQuoteExtraction::test_handle_envelope_marks_quote_to_own_sent_timestamp tests/gateway/test_signal.py::TestSignalQuoteExtraction::test_handle_envelope_quote_without_text_sets_only_reply_id tests/gateway/test_signal.py::TestSignalQuoteExtraction::test_handle_envelope_sets_reply_context_from_quote tests/gateway/test_signal.py::TestSignalQuoteExtraction::test_handle_envelope_without_quote_leaves_reply_fields_none tests/gateway/test_signal.py::TestSignalQuoteExtraction::test_track_sent_timestamp_keeps_reply_detection_cache_after_echo_discard tests/gateway/test_signal.py::TestSignalRateLimitDetection::test_detect_non_rate_limit tests/gateway/test_signal.py::TestSignalRateLimitDetection::test_detect_retry_later_exception_substring tests/gateway/test_signal.py::TestSignalRateLimitDetection::test_detect_substring_fallback tests/gateway/test_signal.py::TestSignalRateLimitDetection::test_detect_typed_code tests/gateway/test_signal.py::TestSignalRateLimitDetection::test_extract_retry_after_from_results tests/gateway/test_signal.py::TestSignalRateLimitDetection::test_extract_retry_after_missing tests/gateway/test_signal.py::TestSignalRateLimitDetection::test_extract_retry_after_parses_message_string tests/gateway/test_signal.py::TestSignalRecipientResolution::test_send_falls_back_to_phone_when_no_uuid_found tests/gateway/test_signal.py::TestSignalRecipientResolution::test_send_looks_up_uuid_via_list_contacts tests/gateway/test_signal.py::TestSignalRecipientResolution::test_send_prefers_cached_uuid_for_direct_messages tests/gateway/test_signal.py::TestSignalRecipientResolution::test_send_typing_uses_cached_uuid tests/gateway/test_signal.py::TestSignalRpcRateLimit::test_default_swallows_rate_limit_returns_none tests/gateway/test_signal.py::TestSignalRpcRateLimit::test_non_rate_limit_error_does_not_raise_when_opted_in tests/gateway/test_signal.py::TestSignalRpcRateLimit::test_raises_on_429_when_opted_in tests/gateway/test_signal.py::TestSignalRpcRateLimit::test_raises_on_rate_limit_exception_substring tests/gateway/test_signal.py::TestSignalRpcRateLimit::test_raises_on_retry_later_inside_attachment_invalid tests/gateway/test_signal.py::TestSignalRpcRateLimit::test_raises_with_retry_after_from_v0_14_3_payload tests/gateway/test_signal.py::TestSignalRpcRateLimit::test_raises_with_retry_after_none_for_old_signal_cli tests/gateway/test_signal.py::TestSignalSSEUrlEncoding::test_sse_url_encodes_plus_in_account tests/gateway/test_signal.py::TestSignalSSEUrlEncoding::test_sse_url_encoding_preserves_digits tests/gateway/test_signal.py::TestSignalSendDocumentViaHelper::test_send_document_error_includes_path tests/gateway/test_signal.py::TestSignalSendDocumentViaHelper::test_send_document_too_large tests/gateway/test_signal.py::TestSignalSendImageFile::test_send_image_file_missing tests/gateway/test_signal.py::TestSignalSendImageFile::test_send_image_file_rpc_failure tests/gateway/test_signal.py::TestSignalSendImageFile::test_send_image_file_sends_via_rpc tests/gateway/test_signal.py::TestSignalSendImageFile::test_send_image_file_to_group tests/gateway/test_signal.py::TestSignalSendImageFile::test_send_image_file_too_large tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_429_calibrates_scheduler_then_retries tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_429_without_retry_after_uses_default_rate tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_all_bad_files_no_rpc tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_empty_list_is_noop tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_full_batch_emits_pacing_notice_for_followup tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_rate_limit_exhaust_continues_to_next_batch tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_short_followup_wait_skips_pacing_notice tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_single_batch_send_does_not_pace tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_single_batch_under_limit tests/gateway/test_signal.py::TestSignalSendMultipleImages::test_skips_bad_images_in_mixed_batch tests/gateway/test_signal.py::TestSignalSendResultValidation::test_rpc_raises_rate_limit_on_results_failure tests/gateway/test_signal.py::TestSignalSendResultValidation::test_send_failure_when_results_has_failure_type tests/gateway/test_signal.py::TestSignalSendResultValidation::test_send_failure_when_results_has_success_false tests/gateway/test_signal.py::TestSignalSendResultValidation::test_send_success_when_results_has_success tests/gateway/test_signal.py::TestSignalSendReturnsMessageId::test_send_returns_none_message_id_even_with_timestamp tests/gateway/test_signal.py::TestSignalSendReturnsMessageId::test_send_returns_none_message_id_for_non_dict tests/gateway/test_signal.py::TestSignalSendReturnsMessageId::test_send_returns_none_message_id_when_no_timestamp tests/gateway/test_signal.py::TestSignalSendTimeout::test_floor_at_60s tests/gateway/test_signal.py::TestSignalSendTimeout::test_scales_with_batch_size tests/gateway/test_signal.py::TestSignalSendTimeout::test_zero_attachments_uses_default tests/gateway/test_signal.py::TestSignalSendVideo::test_send_video_missing_file tests/gateway/test_signal.py::TestSignalSendVideo::test_send_video_rpc_failure tests/gateway/test_signal.py::TestSignalSendVideo::test_send_video_sends_via_rpc tests/gateway/test_signal.py::TestSignalSendVideo::test_send_video_too_large tests/gateway/test_signal.py::TestSignalSendVoice::test_send_voice_missing_file tests/gateway/test_signal.py::TestSignalSendVoice::test_send_voice_rpc_failure tests/gateway/test_signal.py::TestSignalSendVoice::test_send_voice_sends_via_rpc tests/gateway/test_signal.py::TestSignalSendVoice::test_send_voice_to_group tests/gateway/test_signal.py::TestSignalSendVoice::test_send_voice_too_large tests/gateway/test_signal.py::TestSignalSessionSource::test_session_source_alt_fields tests/gateway/test_signal.py::TestSignalSessionSource::test_session_source_roundtrip tests/gateway/test_signal.py::TestSignalStopTyping::test_stop_typing_calls_private_method tests/gateway/test_signal.py::TestSignalStopTypingExplicitRPC::test_stop_typing_indicator_best_effort_on_recipient_failure tests/gateway/test_signal.py::TestSignalStopTypingExplicitRPC::test_stop_typing_indicator_best_effort_on_rpc_failure tests/gateway/test_signal.py::TestSignalStopTypingExplicitRPC::test_stop_typing_indicator_sends_stop_rpc_for_dm tests/gateway/test_signal.py::TestSignalStopTypingExplicitRPC::test_stop_typing_indicator_sends_stop_rpc_for_group tests/gateway/test_signal.py::TestSignalStreamingCapabilities::test_signal_declares_no_message_editing tests/gateway/test_signal.py::TestSignalTypingBackoff::test_cooldown_is_per_chat_not_global tests/gateway/test_signal.py::TestSignalTypingBackoff::test_first_failure_logs_at_warning_subsequent_at_debug tests/gateway/test_signal.py::TestSignalTypingBackoff::test_stop_typing_indicator_clears_backoff_state tests/gateway/test_signal.py::TestSignalTypingBackoff::test_success_resets_failure_counter_and_cooldown tests/gateway/test_signal.py::TestSignalTypingBackoff::test_three_consecutive_failures_trigger_cooldown tests/gateway/test_signal_format.py::TestEdgeCases::test_bold_and_italic_nested tests/gateway/test_signal_format.py::TestEdgeCases::test_bold_inside_bullet tests/gateway/test_signal_format.py::TestEdgeCases::test_code_span_with_underscores tests/gateway/test_signal_format.py::TestEdgeCases::test_consecutive_underscored_words tests/gateway/test_signal_format.py::TestEdgeCases::test_lone_asterisk tests/gateway/test_signal_format.py::TestEdgeCases::test_lone_underscore tests/gateway/test_signal_format.py::TestEdgeCases::test_mixed_formatting_no_bleed tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_bullet_list_file_paths tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_bullet_list_not_italic tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_bullet_list_with_content_before tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_bullet_with_italic_inside tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_hyphen_bullet_list_uses_signal_safe_bullets tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_italic_multi_word tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_italic_single_word tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_markdown_bullets_inside_fenced_code_are_preserved tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_multiple_italic_same_line tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_multiple_snake_case tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_plus_bullet_list_uses_signal_safe_bullets tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_snake_case_between_words tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_snake_case_not_italic tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_snake_case_path tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_star_italic_multiline_response tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_star_italic_no_cross_line tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_star_italic_still_works tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_underscore_italic_no_cross_line tests/gateway/test_signal_format.py::TestItalicFalsePositives::test_underscore_italic_still_works tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_consecutive_newlines_collapsed tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_empty_bold_not_crash tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_fenced_code_block_multiline tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_fenced_code_block_with_language_tag tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_heading_h1 tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_heading_h3 tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_links_preserved tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_multiple_headings tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_no_raw_markdown_markers_in_output tests/gateway/test_signal_format.py::TestMarkdownStripPatch::test_utf16_surrogate_pair_emoji tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_bold_double_asterisk tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_bold_double_underscore tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_empty_string tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_fenced_code_block tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_heading_becomes_bold tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_inline_monospace tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_italic_single_asterisk tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_italic_single_underscore tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_multiple_styles tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_plain_text_no_styles tests/gateway/test_signal_format.py::TestMarkdownToSignalBasic::test_strikethrough tests/gateway/test_signal_format.py::TestSignalStreamingPatch::test_send_returns_no_message_id tests/gateway/test_signal_format.py::TestSignalStreamingPatch::test_signal_does_not_support_editing tests/gateway/test_signal_format.py::TestStylePositions::test_bold_position tests/gateway/test_signal_format.py::TestStylePositions::test_emoji_utf16_offset tests/gateway/test_signal_format.py::TestStylePositions::test_italic_position tests/gateway/test_signal_format.py::TestStylePositions::test_multiple_styles_positions tests/gateway/test_signal_format.py::test_shared_helper_matches_signal_adapter_wrapper tests/gateway/test_signal_rate_limit.py::TestAcquire::test_acquire_more_tokens_than_capacity tests/gateway/test_signal_rate_limit.py::TestAcquire::test_acquire_when_empty_sleeps_for_deficit tests/gateway/test_signal_rate_limit.py::TestAcquire::test_acquire_within_capacity_no_sleep tests/gateway/test_signal_rate_limit.py::TestAcquire::test_acquire_zero_is_noop tests/gateway/test_signal_rate_limit.py::TestAcquire::test_back_to_back_acquires_drain_then_wait tests/gateway/test_signal_rate_limit.py::TestEstimateWait::test_proportional_to_deficit_when_empty tests/gateway/test_signal_rate_limit.py::TestEstimateWait::test_zero_when_bucket_has_enough tests/gateway/test_signal_rate_limit.py::TestFeedback::test_acquire_after_feedback_uses_calibrated_rate tests/gateway/test_signal_rate_limit.py::TestFeedback::test_calibrates_refill_rate_from_retry_after tests/gateway/test_signal_rate_limit.py::TestFeedback::test_none_retry_after_leaves_rate tests/gateway/test_signal_rate_limit.py::TestFeedback::test_zeros_tokens tests/gateway/test_signal_rate_limit.py::TestFifoAcquire::test_concurrent_acquires_serialize tests/gateway/test_signal_rate_limit.py::TestRefillClamping::test_refill_does_not_exceed_capacity tests/gateway/test_signal_rate_limit.py::TestSchedulerInitialState::test_default_capacity_matches_signal_cap tests/gateway/test_signal_rate_limit.py::TestSchedulerInitialState::test_default_refill_rate_from_default_retry_after tests/gateway/test_signal_rate_limit.py::TestSchedulerInitialState::test_starts_full tests/gateway/test_signal_rate_limit.py::TestSingleton::test_get_scheduler_returns_same_instance tests/gateway/test_signal_rate_limit.py::TestSingleton::test_reset_scheduler_yields_new_instance tests/gateway/test_simplex_plugin.py::test_adapter_init_custom_url tests/gateway/test_simplex_plugin.py::test_adapter_init_default_url tests/gateway/test_simplex_plugin.py::test_adapter_platform_identity tests/gateway/test_simplex_plugin.py::test_check_requirements_needs_url tests/gateway/test_simplex_plugin.py::test_check_requirements_true_when_configured tests/gateway/test_simplex_plugin.py::test_corr_id_pending_set_self_trims tests/gateway/test_simplex_plugin.py::test_corr_id_starts_with_prefix_and_tracks_pending tests/gateway/test_simplex_plugin.py::test_document_file_sets_document_type tests/gateway/test_simplex_plugin.py::test_env_enablement_home_channel_defaults_name_to_id tests/gateway/test_simplex_plugin.py::test_env_enablement_none_when_unset tests/gateway/test_simplex_plugin.py::test_env_enablement_seeds_home_channel tests/gateway/test_simplex_plugin.py::test_env_enablement_seeds_ws_url tests/gateway/test_simplex_plugin.py::test_guess_extension_jpg tests/gateway/test_simplex_plugin.py::test_guess_extension_ogg tests/gateway/test_simplex_plugin.py::test_guess_extension_png tests/gateway/test_simplex_plugin.py::test_guess_extension_unknown tests/gateway/test_simplex_plugin.py::test_handle_event_filters_own_corr_id tests/gateway/test_simplex_plugin.py::test_health_monitor_does_not_reconnect_quiet_healthy_ws tests/gateway/test_simplex_plugin.py::test_image_file_still_sets_photo_type tests/gateway/test_simplex_plugin.py::test_is_audio_ext tests/gateway/test_simplex_plugin.py::test_is_connected_mirrors_validate tests/gateway/test_simplex_plugin.py::test_is_image_ext tests/gateway/test_simplex_plugin.py::test_platform_enum_resolves_via_plugin_scan tests/gateway/test_simplex_plugin.py::test_register_calls_register_platform tests/gateway/test_simplex_plugin.py::test_send_dm tests/gateway/test_simplex_plugin.py::test_send_group tests/gateway/test_simplex_plugin.py::test_send_when_ws_not_connected_does_not_crash tests/gateway/test_simplex_plugin.py::test_standalone_send_defaults_to_local_daemon tests/gateway/test_simplex_plugin.py::test_standalone_send_missing_websockets tests/gateway/test_simplex_plugin.py::test_validate_config_uses_env_or_extra tests/gateway/test_slack.py::TestAppMentionHandler::test_app_mention_registered_on_connect tests/gateway/test_slack.py::TestAssistantThreadLifecycle::test_assistant_threads_cache_eviction tests/gateway/test_slack.py::TestAssistantThreadLifecycle::test_lifecycle_event_seeds_session_store tests/gateway/test_slack.py::TestAssistantThreadLifecycle::test_message_uses_cached_assistant_thread_identity tests/gateway/test_slack.py::TestBangPrefixCommands::test_bang_command_with_args_preserved tests/gateway/test_slack.py::TestBangPrefixCommands::test_bang_known_command_is_rewritten_to_slash tests/gateway/test_slack.py::TestBangPrefixCommands::test_bang_unknown_token_passes_through_unchanged tests/gateway/test_slack.py::TestBangPrefixCommands::test_bang_with_bot_suffix_resolves tests/gateway/test_slack.py::TestBangPrefixCommands::test_bang_works_inside_thread tests/gateway/test_slack.py::TestBangPrefixCommands::test_plain_slash_still_works tests/gateway/test_slack.py::TestEditMessage::test_edit_message_escapes_control_chars tests/gateway/test_slack.py::TestEditMessage::test_edit_message_formats_bold tests/gateway/test_slack.py::TestEditMessage::test_edit_message_formats_links tests/gateway/test_slack.py::TestEditMessage::test_edit_message_preserves_blockquotes tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_does_not_double_escape tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_formats_blockquote_in_stream tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_formats_bold_italic tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_formats_code_and_bold tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_formats_progressive_accumulation tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_formats_streaming_updates tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_formats_url_with_parens tests/gateway/test_slack.py::TestEditMessageStreamingPipeline::test_edit_message_not_connected tests/gateway/test_slack.py::TestFallbackPreservesThreadContext::test_send_document_fallback_preserves_thread tests/gateway/test_slack.py::TestFallbackPreservesThreadContext::test_send_image_file_fallback_includes_caption tests/gateway/test_slack.py::TestFallbackPreservesThreadContext::test_send_image_file_fallback_preserves_thread tests/gateway/test_slack.py::TestFallbackPreservesThreadContext::test_send_video_fallback_preserves_thread tests/gateway/test_slack.py::TestFormatMessage::test_blockquote_mixed_with_plain tests/gateway/test_slack.py::TestFormatMessage::test_blockquote_preserved tests/gateway/test_slack.py::TestFormatMessage::test_blockquote_with_code tests/gateway/test_slack.py::TestFormatMessage::test_blockquote_with_formatting tests/gateway/test_slack.py::TestFormatMessage::test_bold_conversion tests/gateway/test_slack.py::TestFormatMessage::test_bold_italic_combined tests/gateway/test_slack.py::TestFormatMessage::test_bold_italic_does_not_break_plain_bold tests/gateway/test_slack.py::TestFormatMessage::test_bold_italic_does_not_break_plain_italic tests/gateway/test_slack.py::TestFormatMessage::test_bold_italic_mixed_with_bold tests/gateway/test_slack.py::TestFormatMessage::test_bold_italic_with_surrounding_text tests/gateway/test_slack.py::TestFormatMessage::test_channel_link_preserved tests/gateway/test_slack.py::TestFormatMessage::test_channel_mention_preserved tests/gateway/test_slack.py::TestFormatMessage::test_code_block_preserved tests/gateway/test_slack.py::TestFormatMessage::test_date_formatting_preserved tests/gateway/test_slack.py::TestFormatMessage::test_emoji_shortcodes_passthrough tests/gateway/test_slack.py::TestFormatMessage::test_empty_string tests/gateway/test_slack.py::TestFormatMessage::test_escapes_control_characters tests/gateway/test_slack.py::TestFormatMessage::test_escaping_is_idempotent tests/gateway/test_slack.py::TestFormatMessage::test_everyone_mention_preserved tests/gateway/test_slack.py::TestFormatMessage::test_header_to_bold tests/gateway/test_slack.py::TestFormatMessage::test_header_with_bold_content tests/gateway/test_slack.py::TestFormatMessage::test_inline_code_preserved tests/gateway/test_slack.py::TestFormatMessage::test_italic_asterisk_conversion tests/gateway/test_slack.py::TestFormatMessage::test_italic_underscore_preserved tests/gateway/test_slack.py::TestFormatMessage::test_link_conversion tests/gateway/test_slack.py::TestFormatMessage::test_link_conversion_strips_markdown_angle_brackets tests/gateway/test_slack.py::TestFormatMessage::test_link_with_angle_brackets_and_parens tests/gateway/test_slack.py::TestFormatMessage::test_link_with_multiple_paren_pairs tests/gateway/test_slack.py::TestFormatMessage::test_link_with_parentheses_in_url tests/gateway/test_slack.py::TestFormatMessage::test_link_without_parens_still_works tests/gateway/test_slack.py::TestFormatMessage::test_literal_asterisks_with_spaces_are_not_treated_as_italic tests/gateway/test_slack.py::TestFormatMessage::test_markdown_image_does_not_create_broken_slack_link tests/gateway/test_slack.py::TestFormatMessage::test_markdown_unordered_list_with_asterisk tests/gateway/test_slack.py::TestFormatMessage::test_message_only_code_block tests/gateway/test_slack.py::TestFormatMessage::test_mixed_content tests/gateway/test_slack.py::TestFormatMessage::test_mixed_raw_and_escaped_entities tests/gateway/test_slack.py::TestFormatMessage::test_multiline_blockquote tests/gateway/test_slack.py::TestFormatMessage::test_multiline_mixed_formatting tests/gateway/test_slack.py::TestFormatMessage::test_nested_blockquote tests/gateway/test_slack.py::TestFormatMessage::test_nested_bold_in_link tests/gateway/test_slack.py::TestFormatMessage::test_non_prefix_gt_still_escaped tests/gateway/test_slack.py::TestFormatMessage::test_none_passthrough tests/gateway/test_slack.py::TestFormatMessage::test_pre_escaped_ampersand_not_double_escaped tests/gateway/test_slack.py::TestFormatMessage::test_pre_escaped_gt_not_double_escaped tests/gateway/test_slack.py::TestFormatMessage::test_pre_escaped_lt_not_double_escaped tests/gateway/test_slack.py::TestFormatMessage::test_preserves_existing_slack_entities tests/gateway/test_slack.py::TestFormatMessage::test_strikethrough tests/gateway/test_slack.py::TestFormatMessage::test_subteam_mention_preserved tests/gateway/test_slack.py::TestFormatMessage::test_url_with_query_string_and_ampersand tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_attachments_unfurl_text_is_appended_even_when_url_is_in_message tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_channel_routing_ignores_bot_mentions_inside_block_text tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_document_download_error_handled tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_download_failure_is_surfaced_in_message_text tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_file_shared_video_fallback_fetches_file_info tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_image_still_handled tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_json_snippet_injects_content tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_large_txt_not_injected tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_md_document_injects_content tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_message_unfurl_attachments_are_skipped tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_oversized_document_skipped tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_pdf_document_cached tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_quoted_slash_command_text_does_not_change_message_type tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_rich_text_blocks_do_not_duplicate_plain_text tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_rich_text_quotes_and_lists_are_extracted tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_txt_document_injects_content tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_video_attachment_cached tests/gateway/test_slack.py::TestIncomingDocumentHandling::test_zip_file_cached tests/gateway/test_slack.py::TestMessageRouting::test_bot_messages_ignored tests/gateway/test_slack.py::TestMessageRouting::test_channel_mention_strips_bot_id tests/gateway/test_slack.py::TestMessageRouting::test_channel_message_requires_mention tests/gateway/test_slack.py::TestMessageRouting::test_dm_processed_without_mention tests/gateway/test_slack.py::TestMessageRouting::test_message_edits_ignored tests/gateway/test_slack.py::TestMessageSplitting::test_long_message_split_into_chunks tests/gateway/test_slack.py::TestMessageSplitting::test_send_does_not_double_escape_entities tests/gateway/test_slack.py::TestMessageSplitting::test_send_explicitly_enables_mrkdwn tests/gateway/test_slack.py::TestMessageSplitting::test_send_formats_bold_italic tests/gateway/test_slack.py::TestMessageSplitting::test_send_formats_url_with_parens tests/gateway/test_slack.py::TestMessageSplitting::test_send_preserves_blockquote_formatting tests/gateway/test_slack.py::TestMessageSplitting::test_short_message_single_send tests/gateway/test_slack.py::TestProgressMessageThread::test_channel_mention_progress_uses_thread_ts tests/gateway/test_slack.py::TestProgressMessageThread::test_dm_toplevel_progress_uses_message_ts_as_thread tests/gateway/test_slack.py::TestProgressMessageThread::test_dm_toplevel_shares_session_when_disabled tests/gateway/test_slack.py::TestReactions::test_add_reaction_calls_api tests/gateway/test_slack.py::TestReactions::test_add_reaction_handles_error tests/gateway/test_slack.py::TestReactions::test_reactions_disabled_via_env tests/gateway/test_slack.py::TestReactions::test_reactions_enabled_by_default tests/gateway/test_slack.py::TestReactions::test_reactions_failure_outcome tests/gateway/test_slack.py::TestReactions::test_reactions_in_message_flow tests/gateway/test_slack.py::TestReactions::test_reactions_skipped_for_non_dm_non_mention tests/gateway/test_slack.py::TestReactions::test_remove_reaction_calls_api tests/gateway/test_slack.py::TestReplyBroadcast::test_broadcast_disabled_by_default tests/gateway/test_slack.py::TestReplyBroadcast::test_broadcast_enabled_via_config tests/gateway/test_slack.py::TestSendDocument::test_send_document_api_error_falls_back tests/gateway/test_slack.py::TestSendDocument::test_send_document_custom_name tests/gateway/test_slack.py::TestSendDocument::test_send_document_missing_file tests/gateway/test_slack.py::TestSendDocument::test_send_document_not_connected tests/gateway/test_slack.py::TestSendDocument::test_send_document_retries_transient_upload_error tests/gateway/test_slack.py::TestSendDocument::test_send_document_success tests/gateway/test_slack.py::TestSendDocument::test_send_document_thread_upload_marks_bot_participation tests/gateway/test_slack.py::TestSendDocument::test_send_document_with_thread tests/gateway/test_slack.py::TestSendImageSSRFGuards::test_send_image_blocks_private_redirect_target tests/gateway/test_slack.py::TestSendImageSSRFGuards::test_send_image_fallback_preserves_thread_metadata tests/gateway/test_slack.py::TestSendPrivateNotice::test_send_private_notice_uses_ephemeral_api tests/gateway/test_slack.py::TestSendTyping::test_handles_missing_scope_gracefully tests/gateway/test_slack.py::TestSendTyping::test_noop_without_thread tests/gateway/test_slack.py::TestSendTyping::test_send_clears_status_after_final_post tests/gateway/test_slack.py::TestSendTyping::test_sets_status_in_thread tests/gateway/test_slack.py::TestSendTyping::test_stop_typing_clears_tracked_thread tests/gateway/test_slack.py::TestSendTyping::test_stop_typing_handles_api_error_gracefully tests/gateway/test_slack.py::TestSendTyping::test_stop_typing_noop_without_tracked_thread tests/gateway/test_slack.py::TestSendTyping::test_streaming_final_edit_clears_status tests/gateway/test_slack.py::TestSendTyping::test_streaming_intermediate_edit_keeps_status tests/gateway/test_slack.py::TestSendTyping::test_uses_thread_ts_fallback tests/gateway/test_slack.py::TestSendVideo::test_send_video_api_error_falls_back tests/gateway/test_slack.py::TestSendVideo::test_send_video_missing_file tests/gateway/test_slack.py::TestSendVideo::test_send_video_not_connected tests/gateway/test_slack.py::TestSendVideo::test_send_video_success tests/gateway/test_slack.py::TestSlackConnectCleanup::test_reconnect_closes_previous_handler_to_prevent_zombie_socket tests/gateway/test_slack.py::TestSlackConnectCleanup::test_releases_platform_lock_when_auth_fails tests/gateway/test_slack.py::TestSlackProxyBehavior::test_connect_clears_proxy_when_no_proxy_matches_slack tests/gateway/test_slack.py::TestSlackProxyBehavior::test_connect_uses_proxy_when_not_bypassed tests/gateway/test_slack.py::TestSlackProxyBehavior::test_no_proxy_helper_matches_slack_hosts tests/gateway/test_slack.py::TestSlackProxyBehavior::test_resolve_slack_proxy_url_checks_all_slack_hosts tests/gateway/test_slack.py::TestSlackProxyBehavior::test_resolve_slack_proxy_url_ignores_unsupported_proxy_schemes tests/gateway/test_slack.py::TestSlackReplyToText::test_slack_reply_to_text_none_for_top_level_message tests/gateway/test_slack.py::TestSlackReplyToText::test_slack_reply_to_text_set_on_thread_reply tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_connect_replaces_prior_watchdog_atomically tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_disconnect_stops_watchdog_and_does_not_reconnect tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_reconnect_lock_prevents_concurrent_reconnects tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_reconnect_refreshes_multi_workspace_state tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_watchdog_cancellation_does_not_respawn tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_watchdog_reconnects_when_socket_task_dies_unexpectedly tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_watchdog_reconnects_when_transport_reports_disconnected tests/gateway/test_slack.py::TestSlackSocketWatchdog::test_watchdog_unexpected_exit_respawns_via_done_callback tests/gateway/test_slack.py::TestSlashCommandSessionIsolation::test_channel_slash_command_uses_group_session_semantics tests/gateway/test_slack.py::TestSlashCommandSessionIsolation::test_dm_slash_command_keeps_dm_session_semantics tests/gateway/test_slack.py::TestSlashCommands::test_background_command tests/gateway/test_slack.py::TestSlashCommands::test_compact_maps_to_compress tests/gateway/test_slack.py::TestSlashCommands::test_legacy_hermes_freeform_question tests/gateway/test_slack.py::TestSlashCommands::test_legacy_hermes_prefix_still_works tests/gateway/test_slack.py::TestSlashCommands::test_native_btw_slash tests/gateway/test_slack.py::TestSlashCommands::test_native_model_slash_with_args tests/gateway/test_slack.py::TestSlashCommands::test_native_stop_slash_no_args tests/gateway/test_slack.py::TestSlashCommands::test_reasoning_command tests/gateway/test_slack.py::TestSlashCommands::test_resume_command tests/gateway/test_slack.py::TestSlashCommands::test_usage_command tests/gateway/test_slack.py::TestSlashEphemeralAck::test_concurrent_users_same_channel_isolates_contexts tests/gateway/test_slack.py::TestSlashEphemeralAck::test_freeform_hermes_question_does_not_stash_context tests/gateway/test_slack.py::TestSlashEphemeralAck::test_legacy_hermes_slash_stashes_context tests/gateway/test_slack.py::TestSlashEphemeralAck::test_native_slash_stashes_context_and_dispatches tests/gateway/test_slack.py::TestSlashEphemeralAck::test_no_contextvar_does_not_match_any_context tests/gateway/test_slack.py::TestSlashEphemeralAck::test_pop_slash_context_discards_stale_entries tests/gateway/test_slack.py::TestSlashEphemeralAck::test_pop_slash_context_returns_and_removes tests/gateway/test_slack.py::TestSlashEphemeralAck::test_pop_slash_context_returns_none_for_no_match tests/gateway/test_slack.py::TestSlashEphemeralAck::test_send_falls_through_without_context tests/gateway/test_slack.py::TestSlashEphemeralAck::test_send_slash_ephemeral_fallback_on_exception tests/gateway/test_slack.py::TestSlashEphemeralAck::test_send_slash_ephemeral_fallback_on_post_failure tests/gateway/test_slack.py::TestSlashEphemeralAck::test_send_uses_response_url_when_context_exists tests/gateway/test_slack.py::TestSlashEphemeralAck::test_slash_command_stashes_response_url tests/gateway/test_slack.py::TestSlashEphemeralAck::test_slash_command_without_response_url_does_not_stash tests/gateway/test_slack.py::TestThreadReplyHandling::test_no_session_store_ignores_thread_replies tests/gateway/test_slack.py::TestThreadReplyHandling::test_thread_reply_with_mention_strips_bot_id tests/gateway/test_slack.py::TestThreadReplyHandling::test_thread_reply_without_mention_no_session_ignored tests/gateway/test_slack.py::TestThreadReplyHandling::test_thread_reply_without_mention_with_session_processed tests/gateway/test_slack.py::TestThreadReplyHandling::test_top_level_message_requires_mention_even_with_session tests/gateway/test_slack.py::TestUserNameResolution::test_caches_result tests/gateway/test_slack.py::TestUserNameResolution::test_falls_back_to_real_name tests/gateway/test_slack.py::TestUserNameResolution::test_handles_api_error tests/gateway/test_slack.py::TestUserNameResolution::test_resolves_display_name tests/gateway/test_slack.py::TestUserNameResolution::test_user_name_in_message_source tests/gateway/test_slack_approval_buttons.py::TestSessionKeyFix::test_no_session_returns_false tests/gateway/test_slack_approval_buttons.py::TestSessionKeyFix::test_no_session_store tests/gateway/test_slack_approval_buttons.py::TestSessionKeyFix::test_uses_build_session_key tests/gateway/test_slack_approval_buttons.py::TestSlackApprovalAction::test_deny_action tests/gateway/test_slack_approval_buttons.py::TestSlackApprovalAction::test_global_allowlist_blocks_unauthorized_click tests/gateway/test_slack_approval_buttons.py::TestSlackApprovalAction::test_prevents_double_click tests/gateway/test_slack_approval_buttons.py::TestSlackApprovalAction::test_resolves_approval tests/gateway/test_slack_approval_buttons.py::TestSlackExecApproval::test_not_connected tests/gateway/test_slack_approval_buttons.py::TestSlackExecApproval::test_sends_blocks_with_buttons tests/gateway/test_slack_approval_buttons.py::TestSlackExecApproval::test_sends_in_thread tests/gateway/test_slack_approval_buttons.py::TestSlackExecApproval::test_truncates_long_command tests/gateway/test_slack_approval_buttons.py::TestSlackInteractiveAuth::test_delegates_to_gateway_runner_auth tests/gateway/test_slack_approval_buttons.py::TestSlackSlashConfirmAction::test_global_allowlist_allows_authorized_click tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_api_failure_returns_empty tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_empty_thread tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_fetch_thread_context_current_ts_excluded tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_fetch_thread_context_excludes_self_bot_replies tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_fetch_thread_context_includes_bot_parent tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_fetch_thread_context_multi_workspace tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_fetch_thread_parent_text_from_cache tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_fetches_and_formats_context tests/gateway/test_slack_approval_buttons.py::TestSlackThreadContext::test_skips_bot_messages tests/gateway/test_slack_approval_buttons.py::TestThreadEngagement::test_bot_message_ts_cap tests/gateway/test_slack_approval_buttons.py::TestThreadEngagement::test_mentioned_threads_cap tests/gateway/test_slack_approval_buttons.py::TestThreadEngagement::test_mentioned_threads_populated_on_mention tests/gateway/test_slack_approval_buttons.py::TestThreadEngagement::test_send_tracks_bot_message_ts tests/gateway/test_slack_channel_session_scope.py::TestChannelSessionScopeDefault::test_top_level_default_behaves_like_true tests/gateway/test_slack_channel_session_scope.py::TestChannelSessionScopeDefault::test_top_level_maps_to_ts_when_reply_in_thread_true tests/gateway/test_slack_channel_session_scope.py::TestChannelSessionScopeShared::test_thread_reply_scopes_by_thread_even_when_shared tests/gateway/test_slack_channel_session_scope.py::TestChannelSessionScopeShared::test_top_level_maps_to_none_when_reply_in_thread_false tests/gateway/test_slack_channel_session_scope.py::TestChannelSessionScopeShared::test_top_level_reply_to_id_stays_none_when_shared tests/gateway/test_slack_channel_session_scope.py::TestThreadReplyAlwaysScopesByThread::test_thread_reply_keyed_by_thread_ts[False] tests/gateway/test_slack_channel_session_scope.py::TestThreadReplyAlwaysScopesByThread::test_thread_reply_keyed_by_thread_ts[True] tests/gateway/test_slack_channel_skills.py::TestSlackMessageEventAutoSkill::test_message_event_carries_auto_skill tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_dedup_preserves_order tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_empty_skill_string_returns_none tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_empty_skills_list_returns_none tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_malformed_entry_skipped tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_match_by_dm_channel_id tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_match_by_parent_id_for_thread tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_multiple_bindings_pick_correct tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_no_bindings_returns_none tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_no_match_returns_none tests/gateway/test_slack_channel_skills.py::TestSlackResolveChannelSkills::test_single_skill_string tests/gateway/test_slack_mention.py::test_allowed_channels_blocks_even_when_mentioned tests/gateway/test_slack_mention.py::test_allowed_channels_blocks_non_whitelisted_channel tests/gateway/test_slack_mention.py::test_allowed_channels_csv_string tests/gateway/test_slack_mention.py::test_allowed_channels_default_empty tests/gateway/test_slack_mention.py::test_allowed_channels_dm_unaffected tests/gateway/test_slack_mention.py::test_allowed_channels_empty_no_restriction tests/gateway/test_slack_mention.py::test_allowed_channels_empty_string tests/gateway/test_slack_mention.py::test_allowed_channels_env_var_blocks_channel tests/gateway/test_slack_mention.py::test_allowed_channels_env_var_fallback tests/gateway/test_slack_mention.py::test_allowed_channels_list tests/gateway/test_slack_mention.py::test_allowed_channels_permits_whitelisted_channel tests/gateway/test_slack_mention.py::test_bot_uid_none_processes_channel_message tests/gateway/test_slack_mention.py::test_channel_in_free_response_processed_without_mention tests/gateway/test_slack_mention.py::test_config_bridges_slack_allowed_channels tests/gateway/test_slack_mention.py::test_config_bridges_slack_allowed_channels_env_takes_precedence tests/gateway/test_slack_mention.py::test_config_bridges_slack_free_response_channels tests/gateway/test_slack_mention.py::test_config_bridges_slack_reply_in_thread tests/gateway/test_slack_mention.py::test_config_bridges_slack_strict_mention tests/gateway/test_slack_mention.py::test_default_require_mention_channel_without_mention_ignored tests/gateway/test_slack_mention.py::test_dm_always_processed_regardless_of_setting tests/gateway/test_slack_mention.py::test_explicit_platforms_slack_enabled_false_wins_over_env_token tests/gateway/test_slack_mention.py::test_explicit_top_level_slack_enabled_false_wins_over_env_token tests/gateway/test_slack_mention.py::test_free_response_channels_bare_int tests/gateway/test_slack_mention.py::test_free_response_channels_csv_string tests/gateway/test_slack_mention.py::test_free_response_channels_default_empty tests/gateway/test_slack_mention.py::test_free_response_channels_empty_string tests/gateway/test_slack_mention.py::test_free_response_channels_env_var_fallback tests/gateway/test_slack_mention.py::test_free_response_channels_int_list tests/gateway/test_slack_mention.py::test_free_response_channels_list tests/gateway/test_slack_mention.py::test_mention_in_strict_mode_does_not_register_thread tests/gateway/test_slack_mention.py::test_mention_outside_strict_mode_still_registers_thread tests/gateway/test_slack_mention.py::test_mentioned_message_always_processed tests/gateway/test_slack_mention.py::test_other_channel_not_in_free_response_still_gated tests/gateway/test_slack_mention.py::test_require_mention_defaults_to_true tests/gateway/test_slack_mention.py::test_require_mention_empty_string_stays_true tests/gateway/test_slack_mention.py::test_require_mention_env_var_default_true tests/gateway/test_slack_mention.py::test_require_mention_env_var_fallback tests/gateway/test_slack_mention.py::test_require_mention_false tests/gateway/test_slack_mention.py::test_require_mention_false_channel_without_mention_processed tests/gateway/test_slack_mention.py::test_require_mention_malformed_string_stays_true tests/gateway/test_slack_mention.py::test_require_mention_string_false tests/gateway/test_slack_mention.py::test_require_mention_string_no tests/gateway/test_slack_mention.py::test_require_mention_string_true tests/gateway/test_slack_mention.py::test_require_mention_string_yes tests/gateway/test_slack_mention.py::test_require_mention_true tests/gateway/test_slack_mention.py::test_strict_mention_defaults_to_false tests/gateway/test_slack_mention.py::test_strict_mention_env_var_fallback tests/gateway/test_slack_mention.py::test_strict_mention_false tests/gateway/test_slack_mention.py::test_strict_mention_malformed_stays_false tests/gateway/test_slack_mention.py::test_strict_mention_string_off tests/gateway/test_slack_mention.py::test_strict_mention_string_true tests/gateway/test_slack_mention.py::test_strict_mention_true tests/gateway/test_slack_mention.py::test_thread_reply_with_active_session_processed tests/gateway/test_slack_mention.py::test_thread_reply_without_active_session_ignored tests/gateway/test_slack_mention.py::test_top_level_slack_settings_do_not_disable_env_token_setup tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_constraint_dict_action_id_is_accepted tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_empty_string_action_id_raises tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_get_slack_action_handlers_returns_copy tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_multiple_plugins_each_recorded tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_non_callable_callback_raises tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_none_action_id_raises tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_regex_action_id_is_accepted tests/gateway/test_slack_plugin_action_handlers.py::TestRegisterSlackActionHandlerAPI::test_string_action_id_is_queued tests/gateway/test_slack_plugin_action_handlers.py::TestSlackAdapterPluginActionWiring::test_no_plugin_handlers_does_not_break_connect tests/gateway/test_slack_plugin_action_handlers.py::TestSlackAdapterPluginActionWiring::test_plugin_exception_does_not_propagate_to_slack tests/gateway/test_slack_plugin_action_handlers.py::TestSlackAdapterPluginActionWiring::test_plugin_handler_invoked_with_slack_args tests/gateway/test_slack_plugin_action_handlers.py::TestSlackAdapterPluginActionWiring::test_plugin_handler_wired_into_app tests/gateway/test_slack_plugin_action_handlers.py::TestSlackAdapterPluginActionWiring::test_plugin_loader_failure_does_not_break_connect tests/gateway/test_slack_plugin_action_handlers.py::TestSlackAdapterPluginActionWiring::test_wrapper_signature_only_exposes_slack_bolt_args tests/gateway/test_slash_access.py::TestPolicyForSource::test_channel_thread_chat_types_treated_as_group_scope tests/gateway/test_slash_access.py::TestPolicyForSource::test_dm_chat_type_resolves_to_dm_scope tests/gateway/test_slash_access.py::TestPolicyForSource::test_group_chat_type_resolves_to_group_scope tests/gateway/test_slash_access.py::TestPolicyForSource::test_no_admin_list_for_dm_means_unrestricted_in_dm tests/gateway/test_slash_access.py::TestPolicyForSource::test_no_config_returns_disabled tests/gateway/test_slash_access.py::TestPolicyForSource::test_no_platform_config_returns_disabled tests/gateway/test_slash_access.py::TestPolicyForSource::test_per_platform_isolation tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_admin_runs_anything tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_always_allowed_floor_for_non_admin tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_command_coercion_csv_string tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_command_coercion_strips_leading_slash_and_lowercases tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_disabled_policy_treats_anyone_as_admin tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_dm_admin_does_not_imply_group_admin tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_dm_admin_list_only tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_dm_falls_back_to_group_user_commands_when_dm_unset tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_empty_extra_is_disabled tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_group_scope_uses_group_keys tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_id_coercion_csv_string tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_id_coercion_ints_become_strings tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_non_admin_runs_only_listed_commands tests/gateway/test_slash_access.py::TestPolicyFromExtra::test_unknown_user_id_blocked tests/gateway/test_slash_access_dispatch.py::test_admin_runs_unlisted_command tests/gateway/test_slash_access_dispatch.py::test_backward_compat_no_admin_list_means_no_gate tests/gateway/test_slash_access_dispatch.py::test_dm_admin_blocked_in_group_with_separate_admin_list tests/gateway/test_slash_access_dispatch.py::test_dm_admin_is_not_group_admin tests/gateway/test_slash_access_dispatch.py::test_gate_does_not_intercept_unknown_command tests/gateway/test_slash_access_dispatch.py::test_gate_uses_canonical_name_not_alias tests/gateway/test_slash_access_dispatch.py::test_gating_isolated_per_platform tests/gateway/test_slash_access_dispatch.py::test_group_only_gating_leaves_dm_unrestricted tests/gateway/test_slash_access_dispatch.py::test_non_admin_denied_for_unlisted_command tests/gateway/test_slash_access_dispatch.py::test_non_admin_with_empty_user_commands_gets_floor_only tests/gateway/test_slash_access_dispatch.py::test_plugin_registered_command_is_gated tests/gateway/test_slash_access_dispatch.py::test_running_agent_fastpath_allows_admin_command tests/gateway/test_slash_access_dispatch.py::test_running_agent_fastpath_blocks_non_admin_command tests/gateway/test_slash_access_dispatch.py::test_running_agent_fastpath_status_always_works tests/gateway/test_slash_access_dispatch.py::test_user_runs_listed_command tests/gateway/test_slash_access_dispatch.py::test_whoami_admin_user tests/gateway/test_slash_access_dispatch.py::test_whoami_non_admin_lists_runnable_commands tests/gateway/test_slash_access_dispatch.py::test_whoami_unrestricted_when_no_admin_list tests/gateway/test_sms.py::TestSmsConfigLoading::test_env_overrides_create_sms_config tests/gateway/test_sms.py::TestSmsConfigLoading::test_env_overrides_set_home_channel tests/gateway/test_sms.py::TestSmsEchoPrevention::test_own_number_detection tests/gateway/test_sms.py::TestSmsFormatAndTruncate::test_collapses_newlines tests/gateway/test_sms.py::TestSmsFormatAndTruncate::test_strips_bold tests/gateway/test_sms.py::TestSmsFormatAndTruncate::test_strips_code_blocks tests/gateway/test_sms.py::TestSmsFormatAndTruncate::test_strips_headers tests/gateway/test_sms.py::TestSmsFormatAndTruncate::test_strips_inline_code tests/gateway/test_sms.py::TestSmsFormatAndTruncate::test_strips_italic tests/gateway/test_sms.py::TestSmsFormatAndTruncate::test_strips_links tests/gateway/test_sms.py::TestSmsRequirements::test_check_sms_requirements_both_set tests/gateway/test_sms.py::TestSmsRequirements::test_check_sms_requirements_missing_sid tests/gateway/test_sms.py::TestSmsRequirements::test_check_sms_requirements_missing_token tests/gateway/test_sms.py::TestStartupGuard::test_insecure_flag_allows_start_without_url tests/gateway/test_sms.py::TestStartupGuard::test_insecure_flag_does_not_set_fatal_error tests/gateway/test_sms.py::TestStartupGuard::test_missing_phone_number_is_non_retryable tests/gateway/test_sms.py::TestStartupGuard::test_missing_webhook_url_is_non_retryable tests/gateway/test_sms.py::TestStartupGuard::test_refuses_start_without_webhook_url tests/gateway/test_sms.py::TestStartupGuard::test_webhook_url_allows_start tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_empty_param_values_included tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_invalid_signature_rejected tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_non_standard_port_no_variant tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_params_sorted_by_key tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_port_variant_443_matches_without_port tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_port_variant_http_80 tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_port_variant_without_port_matches_443 tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_url_matters tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_valid_signature_accepted tests/gateway/test_sms.py::TestTwilioSignatureValidation::test_wrong_token_rejected tests/gateway/test_sms.py::TestWebhookHostConfig::test_default_host_is_localhost tests/gateway/test_sms.py::TestWebhookHostConfig::test_host_from_env tests/gateway/test_sms.py::TestWebhookHostConfig::test_webhook_url_from_env tests/gateway/test_sms.py::TestWebhookHostConfig::test_webhook_url_stripped tests/gateway/test_sms.py::TestWebhookSignatureEnforcement::test_insecure_flag_skips_validation tests/gateway/test_sms.py::TestWebhookSignatureEnforcement::test_insecure_flag_with_url_still_validates tests/gateway/test_sms.py::TestWebhookSignatureEnforcement::test_invalid_signature_returns_403 tests/gateway/test_sms.py::TestWebhookSignatureEnforcement::test_missing_signature_returns_403 tests/gateway/test_sms.py::TestWebhookSignatureEnforcement::test_port_variant_signature_returns_200 tests/gateway/test_sms.py::TestWebhookSignatureEnforcement::test_valid_signature_returns_200 tests/gateway/test_sse_agent_cancel.py::TestSSEAgentCancelOnDisconnect::test_agent_interrupt_called_on_disconnect tests/gateway/test_sse_agent_cancel.py::TestSSEAgentCancelOnDisconnect::test_agent_ref_none_still_cancels_task tests/gateway/test_sse_agent_cancel.py::TestSSEAgentCancelOnDisconnect::test_agent_task_cancelled_on_client_disconnect tests/gateway/test_sse_agent_cancel.py::TestSSEAgentCancelOnDisconnect::test_agent_task_not_cancelled_on_normal_completion tests/gateway/test_sse_agent_cancel.py::TestSSEAgentCancelOnDisconnect::test_already_done_task_not_cancelled_on_disconnect tests/gateway/test_sse_agent_cancel.py::TestSSEAgentCancelOnDisconnect::test_broken_pipe_also_cancels_agent tests/gateway/test_ssl_cert_detection.py::test_ensure_ssl_certs_ignores_stale_ssl_cert_file tests/gateway/test_ssl_cert_detection.py::test_ensure_ssl_certs_keeps_existing_ssl_cert_file tests/gateway/test_ssl_certs.py::TestEnsureSslCerts::test_no_op_when_nothing_found tests/gateway/test_ssl_certs.py::TestEnsureSslCerts::test_respects_existing_env_var tests/gateway/test_ssl_certs.py::TestEnsureSslCerts::test_sets_from_ssl_default_paths tests/gateway/test_status.py::TestCorruptStatusFiles::test_read_json_file_returns_none_on_binary_garbage tests/gateway/test_status.py::TestCorruptStatusFiles::test_read_json_file_still_parses_valid_json tests/gateway/test_status.py::TestCorruptStatusFiles::test_read_pid_record_returns_none_on_binary_garbage tests/gateway/test_status.py::TestCorruptStatusFiles::test_read_pid_record_still_parses_bare_pid tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_accepts_explicit_pid_path_without_cleanup tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_accepts_gateway_metadata_when_cmdline_unavailable tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_accepts_script_style_gateway_cmdline tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_cleans_stale_metadata_from_dead_foreign_pid tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_cleans_stale_record_from_dead_process tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_falls_back_to_live_lock_record tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_rejects_live_non_gateway_pid tests/gateway/test_status.py::TestGatewayPidState::test_get_running_pid_treats_pid_file_as_stale_without_runtime_lock tests/gateway/test_status.py::TestGatewayPidState::test_runtime_lock_claims_and_releases_liveness tests/gateway/test_status.py::TestGatewayPidState::test_write_pid_file_is_atomic_against_concurrent_writers tests/gateway/test_status.py::TestGatewayPidState::test_write_pid_file_records_gateway_metadata tests/gateway/test_status.py::TestGatewayRuntimeStatus::test_write_json_file_uses_atomic_json_write tests/gateway/test_status.py::TestGatewayRuntimeStatus::test_write_runtime_status_explicit_none_clears_stale_fields tests/gateway/test_status.py::TestGatewayRuntimeStatus::test_write_runtime_status_overwrites_stale_argv_on_restart tests/gateway/test_status.py::TestGatewayRuntimeStatus::test_write_runtime_status_overwrites_stale_pid_on_restart tests/gateway/test_status.py::TestGatewayRuntimeStatus::test_write_runtime_status_records_platform_failure tests/gateway/test_status.py::TestPlannedStopMarker::test_clear_planned_stop_marker_is_idempotent tests/gateway/test_status.py::TestPlannedStopMarker::test_consume_returns_false_for_different_pid tests/gateway/test_status.py::TestPlannedStopMarker::test_consume_returns_false_for_stale_marker tests/gateway/test_status.py::TestPlannedStopMarker::test_consume_returns_true_on_windows_when_start_time_unavailable tests/gateway/test_status.py::TestPlannedStopMarker::test_consume_returns_true_when_marker_names_self tests/gateway/test_status.py::TestPlannedStopMarker::test_consume_still_rejects_foreign_pid_when_start_time_unavailable tests/gateway/test_status.py::TestPlannedStopMarker::test_consume_still_rejects_start_time_mismatch_when_both_known tests/gateway/test_status.py::TestPlannedStopMarker::test_write_marker_records_target_identity tests/gateway/test_status.py::TestPlannedStopMarker::test_write_marker_returns_false_on_write_failure tests/gateway/test_status.py::TestReadProcessCmdlinePsFallback::test_proc_cmdline_takes_priority_over_ps tests/gateway/test_status.py::TestReadProcessCmdlinePsFallback::test_ps_fallback_returns_none_on_failure tests/gateway/test_status.py::TestReadProcessCmdlinePsFallback::test_ps_fallback_used_when_proc_returns_empty tests/gateway/test_status.py::TestReadProcessCmdlinePsFallback::test_ps_fallback_when_proc_unavailable tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_keeps_lock_when_cmdline_unreadable_but_record_is_gateway tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_keeps_lock_when_pid_reused_by_gateway tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_recovers_corrupt_lock_file tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_recovers_empty_lock_file tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_rejects_live_other_process tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_replaces_pid_reused_by_unrelated_process tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_replaces_reused_pid_even_with_matching_start_time tests/gateway/test_status.py::TestScopedLocks::test_acquire_scoped_lock_replaces_stale_record tests/gateway/test_status.py::TestScopedLocks::test_release_all_scoped_locks_can_target_single_owner tests/gateway/test_status.py::TestScopedLocks::test_release_all_scoped_locks_skips_pid_reuse_mismatch tests/gateway/test_status.py::TestScopedLocks::test_release_scoped_lock_only_removes_current_owner tests/gateway/test_status.py::TestScopedLocks::test_windows_file_lock_uses_high_offset tests/gateway/test_status.py::TestTakeoverMarker::test_clear_takeover_marker_is_idempotent tests/gateway/test_status.py::TestTakeoverMarker::test_consume_handles_malformed_marker_gracefully tests/gateway/test_status.py::TestTakeoverMarker::test_consume_handles_marker_with_missing_fields tests/gateway/test_status.py::TestTakeoverMarker::test_consume_ignores_marker_for_different_process_and_prevents_stale_grief tests/gateway/test_status.py::TestTakeoverMarker::test_consume_returns_false_for_different_pid tests/gateway/test_status.py::TestTakeoverMarker::test_consume_returns_false_for_stale_marker tests/gateway/test_status.py::TestTakeoverMarker::test_consume_returns_false_on_start_time_mismatch tests/gateway/test_status.py::TestTakeoverMarker::test_consume_returns_false_when_marker_missing tests/gateway/test_status.py::TestTakeoverMarker::test_consume_returns_true_on_windows_when_start_time_unavailable tests/gateway/test_status.py::TestTakeoverMarker::test_consume_returns_true_when_marker_names_self tests/gateway/test_status.py::TestTakeoverMarker::test_write_marker_records_target_identity tests/gateway/test_status.py::TestTakeoverMarker::test_write_marker_returns_false_on_write_failure tests/gateway/test_status.py::TestTerminatePid::test_force_falls_back_to_sigterm_when_taskkill_missing tests/gateway/test_status.py::TestTerminatePid::test_force_uses_taskkill_on_windows tests/gateway/test_status_command.py::test_agents_command_reports_active_agents_and_processes tests/gateway/test_status_command.py::test_first_run_non_slack_home_channel_onboarding_keeps_direct_command tests/gateway/test_status_command.py::test_first_run_slack_home_channel_onboarding_uses_parent_command tests/gateway/test_status_command.py::test_handle_message_discards_stale_result_after_session_invalidation tests/gateway/test_status_command.py::test_handle_message_persists_agent_token_counts tests/gateway/test_status_command.py::test_handle_message_stale_result_keeps_newer_generation_callback tests/gateway/test_status_command.py::test_post_delivery_callback_generation_snapshot_happens_after_bind tests/gateway/test_status_command.py::test_profile_command_reports_custom_root_profile tests/gateway/test_status_command.py::test_status_command_bypasses_active_session_guard tests/gateway/test_status_command.py::test_status_command_includes_cached_agent_model_and_context tests/gateway/test_status_command.py::test_status_command_includes_live_agent_model_and_context tests/gateway/test_status_command.py::test_status_command_includes_persisted_model_and_context_when_agent_not_running tests/gateway/test_status_command.py::test_status_command_includes_session_title_when_present tests/gateway/test_status_command.py::test_status_command_reads_token_totals_from_session_db tests/gateway/test_status_command.py::test_status_command_reports_running_agent_without_interrupt tests/gateway/test_status_command.py::test_status_command_tokens_zero_when_session_db_row_missing tests/gateway/test_status_command.py::test_tasks_alias_routes_to_agents_command tests/gateway/test_steer_command.py::test_steer_agent_without_steer_method_falls_back tests/gateway/test_steer_command.py::test_steer_calls_agent_steer_and_does_not_interrupt tests/gateway/test_steer_command.py::test_steer_rejected_payload_returns_rejection_message tests/gateway/test_steer_command.py::test_steer_with_pending_sentinel_falls_back_to_queue tests/gateway/test_steer_command.py::test_steer_without_payload_returns_usage tests/gateway/test_step_callback_compat.py::TestStepCallbackNormalization::test_dict_prev_tools_produce_string_tool_names tests/gateway/test_step_callback_compat.py::TestStepCallbackNormalization::test_empty_prev_tools tests/gateway/test_step_callback_compat.py::TestStepCallbackNormalization::test_joinable_for_hook_example tests/gateway/test_step_callback_compat.py::TestStepCallbackNormalization::test_string_prev_tools_still_work tests/gateway/test_sticker_cache.py::TestBuildAnimatedStickerInjection::test_empty_emoji_same_as_no_emoji tests/gateway/test_sticker_cache.py::TestBuildAnimatedStickerInjection::test_exact_format_with_emoji tests/gateway/test_sticker_cache.py::TestBuildAnimatedStickerInjection::test_exact_format_without_emoji tests/gateway/test_sticker_cache.py::TestBuildStickerInjection::test_description_with_quotes tests/gateway/test_sticker_cache.py::TestBuildStickerInjection::test_empty_description tests/gateway/test_sticker_cache.py::TestBuildStickerInjection::test_exact_format_emoji_and_set_name tests/gateway/test_sticker_cache.py::TestBuildStickerInjection::test_exact_format_emoji_only tests/gateway/test_sticker_cache.py::TestBuildStickerInjection::test_exact_format_no_context tests/gateway/test_sticker_cache.py::TestBuildStickerInjection::test_set_name_without_emoji_ignored tests/gateway/test_sticker_cache.py::TestCacheSticker::test_cache_and_retrieve tests/gateway/test_sticker_cache.py::TestCacheSticker::test_missing_sticker_returns_none tests/gateway/test_sticker_cache.py::TestCacheSticker::test_multiple_stickers tests/gateway/test_sticker_cache.py::TestCacheSticker::test_overwrite_existing tests/gateway/test_sticker_cache.py::TestLoadSaveCache::test_load_corrupt_file tests/gateway/test_sticker_cache.py::TestLoadSaveCache::test_load_missing_file tests/gateway/test_sticker_cache.py::TestLoadSaveCache::test_save_and_load_roundtrip tests/gateway/test_sticker_cache.py::TestLoadSaveCache::test_save_creates_parent_dirs tests/gateway/test_stop_thread_sibling.py::test_sibling_does_not_match_different_thread_same_chat tests/gateway/test_stop_thread_sibling.py::test_sibling_excludes_callers_own_key tests/gateway/test_stop_thread_sibling.py::test_sibling_finds_other_users_run_in_same_thread tests/gateway/test_stop_thread_sibling.py::test_sibling_returns_empty_for_non_thread_source tests/gateway/test_stop_thread_sibling.py::test_sibling_skips_pending_sentinel tests/gateway/test_stop_thread_sibling.py::test_stop_does_not_interrupt_sibling_when_unauthorized tests/gateway/test_stop_thread_sibling.py::test_stop_interrupts_sibling_thread_run_when_authorized tests/gateway/test_stream_consumer.py::TestBufferOnlyMode::test_default_mode_still_triggers_intermediate_edits tests/gateway/test_stream_consumer.py::TestBufferOnlyMode::test_flushes_on_commentary tests/gateway/test_stream_consumer.py::TestBufferOnlyMode::test_flushes_on_segment_break tests/gateway/test_stream_consumer.py::TestBufferOnlyMode::test_suppresses_intermediate_edits tests/gateway/test_stream_consumer.py::TestCancelledConsumerSetsFlags::test_cancelled_with_already_sent_marks_final_response_sent tests/gateway/test_stream_consumer.py::TestCancelledConsumerSetsFlags::test_cancelled_without_any_sends_does_not_mark_final tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_audio_as_voice_stripped tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_excessive_newlines_collapsed tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_media_mid_sentence tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_media_only_response tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_media_tag_stripped tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_media_tag_with_quotes tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_media_tag_with_space tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_multiple_media_tags tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_no_media_passthrough tests/gateway/test_stream_consumer.py::TestCleanForDisplay::test_preserves_non_media_colons tests/gateway/test_stream_consumer.py::TestCursorStrippingOnFallback::test_cursor_not_stripped_when_no_cursor_configured tests/gateway/test_stream_consumer.py::TestCursorStrippingOnFallback::test_cursor_strip_edit_failure_handled tests/gateway/test_stream_consumer.py::TestCursorStrippingOnFallback::test_cursor_stripped_when_continuation_empty tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[gateway.platforms.dingtalk-DingTalkAdapter] tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[gateway.platforms.feishu-FeishuAdapter] tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[gateway.platforms.matrix-MatrixAdapter] tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[gateway.platforms.slack-SlackAdapter] tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[gateway.platforms.telegram-TelegramAdapter] tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[gateway.platforms.whatsapp-WhatsAppAdapter] tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[plugins.platforms.discord.adapter-DiscordAdapter] tests/gateway/test_stream_consumer.py::TestEditMessageFinalizeSignature::test_edit_message_accepts_finalize[plugins.platforms.mattermost.adapter-MattermostAdapter] tests/gateway/test_stream_consumer.py::TestEditOverflowSplitAndDeliver::test_consumer_advances_message_id_on_split_and_deliver tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_case_insensitive_THINKING tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_closing_tag_split_across_deltas tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_complete_think_block_stripped tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_flush_think_buffer_on_non_tag tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_flush_think_buffer_when_inside_block tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_multiline_think_block tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_multiple_think_blocks tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_multiple_think_blocks_with_text_between tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_opening_tag_split_across_deltas tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_plain_text_passes_through tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_prose_mention_after_text tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_prose_mention_not_stripped tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_reasoning_scratchpad_variant tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_segment_reset_preserves_think_state tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_think_at_line_start_is_stripped tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_think_block_in_middle tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_think_block_split_across_deltas tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_think_with_only_whitespace_before tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_thinking_tag_variant tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_thought_tag_variant tests/gateway/test_stream_consumer.py::TestFilterAndAccumulate::test_unclosed_think_block_suppresses tests/gateway/test_stream_consumer.py::TestFilterAndAccumulateIntegration::test_think_block_not_sent_to_platform tests/gateway/test_stream_consumer.py::TestFinalContentDeliveredGuard::test_fallback_partial_send_does_not_mark_final_sent tests/gateway/test_stream_consumer.py::TestFinalContentDeliveredGuard::test_final_edit_success_does_mark_content_delivered tests/gateway/test_stream_consumer.py::TestFinalContentDeliveredGuard::test_mid_stream_edit_success_does_not_mark_content_delivered tests/gateway/test_stream_consumer.py::TestFinalResponseDeliveryGuard::test_split_overflow_failed_send_does_not_mark_final_sent tests/gateway/test_stream_consumer.py::TestFinalResponseDeliveryGuard::test_split_overflow_partial_send_marks_final_sent tests/gateway/test_stream_consumer.py::TestFinalizeCapabilityGate::test_identical_text_skip_respects_adapter_flag tests/gateway/test_stream_consumer.py::TestInterimCommentaryMessages::test_commentary_message_stays_separate_from_final_stream tests/gateway/test_stream_consumer.py::TestInterimCommentaryMessages::test_failed_final_send_does_not_mark_final_response_sent tests/gateway/test_stream_consumer.py::TestInterimCommentaryMessages::test_success_without_message_id_marks_visible_and_sends_only_tail tests/gateway/test_stream_consumer.py::TestOnNewMessageCallback::test_callback_error_swallowed tests/gateway/test_stream_consumer.py::TestOnNewMessageCallback::test_callback_fires_on_commentary tests/gateway/test_stream_consumer.py::TestOnNewMessageCallback::test_callback_fires_on_first_send tests/gateway/test_stream_consumer.py::TestOnNewMessageCallback::test_callback_fires_once_per_segment tests/gateway/test_stream_consumer.py::TestOnNewMessageCallback::test_callback_not_fired_on_edit tests/gateway/test_stream_consumer.py::TestOnNewMessageCallback::test_no_callback_when_none tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_already_sent_stays_true_after_segment tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_edit_failure_sends_only_unsent_tail_at_finish tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_fallback_final_deletes_partial_after_full_resend tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_fallback_final_does_not_delete_when_no_chunks_reach_user tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_fallback_final_keeps_partial_after_tail_only_send tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_fallback_final_sends_full_text_at_tool_boundary tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_fallback_final_skips_delete_when_adapter_lacks_method tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_fallback_final_splits_long_continuation_without_dropping_text tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_multiple_segment_breaks tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_no_message_id_enters_fallback_mode tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_no_message_id_segment_breaks_do_not_resend tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_no_message_id_single_delta_marks_already_sent tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_segment_break_after_mid_stream_edit_failure_preserves_tail tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_segment_break_clears_failed_edit_fallback_state tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_segment_break_creates_new_message tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_segment_break_no_text_before tests/gateway/test_stream_consumer.py::TestSegmentBreakOnToolBoundary::test_segment_break_removes_cursor tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_cursor_only_update_skips_send tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_edit_strips_media tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_first_send_strips_media tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_longer_text_with_cursor_sends_new_message tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_media_only_skips_send tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_short_text_cursor_edit_existing_message_allowed tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_short_text_with_cursor_skips_new_message tests/gateway/test_stream_consumer.py::TestSendOrEditMediaStripping::test_short_text_without_cursor_sends_normally tests/gateway/test_stream_consumer.py::TestStreamRunMediaStripping::test_stream_with_media_tag tests/gateway/test_stream_consumer.py::TestUtf16OverflowDetection::test_codepoint_only_adapter_falls_back_to_len tests/gateway/test_stream_consumer.py::TestUtf16OverflowDetection::test_emoji_text_exceeding_utf16_limit_triggers_overflow_split tests/gateway/test_stream_consumer_draft.py::TestAdapterPrefersFreshFinal::test_edit_stream_finalizes_with_fresh_send_and_deletes_preview tests/gateway/test_stream_consumer_draft.py::TestAlreadySentInDraftMode::test_drafts_do_not_set_already_sent_until_real_message tests/gateway/test_stream_consumer_draft.py::TestDraftFallbackOnFailure::test_first_draft_failure_disables_drafts_for_run tests/gateway/test_stream_consumer_draft.py::TestDraftIdLifecycle::test_consecutive_responses_use_distinct_draft_ids tests/gateway/test_stream_consumer_draft.py::TestDraftIdLifecycle::test_tool_boundary_bumps_draft_id tests/gateway/test_stream_consumer_draft.py::TestDraftStreamingHappyPath::test_dm_stream_animates_draft_then_finalizes_with_send tests/gateway/test_stream_consumer_draft.py::TestDraftStreamingHappyPath::test_group_chat_skips_draft_path tests/gateway/test_stream_consumer_draft.py::TestDraftTransportSelection::test_auto_dm_with_draft_capable_adapter_picks_draft tests/gateway/test_stream_consumer_draft.py::TestDraftTransportSelection::test_auto_group_falls_back_to_edit tests/gateway/test_stream_consumer_draft.py::TestDraftTransportSelection::test_default_transport_stays_on_edit tests/gateway/test_stream_consumer_draft.py::TestDraftTransportSelection::test_explicit_draft_unsupported_falls_back tests/gateway/test_stream_consumer_draft.py::TestDraftTransportSelection::test_explicit_edit_never_uses_drafts tests/gateway/test_stream_consumer_draft.py::TestDraftTransportSelection::test_magicmock_adapter_falls_back_to_edit tests/gateway/test_stream_consumer_draft.py::TestRichAwareOverflow::test_fresh_final_deletes_all_preview_fragments tests/gateway/test_stream_consumer_draft.py::TestRichAwareOverflow::test_long_rich_reply_not_split_and_final_is_whole tests/gateway/test_stream_consumer_draft.py::TestRichAwareOverflow::test_raw_message_limit_falls_back_to_max_length tests/gateway/test_stream_consumer_draft.py::TestRichAwareOverflow::test_raw_message_limit_mock_adapter_is_safe tests/gateway/test_stream_consumer_draft.py::TestRichAwareOverflow::test_raw_message_limit_uses_adapter_rich_cap tests/gateway/test_stream_consumer_fresh_final.py::TestCancelledBestEffortDeliveryFinalizes::test_cancel_best_effort_edit_is_finalized tests/gateway/test_stream_consumer_fresh_final.py::TestCancelledBestEffortDeliveryFinalizes::test_cancel_best_effort_failure_keeps_gateway_resend_possible tests/gateway/test_stream_consumer_fresh_final.py::TestCancelledBestEffortDeliveryFinalizes::test_cancel_with_fresh_final_enabled_delivers_and_flags_via_handler tests/gateway/test_stream_consumer_fresh_final.py::TestCancelledBestEffortDeliveryFinalizes::test_cancel_without_preview_makes_no_delivery_attempt tests/gateway/test_stream_consumer_fresh_final.py::TestFinalCleanupEditFloodControl::test_failed_final_cleanup_edit_marks_visible_content_delivered tests/gateway/test_stream_consumer_fresh_final.py::TestFinalCleanupEditFloodControl::test_failed_final_edit_does_not_mark_undelivered_tail tests/gateway/test_stream_consumer_fresh_final.py::TestFreshFinalForLongLivedPreviews::test_disabled_by_default_still_edits_in_place tests/gateway/test_stream_consumer_fresh_final.py::TestFreshFinalForLongLivedPreviews::test_fresh_final_fallback_to_edit_on_send_failure tests/gateway/test_stream_consumer_fresh_final.py::TestFreshFinalForLongLivedPreviews::test_fresh_final_without_delete_support_is_best_effort tests/gateway/test_stream_consumer_fresh_final.py::TestFreshFinalForLongLivedPreviews::test_long_lived_preview_sends_fresh_final tests/gateway/test_stream_consumer_fresh_final.py::TestFreshFinalForLongLivedPreviews::test_no_edit_sentinel_is_not_affected tests/gateway/test_stream_consumer_fresh_final.py::TestFreshFinalForLongLivedPreviews::test_only_finalize_triggers_fresh_final tests/gateway/test_stream_consumer_fresh_final.py::TestFreshFinalForLongLivedPreviews::test_short_lived_preview_edits_in_place tests/gateway/test_stream_consumer_fresh_final.py::TestGotDoneOverflowSplitNotRefinalized::test_non_split_finalize_edit_still_gets_explicit_refinalize tests/gateway/test_stream_consumer_fresh_final.py::TestGotDoneOverflowSplitNotRefinalized::test_split_finalize_edit_is_not_refinalized tests/gateway/test_stream_consumer_fresh_final.py::TestSegmentBreakDoesNotMarkFinalSent::test_final_answer_after_preamble_is_delivered_exactly_once tests/gateway/test_stream_consumer_fresh_final.py::TestSegmentBreakDoesNotMarkFinalSent::test_genuine_final_answer_without_tools_marks_delivered tests/gateway/test_stream_consumer_fresh_final.py::TestSegmentBreakDoesNotMarkFinalSent::test_multi_tool_call_turn_delivers_final_once tests/gateway/test_stream_consumer_fresh_final.py::TestSegmentBreakDoesNotMarkFinalSent::test_no_edit_adapter_delivers_final_after_preamble tests/gateway/test_stream_consumer_fresh_final.py::TestSegmentBreakDoesNotMarkFinalSent::test_preamble_fresh_final_at_tool_boundary_does_not_mark_final tests/gateway/test_stream_consumer_fresh_final.py::TestStreamConsumerConfigFreshFinalField::test_default_is_disabled tests/gateway/test_stream_consumer_fresh_final.py::TestStreamConsumerConfigFreshFinalField::test_field_is_configurable tests/gateway/test_stream_consumer_fresh_final.py::TestStreamingConfigFreshFinalField::test_default_is_disabled tests/gateway/test_stream_consumer_fresh_final.py::TestStreamingConfigFreshFinalField::test_from_dict_respects_explicit_zero tests/gateway/test_stream_consumer_fresh_final.py::TestStreamingConfigFreshFinalField::test_from_dict_uses_default_when_missing tests/gateway/test_stream_consumer_fresh_final.py::TestStreamingConfigFreshFinalField::test_to_dict_round_trip tests/gateway/test_stream_consumer_fresh_final.py::TestTelegramAdapterDeleteMessage::test_base_adapter_default_returns_false tests/gateway/test_stream_consumer_fresh_final.py::TestTelegramAdapterDeleteMessage::test_delete_message_method_exists tests/gateway/test_stream_consumer_thread_routing.py::TestFeishuFallbackThreadRouting::test_create_uses_chat_id_when_no_thread tests/gateway/test_stream_consumer_thread_routing.py::TestFeishuFallbackThreadRouting::test_create_uses_thread_id_when_available tests/gateway/test_stream_consumer_thread_routing.py::TestInitialReplyToId::test_final_first_send_marks_metadata_notify_true tests/gateway/test_stream_consumer_thread_routing.py::TestInitialReplyToId::test_first_send_uses_initial_reply_to_id tests/gateway/test_stream_consumer_thread_routing.py::TestInitialReplyToId::test_first_send_without_initial_reply_to_id tests/gateway/test_stream_consumer_thread_routing.py::TestInitialReplyToId::test_metadata_passed_on_first_send tests/gateway/test_stream_consumer_thread_routing.py::TestInitialReplyToId::test_nonfinal_first_send_does_not_mark_notify tests/gateway/test_stream_consumer_thread_routing.py::TestInitialReplyToId::test_subsequent_edits_ignore_initial_reply_to_id tests/gateway/test_stream_consumer_thread_routing.py::TestOverflowFirstMessage::test_overflow_first_send_uses_initial_reply_to_id tests/gateway/test_stream_events.py::test_adapter_can_eat_tool_chrome tests/gateway/test_stream_events.py::test_commentary_flows_to_sink tests/gateway/test_stream_events.py::test_dispatch_swallows_render_errors tests/gateway/test_stream_events.py::test_gateway_notice_routes_to_hook tests/gateway/test_stream_events.py::test_intermediate_message_stop_breaks_segment_but_final_does_not tests/gateway/test_stream_events.py::test_long_tool_hint_routes_to_hook tests/gateway/test_stream_events.py::test_message_chunk_flows_to_sink_on_delta tests/gateway/test_stream_events.py::test_message_events_dropped_when_no_sink tests/gateway/test_stream_events.py::test_new_mode_dedups_same_tool tests/gateway/test_stream_events.py::test_off_mode_emits_nothing tests/gateway/test_stream_events.py::test_tool_call_chunk_renders_default_chrome tests/gateway/test_stream_events.py::test_tool_finished_emits_no_chrome tests/gateway/test_stream_events.py::test_tool_preview_truncated_to_cap tests/gateway/test_stt_config.py::test_enrich_message_with_transcription_avoids_bogus_no_provider_message_for_backend_key_errors tests/gateway/test_stt_config.py::test_enrich_message_with_transcription_omits_duration_on_probe_failure tests/gateway/test_stt_config.py::test_enrich_message_with_transcription_returns_tuple_for_empty_content_placeholder tests/gateway/test_stt_config.py::test_enrich_message_with_transcription_surfaces_path_when_stt_disabled tests/gateway/test_stt_config.py::test_gateway_config_stt_disabled_from_dict_nested tests/gateway/test_stt_config.py::test_load_gateway_config_bridges_stt_enabled_from_config_yaml tests/gateway/test_stt_config.py::test_prepare_inbound_message_text_transcribes_queued_voice_event tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_clear_on_success tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_clear_removes_file_when_empty tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_increment_accumulates tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_increment_creates_file tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_increment_drops_inactive_sessions tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_no_file_no_crash tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_no_suspend_below_threshold tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_suspend_at_threshold tests/gateway/test_stuck_loop.py::TestStuckLoopDetection::test_suspend_clears_file tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_accepts_list_tuple_set[list] tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_accepts_list_tuple_set[set] tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_accepts_list_tuple_set[tuple] tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_rejects_truthy_non_collection_attribute tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_returns_false_for_empty_list tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_returns_false_for_none tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_returns_false_for_pending_sentinel tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_returns_false_when_attribute_missing tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_returns_true_for_many_children tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_returns_true_for_single_child tests/gateway/test_subagent_protection_30170.py::TestAgentHasActiveSubagents::test_works_without_lock tests/gateway/test_subagent_protection_30170.py::TestBusyHandlerDemotesInterruptForSubagents::test_ack_explains_the_demotion tests/gateway/test_subagent_protection_30170.py::TestBusyHandlerDemotesInterruptForSubagents::test_does_not_call_interrupt_when_subagents_active tests/gateway/test_subagent_protection_30170.py::TestBusyHandlerDemotesInterruptForSubagents::test_interrupt_still_fires_when_no_subagents tests/gateway/test_subagent_protection_30170.py::TestBusyHandlerDemotesInterruptForSubagents::test_pending_sentinel_does_not_demote tests/gateway/test_subagent_protection_30170.py::TestBusyHandlerDemotesInterruptForSubagents::test_queue_mode_unchanged_with_subagents tests/gateway/test_subagent_protection_30170.py::TestBusyHandlerDemotesInterruptForSubagents::test_steer_mode_still_routes_through_running_agent_steer tests/gateway/test_teams.py::TestTeamsAdapterInit::test_custom_port_from_env tests/gateway/test_teams.py::TestTeamsAdapterInit::test_custom_port_from_extra tests/gateway/test_teams.py::TestTeamsAdapterInit::test_default_port tests/gateway/test_teams.py::TestTeamsAdapterInit::test_falls_back_to_env_vars tests/gateway/test_teams.py::TestTeamsAdapterInit::test_invalid_port_from_env_falls_back_to_default tests/gateway/test_teams.py::TestTeamsAdapterInit::test_invalid_port_from_extra_falls_back_to_default tests/gateway/test_teams.py::TestTeamsAdapterInit::test_platform_value tests/gateway/test_teams.py::TestTeamsAdapterInit::test_reads_config_from_extra tests/gateway/test_teams.py::TestTeamsAttachmentClassification::test_download_failure_degrades_to_text[asyncio] tests/gateway/test_teams.py::TestTeamsAttachmentClassification::test_file_download_info_sets_document_type[asyncio] tests/gateway/test_teams.py::TestTeamsAttachmentClassification::test_html_body_attachment_stays_text[asyncio] tests/gateway/test_teams.py::TestTeamsAttachmentClassification::test_image_only_still_photo[asyncio] tests/gateway/test_teams.py::TestTeamsAttachmentClassification::test_mixed_image_and_document_prefers_document[asyncio] tests/gateway/test_teams.py::TestTeamsConnect::test_connect_fails_without_credentials[asyncio] tests/gateway/test_teams.py::TestTeamsConnect::test_connect_fails_without_sdk[asyncio] tests/gateway/test_teams.py::TestTeamsConnect::test_disconnect_cleans_up[asyncio] tests/gateway/test_teams.py::TestTeamsInteractiveSetup::test_interactive_setup_persists_credentials tests/gateway/test_teams.py::TestTeamsMediaAttachments::test_send_document_local_file_base64 tests/gateway/test_teams.py::TestTeamsMediaAttachments::test_send_document_missing_file_fails_gracefully tests/gateway/test_teams.py::TestTeamsMediaAttachments::test_send_video_remote_url_succeeds tests/gateway/test_teams.py::TestTeamsMediaAttachments::test_send_video_without_app_fails tests/gateway/test_teams.py::TestTeamsMediaAttachments::test_send_voice_local_file_base64 tests/gateway/test_teams.py::TestTeamsMessageHandling::test_bot_mention_stripped_from_text[asyncio] tests/gateway/test_teams.py::TestTeamsMessageHandling::test_channel_message_creates_channel_event[asyncio] tests/gateway/test_teams.py::TestTeamsMessageHandling::test_deduplication[asyncio] tests/gateway/test_teams.py::TestTeamsMessageHandling::test_group_message_creates_group_event[asyncio] tests/gateway/test_teams.py::TestTeamsMessageHandling::test_personal_message_creates_dm_event[asyncio] tests/gateway/test_teams.py::TestTeamsMessageHandling::test_self_message_filtered[asyncio] tests/gateway/test_teams.py::TestTeamsMessageHandling::test_user_id_uses_aad_object_id[asyncio] tests/gateway/test_teams.py::TestTeamsPluginRegistration::test_register_auth_env_vars tests/gateway/test_teams.py::TestTeamsPluginRegistration::test_register_calls_ctx tests/gateway/test_teams.py::TestTeamsPluginRegistration::test_register_has_platform_hint tests/gateway/test_teams.py::TestTeamsPluginRegistration::test_register_has_setup_fn tests/gateway/test_teams.py::TestTeamsPluginRegistration::test_register_max_message_length tests/gateway/test_teams.py::TestTeamsPluginRegistration::test_register_name tests/gateway/test_teams.py::TestTeamsRequirements::test_check_teams_requirements_lazy_installs_when_missing tests/gateway/test_teams.py::TestTeamsRequirements::test_check_teams_requirements_shortcircuits_when_present tests/gateway/test_teams.py::TestTeamsRequirements::test_returns_false_when_aiohttp_missing tests/gateway/test_teams.py::TestTeamsRequirements::test_returns_false_when_sdk_missing tests/gateway/test_teams.py::TestTeamsRequirements::test_returns_true_when_deps_available tests/gateway/test_teams.py::TestTeamsRequirements::test_validate_config_from_extra tests/gateway/test_teams.py::TestTeamsRequirements::test_validate_config_missing tests/gateway/test_teams.py::TestTeamsRequirements::test_validate_config_missing_tenant tests/gateway/test_teams.py::TestTeamsRequirements::test_validate_config_with_env tests/gateway/test_teams.py::TestTeamsSend::test_send_calls_app_send[asyncio] tests/gateway/test_teams.py::TestTeamsSend::test_send_handles_error[asyncio] tests/gateway/test_teams.py::TestTeamsSend::test_send_returns_error_without_app[asyncio] tests/gateway/test_teams.py::TestTeamsSend::test_send_typing[asyncio] tests/gateway/test_teams.py::TestTeamsStandaloneSend::test_standalone_send_acquires_token_and_posts_activity tests/gateway/test_teams.py::TestTeamsStandaloneSend::test_standalone_send_propagates_token_failure tests/gateway/test_teams.py::TestTeamsStandaloneSend::test_standalone_send_rejects_chat_id_with_path_traversal tests/gateway/test_teams.py::TestTeamsStandaloneSend::test_standalone_send_rejects_off_allowlist_service_url tests/gateway/test_teams.py::TestTeamsStandaloneSend::test_standalone_send_returns_error_when_unconfigured tests/gateway/test_teams.py::TestTeamsSummaryWriter::test_existing_record_is_reused_without_force_resend[asyncio] tests/gateway/test_teams.py::TestTeamsSummaryWriter::test_graph_delivery_falls_back_to_platform_home_channel[asyncio] tests/gateway/test_teams.py::TestTeamsSummaryWriter::test_graph_delivery_posts_to_channel[asyncio] tests/gateway/test_teams.py::TestTeamsSummaryWriter::test_incoming_webhook_posts_summary_text[asyncio] tests/gateway/test_teams_pipeline_runtime_wiring.py::test_bind_gateway_runtime_installs_drop_scheduler_on_failure tests/gateway/test_teams_pipeline_runtime_wiring.py::test_build_pipeline_runtime_only_wires_sender_when_delivery_configured tests/gateway/test_teams_pipeline_runtime_wiring.py::test_build_pipeline_runtime_skips_sender_when_adapter_layer_is_unavailable tests/gateway/test_teams_pipeline_runtime_wiring.py::test_gateway_runner_skips_wiring_when_teams_pipeline_plugin_disabled tests/gateway/test_teams_pipeline_runtime_wiring.py::test_gateway_runner_skips_wiring_without_msgraph_adapter tests/gateway/test_teams_pipeline_runtime_wiring.py::test_gateway_runner_wires_teams_pipeline_runtime tests/gateway/test_teams_pipeline_runtime_wiring.py::test_runtime_config_disables_teams_delivery_without_target tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_already_resolved tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_approval_callback_escapes_dynamic_user_name tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_approval_callback_rejects_user_blocked_by_global_allowlist tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_deny_button tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_model_picker_callback_not_affected tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_resolves_approval_on_click tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_resume_typing_after_inline_approval tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_typing_stays_paused_when_resolve_returns_zero tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_update_prompt_callback_allows_authorized_user tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_update_prompt_callback_not_affected tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_update_prompt_callback_rejects_unauthorized_user tests/gateway/test_telegram_approval_buttons.py::TestTelegramApprovalCallback::test_update_prompt_callback_rejects_user_blocked_by_global_allowlist tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_disable_link_previews_sets_preview_kwargs tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_not_connected tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_retries_without_thread_when_thread_not_found tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_send_update_prompt_escapes_dynamic_prompt tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_sends_in_thread tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_sends_inline_keyboard tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_stores_approval_state tests/gateway/test_telegram_approval_buttons.py::TestTelegramExecApproval::test_truncates_long_command tests/gateway/test_telegram_audio_vs_voice.py::test_audio_attachment_context_note_format tests/gateway/test_telegram_audio_vs_voice.py::test_audio_attachment_skips_stt tests/gateway/test_telegram_audio_vs_voice.py::test_audio_attachment_skips_stt_when_stt_disabled tests/gateway/test_telegram_audio_vs_voice.py::test_telegram_media_type_detection_audio_vs_voice tests/gateway/test_telegram_audio_vs_voice.py::test_voice_message_still_transcribed tests/gateway/test_telegram_callback_auth_fail_closed.py::TestCallbackAuthFailClosed::test_allowlist_wildcard_permits tests/gateway/test_telegram_callback_auth_fail_closed.py::TestCallbackAuthFailClosed::test_allowlist_with_matching_user_permits tests/gateway/test_telegram_callback_auth_fail_closed.py::TestCallbackAuthFailClosed::test_allowlist_without_matching_user_denies tests/gateway/test_telegram_callback_auth_fail_closed.py::TestCallbackAuthFailClosed::test_no_allowlist_no_allow_all_denies tests/gateway/test_telegram_callback_auth_fail_closed.py::TestCallbackAuthFailClosed::test_no_allowlist_with_global_allow_all_permits tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionBasic::test_different_captions_merged tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionBasic::test_empty_existing_text tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionBasic::test_exact_duplicate_dropped tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionBasic::test_no_existing_text tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionMultipleItems::test_album_scenario_revenue_profit tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionMultipleItems::test_duplicate_in_middle_dropped tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionMultipleItems::test_three_unique_captions_all_present tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionSubstringBug::test_longer_caption_not_dropped_when_contains_existing tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionSubstringBug::test_prefix_caption_not_dropped tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionSubstringBug::test_shorter_caption_not_dropped_when_substring tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionWhitespace::test_leading_space_treated_as_duplicate tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionWhitespace::test_trailing_space_treated_as_duplicate tests/gateway/test_telegram_caption_merge.py::TestMergeCaptionWhitespace::test_whitespace_only_new_text_not_added tests/gateway/test_telegram_channel_posts.py::test_build_message_event_uses_channel_identity_for_channel_posts tests/gateway/test_telegram_channel_posts.py::test_command_handler_uses_effective_message_for_channel_post tests/gateway/test_telegram_channel_posts.py::test_text_handler_uses_effective_message_for_channel_post tests/gateway/test_telegram_clarify_buttons.py::TestBaseAdapterClarifyFallback::test_numbered_text_fallback tests/gateway/test_telegram_clarify_buttons.py::TestBaseAdapterClarifyFallback::test_open_ended_fallback_renders_question_only tests/gateway/test_telegram_clarify_buttons.py::TestTelegramClarifyCallback::test_already_resolved tests/gateway/test_telegram_clarify_buttons.py::TestTelegramClarifyCallback::test_invalid_choice_token tests/gateway/test_telegram_clarify_buttons.py::TestTelegramClarifyCallback::test_numeric_choice_resolves_with_choice_text tests/gateway/test_telegram_clarify_buttons.py::TestTelegramClarifyCallback::test_other_button_flips_to_text_mode tests/gateway/test_telegram_clarify_buttons.py::TestTelegramClarifyCallback::test_unauthorized_user_rejected tests/gateway/test_telegram_clarify_buttons.py::TestTelegramSendClarify::test_html_escapes_question tests/gateway/test_telegram_clarify_buttons.py::TestTelegramSendClarify::test_long_choice_rendered_in_body_not_truncated tests/gateway/test_telegram_clarify_buttons.py::TestTelegramSendClarify::test_multi_choice_renders_buttons_and_other tests/gateway/test_telegram_clarify_buttons.py::TestTelegramSendClarify::test_not_connected tests/gateway/test_telegram_clarify_buttons.py::TestTelegramSendClarify::test_open_ended_no_keyboard tests/gateway/test_telegram_conflict.py::test_connect_clears_webhook_before_polling tests/gateway/test_telegram_conflict.py::test_connect_marks_retryable_fatal_error_for_startup_network_failure tests/gateway/test_telegram_conflict.py::test_connect_rejects_same_host_token_lock tests/gateway/test_telegram_conflict.py::test_disconnect_skips_inactive_updater_and_app tests/gateway/test_telegram_conflict.py::test_polling_conflict_becomes_fatal_after_retries tests/gateway/test_telegram_conflict.py::test_polling_conflict_reschedule_uses_running_loop tests/gateway/test_telegram_conflict.py::test_polling_conflict_retries_before_fatal tests/gateway/test_telegram_customer_bootstrap_invite_ttl.py::test_invite_claimed_before_24_hours_remains_single_use tests/gateway/test_telegram_customer_bootstrap_invite_ttl.py::test_unclaimed_invite_expires_at_24_hour_boundary tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_caption_preserved_with_injection tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_download_exception_handled tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_missing_filename_and_mime_rejected tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_missing_filename_uses_mime_lookup tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_none_file_size_rejected tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_oversized_file_rejected tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_png_document_is_routed_as_image tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_spoofed_png_document_falls_back_with_error tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_supported_md_injects_content tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_supported_pdf_is_cached tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_supported_txt_injects_content tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_text_injection_capped tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_unicode_decode_error_handled tests/gateway/test_telegram_documents.py::TestDocumentDownloadBlock::test_zip_document_cached tests/gateway/test_telegram_documents.py::TestDocumentTypeDetection::test_document_detected_explicitly tests/gateway/test_telegram_documents.py::TestDocumentTypeDetection::test_fallback_is_document tests/gateway/test_telegram_documents.py::TestMediaGroups::test_disconnect_cancels_pending_media_group_flush tests/gateway/test_telegram_documents.py::TestMediaGroups::test_non_album_photo_burst_is_buffered_and_combined tests/gateway/test_telegram_documents.py::TestMediaGroups::test_photo_album_is_buffered_and_combined tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_api_error_falls_back tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_caption_truncated tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_custom_filename tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_file_not_found tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_not_connected tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_outputs_path_has_docker_hint tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_reply_to tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_success tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_thread_id tests/gateway/test_telegram_documents.py::TestSendDocument::test_send_document_workspace_path_has_docker_hint tests/gateway/test_telegram_documents.py::TestSendVideo::test_send_video_file_not_found tests/gateway/test_telegram_documents.py::TestSendVideo::test_send_video_not_connected tests/gateway/test_telegram_documents.py::TestSendVideo::test_send_video_success tests/gateway/test_telegram_documents.py::TestSendVideo::test_send_video_thread_id tests/gateway/test_telegram_documents.py::TestSendVideo::test_send_video_workspace_path_has_docker_hint tests/gateway/test_telegram_documents.py::TestSendVoice::test_flac_falls_back_to_document tests/gateway/test_telegram_documents.py::TestSendVoice::test_mp3_routes_to_send_audio tests/gateway/test_telegram_documents.py::TestSendVoice::test_wav_falls_back_to_document tests/gateway/test_telegram_documents.py::TestTelegramPhotoBatching::test_disconnect_cancels_pending_photo_batch_tasks tests/gateway/test_telegram_documents.py::TestTelegramPhotoBatching::test_flush_photo_batch_does_not_drop_newer_scheduled_task tests/gateway/test_telegram_documents.py::TestVideoDownloadBlock::test_mp4_document_is_treated_as_video tests/gateway/test_telegram_documents.py::TestVideoDownloadBlock::test_native_video_is_cached tests/gateway/test_telegram_format.py::TestEditMessageStreamingSafety::test_final_edit_uses_markdownv2_with_plain_fallback tests/gateway/test_telegram_format.py::TestEditMessageStreamingSafety::test_message_too_long_continuations_preserve_topic_metadata tests/gateway/test_telegram_format.py::TestEditMessageStreamingSafety::test_message_too_long_splits_into_continuations_not_silent_truncation tests/gateway/test_telegram_format.py::TestEditMessageStreamingSafety::test_non_final_edit_uses_plain_text_without_markdown tests/gateway/test_telegram_format.py::TestEscapeMdv2::test_backslash_escaped tests/gateway/test_telegram_format.py::TestEscapeMdv2::test_dot_escaped tests/gateway/test_telegram_format.py::TestEscapeMdv2::test_empty_string tests/gateway/test_telegram_format.py::TestEscapeMdv2::test_escapes_all_special_characters tests/gateway/test_telegram_format.py::TestEscapeMdv2::test_exclamation_escaped tests/gateway/test_telegram_format.py::TestEscapeMdv2::test_mixed_text_and_specials tests/gateway/test_telegram_format.py::TestEscapeMdv2::test_no_special_characters tests/gateway/test_telegram_format.py::TestFormatMessageBasic::test_empty_string tests/gateway/test_telegram_format.py::TestFormatMessageBasic::test_none_input tests/gateway/test_telegram_format.py::TestFormatMessageBasic::test_plain_text_no_markdown tests/gateway/test_telegram_format.py::TestFormatMessageBasic::test_plain_text_specials_escaped tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_blockquote_converted tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_blockquote_in_code_not_converted tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_blockquote_multiline tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_blockquote_with_special_chars tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_expandable_blockquote tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_gt_in_middle_of_line_still_escaped tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_nested_blockquote tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_regular_blockquote_with_pipes_escaped tests/gateway/test_telegram_format.py::TestFormatMessageBlockquote::test_single_asterisk_gt_not_blockquote tests/gateway/test_telegram_format.py::TestFormatMessageBoldItalic::test_bold_and_italic_in_same_line tests/gateway/test_telegram_format.py::TestFormatMessageBoldItalic::test_bold_converted tests/gateway/test_telegram_format.py::TestFormatMessageBoldItalic::test_bold_with_special_chars tests/gateway/test_telegram_format.py::TestFormatMessageBoldItalic::test_italic_converted tests/gateway/test_telegram_format.py::TestFormatMessageBoldItalic::test_italic_with_special_chars tests/gateway/test_telegram_format.py::TestFormatMessageBoldItalic::test_reload_mcp_summary_escapes_dynamic_server_names tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_code_block_special_chars_not_escaped tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_fenced_code_block_backslashes_escaped tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_fenced_code_block_backticks_escaped tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_fenced_code_block_preserved tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_inline_code_backslashes_escaped tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_inline_code_no_double_escape tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_inline_code_preserved tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_inline_code_special_chars_not_escaped tests/gateway/test_telegram_format.py::TestFormatMessageCodeBlocks::test_multiple_code_blocks tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_bold_inside_code_not_converted tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_code_block_with_bold_outside tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_empty_bold tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_empty_code_block tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_header_after_code_block tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_link_inside_code_not_converted tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_multiple_bold_segments tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_placeholder_collision tests/gateway/test_telegram_format.py::TestFormatMessageComplex::test_special_chars_in_plain_text tests/gateway/test_telegram_format.py::TestFormatMessageHeaders::test_h1_converted_to_bold tests/gateway/test_telegram_format.py::TestFormatMessageHeaders::test_h2_converted tests/gateway/test_telegram_format.py::TestFormatMessageHeaders::test_header_with_inner_bold_stripped tests/gateway/test_telegram_format.py::TestFormatMessageHeaders::test_header_with_special_chars tests/gateway/test_telegram_format.py::TestFormatMessageHeaders::test_multiline_headers tests/gateway/test_telegram_format.py::TestFormatMessageLinks::test_link_display_text_escaped tests/gateway/test_telegram_format.py::TestFormatMessageLinks::test_link_url_parentheses_escaped tests/gateway/test_telegram_format.py::TestFormatMessageLinks::test_link_with_surrounding_text tests/gateway/test_telegram_format.py::TestFormatMessageLinks::test_markdown_link_converted tests/gateway/test_telegram_format.py::TestFormatMessageSpoiler::test_spoiler_converted tests/gateway/test_telegram_format.py::TestFormatMessageSpoiler::test_spoiler_in_code_not_converted tests/gateway/test_telegram_format.py::TestFormatMessageSpoiler::test_spoiler_pipes_not_escaped tests/gateway/test_telegram_format.py::TestFormatMessageSpoiler::test_spoiler_with_special_chars tests/gateway/test_telegram_format.py::TestFormatMessageStrikethrough::test_strikethrough_converted tests/gateway/test_telegram_format.py::TestFormatMessageStrikethrough::test_strikethrough_in_code_not_converted tests/gateway/test_telegram_format.py::TestFormatMessageStrikethrough::test_strikethrough_with_bold tests/gateway/test_telegram_format.py::TestFormatMessageStrikethrough::test_strikethrough_with_special_chars tests/gateway/test_telegram_format.py::TestFormatMessageTables::test_multiple_tables_in_single_message tests/gateway/test_telegram_format.py::TestFormatMessageTables::test_table_rendered_as_bullets tests/gateway/test_telegram_format.py::TestFormatMessageTables::test_text_after_table_still_formatted tests/gateway/test_telegram_format.py::TestItalicNewlineBug::test_asterisk_list_items_preserved tests/gateway/test_telegram_format.py::TestItalicNewlineBug::test_bullet_list_not_corrupted tests/gateway/test_telegram_format.py::TestItalicNewlineBug::test_italic_does_not_span_lines tests/gateway/test_telegram_format.py::TestItalicNewlineBug::test_single_line_italic_still_works tests/gateway/test_telegram_format.py::TestStripMdv2::test_empty_string tests/gateway/test_telegram_format.py::TestStripMdv2::test_plain_text_unchanged tests/gateway/test_telegram_format.py::TestStripMdv2::test_preserves_multi_underscore_identifier tests/gateway/test_telegram_format.py::TestStripMdv2::test_preserves_snake_case tests/gateway/test_telegram_format.py::TestStripMdv2::test_removes_bold_markers tests/gateway/test_telegram_format.py::TestStripMdv2::test_removes_both_bold_and_italic tests/gateway/test_telegram_format.py::TestStripMdv2::test_removes_escape_backslashes tests/gateway/test_telegram_format.py::TestStripMdv2::test_removes_italic_markers tests/gateway/test_telegram_format.py::TestStripMdv2::test_removes_spoiler_markers tests/gateway/test_telegram_format.py::TestStripMdv2::test_removes_strikethrough_markers tests/gateway/test_telegram_format.py::TestTelegramGuestMentionGating::test_guest_mode_allows_bot_command_entity_outside_allowed_chats tests/gateway/test_telegram_format.py::TestTelegramGuestMentionGating::test_guest_mode_allows_explicit_mention_outside_allowed_chats tests/gateway/test_telegram_format.py::TestTelegramGuestMentionGating::test_guest_mode_allows_mention_in_caption_outside_allowed_chats tests/gateway/test_telegram_format.py::TestTelegramGuestMentionGating::test_guest_mode_allows_text_mention_entity_outside_allowed_chats tests/gateway/test_telegram_format.py::TestTelegramGuestMentionGating::test_guest_mode_disabled_keeps_allowed_chats_as_hard_gate_for_mentions tests/gateway/test_telegram_format.py::TestTelegramGuestMentionGating::test_guest_mode_does_not_allow_reply_outside_allowed_chats tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_alignment_separators tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_bare_pipe_table_rewritten tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_basic_table_rewritten_as_row_groups tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_existing_code_block_with_pipes_left_alone tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_horizontal_rule_not_wrapped tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_no_dash_short_circuits tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_no_pipe_character_short_circuits tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_plain_text_with_pipes_not_wrapped tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_row_group_uses_single_newlines_within_group tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_row_label_column_preserves_first_bullet tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_single_column_separator_not_matched tests/gateway/test_telegram_format.py::TestWrapMarkdownTables::test_two_consecutive_tables_rewritten_separately tests/gateway/test_telegram_format.py::test_send_escapes_chunk_indicator_for_markdownv2 tests/gateway/test_telegram_forum_commands.py::test_ensure_forum_commands_handles_set_failure tests/gateway/test_telegram_forum_commands.py::test_ensure_forum_commands_race_safety tests/gateway/test_telegram_forum_commands.py::test_ensure_forum_commands_registers_once tests/gateway/test_telegram_forum_commands.py::test_ensure_forum_commands_skips_already_registered tests/gateway/test_telegram_forum_commands.py::test_ensure_forum_commands_skips_non_forum tests/gateway/test_telegram_group_gating.py::test_adaptive_card_with_invalid_grounding_is_not_published tests/gateway/test_telegram_group_gating.py::test_adaptive_customer_selection_renders_explicit_create_button tests/gateway/test_telegram_group_gating.py::test_adaptive_edit_note_shows_persistent_reply_instruction tests/gateway/test_telegram_group_gating.py::test_adaptive_lifecycle_callback_confirms_visible_next_step[activated-\ud65c\uc131\ud654 \uc644\ub8cc. \ub2e4\uc74c \ub2e8\uacc4\ub294 \uace0\uac1d \uc804\uc1a1 \ud5c8\uc6a9\uc785\ub2c8\ub2e4.] tests/gateway/test_telegram_group_gating.py::test_adaptive_lifecycle_callback_confirms_visible_next_step[approved-\uc2b9\uc778 \uc644\ub8cc. \ub2e4\uc74c \ub2e8\uacc4\ub294 \ud65c\uc131\ud654\ud558\uae30\uc785\ub2c8\ub2e4.] tests/gateway/test_telegram_group_gating.py::test_adaptive_lifecycle_callback_confirms_visible_next_step[delivery_enabled-\uc804\uc1a1 \ud5c8\uc6a9 \uc644\ub8cc. \ub2e4\uc74c \ub2e8\uacc4\ub294 \uace0\uac1d\uc5d0\uac8c \uc804\uc1a1\uc785\ub2c8\ub2e4.] tests/gateway/test_telegram_group_gating.py::test_adaptive_menu_rebinds_callbacks_to_published_bot_message tests/gateway/test_telegram_group_gating.py::test_adaptive_menu_rejects_missing_publication_message_id tests/gateway/test_telegram_group_gating.py::test_adaptive_review_chat_topic_reserves_wrong_user_without_generic_downstream tests/gateway/test_telegram_group_gating.py::test_adaptive_review_unrelated_callback_is_reserved_before_generic_callbacks tests/gateway/test_telegram_group_gating.py::test_adaptive_terminal_delivery_replaces_send_card[audit_pending-\uace0\uac1d \uc804\uc1a1 \uc644\ub8cc. \uac10\uc0ac \uae30\ub85d \ubcf5\uad6c\uac00 \ud544\uc694\ud569\ub2c8\ub2e4.-True] tests/gateway/test_telegram_group_gating.py::test_adaptive_terminal_delivery_replaces_send_card[delivery_unknown-\uc804\uc1a1 \uacb0\uacfc \ud655\uc778 \ubd88\uac00. \uc7ac\uc804\uc1a1\ud558\uc9c0 \ub9c8\uc138\uc694.-False] tests/gateway/test_telegram_group_gating.py::test_adaptive_terminal_delivery_replaces_send_card[sent_audited-\uace0\uac1d \uc804\uc1a1 \ubc0f \uac10\uc0ac \uae30\ub85d \uc644\ub8cc.-False] tests/gateway/test_telegram_group_gating.py::test_allowed_topics_do_not_filter_dms tests/gateway/test_telegram_group_gating.py::test_allowed_topics_drop_other_forum_topics_before_other_gates tests/gateway/test_telegram_group_gating.py::test_allowed_topics_treat_missing_thread_as_general_topic tests/gateway/test_telegram_group_gating.py::test_bot_command_addressed_to_other_bot_is_exclusive_even_when_mentions_not_required tests/gateway/test_telegram_group_gating.py::test_config_bridges_telegram_group_settings tests/gateway/test_telegram_group_gating.py::test_config_bridges_telegram_ignored_threads tests/gateway/test_telegram_group_gating.py::test_config_bridges_telegram_user_allowlists tests/gateway/test_telegram_group_gating.py::test_config_env_overrides_telegram_user_allowlists tests/gateway/test_telegram_group_gating.py::test_customer_topic_is_reserved_from_all_generic_message_handlers tests/gateway/test_telegram_group_gating.py::test_customer_topic_reserves_unknown_callback_namespaces tests/gateway/test_telegram_group_gating.py::test_dm_allow_from_is_enforced_by_gateway_authorization_not_trigger_gate tests/gateway/test_telegram_group_gating.py::test_enabled_customer_feature_load_failure_blocks_generic_ingress tests/gateway/test_telegram_group_gating.py::test_entityless_multi_bot_mentions_still_route_exclusively tests/gateway/test_telegram_group_gating.py::test_exclusive_bot_mentions_can_be_disabled_for_legacy_groups tests/gateway/test_telegram_group_gating.py::test_explicit_multi_bot_mentions_route_only_to_named_bots tests/gateway/test_telegram_group_gating.py::test_foreign_sender_in_customer_topic_never_reaches_generic_agent tests/gateway/test_telegram_group_gating.py::test_free_response_chats_bypass_mention_requirement tests/gateway/test_telegram_group_gating.py::test_group_allow_from_is_enforced_by_gateway_authorization_not_trigger_gate tests/gateway/test_telegram_group_gating.py::test_group_messages_can_be_opened_via_config tests/gateway/test_telegram_group_gating.py::test_group_messages_can_require_direct_trigger_via_config tests/gateway/test_telegram_group_gating.py::test_guest_mode_allows_only_direct_mentions_outside_allowed_chats tests/gateway/test_telegram_group_gating.py::test_guest_mode_defaults_to_false_for_allowed_chat_bypass tests/gateway/test_telegram_group_gating.py::test_guest_mode_mention_dropped_in_ignored_thread tests/gateway/test_telegram_group_gating.py::test_ignored_threads_drop_group_messages_before_other_gates tests/gateway/test_telegram_group_gating.py::test_intern_bots_ignore_messages_addressed_to_other_intern_bot tests/gateway/test_telegram_group_gating.py::test_invalid_regex_patterns_are_ignored tests/gateway/test_telegram_group_gating.py::test_legacy_nutrition_operator_review_is_not_an_adaptive_ingress tests/gateway/test_telegram_group_gating.py::test_legacy_nutrition_review_triple_routes_coaching_without_adaptive_ingress tests/gateway/test_telegram_group_gating.py::test_observed_group_context_does_not_hide_current_user_turn_behind_history_offset tests/gateway/test_telegram_group_gating.py::test_observed_group_context_preserves_slash_command_text_for_dispatch tests/gateway/test_telegram_group_gating.py::test_observed_group_context_replays_as_current_message_context_not_user_turns tests/gateway/test_telegram_group_gating.py::test_observed_group_context_replays_normally_without_telegram_prompt tests/gateway/test_telegram_group_gating.py::test_observed_group_context_uses_shared_source_and_prompt_for_later_mentions tests/gateway/test_telegram_group_gating.py::test_observed_group_context_wraps_multimodal_current_message_without_mutating_parts tests/gateway/test_telegram_group_gating.py::test_raw_bot_mention_fallback_does_not_match_email_or_substring tests/gateway/test_telegram_group_gating.py::test_regex_mention_patterns_allow_custom_wake_words tests/gateway/test_telegram_group_gating.py::test_restart_recovery_rebuilds_validated_adaptive_inline_buttons tests/gateway/test_telegram_group_gating.py::test_review_space_collision_categories_fail_closed[customer_routes] tests/gateway/test_telegram_group_gating.py::test_review_space_collision_categories_fail_closed[generic_reserved_routes] tests/gateway/test_telegram_group_gating.py::test_review_space_collision_categories_fail_closed[owner_scheduled_routes] tests/gateway/test_telegram_group_gating.py::test_review_space_collision_categories_fail_closed[trainer_routes] tests/gateway/test_telegram_group_gating.py::test_review_surface_reserves_contact_edited_and_channel_ingress tests/gateway/test_telegram_group_gating.py::test_shared_group_observe_source_is_authorized_by_group_allowed_chats tests/gateway/test_telegram_group_gating.py::test_text_reply_to_photo_caches_referenced_media tests/gateway/test_telegram_group_gating.py::test_top_level_require_mention_bridges_to_telegram tests/gateway/test_telegram_group_gating.py::test_top_level_require_mention_does_not_override_telegram_section tests/gateway/test_telegram_group_gating.py::test_trainer_topic_keyboard_is_persistent_and_sent_once tests/gateway/test_telegram_group_gating.py::test_triggered_location_message_uses_shared_session_in_observe_mode tests/gateway/test_telegram_group_gating.py::test_triggered_voice_message_uses_shared_session_in_observe_mode tests/gateway/test_telegram_group_gating.py::test_unconfigured_nutrition_operator_never_probes_coordinator_owner tests/gateway/test_telegram_group_gating.py::test_unmentioned_document_observed_with_cached_path tests/gateway/test_telegram_group_gating.py::test_unmentioned_group_messages_can_be_observed_without_dispatching tests/gateway/test_telegram_group_gating.py::test_unmentioned_group_observe_requires_chat_allowlist_for_shared_context tests/gateway/test_telegram_group_gating.py::test_unmentioned_group_observe_respects_chat_allowlist tests/gateway/test_telegram_group_gating.py::test_unmentioned_large_document_observed_without_download tests/gateway/test_telegram_group_gating.py::test_unmentioned_location_message_observed_in_group tests/gateway/test_telegram_group_gating.py::test_unmentioned_photo_observed_with_cached_path tests/gateway/test_telegram_group_gating.py::test_unmentioned_unsupported_document_observed_without_caching tests/gateway/test_telegram_group_gating.py::test_unmentioned_voice_message_observed_in_group tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_channel_post-channel_post] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_command-message] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_contact_message-message:contact] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_edited_channel_post-edited_channel_post] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_edited_message-edited_message] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_location_message-message] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_media_message-message:audio] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_media_message-message:document] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_media_message-message:photo] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_media_message-message:sticker] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_media_message-message:video] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_media_message-message:voice] tests/gateway/test_telegram_group_gating.py::test_wrong_user_review_space_reserves_every_message_ingress_without_downstream[_handle_text_message-message] tests/gateway/test_telegram_max_doc_bytes.py::test_max_doc_bytes_defaults_to_20mb_without_base_url tests/gateway/test_telegram_max_doc_bytes.py::test_max_doc_bytes_empty_base_url_keeps_default tests/gateway/test_telegram_max_doc_bytes.py::test_max_doc_bytes_raised_to_2gb_when_base_url_set tests/gateway/test_telegram_mention_boundaries.py::TestCaseInsensitivity::test_mixed_case_mention tests/gateway/test_telegram_mention_boundaries.py::TestCaseInsensitivity::test_uppercase_mention tests/gateway/test_telegram_mention_boundaries.py::TestEntityEdgeCases::test_malformed_entity_with_negative_offset tests/gateway/test_telegram_mention_boundaries.py::TestEntityEdgeCases::test_malformed_entity_with_zero_length tests/gateway/test_telegram_mention_boundaries.py::TestEntityEdgeCases::test_mention_entity_for_different_username tests/gateway/test_telegram_mention_boundaries.py::TestEntityEdgeCases::test_text_mention_entity_for_different_user tests/gateway/test_telegram_mention_boundaries.py::TestRealMentionsAreDetected::test_mention_at_end_of_message tests/gateway/test_telegram_mention_boundaries.py::TestRealMentionsAreDetected::test_mention_at_start_of_message tests/gateway/test_telegram_mention_boundaries.py::TestRealMentionsAreDetected::test_mention_in_caption tests/gateway/test_telegram_mention_boundaries.py::TestRealMentionsAreDetected::test_mention_mid_sentence tests/gateway/test_telegram_mention_boundaries.py::TestRealMentionsAreDetected::test_text_mention_entity_targets_bot tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_email_like_substring tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_email_substring_in_caption tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_hostname_substring tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_plain_text_with_no_at_sign tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_substring_inside_code_block_without_entity tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_substring_inside_url_without_entity tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_superstring_username tests/gateway/test_telegram_mention_boundaries.py::TestSubstringFalsePositivesAreRejected::test_underscore_suffix_substring tests/gateway/test_telegram_model_picker.py::TestTelegramModelPicker::test_back_button_escapes_dynamic_provider_label tests/gateway/test_telegram_model_picker.py::TestTelegramModelPicker::test_expensive_model_requires_confirmation tests/gateway/test_telegram_model_picker.py::TestTelegramModelPicker::test_model_selected_edits_message_on_success tests/gateway/test_telegram_model_picker.py::TestTelegramModelPicker::test_provider_group_folds_and_drills_down tests/gateway/test_telegram_model_picker.py::TestTelegramModelPicker::test_retries_without_thread_when_thread_not_found tests/gateway/test_telegram_model_picker.py::TestTelegramModelPicker::test_send_model_picker_escapes_dynamic_provider_label tests/gateway/test_telegram_network.py::TestAdapterFallbackIps::test_csv_string_in_extra tests/gateway/test_telegram_network.py::TestAdapterFallbackIps::test_empty_extra tests/gateway/test_telegram_network.py::TestAdapterFallbackIps::test_invalid_ips_filtered tests/gateway/test_telegram_network.py::TestAdapterFallbackIps::test_list_in_extra tests/gateway/test_telegram_network.py::TestAdapterFallbackIps::test_no_extra_attr tests/gateway/test_telegram_network.py::TestConfigFallbackIps::test_empty_env_var_does_not_populate tests/gateway/test_telegram_network.py::TestConfigFallbackIps::test_env_var_creates_platform_if_missing tests/gateway/test_telegram_network.py::TestConfigFallbackIps::test_env_var_populates_config_extra tests/gateway/test_telegram_network.py::TestConfigFallbackIps::test_env_var_strips_whitespace tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_all_doh_ips_same_as_system_dns_kept tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_cloudflare_gets_accept_header tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_doh_connect_error_falls_back_to_seed tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_doh_malformed_json_falls_back_to_seed tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_doh_results_deduplicated tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_doh_timeout_falls_back_to_seed tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_google_and_cloudflare_ips_collected tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_invalid_ip_in_doh_response_skipped tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_non_a_records_ignored tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_one_provider_fails_other_succeeds tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_system_dns_failure_keeps_all_doh_ips tests/gateway/test_telegram_network.py::TestDiscoverFallbackIps::test_system_dns_ip_kept_when_doh_confirms tests/gateway/test_telegram_network.py::TestFallbackTransport::test_all_ips_fail_raises_last_error tests/gateway/test_telegram_network.py::TestFallbackTransport::test_does_not_fallback_on_non_connect_error tests/gateway/test_telegram_network.py::TestFallbackTransport::test_falls_back_on_connect_error tests/gateway/test_telegram_network.py::TestFallbackTransport::test_falls_back_on_connect_timeout_and_becomes_sticky tests/gateway/test_telegram_network.py::TestFallbackTransport::test_multiple_fallback_ips_tried_in_order tests/gateway/test_telegram_network.py::TestFallbackTransport::test_sticky_ip_tried_first_but_falls_through_if_stale tests/gateway/test_telegram_network.py::TestFallbackTransportClose::test_aclose_closes_all_transports tests/gateway/test_telegram_network.py::TestFallbackTransportInit::test_deduplicates_fallback_ips tests/gateway/test_telegram_network.py::TestFallbackTransportInit::test_filters_invalid_ips_at_init tests/gateway/test_telegram_network.py::TestFallbackTransportInit::test_no_proxy_bypasses_fallback_ip_cidr tests/gateway/test_telegram_network.py::TestFallbackTransportInit::test_uses_proxy_env_for_primary_and_fallback_transports tests/gateway/test_telegram_network.py::TestFallbackTransportPassthrough::test_empty_fallback_list_uses_primary_only tests/gateway/test_telegram_network.py::TestFallbackTransportPassthrough::test_non_telegram_host_bypasses_fallback tests/gateway/test_telegram_network.py::TestFallbackTransportPassthrough::test_primary_succeeds_no_fallback_needed tests/gateway/test_telegram_network.py::TestNormalizeFallbackIps::test_deduplication_happens_at_transport_level tests/gateway/test_telegram_network.py::TestNormalizeFallbackIps::test_empty_strings_skipped tests/gateway/test_telegram_network.py::TestParseFallbackIpEnv::test_empty_string_returns_empty tests/gateway/test_telegram_network.py::TestParseFallbackIpEnv::test_filters_invalid_and_ipv6 tests/gateway/test_telegram_network.py::TestParseFallbackIpEnv::test_multiple_valid_ips tests/gateway/test_telegram_network.py::TestParseFallbackIpEnv::test_none_returns_empty tests/gateway/test_telegram_network.py::TestParseFallbackIpEnv::test_rejects_leading_zeros tests/gateway/test_telegram_network.py::TestParseFallbackIpEnv::test_single_valid_ip tests/gateway/test_telegram_network.py::TestParseFallbackIpEnv::test_whitespace_only_returns_empty tests/gateway/test_telegram_network.py::TestRewriteRequestForIp::test_preserves_host_and_sni tests/gateway/test_telegram_network.py::TestRewriteRequestForIp::test_preserves_method_and_path tests/gateway/test_telegram_network_reconnect.py::test_conflict_retry_also_drains_polling_connections tests/gateway/test_telegram_network_reconnect.py::test_drain_helper_noop_without_app tests/gateway/test_telegram_network_reconnect.py::test_heartbeat_probe_no_op_when_polling_healthy tests/gateway/test_telegram_network_reconnect.py::test_heartbeat_probe_reenters_ladder_on_get_me_network_error tests/gateway/test_telegram_network_reconnect.py::test_heartbeat_probe_reenters_ladder_when_get_me_times_out tests/gateway/test_telegram_network_reconnect.py::test_heartbeat_probe_reenters_ladder_when_updater_not_running tests/gateway/test_telegram_network_reconnect.py::test_heartbeat_probe_skips_when_already_fatal tests/gateway/test_telegram_network_reconnect.py::test_initialize_still_runs_when_shutdown_fails tests/gateway/test_telegram_network_reconnect.py::test_reconnect_continues_if_drain_fails tests/gateway/test_telegram_network_reconnect.py::test_reconnect_does_not_self_schedule_when_fatal_error_set tests/gateway/test_telegram_network_reconnect.py::test_reconnect_drains_polling_request_only tests/gateway/test_telegram_network_reconnect.py::test_reconnect_schedules_heartbeat_probe_on_success tests/gateway/test_telegram_network_reconnect.py::test_reconnect_self_schedules_on_start_polling_failure tests/gateway/test_telegram_network_reconnect.py::test_reconnect_success_resets_error_count tests/gateway/test_telegram_network_reconnect.py::test_reconnect_triggers_fatal_after_max_retries tests/gateway/test_telegram_noise_filter.py::test_non_telegram_status_is_unchanged tests/gateway/test_telegram_noise_filter.py::test_telegram_final_response_keeps_normal_answers tests/gateway/test_telegram_noise_filter.py::test_telegram_final_response_redacts_auth_secrets tests/gateway/test_telegram_noise_filter.py::test_telegram_final_response_sanitizes_raw_provider_errors tests/gateway/test_telegram_noise_filter.py::test_telegram_status_sanitizes_raw_provider_security_errors tests/gateway/test_telegram_noise_filter.py::test_telegram_status_suppresses_auxiliary_and_retry_noise tests/gateway/test_telegram_operator_notification_recovery.py::test_acknowledged_hold_does_not_republish_on_successor_startup tests/gateway/test_telegram_operator_notification_recovery.py::test_enabling_owner_risk_republishes_acknowledged_hold_card tests/gateway/test_telegram_operator_notification_recovery.py::test_operator_status_recovers_current_card_only_for_exact_owner tests/gateway/test_telegram_operator_notification_recovery.py::test_owner_approval_preflights_plan_before_committing_review tests/gateway/test_telegram_operator_notification_recovery.py::test_owner_risk_callback_transitions_and_publishes_owner_review tests/gateway/test_telegram_operator_notification_recovery.py::test_owner_risk_capability_requires_exact_candidate_owner_and_seal tests/gateway/test_telegram_operator_notification_recovery.py::test_recovery_capability_requires_exact_candidate_owner_and_seal tests/gateway/test_telegram_operator_notification_recovery.py::test_runtime_acknowledges_hold_without_domain_transition tests/gateway/test_telegram_operator_notification_recovery.py::test_safety_hold_acknowledgement_is_append_only_and_idempotent tests/gateway/test_telegram_operator_notification_recovery.py::test_safety_hold_card_exposes_owner_risk_action_only_when_authorized tests/gateway/test_telegram_operator_notification_recovery.py::test_startup_recovers_hold_when_bootstrap_consent_handoff_is_missing tests/gateway/test_telegram_operator_notification_recovery.py::test_status_command_uses_deterministic_onboarding_recovery tests/gateway/test_telegram_operator_notification_recovery.py::test_status_recovery_then_same_candidate_restart_is_deduplicated tests/gateway/test_telegram_operator_notification_recovery.py::test_unacknowledged_hold_republishes_once_per_candidate_epoch tests/gateway/test_telegram_overflow_partial.py::test_edit_overflow_split_reports_later_partial_failure_after_some_continuations_land tests/gateway/test_telegram_overflow_partial.py::test_edit_overflow_split_reports_partial_failure_when_continuation_fails tests/gateway/test_telegram_overflow_partial.py::test_edit_overflow_split_reports_success_when_all_continuations_land tests/gateway/test_telegram_overflow_partial.py::test_stream_consumer_fallback_sends_tail_after_partial_overflow tests/gateway/test_telegram_photo_interrupts.py::test_handle_message_does_not_priority_interrupt_photo_followup tests/gateway/test_telegram_physique_checkin.py::TestNutritionCopySurfaces::test_daily_copy_fails_closed_when_facts_or_model_are_missing tests/gateway/test_telegram_physique_checkin.py::TestNutritionCopySurfaces::test_daily_copy_keeps_the_approved_sections_and_spacing tests/gateway/test_telegram_physique_checkin.py::TestNutritionCopySurfaces::test_weekly_copy_fails_closed_when_no_report_data_exists tests/gateway/test_telegram_physique_checkin.py::TestNutritionCopySurfaces::test_weekly_copy_renders_averages_rate_judgment_and_actions tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_concurrent_ticks_share_one_durable_provider_authority tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_daily_customer_and_weekly_owner_destinations_are_pinned tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_delivered_receipt_restarts_into_audit_without_provider tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_ambiguous_rejection_remains_unknown tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_expired_audited_delivery_creates_one_review tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_explicit_no_send_rejection_is_replaceable tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_is_static_pinned_and_exactly_once tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_provider_unknown_is_never_retried tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_stale_authority_never_calls_provider[config] tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_stale_authority_never_calls_provider[destination] tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_dual_coach_reminder_stale_authority_never_calls_provider[registration] tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_duplicate_tick_has_one_provider_delivery tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_invalid_cutover_fence_sends_nothing[corrupt] tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_invalid_cutover_fence_sends_nothing[preparing] tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_orphan_tombstone_recovery_is_terminal_and_never_calls_provider tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_provider_timeout_is_unknown_and_never_retried tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_terminal_response_after_sending_abandons_without_provider_or_review tests/gateway/test_telegram_physique_checkin.py::TestNutritionScheduleDelivery::test_tick_success_persists_audited_receipt tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_data_is_compact_and_contains_no_answer tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_data_rejects_oversize_or_personal_value_actions tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_grammar_accepts_only_canonical_adaptive_steps[Q-COND-INTENSITY] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_grammar_accepts_only_canonical_adaptive_steps[Q-COND-SYMPTOM] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_grammar_accepts_only_canonical_adaptive_steps[Q-PERF-NEXT] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_grammar_accepts_only_canonical_adaptive_steps[Q-PERF-REASON] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_grammar_accepts_only_canonical_adaptive_steps[Q-SLEEP-ADJUST] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_callback_grammar_accepts_only_canonical_adaptive_steps[Q-SLEEP-CAUSE] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCallbackGrammar::test_customer_nutrition_steps_fit_the_opaque_callback_contract tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_all_fixed_coach_prompts_use_honorific_korean[morning] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_all_fixed_coach_prompts_use_honorific_korean[nutrition_daily] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_all_fixed_coach_prompts_use_honorific_korean[workout] tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_all_rendered_callbacks_are_opaque_and_telegram_sized tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_customer_nutrition_edit_menu_uses_compact_korean_fields tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_disabled_config_is_a_true_noop tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_edit_tab_changes_the_same_binding_screen_and_field_callback_enters_correction tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_finalized_snapshot_exports_branch_state_for_grounding tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_fresh_bridge_rehydrates_persisted_active_draft_and_consumes_typed_value tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_model_can_mark_missing_bodyweight_and_advance_without_creating_a_trend_value tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_model_can_rewrite_the_current_sleep_quality_prompt_without_advancing_the_draft tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_optional_topic_allowlists_must_match_the_exact_wizard_target tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_recovery_command_boundary_requires_exact_owner_chat_and_topic tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_replay_and_expiry_are_rejected_without_mutating_service tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_start_binds_exact_owner_chat_topic_and_message tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_summary_uses_three_compact_actions_and_a_flow_specific_two_column_edit_menu tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_trainer_bridge_start_to_save_scopes_event_to_registered_customer tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_typed_action_replaces_buttons_with_the_exact_expected_question tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_typed_value_requires_exact_active_binding_then_bypasses_agent tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueCheckinBridge::test_urgent_text_reaches_safety_transition_during_button_only_step tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_active_natural_language_turn_uses_model_action_instead_of_static_invalid_template tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_anonymous_sleep_quality_feedback_rewrites_the_active_card_without_generic_ingress tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_anonymous_typed_value_uses_owner_only_for_the_exact_opted_in_topic tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_anonymous_typed_value_uses_sender_chat_when_telegram_supplies_a_fake_user tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_completed_customer_checkin_publishes_generation_card_only_to_operator_topic tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_dedicated_operator_topic_maps_to_canonical_owner_actor tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_disabled_pc1_callback_falls_through_existing_router tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_enabled_pc1_callback_is_consumed_before_existing_callbacks tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_enabled_pc1_text_is_consumed_before_generic_aggregation tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_expired_real_binding_numeric_answer_is_recovered_before_generic_ingress tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_expired_target_numeric_answer_reopens_checkin_instead_of_reaching_generic_agent tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_failed_scheduled_launch_recovers_once_by_owner_command_without_automatic_retry tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_final_feedback_request_includes_profile_doctrine_and_verified_history tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_foreign_or_wrong_topic_recovery_command_is_denied_before_generic_ingress tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_inline_card_capability_is_inert_when_profile_feature_is_disabled tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_invalid_anonymous_natural_language_wizard_text_uses_model_without_generic_ingress tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_launcher_shows_kst_date_and_korean_weekday_in_its_topic_card tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_natural_language_source_approval_consumes_the_latest_notified_candidate tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_nutrition_private_dm_address_uses_registry_topic_zero tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_operator_draft_view_lists_every_final_checkin_field tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_owner_recovery_command_sends_one_topic_bound_card_before_generic_ingress tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_save_callback_records_once_and_replaces_summary_with_confirmation tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_saved_checkin_defers_model_feedback_to_worker_without_generic_ingress tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_source_review_callback_requires_the_exact_owner_topic_and_approves_one_candidate tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_summary_keyboard_keeps_three_actions_in_one_telegram_row tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_target_topic_conversation_uses_isolated_chos_coach_model_without_generic_ingress tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_today_feedback_replay_uses_saved_checkin_after_a_new_launcher_replaces_active_session tests/gateway/test_telegram_physique_checkin.py::TestPhysiqueTelegramAdapterIngress::test_typed_action_edits_the_same_topic_prompt_to_a_direct_question tests/gateway/test_telegram_physique_checkin.py::TestStrictCoachingClosure::test_adaptive_payload_requires_exact_proposal_revision_and_digest tests/gateway/test_telegram_physique_checkin.py::TestStrictCoachingClosure::test_adaptive_publication_rechecks_revision_before_reservation tests/gateway/test_telegram_physique_checkin.py::TestStrictCoachingClosure::test_daily_publication_rechecks_revision_before_edit tests/gateway/test_telegram_physique_checkin.py::TestStrictCoachingClosure::test_malformed_grounding_containers_are_canonical_with_empty_binding tests/gateway/test_telegram_physique_checkin.py::TestStrictCoachingClosure::test_revision_drift_before_stage_one_skips_grounding_and_model tests/gateway/test_telegram_physique_checkin.py::TestStrictCoachingClosure::test_revision_drift_between_stages_discards_model_output tests/gateway/test_telegram_physique_checkin.py::test_coaching_stage_uses_resolved_provider_token_parameter tests/gateway/test_telegram_physique_checkin.py::test_dual_coach_review_recovery_is_topic_bound_and_deduplicated tests/gateway/test_telegram_physique_checkin.py::test_dual_coach_review_runtime_drain_requires_topic_59_and_persists_receipt tests/gateway/test_telegram_physique_checkin.py::test_normal_adaptive_card_redacts_lifecycle_diagnostics tests/gateway/test_telegram_physique_checkin.py::test_topic_59_dual_coach_drain_coexists_with_adaptive_operator tests/gateway/test_telegram_progress_edit_transient.py::test_flood_control_sets_can_edit_false tests/gateway/test_telegram_progress_edit_transient.py::test_multiple_transient_then_success_keeps_can_edit_true tests/gateway/test_telegram_progress_edit_transient.py::test_permanent_errors_are_not_transient[Bad Request: MESSAGE_ID_INVALID] tests/gateway/test_telegram_progress_edit_transient.py::test_permanent_errors_are_not_transient[Bad Request: message can't be edited] tests/gateway/test_telegram_progress_edit_transient.py::test_permanent_errors_are_not_transient[Bad Request: message to edit not found] tests/gateway/test_telegram_progress_edit_transient.py::test_permanent_errors_are_not_transient[Bad Request: not enough rights to edit the message] tests/gateway/test_telegram_progress_edit_transient.py::test_permanent_errors_are_not_transient[Forbidden: bot was blocked by the user] tests/gateway/test_telegram_progress_edit_transient.py::test_permanent_errors_are_not_transient[flood_control:30.0] tests/gateway/test_telegram_progress_edit_transient.py::test_permanent_failure_sets_can_edit_false tests/gateway/test_telegram_progress_edit_transient.py::test_send_result_retryable_can_be_set_true tests/gateway/test_telegram_progress_edit_transient.py::test_send_result_retryable_default_is_false tests/gateway/test_telegram_progress_edit_transient.py::test_send_result_retryable_false_for_permanent tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[Connection error: failed to connect] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[NetworkError: remote end closed connection without response] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[ReadTimeout: timed out] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[Server disconnected] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[Temporarily unavailable] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[Temporary failure in name resolution] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[httpx.ConnectError: Connection refused] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[httpx.ReadTimeout: read timed out] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_errors_are_classified_as_transient[telegram.error.NetworkError: httpx.ConnectError] tests/gateway/test_telegram_progress_edit_transient.py::test_transient_failure_keeps_can_edit_true tests/gateway/test_telegram_reactions.py::test_clear_reactions_handles_api_error_gracefully tests/gateway/test_telegram_reactions.py::test_clear_reactions_returns_false_without_bot tests/gateway/test_telegram_reactions.py::test_config_bridges_telegram_reactions tests/gateway/test_telegram_reactions.py::test_config_reactions_env_takes_precedence tests/gateway/test_telegram_reactions.py::test_on_processing_complete_cancelled_clears_reaction tests/gateway/test_telegram_reactions.py::test_on_processing_complete_cancelled_skipped_when_disabled tests/gateway/test_telegram_reactions.py::test_on_processing_complete_failure tests/gateway/test_telegram_reactions.py::test_on_processing_complete_skipped_when_disabled tests/gateway/test_telegram_reactions.py::test_on_processing_complete_success tests/gateway/test_telegram_reactions.py::test_on_processing_start_adds_eyes_reaction tests/gateway/test_telegram_reactions.py::test_on_processing_start_handles_missing_ids tests/gateway/test_telegram_reactions.py::test_on_processing_start_skipped_when_disabled tests/gateway/test_telegram_reactions.py::test_reactions_disabled_by_default tests/gateway/test_telegram_reactions.py::test_reactions_disabled_with_0 tests/gateway/test_telegram_reactions.py::test_reactions_disabled_with_false tests/gateway/test_telegram_reactions.py::test_reactions_disabled_with_no tests/gateway/test_telegram_reactions.py::test_reactions_enabled_when_set_true tests/gateway/test_telegram_reactions.py::test_reactions_enabled_with_1 tests/gateway/test_telegram_reactions.py::test_set_reaction_calls_bot_api tests/gateway/test_telegram_reactions.py::test_set_reaction_handles_api_error_gracefully tests/gateway/test_telegram_reactions.py::test_set_reaction_returns_false_without_bot tests/gateway/test_telegram_reply_mode.py::TestConfigSerialization::test_from_dict_defaults_to_first tests/gateway/test_telegram_reply_mode.py::TestConfigSerialization::test_from_dict_loads_reply_to_mode tests/gateway/test_telegram_reply_mode.py::TestConfigSerialization::test_to_dict_includes_reply_to_mode tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_explicit_reply_to_overrides_mode tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_reply_to_id_returned_when_all tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_reply_to_id_returned_when_first tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_reply_to_id_returned_when_no_mode tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_reply_to_id_suppressed_when_off tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_send_dm_topic_first_still_quotes tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_send_dm_topic_off_no_quote tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_thread_kwargs_no_mode_backward_compat tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_thread_kwargs_returns_full_when_first tests/gateway/test_telegram_reply_mode.py::TestDMTopicFallbackReplyToMode::test_thread_kwargs_suppressed_reply_anchor_when_off tests/gateway/test_telegram_reply_mode.py::TestEnvVarOverride::test_env_var_case_insensitive tests/gateway/test_telegram_reply_mode.py::TestEnvVarOverride::test_env_var_empty_value_ignored tests/gateway/test_telegram_reply_mode.py::TestEnvVarOverride::test_env_var_invalid_value_ignored tests/gateway/test_telegram_reply_mode.py::TestEnvVarOverride::test_env_var_sets_all_mode tests/gateway/test_telegram_reply_mode.py::TestEnvVarOverride::test_env_var_sets_off_mode tests/gateway/test_telegram_reply_mode.py::TestReplyToModeConfig::test_all_mode tests/gateway/test_telegram_reply_mode.py::TestReplyToModeConfig::test_default_mode_is_first tests/gateway/test_telegram_reply_mode.py::TestReplyToModeConfig::test_empty_string_mode_defaults_to_first tests/gateway/test_telegram_reply_mode.py::TestReplyToModeConfig::test_first_mode tests/gateway/test_telegram_reply_mode.py::TestReplyToModeConfig::test_invalid_mode_stored_as_is tests/gateway/test_telegram_reply_mode.py::TestReplyToModeConfig::test_none_mode_defaults_to_first tests/gateway/test_telegram_reply_mode.py::TestReplyToModeConfig::test_off_mode tests/gateway/test_telegram_reply_mode.py::TestSendWithReplyToMode::test_all_mode_all_chunks_thread tests/gateway/test_telegram_reply_mode.py::TestSendWithReplyToMode::test_first_mode_only_first_chunk_threads tests/gateway/test_telegram_reply_mode.py::TestSendWithReplyToMode::test_no_reply_to_param_no_threading tests/gateway/test_telegram_reply_mode.py::TestSendWithReplyToMode::test_off_mode_no_reply_threading tests/gateway/test_telegram_reply_mode.py::TestSendWithReplyToMode::test_single_chunk_respects_mode tests/gateway/test_telegram_reply_mode.py::TestShouldThreadReply::test_all_mode_all_chunks tests/gateway/test_telegram_reply_mode.py::TestShouldThreadReply::test_first_mode_only_first_chunk tests/gateway/test_telegram_reply_mode.py::TestShouldThreadReply::test_invalid_mode_falls_back_to_first tests/gateway/test_telegram_reply_mode.py::TestShouldThreadReply::test_no_reply_to_returns_false tests/gateway/test_telegram_reply_mode.py::TestShouldThreadReply::test_off_mode_never_threads tests/gateway/test_telegram_reply_mode.py::TestTelegramYamlConfigLoading::test_env_var_takes_precedence_over_yaml tests/gateway/test_telegram_reply_mode.py::TestTelegramYamlConfigLoading::test_extra_reply_to_mode_off tests/gateway/test_telegram_reply_mode.py::TestTelegramYamlConfigLoading::test_top_level_reply_to_mode_all tests/gateway/test_telegram_reply_mode.py::TestTelegramYamlConfigLoading::test_top_level_reply_to_mode_off tests/gateway/test_telegram_reply_mode.py::TestTelegramYamlConfigLoading::test_top_level_takes_precedence_over_extra tests/gateway/test_telegram_reply_quote.py::test_caption_fallback_when_no_quote_and_no_text tests/gateway/test_telegram_reply_quote.py::test_empty_quote_text_falls_back_to_full_reply tests/gateway/test_telegram_reply_quote.py::test_full_reply_text_used_when_no_native_quote tests/gateway/test_telegram_reply_quote.py::test_native_partial_quote_used_as_reply_to_text tests/gateway/test_telegram_rich_messages.py::test_capability_error_latches_rich_send_off tests/gateway/test_telegram_rich_messages.py::test_details_with_math_skips_rich_draft_to_avoid_tdesktop_crash tests/gateway/test_telegram_rich_messages.py::test_details_with_math_skips_rich_send_to_avoid_tdesktop_crash tests/gateway/test_telegram_rich_messages.py::test_details_without_math_still_uses_rich_send tests/gateway/test_telegram_rich_messages.py::test_expect_edits_metadata_keeps_preview_on_legacy_path tests/gateway/test_telegram_rich_messages.py::test_finalize_edit_opt_out_uses_legacy tests/gateway/test_telegram_rich_messages.py::test_finalize_edit_plain_content_stays_legacy tests/gateway/test_telegram_rich_messages.py::test_finalize_edit_rich_capability_error_falls_back_to_legacy tests/gateway/test_telegram_rich_messages.py::test_finalize_edit_rich_not_modified_is_success_noop tests/gateway/test_telegram_rich_messages.py::test_finalize_edit_rich_over_markdownv2_limit_not_split tests/gateway/test_telegram_rich_messages.py::test_finalize_edit_uses_rich_for_table_content tests/gateway/test_telegram_rich_messages.py::test_math_outside_details_still_uses_rich_send tests/gateway/test_telegram_rich_messages.py::test_non_finalize_edit_never_uses_rich tests/gateway/test_telegram_rich_messages.py::test_notification_opt_in_drops_disable_flag tests/gateway/test_telegram_rich_messages.py::test_notification_silent_by_default tests/gateway/test_telegram_rich_messages.py::test_oversized_content_skips_rich_and_chunks tests/gateway/test_telegram_rich_messages.py::test_per_message_bad_request_does_not_latch_off tests/gateway/test_telegram_rich_messages.py::test_permanent_rich_error_falls_back_to_legacy[exc0] tests/gateway/test_telegram_rich_messages.py::test_permanent_rich_error_falls_back_to_legacy[exc1] tests/gateway/test_telegram_rich_messages.py::test_plain_markdown_stays_on_legacy_path tests/gateway/test_telegram_rich_messages.py::test_prefers_fresh_final_streaming_honors_rich_opt_out tests/gateway/test_telegram_rich_messages.py::test_prefers_fresh_final_streaming_stays_disabled_when_rich_enabled tests/gateway/test_telegram_rich_messages.py::test_real_ptb_endpoint_missing_falls_back_and_latches_off[exc0] tests/gateway/test_telegram_rich_messages.py::test_real_ptb_endpoint_missing_falls_back_and_latches_off[exc1] tests/gateway/test_telegram_rich_messages.py::test_reply_to_propagates_as_reply_parameters tests/gateway/test_telegram_rich_messages.py::test_rich_draft_capability_failure_falls_back_and_latches_off tests/gateway/test_telegram_rich_messages.py::test_rich_draft_happy_path_sends_raw_markdown tests/gateway/test_telegram_rich_messages.py::test_rich_draft_opt_out_uses_legacy tests/gateway/test_telegram_rich_messages.py::test_rich_draft_oversized_uses_legacy tests/gateway/test_telegram_rich_messages.py::test_rich_draft_transient_failure_does_not_latch_off tests/gateway/test_telegram_rich_messages.py::test_rich_gate_tolerates_minimal_bot_without_raw_endpoint tests/gateway/test_telegram_rich_messages.py::test_rich_happy_path_sends_raw_markdown tests/gateway/test_telegram_rich_messages.py::test_rich_limit_is_characters_not_bytes tests/gateway/test_telegram_rich_messages.py::test_rich_messages_can_be_opted_out tests/gateway/test_telegram_rich_messages.py::test_rich_messages_default_is_enabled tests/gateway/test_telegram_rich_messages.py::test_rich_messages_opt_out_accepts_string_false tests/gateway/test_telegram_rich_messages.py::test_rich_messages_opt_out_uses_legacy_send_path tests/gateway/test_telegram_rich_messages.py::test_rich_payload_preserves_link_preview_disable tests/gateway/test_telegram_rich_messages.py::test_rich_reply_caption_wins_over_lookup tests/gateway/test_telegram_rich_messages.py::test_rich_reply_lookup_miss_leaves_text_none tests/gateway/test_telegram_rich_messages.py::test_rich_reply_native_quote_wins_over_lookup tests/gateway/test_telegram_rich_messages.py::test_rich_reply_records_and_recovers_text tests/gateway/test_telegram_rich_messages.py::test_rich_result_shapes_extract_message_id[raw0-123] tests/gateway/test_telegram_rich_messages.py::test_rich_result_shapes_extract_message_id[raw1-123] tests/gateway/test_telegram_rich_messages.py::test_rich_result_shapes_extract_message_id[raw2-123] tests/gateway/test_telegram_rich_messages.py::test_rich_result_shapes_extract_message_id[raw3-None] tests/gateway/test_telegram_rich_messages.py::test_routing_direct_messages_topic_id_drops_message_thread_id tests/gateway/test_telegram_rich_messages.py::test_routing_thread_id_maps_to_message_thread_id tests/gateway/test_telegram_rich_messages.py::test_streaming_overflow_limit_is_rich_cap_when_enabled tests/gateway/test_telegram_rich_messages.py::test_streaming_overflow_limit_none_when_rich_latched_off tests/gateway/test_telegram_rich_messages.py::test_streaming_overflow_limit_none_when_rich_opted_out tests/gateway/test_telegram_rich_messages.py::test_transient_rich_error_does_not_legacy_resend[exc0] tests/gateway/test_telegram_rich_messages.py::test_transient_rich_error_does_not_legacy_resend[exc1] tests/gateway/test_telegram_rich_messages.py::test_transient_timeout_is_not_retryable tests/gateway/test_telegram_rich_messages.py::test_unknown_endpoint_error_falls_back_to_legacy tests/gateway/test_telegram_send_draft_format.py::test_send_draft_falls_back_to_plain_text_on_markdownv2_error tests/gateway/test_telegram_send_draft_format.py::test_send_draft_non_badrequest_propagates_without_retry tests/gateway/test_telegram_send_draft_format.py::test_send_draft_passes_markdownv2_parse_mode tests/gateway/test_telegram_send_path_health.py::test_reconnect_storm_sets_and_heartbeat_clears_flag tests/gateway/test_telegram_send_path_health.py::test_send_short_circuits_when_path_degraded tests/gateway/test_telegram_send_path_health.py::test_send_succeeds_when_path_healthy tests/gateway/test_telegram_slash_confirm.py::TestSendSlashConfirm::test_not_connected_returns_failure tests/gateway/test_telegram_slash_confirm.py::TestSendSlashConfirm::test_stores_slash_confirm_state tests/gateway/test_telegram_slash_confirm.py::TestSendSlashConfirm::test_uses_markdown_v2_and_escapes_special_chars tests/gateway/test_telegram_status_indicator.py::test_api_failure_is_swallowed tests/gateway/test_telegram_status_indicator.py::test_custom_status_strings tests/gateway/test_telegram_status_indicator.py::test_disabled_by_default tests/gateway/test_telegram_status_indicator.py::test_disabled_is_noop tests/gateway/test_telegram_status_indicator.py::test_enabled_via_extra tests/gateway/test_telegram_status_indicator.py::test_noop_when_bot_is_none tests/gateway/test_telegram_status_indicator.py::test_offline_sets_default_text tests/gateway/test_telegram_status_indicator.py::test_online_sets_default_text tests/gateway/test_telegram_status_indicator.py::test_text_truncated_to_120_chars tests/gateway/test_telegram_status_update.py::test_distinct_chat_ids_do_not_collide tests/gateway/test_telegram_status_update.py::test_distinct_status_keys_do_not_collide tests/gateway/test_telegram_status_update.py::test_edit_failure_falls_back_to_fresh_send tests/gateway/test_telegram_status_update.py::test_first_call_sends_and_caches_message_id tests/gateway/test_telegram_status_update.py::test_second_call_edits_in_place tests/gateway/test_telegram_text_batch_perf.py::TestAdaptiveTextBatchTiers::test_class_constants_are_sensible tests/gateway/test_telegram_text_batch_perf.py::TestAdaptiveTextBatchTiers::test_fast_tier_uses_min_with_configured_cap tests/gateway/test_telegram_text_batch_perf.py::TestAdaptiveTextBatchTiers::test_long_message_uses_full_cap tests/gateway/test_telegram_text_batch_perf.py::TestAdaptiveTextBatchTiers::test_short_tier_uses_min_with_configured_cap tests/gateway/test_telegram_text_batch_perf.py::TestAdaptiveTextBatchTiers::test_split_threshold_takes_priority_over_fast_tier tests/gateway/test_telegram_text_batch_perf.py::TestEnvFloatClamped::test_clamps_above_max tests/gateway/test_telegram_text_batch_perf.py::TestEnvFloatClamped::test_clamps_below_min tests/gateway/test_telegram_text_batch_perf.py::TestEnvFloatClamped::test_default_when_unset tests/gateway/test_telegram_text_batch_perf.py::TestEnvFloatClamped::test_falls_back_to_default_on_garbage tests/gateway/test_telegram_text_batch_perf.py::TestEnvFloatClamped::test_parses_valid_value tests/gateway/test_telegram_text_batch_perf.py::TestEnvFloatClamped::test_rejects_inf tests/gateway/test_telegram_text_batch_perf.py::TestEnvFloatClamped::test_rejects_nan tests/gateway/test_telegram_text_batching.py::TestTextBatching::test_batch_cleans_up_after_flush tests/gateway/test_telegram_text_batching.py::TestTextBatching::test_different_chats_not_merged tests/gateway/test_telegram_text_batching.py::TestTextBatching::test_dm_topic_batching_recovers_thread_before_keying tests/gateway/test_telegram_text_batching.py::TestTextBatching::test_single_message_dispatched_after_delay tests/gateway/test_telegram_text_batching.py::TestTextBatching::test_split_messages_aggregated tests/gateway/test_telegram_text_batching.py::TestTextBatching::test_three_way_split_aggregated tests/gateway/test_telegram_thread_fallback.py::test_animation_dm_topic_reply_not_found_retry_drops_thread_id tests/gateway/test_telegram_thread_fallback.py::test_base_gateway_metadata_for_resumed_telegram_dm_topic_uses_direct_topic tests/gateway/test_telegram_thread_fallback.py::test_base_gateway_metadata_marks_telegram_dm_topics_as_reply_fallback tests/gateway/test_telegram_thread_fallback.py::test_base_gateway_replies_to_triggering_message_for_telegram_dm_topic tests/gateway/test_telegram_thread_fallback.py::test_base_send_image_fallback_preserves_metadata tests/gateway/test_telegram_thread_fallback.py::test_created_private_topic_thread_not_found_fails_without_root_fallback tests/gateway/test_telegram_thread_fallback.py::test_forum_general_topic_without_message_thread_id_keeps_thread_context tests/gateway/test_telegram_thread_fallback.py::test_forum_group_topic_message_preserves_thread_session_key tests/gateway/test_telegram_thread_fallback.py::test_gateway_runner_busy_ack_replies_to_triggering_message_for_telegram_dm_topic tests/gateway/test_telegram_thread_fallback.py::test_media_group_dm_topic_reply_not_found_retry_drops_thread_id tests/gateway/test_telegram_thread_fallback.py::test_native_media_dm_topic_reply_not_found_retry_drops_thread_id[send_document-send_document-file_path-report.txt-report-data] tests/gateway/test_telegram_thread_fallback.py::test_native_media_dm_topic_reply_not_found_retry_drops_thread_id[send_image_file-send_photo-image_path-photo.png-png-data] tests/gateway/test_telegram_thread_fallback.py::test_native_media_dm_topic_reply_not_found_retry_drops_thread_id[send_video-send_video-video_path-clip.mp4-video-data] tests/gateway/test_telegram_thread_fallback.py::test_native_media_dm_topic_reply_not_found_retry_drops_thread_id[send_voice-send_audio-audio_path-clip.mp3-mp3-data] tests/gateway/test_telegram_thread_fallback.py::test_native_media_dm_topic_reply_not_found_retry_drops_thread_id[send_voice-send_voice-audio_path-clip.ogg-ogg-data] tests/gateway/test_telegram_thread_fallback.py::test_non_forum_group_reply_thread_id_does_not_fork_session_key tests/gateway/test_telegram_thread_fallback.py::test_send_created_private_topic_uses_message_thread_without_anchor tests/gateway/test_telegram_thread_fallback.py::test_send_dm_topic_fallback_without_anchor_does_not_crash tests/gateway/test_telegram_thread_fallback.py::test_send_dm_topic_reply_not_found_fails_closed tests/gateway/test_telegram_thread_fallback.py::test_send_does_not_retry_timeout tests/gateway/test_telegram_thread_fallback.py::test_send_image_upload_dm_topic_reply_not_found_retry_drops_thread_id tests/gateway/test_telegram_thread_fallback.py::test_send_image_url_dm_topic_reply_not_found_retry_drops_thread_id tests/gateway/test_telegram_thread_fallback.py::test_send_marks_pool_timeout_retryable_after_exhaustion tests/gateway/test_telegram_thread_fallback.py::test_send_marks_wrapped_connect_timeout_retryable_after_exhaustion tests/gateway/test_telegram_thread_fallback.py::test_send_model_picker_uses_metadata_reply_fallback_for_dm_topics tests/gateway/test_telegram_thread_fallback.py::test_send_omits_general_topic_thread_id tests/gateway/test_telegram_thread_fallback.py::test_send_private_dm_topic_uses_direct_messages_topic_id tests/gateway/test_telegram_thread_fallback.py::test_send_raises_on_other_bad_request tests/gateway/test_telegram_thread_fallback.py::test_send_reply_fallback_applies_to_every_chunk_for_dm_topics tests/gateway/test_telegram_thread_fallback.py::test_send_retries_network_errors_normally tests/gateway/test_telegram_thread_fallback.py::test_send_retries_pool_timeout tests/gateway/test_telegram_thread_fallback.py::test_send_retries_retry_after_errors tests/gateway/test_telegram_thread_fallback.py::test_send_retries_transient_thread_not_found_before_fallback tests/gateway/test_telegram_thread_fallback.py::test_send_retries_without_thread_on_thread_not_found tests/gateway/test_telegram_thread_fallback.py::test_send_retries_wrapped_connect_timeout tests/gateway/test_telegram_thread_fallback.py::test_send_typing_attempts_api_call_for_dm_topic_reply_fallback tests/gateway/test_telegram_thread_fallback.py::test_send_typing_does_not_fall_back_to_root_for_dm_topic tests/gateway/test_telegram_thread_fallback.py::test_send_typing_falls_back_without_thread_on_bad_request tests/gateway/test_telegram_thread_fallback.py::test_send_typing_preserves_general_topic_thread_id tests/gateway/test_telegram_thread_fallback.py::test_send_uses_metadata_reply_fallback_for_streaming_dm_topics tests/gateway/test_telegram_thread_fallback.py::test_send_uses_reply_anchor_when_direct_topic_fallback_metadata_exists tests/gateway/test_telegram_thread_fallback.py::test_send_uses_reply_fallback_for_hermes_dm_topics tests/gateway/test_telegram_thread_fallback.py::test_send_without_thread_id_unaffected tests/gateway/test_telegram_thread_fallback.py::test_slash_confirm_forum_callback_followup_keeps_existing_thread_behavior tests/gateway/test_telegram_thread_fallback.py::test_slash_confirm_private_topic_callback_followup_sends_thread_and_reply tests/gateway/test_telegram_thread_fallback.py::test_thread_fallback_only_fires_once tests/gateway/test_telegram_topic_mode.py::test_auto_generated_title_does_not_rename_topic_bound_to_other_session tests/gateway/test_telegram_topic_mode.py::test_auto_generated_title_renames_bound_telegram_topic tests/gateway/test_telegram_topic_mode.py::test_binding_survives_session_deletion_via_cascade tests/gateway/test_telegram_topic_mode.py::test_disable_topic_auto_rename_extra_skips_rename tests/gateway/test_telegram_topic_mode.py::test_first_message_inside_topic_records_topic_binding tests/gateway/test_telegram_topic_mode.py::test_general_topic_is_treated_as_root_lobby tests/gateway/test_telegram_topic_mode.py::test_get_telegram_topic_binding_by_session_returns_binding tests/gateway/test_telegram_topic_mode.py::test_get_telegram_topic_binding_by_session_returns_none_for_unknown tests/gateway/test_telegram_topic_mode.py::test_group_new_keeps_existing_reset_semantics_when_dm_topic_mode_enabled tests/gateway/test_telegram_topic_mode.py::test_list_telegram_topic_bindings_for_chat tests/gateway/test_telegram_topic_mode.py::test_list_telegram_topic_bindings_for_chat_no_table tests/gateway/test_telegram_topic_mode.py::test_lobby_reminder_is_debounced_per_chat tests/gateway/test_telegram_topic_mode.py::test_managed_topic_binding_reuses_restored_session_over_static_lane_session tests/gateway/test_telegram_topic_mode.py::test_migration_rebuilds_v1_binding_table_with_cascade_fk tests/gateway/test_telegram_topic_mode.py::test_new_inside_telegram_topic_resets_current_topic_with_parallel_tip tests/gateway/test_telegram_topic_mode.py::test_new_inside_telegram_topic_rewrites_binding_to_new_session tests/gateway/test_telegram_topic_mode.py::test_operator_declared_topic_is_not_auto_renamed tests/gateway/test_telegram_topic_mode.py::test_recover_preserves_unknown_thread_id_for_new_topic tests/gateway/test_telegram_topic_mode.py::test_recover_returns_none_for_brand_new_topic tests/gateway/test_telegram_topic_mode.py::test_recover_returns_none_for_known_topic tests/gateway/test_telegram_topic_mode.py::test_recover_returns_none_when_no_bindings_yet tests/gateway/test_telegram_topic_mode.py::test_recover_returns_none_when_topic_mode_disabled tests/gateway/test_telegram_topic_mode.py::test_recover_rewrites_lobby_thread_id_to_most_recent tests/gateway/test_telegram_topic_mode.py::test_root_telegram_dm_new_shows_create_topic_instruction tests/gateway/test_telegram_topic_mode.py::test_root_telegram_dm_prompt_is_system_lobby_when_topic_mode_enabled tests/gateway/test_telegram_topic_mode.py::test_schedule_topic_rename_respects_disable_flag tests/gateway/test_telegram_topic_mode.py::test_session_split_restores_source_thread_id_from_binding tests/gateway/test_telegram_topic_mode.py::test_telegram_group_prompt_is_not_topic_lobby_even_when_dm_topic_mode_enabled tests/gateway/test_telegram_topic_mode.py::test_telegram_topic_auto_rename_disabled_string_truthy tests/gateway/test_telegram_topic_mode.py::test_telegram_topic_prompt_still_runs_agent_when_topic_mode_enabled tests/gateway/test_telegram_topic_mode.py::test_topic_binding_follows_compression_tip_on_read tests/gateway/test_telegram_topic_mode.py::test_topic_command_inside_bound_topic_shows_current_session tests/gateway/test_telegram_topic_mode.py::test_topic_command_is_private_dm_only_and_does_not_enable_group_topic_mode tests/gateway/test_telegram_topic_mode.py::test_topic_help_subcommand_returns_usage tests/gateway/test_telegram_topic_mode.py::test_topic_off_disables_mode_and_clears_bindings tests/gateway/test_telegram_topic_mode.py::test_topic_off_is_idempotent_when_never_enabled tests/gateway/test_telegram_topic_mode.py::test_topic_refuses_unauthorized_user tests/gateway/test_telegram_topic_mode.py::test_topic_restore_inside_topic_binds_old_session_and_returns_last_assistant_message tests/gateway/test_telegram_topic_mode.py::test_topic_restore_refuses_already_linked_session tests/gateway/test_telegram_topic_mode.py::test_topic_restore_refuses_session_owned_by_another_telegram_user tests/gateway/test_telegram_topic_mode.py::test_topic_root_command_creates_and_pins_system_topic tests/gateway/test_telegram_topic_mode.py::test_topic_root_command_explicitly_migrates_and_enables_topic_mode tests/gateway/test_telegram_topic_mode.py::test_topic_root_command_handles_no_unlinked_sessions tests/gateway/test_telegram_topic_mode.py::test_topic_root_command_lists_unlinked_sessions_for_restore tests/gateway/test_telegram_voice_v0_regressions.py::test_telegram_audio_size_gate_rejects_oversized_media_before_download tests/gateway/test_telegram_voice_v0_regressions.py::test_voice_tts_is_explicit_audio_reply_opt_in tests/gateway/test_telegram_webhook_secret.py::TestTelegramWebhookSecretRequired::test_guard_message_explains_remediation tests/gateway/test_telegram_webhook_secret.py::TestTelegramWebhookSecretRequired::test_guard_message_includes_advisory_link tests/gateway/test_telegram_webhook_secret.py::TestTelegramWebhookSecretRequired::test_guard_raises_runtime_error tests/gateway/test_telegram_webhook_secret.py::TestTelegramWebhookSecretRequired::test_polling_branch_has_no_secret_guard tests/gateway/test_telegram_webhook_secret.py::TestTelegramWebhookSecretRequired::test_webhook_branch_checks_secret tests/gateway/test_text_batching.py::TestDiscordTextBatching::test_adaptive_delay_for_near_limit_chunk tests/gateway/test_text_batching.py::TestDiscordTextBatching::test_batch_cleans_up_after_flush tests/gateway/test_text_batching.py::TestDiscordTextBatching::test_different_chats_not_merged tests/gateway/test_text_batching.py::TestDiscordTextBatching::test_shield_protects_handle_message_from_cancel tests/gateway/test_text_batching.py::TestDiscordTextBatching::test_single_message_dispatched_after_delay tests/gateway/test_text_batching.py::TestDiscordTextBatching::test_split_messages_aggregated tests/gateway/test_text_batching.py::TestDiscordTextBatching::test_three_way_split_aggregated tests/gateway/test_text_batching.py::TestFeishuAdaptiveDelay::test_near_limit_chunk_uses_split_delay tests/gateway/test_text_batching.py::TestFeishuAdaptiveDelay::test_short_chunk_uses_normal_delay tests/gateway/test_text_batching.py::TestFeishuAdaptiveDelay::test_split_continuation_merged tests/gateway/test_text_batching.py::TestMatrixTextBatching::test_adaptive_delay_for_near_limit_chunk tests/gateway/test_text_batching.py::TestMatrixTextBatching::test_batch_cleans_up_after_flush tests/gateway/test_text_batching.py::TestMatrixTextBatching::test_different_rooms_not_merged tests/gateway/test_text_batching.py::TestMatrixTextBatching::test_single_message_dispatched_after_delay tests/gateway/test_text_batching.py::TestMatrixTextBatching::test_split_messages_aggregated tests/gateway/test_text_batching.py::TestTelegramAdaptiveDelay::test_near_limit_chunk_uses_split_delay tests/gateway/test_text_batching.py::TestTelegramAdaptiveDelay::test_short_chunk_uses_normal_delay tests/gateway/test_text_batching.py::TestTelegramAdaptiveDelay::test_split_continuation_merged tests/gateway/test_text_batching.py::TestWeComTextBatching::test_adaptive_delay_for_near_limit_chunk tests/gateway/test_text_batching.py::TestWeComTextBatching::test_batch_cleans_up_after_flush tests/gateway/test_text_batching.py::TestWeComTextBatching::test_different_chats_not_merged tests/gateway/test_text_batching.py::TestWeComTextBatching::test_single_message_dispatched_after_delay tests/gateway/test_text_batching.py::TestWeComTextBatching::test_split_messages_aggregated tests/gateway/test_title_command.py::TestHandleTitleCommand::test_no_session_db tests/gateway/test_title_command.py::TestHandleTitleCommand::test_set_title tests/gateway/test_title_command.py::TestHandleTitleCommand::test_set_title_propagates_to_telegram_topic_rename tests/gateway/test_title_command.py::TestHandleTitleCommand::test_show_title_does_not_rename_topic tests/gateway/test_title_command.py::TestHandleTitleCommand::test_show_title_when_not_set tests/gateway/test_title_command.py::TestHandleTitleCommand::test_show_title_when_set tests/gateway/test_title_command.py::TestHandleTitleCommand::test_title_conflict tests/gateway/test_title_command.py::TestHandleTitleCommand::test_title_control_chars_sanitized tests/gateway/test_title_command.py::TestHandleTitleCommand::test_title_only_control_chars tests/gateway/test_title_command.py::TestHandleTitleCommand::test_title_too_long tests/gateway/test_title_command.py::TestHandleTitleCommand::test_works_across_platforms tests/gateway/test_title_command.py::TestNewInHelp::test_new_command_in_help_output tests/gateway/test_title_command.py::TestResetCommandWithTitle::test_reset_command_duplicate_title_surfaces_warning tests/gateway/test_title_command.py::TestResetCommandWithTitle::test_reset_command_with_title tests/gateway/test_title_command.py::TestTitleInHelp::test_title_in_help_output tests/gateway/test_title_command.py::TestTitleInHelp::test_title_is_known_command tests/gateway/test_tool_response_drop_recovery.py::TestExtractStripRecoveryAllPlatforms::test_directives_stripped_from_fallback_text[Platform.DISCORD] tests/gateway/test_tool_response_drop_recovery.py::TestExtractStripRecoveryAllPlatforms::test_directives_stripped_from_fallback_text[Platform.TELEGRAM] tests/gateway/test_tool_response_drop_recovery.py::TestExtractStripRecoveryAllPlatforms::test_no_fallback_when_attachment_produced[Platform.DISCORD] tests/gateway/test_tool_response_drop_recovery.py::TestExtractStripRecoveryAllPlatforms::test_no_fallback_when_attachment_produced[Platform.TELEGRAM] tests/gateway/test_tool_response_drop_recovery.py::TestExtractStripRecoveryAllPlatforms::test_response_reduced_to_empty_is_recovered_and_sent[Platform.DISCORD] tests/gateway/test_tool_response_drop_recovery.py::TestExtractStripRecoveryAllPlatforms::test_response_reduced_to_empty_is_recovered_and_sent[Platform.TELEGRAM] tests/gateway/test_tool_response_drop_recovery.py::TestRecoveryDoesNotLeakMediaFragments::test_spaced_media_path_does_not_leak_fragment tests/gateway/test_tool_response_drop_recovery.py::TestUnrecoverableDropIsLoud::test_directive_only_response_logs_dropped tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_else_branch_returns_empty_list tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_multiple_session_meta_larger_drift tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_no_session_meta_same_result tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_recursive_queued_followup_keeps_outer_history_offset tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_recursive_queued_followup_preserves_smaller_existing_offset tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_session_meta_causes_offset_mismatch tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_system_messages_also_filtered tests/gateway/test_transcript_offset.py::TestTranscriptHistoryOffset::test_tool_call_messages_preserved_in_filter tests/gateway/test_tts_media_routing.py::test_base_adapter_routes_non_voice_telegram_ogg_media_tag_to_document_sender tests/gateway/test_tts_media_routing.py::test_base_adapter_routes_telegram_flac_media_tag_to_document_sender tests/gateway/test_tts_media_routing.py::test_base_adapter_routes_voice_tagged_telegram_ogg_media_tag_to_voice_sender tests/gateway/test_tts_media_routing.py::test_streaming_delivery_blocks_media_path_outside_allowed_roots tests/gateway/test_tts_media_routing.py::test_streaming_delivery_routes_non_voice_telegram_ogg_media_tag_to_document_sender tests/gateway/test_tts_media_routing.py::test_streaming_delivery_routes_telegram_flac_media_tag_to_document_sender tests/gateway/test_tts_media_routing.py::test_streaming_delivery_routes_telegram_mp3_media_tag_to_voice_sender tests/gateway/test_unauthorized_dm_behavior.py::test_allowlist_authorized_user_returns_ignore_for_unauthorized tests/gateway/test_unauthorized_dm_behavior.py::test_explicit_pair_config_overrides_allowlist_default tests/gateway/test_unauthorized_dm_behavior.py::test_get_unauthorized_dm_behavior_no_allowlist_returns_pair tests/gateway/test_unauthorized_dm_behavior.py::test_global_allowlist_ignores_unauthorized_dm tests/gateway/test_unauthorized_dm_behavior.py::test_global_ignore_suppresses_pairing_reply tests/gateway/test_unauthorized_dm_behavior.py::test_handle_message_does_not_drop_anonymous_sender_in_allowlisted_chat tests/gateway/test_unauthorized_dm_behavior.py::test_handle_message_drops_anonymous_sender_outside_allowlist tests/gateway/test_unauthorized_dm_behavior.py::test_no_allowlist_still_pairs_by_default tests/gateway/test_unauthorized_dm_behavior.py::test_qq_group_allowlist_authorizes_group_chat_without_user_allowlist tests/gateway/test_unauthorized_dm_behavior.py::test_qq_group_allowlist_does_not_authorize_other_groups tests/gateway/test_unauthorized_dm_behavior.py::test_qqbot_with_allowlist_ignores_unauthorized_dm tests/gateway/test_unauthorized_dm_behavior.py::test_rate_limited_user_gets_no_response tests/gateway/test_unauthorized_dm_behavior.py::test_rejection_message_records_rate_limit tests/gateway/test_unauthorized_dm_behavior.py::test_signal_with_allowlist_ignores_unauthorized_dm tests/gateway/test_unauthorized_dm_behavior.py::test_simplex_allowlist_accepts_display_name tests/gateway/test_unauthorized_dm_behavior.py::test_simplex_allowlist_accepts_numeric_contact_id tests/gateway/test_unauthorized_dm_behavior.py::test_simplex_allowlist_denies_unlisted tests/gateway/test_unauthorized_dm_behavior.py::test_star_wildcard_in_allowlist_authorizes_any_user tests/gateway/test_unauthorized_dm_behavior.py::test_star_wildcard_works_for_any_platform tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_chat_allowlist_authorizes_anonymous_sender tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_chat_allowlist_authorizes_group_chat_without_user_allowlist tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_chat_allowlist_rejects_anonymous_sender_in_other_chat tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_user_allowlist_authorizes_forum_sender_without_dm_allowlist tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_user_allowlist_does_not_authorize_dms tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_user_allowlist_rejects_other_senders tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_user_allowlist_wildcard_authorizes_any_sender tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_users_legacy_chat_ids_still_authorize tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_users_legacy_does_not_cross_chats tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_group_users_mixed_sender_and_legacy_chat tests/gateway/test_unauthorized_dm_behavior.py::test_telegram_with_allowlist_ignores_unauthorized_dm tests/gateway/test_unauthorized_dm_behavior.py::test_unauthorized_dm_pairs_by_default tests/gateway/test_unauthorized_dm_behavior.py::test_unauthorized_whatsapp_dm_can_be_ignored tests/gateway/test_unauthorized_dm_behavior.py::test_whatsapp_lid_user_matches_phone_allowlist_via_session_mapping tests/gateway/test_unavailable_skill_hint.py::test_frontmatter_slug_matched_even_when_dir_name_differs tests/gateway/test_unavailable_skill_hint.py::test_matched_but_not_disabled_returns_none tests/gateway/test_unavailable_skill_hint.py::test_optional_skill_uses_frontmatter_slug tests/gateway/test_unavailable_skill_hint.py::test_slug_normalization_strips_non_alnum tests/gateway/test_unavailable_skill_hint.py::test_unknown_command_still_returns_none tests/gateway/test_undo_rewind_session.py::test_rewind_clamps_negative_count_to_one tests/gateway/test_undo_rewind_session.py::test_rewind_clamps_to_oldest_turn tests/gateway/test_undo_rewind_session.py::test_rewind_default_one_turn tests/gateway/test_undo_rewind_session.py::test_rewind_empty_session_returns_none tests/gateway/test_undo_rewind_session.py::test_rewind_n_turns tests/gateway/test_undo_rewind_session.py::test_rewind_soft_deletes_rows_for_audit tests/gateway/test_unknown_command.py::test_command_hook_allow_decision_is_passthrough tests/gateway/test_unknown_command.py::test_command_hook_can_deny_before_dispatch tests/gateway/test_unknown_command.py::test_command_hook_can_mark_command_as_handled tests/gateway/test_unknown_command.py::test_command_hook_deny_without_message_uses_default tests/gateway/test_unknown_command.py::test_command_hook_fires_for_plugin_registered_command tests/gateway/test_unknown_command.py::test_command_hook_non_dict_return_values_ignored tests/gateway/test_unknown_command.py::test_command_hook_rewrite_routes_to_plugin tests/gateway/test_unknown_command.py::test_known_slash_command_not_flagged_as_unknown tests/gateway/test_unknown_command.py::test_underscored_alias_for_hyphenated_builtin_not_flagged tests/gateway/test_unknown_command.py::test_unknown_slash_command_returns_guidance tests/gateway/test_unknown_command.py::test_unknown_slash_command_underscored_form_also_guarded tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_fallback_to_sys_executable tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_fallback_when_no_setsid tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_managed_install_returns_package_manager_guidance tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_no_git_directory tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_no_hermes_binary tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_popen_failure_cleans_up tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_resolve_hermes_bin_fallback tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_resolve_hermes_bin_prefers_which tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_resolve_hermes_bin_returns_none_when_both_fail tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_returns_user_friendly_message tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_spawns_setsid tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_writes_pending_marker tests/gateway/test_update_command.py::TestHandleUpdateCommand::test_writes_pending_marker_with_thread_id tests/gateway/test_update_command.py::TestSendUpdateNotification::test_cleans_up_files_after_notification tests/gateway/test_update_command.py::TestSendUpdateNotification::test_cleans_up_on_error tests/gateway/test_update_command.py::TestSendUpdateNotification::test_deferred_notification_delivers_after_reconnect tests/gateway/test_update_command.py::TestSendUpdateNotification::test_defers_notification_while_update_still_running tests/gateway/test_update_command.py::TestSendUpdateNotification::test_handles_corrupt_pending_file tests/gateway/test_update_command.py::TestSendUpdateNotification::test_no_adapter_for_platform_preserves_markers tests/gateway/test_update_command.py::TestSendUpdateNotification::test_no_pending_file_is_noop tests/gateway/test_update_command.py::TestSendUpdateNotification::test_recovers_from_claimed_pending_file tests/gateway/test_update_command.py::TestSendUpdateNotification::test_sends_failure_message_when_update_fails tests/gateway/test_update_command.py::TestSendUpdateNotification::test_sends_generic_message_when_no_output tests/gateway/test_update_command.py::TestSendUpdateNotification::test_sends_notification_with_output tests/gateway/test_update_command.py::TestSendUpdateNotification::test_sends_notification_with_thread_metadata tests/gateway/test_update_command.py::TestSendUpdateNotification::test_strips_ansi_codes tests/gateway/test_update_command.py::TestSendUpdateNotification::test_truncates_long_output tests/gateway/test_update_command.py::TestUpdateCommandPlatformGate::test_allows_builtin_platform_in_allowlist tests/gateway/test_update_command.py::TestUpdateCommandPlatformGate::test_allows_homeassistant_via_registry_fallback tests/gateway/test_update_command.py::TestUpdateCommandPlatformGate::test_allows_mattermost_via_registry_fallback tests/gateway/test_update_command.py::TestUpdateCommandPlatformGate::test_allows_plugin_platform_via_registry_fallback tests/gateway/test_update_command.py::TestUpdateCommandPlatformGate::test_blocks_api_server_platform tests/gateway/test_update_command.py::TestUpdateCommandPlatformGate::test_blocks_programmatic_interface tests/gateway/test_update_command.py::TestUpdateInHelp::test_update_in_help_output tests/gateway/test_update_command.py::TestUpdateInHelp::test_update_is_known_command tests/gateway/test_update_streaming.py::TestCmdUpdateGatewayMode::test_gateway_flag_enables_gateway_prompt_for_stash tests/gateway/test_update_streaming.py::TestCmdUpdateGatewayMode::test_gateway_flag_parsed tests/gateway/test_update_streaming.py::TestGatewayPrompt::test_empty_response_returns_default tests/gateway/test_update_streaming.py::TestGatewayPrompt::test_prompt_file_content tests/gateway/test_update_streaming.py::TestGatewayPrompt::test_timeout_returns_default tests/gateway/test_update_streaming.py::TestGatewayPrompt::test_writes_prompt_file_and_reads_response tests/gateway/test_update_streaming.py::TestRestoreStashWithInputFn::test_input_fn_yes_proceeds_with_restore tests/gateway/test_update_streaming.py::TestRestoreStashWithInputFn::test_uses_input_fn_when_provided tests/gateway/test_update_streaming.py::TestUpdateCommandGatewayFlag::test_spawns_with_gateway_flag tests/gateway/test_update_streaming.py::TestUpdatePromptInterception::test_intercepts_response_when_prompt_pending tests/gateway/test_update_streaming.py::TestUpdatePromptInterception::test_normal_message_when_no_prompt_pending tests/gateway/test_update_streaming.py::TestUpdatePromptInterception::test_recognized_slash_command_bypasses_pending_update_prompt tests/gateway/test_update_streaming.py::TestUpdatePromptInterception::test_unrecognized_slash_command_still_consumed_as_response tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_cleans_up_on_completion tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_detects_and_forwards_prompt tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_failure_exit_code tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_falls_back_and_delivers_after_reconnect tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_prompt_forwarded_only_once tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_prompt_forwarding_preserves_thread_metadata tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_prompt_is_recovered_after_watcher_restart tests/gateway/test_update_streaming.py::TestWatchUpdateProgress::test_streams_output_to_adapter tests/gateway/test_usage_command.py::TestUsageAccountSection::test_usage_command_includes_account_section tests/gateway/test_usage_command.py::TestUsageAccountSection::test_usage_command_uses_persisted_provider_when_agent_not_running tests/gateway/test_usage_command.py::TestUsageCachedAgent::test_cache_read_write_hidden_when_zero tests/gateway/test_usage_command.py::TestUsageCachedAgent::test_cached_agent_shows_detailed_usage tests/gateway/test_usage_command.py::TestUsageCachedAgent::test_cost_included_status tests/gateway/test_usage_command.py::TestUsageCachedAgent::test_no_agent_anywhere_falls_to_history tests/gateway/test_usage_command.py::TestUsageCachedAgent::test_running_agent_preferred_over_cache tests/gateway/test_usage_command.py::TestUsageCachedAgent::test_sentinel_skipped_uses_cache tests/gateway/test_verbose_command.py::TestVerboseCommand::test_cycles_through_all_modes tests/gateway/test_verbose_command.py::TestVerboseCommand::test_defaults_to_platform_default_when_no_tool_progress_set tests/gateway/test_verbose_command.py::TestVerboseCommand::test_disabled_by_default tests/gateway/test_verbose_command.py::TestVerboseCommand::test_enabled_cycles_mode tests/gateway/test_verbose_command.py::TestVerboseCommand::test_no_config_file_returns_disabled tests/gateway/test_verbose_command.py::TestVerboseCommand::test_per_platform_isolation tests/gateway/test_verbose_command.py::TestVerboseCommand::test_quoted_false_keeps_command_disabled tests/gateway/test_verbose_command.py::TestVerboseCommand::test_verbose_is_in_gateway_known_commands tests/gateway/test_verify_dualcoach_v11_candidate.py::test_release_inputs_bind_fresh_source_and_installed_golden_paths tests/gateway/test_verify_dualcoach_v11_candidate.py::test_successor_binding_changes_only_the_hermes_wheel tests/gateway/test_verify_dualcoach_v11_candidate.py::test_successor_wheel_has_only_the_ttl_and_record_delta tests/gateway/test_verify_dualcoach_v11_candidate.py::test_successor_wheel_rejects_unrecorded_member_tampering tests/gateway/test_version_command.py::test_gateway_version_command_returns_release_line tests/gateway/test_video_context_note.py::test_video_attachment_adds_path_note_without_document_wording tests/gateway/test_vision_memory_leak.py::TestEnrichMessageWithVision::test_clean_description_passes_through tests/gateway/test_vision_memory_leak.py::TestEnrichMessageWithVision::test_fenced_leak_stripped_plugin_header_preserved tests/gateway/test_vision_memory_leak.py::TestEnrichMessageWithVision::test_memory_context_fence_stripped tests/gateway/test_voice_command.py::TestAutoTtsEmptyTextGuard::test_base_empty_check_in_source tests/gateway/test_voice_command.py::TestAutoTtsEmptyTextGuard::test_code_block_response_skips_tts tests/gateway/test_voice_command.py::TestAutoTtsEmptyTextGuard::test_empty_after_strip_skips_tts tests/gateway/test_voice_command.py::TestAutoTtsTempFileCleanup::test_source_has_finally_remove tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_dedup_skips_when_agent_called_tts tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_discord_vc_voice_input_base_handles tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_discord_vc_voice_only_base_handles tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_empty_response_skipped tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_error_response_skipped tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_no_dedup_for_other_tools tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_off_mode_text tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_off_mode_voice tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_text_input_all_mode_runner_fires tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_text_input_voice_only_no_reply tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_voice_input_all_mode_skipped tests/gateway/test_voice_command.py::TestAutoVoiceReply::test_voice_input_voice_only_skipped tests/gateway/test_voice_command.py::TestCallbackWiringOrder::test_callback_set_before_join tests/gateway/test_voice_command.py::TestCallbackWiringOrder::test_join_failure_clears_callback tests/gateway/test_voice_command.py::TestCallbackWiringOrder::test_join_returns_false_clears_callback tests/gateway/test_voice_command.py::TestDisconnectVoiceCleanup::test_disconnect_clears_voice_state tests/gateway/test_voice_command.py::TestDiscordPlayTtsSkip::test_play_tts_not_skipped_for_different_channel tests/gateway/test_voice_command.py::TestDiscordPlayTtsSkip::test_play_tts_not_skipped_when_not_in_vc tests/gateway/test_voice_command.py::TestDiscordPlayTtsSkip::test_play_tts_plays_in_vc_when_connected tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_get_user_voice_channel_no_client tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_get_user_voice_channel_no_guild tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_get_user_voice_channel_success tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_get_user_voice_channel_user_not_in_vc tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_is_allowed_user_empty_list tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_is_allowed_user_in_list tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_is_allowed_user_not_in_list tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_is_in_voice_channel_false_disconnected tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_is_in_voice_channel_false_no_client tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_is_in_voice_channel_true tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_leave_voice_channel_cleans_up tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_leave_voice_channel_no_connection tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_play_in_voice_channel_not_connected tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_process_voice_input_exception_caught tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_process_voice_input_hallucination_filtered tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_process_voice_input_stt_failure tests/gateway/test_voice_command.py::TestDiscordVoiceChannelMethods::test_process_voice_input_success tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_per_chat_isolation tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_persistence_loaded tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_persistence_saved tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_persistence_saved_for_off tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_platform_isolation tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_restart_restores_voice_off_state tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_sync_populates_enabled_chats_from_voice_modes tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_sync_pushes_config_default_onto_adapter tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_sync_voice_mode_state_to_adapter_restores_off_chats tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_toggle_off_to_on tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_toggle_on_to_off tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_voice_off tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_voice_on tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_voice_status_off tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_voice_status_on tests/gateway/test_voice_command.py::TestHandleVoiceCommand::test_voice_tts tests/gateway/test_voice_command.py::TestLeaveExceptionHandling::test_leave_clears_callback tests/gateway/test_voice_command.py::TestLeaveExceptionHandling::test_leave_exception_still_cleans_state tests/gateway/test_voice_command.py::TestPacketDebugCounterIsInstanceLevel::test_counter_initialized_in_init tests/gateway/test_voice_command.py::TestPacketDebugCounterIsInstanceLevel::test_counter_is_per_instance tests/gateway/test_voice_command.py::TestPlayInVoiceChannelUsesRunningLoop::test_source_uses_get_running_loop tests/gateway/test_voice_command.py::TestPlaybackTimeout::test_is_playing_wait_has_timeout tests/gateway/test_voice_command.py::TestPlaybackTimeout::test_playback_timeout_constant_exists tests/gateway/test_voice_command.py::TestPlaybackTimeout::test_playback_timeout_fires tests/gateway/test_voice_command.py::TestPlaybackTimeout::test_source_has_wait_for_timeout tests/gateway/test_voice_command.py::TestSendVoiceReply::test_auto_voice_reply_uses_thread_metadata_helper tests/gateway/test_voice_command.py::TestSendVoiceReply::test_calls_tts_and_send_voice tests/gateway/test_voice_command.py::TestSendVoiceReply::test_empty_text_after_strip_skips tests/gateway/test_voice_command.py::TestSendVoiceReply::test_exception_caught tests/gateway/test_voice_command.py::TestSendVoiceReply::test_non_telegram_auto_voice_reply_uses_mp3 tests/gateway/test_voice_command.py::TestSendVoiceReply::test_tts_failure_no_crash tests/gateway/test_voice_command.py::TestSendVoiceReplyCleanup::test_cleanup_in_finally tests/gateway/test_voice_command.py::TestSendVoiceReplyCleanup::test_files_cleaned_on_send_exception tests/gateway/test_voice_command.py::TestSendVoiceReplyFilename::test_filename_uses_uuid tests/gateway/test_voice_command.py::TestSendVoiceReplyFilename::test_filenames_are_unique tests/gateway/test_voice_command.py::TestShouldAutoTtsForChat::test_default_false_no_override_suppresses tests/gateway/test_voice_command.py::TestShouldAutoTtsForChat::test_default_true_no_override_fires tests/gateway/test_voice_command.py::TestShouldAutoTtsForChat::test_enabled_wins_over_disabled tests/gateway/test_voice_command.py::TestShouldAutoTtsForChat::test_explicit_disable_overrides_true_default tests/gateway/test_voice_command.py::TestShouldAutoTtsForChat::test_explicit_enable_overrides_false_default tests/gateway/test_voice_command.py::TestShouldAutoTtsForChat::test_per_chat_isolation tests/gateway/test_voice_command.py::TestStopAcquiresLock::test_stop_clears_under_lock tests/gateway/test_voice_command.py::TestStopAcquiresLock::test_stop_does_not_deadlock_with_on_packet tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_done_event_set_on_exception tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_duplicate_sentences_deduped tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_long_buffer_flushed_on_timeout tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_markdown_stripped_in_speech tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_no_api_key_display_only tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_none_sentinel_flushes_buffer tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_sentence_splitting tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_stop_event_aborts_early tests/gateway/test_voice_command.py::TestStreamTtsToSpeaker::test_think_blocks_stripped tests/gateway/test_voice_command.py::TestUDPKeepalive::test_keepalive_interval_is_reasonable tests/gateway/test_voice_command.py::TestUDPKeepalive::test_keepalive_sends_silence_frame tests/gateway/test_voice_command.py::TestVoiceChannelAwareness::test_context_empty_when_not_connected tests/gateway/test_voice_command.py::TestVoiceChannelAwareness::test_context_string_format tests/gateway/test_voice_command.py::TestVoiceChannelAwareness::test_returns_info_with_members tests/gateway/test_voice_command.py::TestVoiceChannelAwareness::test_returns_none_when_not_connected tests/gateway/test_voice_command.py::TestVoiceChannelAwareness::test_returns_none_when_vc_disconnected tests/gateway/test_voice_command.py::TestVoiceChannelAwareness::test_speaking_detection tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_get_guild_id_dm tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_get_guild_id_from_guild tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_get_guild_id_from_interaction tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_get_guild_id_none tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_input_creates_event_and_dispatches tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_input_no_adapter tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_input_no_text_channel tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_input_posts_transcript_in_text_channel tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_input_reuses_bound_source_metadata tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_input_suppresses_duplicate_transcript tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_input_suppresses_near_duplicate_transcript tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_join_exception tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_join_failure tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_join_missing_voice_dependencies tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_join_no_guild_id tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_join_success tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_join_unsupported_platform tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_join_user_not_in_vc tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_leave_no_guild tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_leave_not_in_vc tests/gateway/test_voice_command.py::TestVoiceChannelCommands::test_leave_success tests/gateway/test_voice_command.py::TestVoiceInHelp::test_voice_in_help_output tests/gateway/test_voice_command.py::TestVoiceInHelp::test_voice_is_known_command tests/gateway/test_voice_command.py::TestVoiceReceiver::test_check_silence_empty tests/gateway/test_voice_command.py::TestVoiceReceiver::test_check_silence_ignores_recent_audio tests/gateway/test_voice_command.py::TestVoiceReceiver::test_check_silence_ignores_short_buffer tests/gateway/test_voice_command.py::TestVoiceReceiver::test_check_silence_returns_completed_utterance tests/gateway/test_voice_command.py::TestVoiceReceiver::test_check_silence_unknown_user_discarded tests/gateway/test_voice_command.py::TestVoiceReceiver::test_initial_state tests/gateway/test_voice_command.py::TestVoiceReceiver::test_map_ssrc tests/gateway/test_voice_command.py::TestVoiceReceiver::test_map_ssrc_overwrites tests/gateway/test_voice_command.py::TestVoiceReceiver::test_on_packet_skips_non_rtp tests/gateway/test_voice_command.py::TestVoiceReceiver::test_on_packet_skips_short_data tests/gateway/test_voice_command.py::TestVoiceReceiver::test_on_packet_skips_when_not_running tests/gateway/test_voice_command.py::TestVoiceReceiver::test_on_packet_skips_when_paused tests/gateway/test_voice_command.py::TestVoiceReceiver::test_pause_resume tests/gateway/test_voice_command.py::TestVoiceReceiver::test_stale_buffer_discarded tests/gateway/test_voice_command.py::TestVoiceReceiver::test_start_sets_running tests/gateway/test_voice_command.py::TestVoiceReceiver::test_stop_clears_state tests/gateway/test_voice_command.py::TestVoiceReceiverThreadSafety::test_check_silence_holds_lock tests/gateway/test_voice_command.py::TestVoiceReceiverThreadSafety::test_concurrent_buffer_access_safe tests/gateway/test_voice_command.py::TestVoiceReceiverThreadSafety::test_on_packet_buffer_write_holds_lock tests/gateway/test_voice_command.py::TestVoiceReception::test_automap_multiple_allowed_users_no_map tests/gateway/test_voice_command.py::TestVoiceReception::test_automap_no_allowlist_single_member tests/gateway/test_voice_command.py::TestVoiceReception::test_automap_only_bot_in_channel tests/gateway/test_voice_command.py::TestVoiceReception::test_automap_persists_across_calls tests/gateway/test_voice_command.py::TestVoiceReception::test_automap_single_allowed_user tests/gateway/test_voice_command.py::TestVoiceReception::test_automap_unallowed_user_rejected tests/gateway/test_voice_command.py::TestVoiceReception::test_known_ssrc_recent_audio_waits tests/gateway/test_voice_command.py::TestVoiceReception::test_known_ssrc_returns_completed tests/gateway/test_voice_command.py::TestVoiceReception::test_known_ssrc_short_buffer_ignored tests/gateway/test_voice_command.py::TestVoiceReception::test_on_packet_bot_own_ssrc_ignored tests/gateway/test_voice_command.py::TestVoiceReception::test_on_packet_dave_known_user_decrypt_ok tests/gateway/test_voice_command.py::TestVoiceReception::test_on_packet_dave_other_error_drops tests/gateway/test_voice_command.py::TestVoiceReception::test_on_packet_dave_unencrypted_error_passthrough tests/gateway/test_voice_command.py::TestVoiceReception::test_on_packet_dave_unknown_ssrc_passthrough tests/gateway/test_voice_command.py::TestVoiceReception::test_on_packet_multiple_ssrcs_separate_buffers tests/gateway/test_voice_command.py::TestVoiceReception::test_on_packet_no_dave_direct_decode tests/gateway/test_voice_command.py::TestVoiceReception::test_paused_receiver_ignores_packets tests/gateway/test_voice_command.py::TestVoiceReception::test_resumed_receiver_accepts_packets tests/gateway/test_voice_command.py::TestVoiceReception::test_stale_unknown_buffer_discarded tests/gateway/test_voice_command.py::TestVoiceReception::test_unknown_ssrc_late_speaking_event tests/gateway/test_voice_command.py::TestVoiceReception::test_unknown_ssrc_no_automap_no_completed tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_agent_tts_tool_dedup tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_empty_response_no_tts tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_error_response_no_tts tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_play_tts_fallback_when_not_in_vc tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_play_tts_plays_in_vc tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_play_tts_wrong_channel_no_match tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_streaming_on_agent_tts_dedup tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_streaming_on_empty_response_no_tts tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_streaming_on_text_input_runner_fires tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_streaming_on_voice_input_runner_fires tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_streaming_on_voice_off_no_tts tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_text_input_voice_all_runner_fires tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_text_input_voice_off_no_tts tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_text_input_voice_only_no_tts tests/gateway/test_voice_command.py::TestVoiceTTSPlayback::test_voice_input_runner_skips tests/gateway/test_voice_command.py::TestVoiceTimeoutCleansRunnerState::test_adapter_has_on_voice_disconnect_attr tests/gateway/test_voice_command.py::TestVoiceTimeoutCleansRunnerState::test_runner_cleanup_method_removes_voice_mode tests/gateway/test_voice_command.py::TestVoiceTimeoutCleansRunnerState::test_timeout_calls_disconnect_callback tests/gateway/test_voice_command.py::TestVoiceTimeoutCleansRunnerState::test_timeout_skips_disconnect_when_voice_mode_off tests/gateway/test_voice_command.py::TestVoiceTimeoutCleansRunnerState::test_timeout_still_disconnects_when_voice_mode_active tests/gateway/test_voice_command.py::TestVoiceTimeoutCleansRunnerState::test_timeout_without_callback_does_not_crash tests/gateway/test_voice_mode_platform_isolation.py::TestLegacyKeyMigration::test_load_voice_modes_invalid_modes_filtered tests/gateway/test_voice_mode_platform_isolation.py::TestLegacyKeyMigration::test_load_voice_modes_preserves_prefixed_keys tests/gateway/test_voice_mode_platform_isolation.py::TestLegacyKeyMigration::test_load_voice_modes_skips_legacy_keys tests/gateway/test_voice_mode_platform_isolation.py::TestSyncVoiceModeStateToAdapter::test_sync_clears_existing_state tests/gateway/test_voice_mode_platform_isolation.py::TestSyncVoiceModeStateToAdapter::test_sync_only_includes_platform_chats tests/gateway/test_voice_mode_platform_isolation.py::TestSyncVoiceModeStateToAdapter::test_sync_returns_early_without_auto_tts_disabled_chats tests/gateway/test_voice_mode_platform_isolation.py::TestSyncVoiceModeStateToAdapter::test_sync_returns_early_without_platform tests/gateway/test_voice_mode_platform_isolation.py::TestVoiceKeyHelper::test_voice_key_different_platforms_same_chat_id tests/gateway/test_voice_mode_platform_isolation.py::TestVoiceKeyHelper::test_voice_key_format tests/gateway/test_voice_mode_platform_isolation.py::TestVoiceModePlatformIsolation::test_telegram_and_slack_voice_mode_independent tests/gateway/test_weak_credential_guard.py::TestAPIServerPlaceholderKeyGuard::test_allows_loopback_with_placeholder_key tests/gateway/test_weak_credential_guard.py::TestAPIServerPlaceholderKeyGuard::test_refuses_wildcard_with_asterisk_key tests/gateway/test_weak_credential_guard.py::TestAPIServerPlaceholderKeyGuard::test_refuses_wildcard_with_placeholder_key tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_accepts_empty_token_without_error tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_accepts_real_token tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_disabled_platform_not_checked tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_rejects_changeme tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_rejects_placeholder tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_rejects_triple_asterisk tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_rejects_whitespace_padded_placeholder tests/gateway/test_weak_credential_guard.py::TestPlatformTokenPlaceholderGuard::test_rejects_your_api_key tests/gateway/test_webhook_adapter.py::TestBodySize::test_oversized_payload_rejected tests/gateway/test_webhook_adapter.py::TestCheckRequirements::test_returns_false_without_aiohttp tests/gateway/test_webhook_adapter.py::TestCheckRequirements::test_returns_true_when_aiohttp_available tests/gateway/test_webhook_adapter.py::TestDeliverCrossPlatformThreadId::test_message_thread_id_passed_as_thread_id tests/gateway/test_webhook_adapter.py::TestDeliverCrossPlatformThreadId::test_no_thread_id_sends_no_metadata tests/gateway/test_webhook_adapter.py::TestDeliverCrossPlatformThreadId::test_thread_id_passed_as_metadata tests/gateway/test_webhook_adapter.py::TestDeliveryCleanup::test_delivery_info_prune_uses_ordered_incremental_queue tests/gateway/test_webhook_adapter.py::TestDeliveryCleanup::test_delivery_info_pruned_via_ttl tests/gateway/test_webhook_adapter.py::TestDeliveryCleanup::test_delivery_info_survives_multiple_sends tests/gateway/test_webhook_adapter.py::TestEventFilter::test_event_filter_accepts_matching tests/gateway/test_webhook_adapter.py::TestEventFilter::test_event_filter_accepts_payload_type_field tests/gateway/test_webhook_adapter.py::TestEventFilter::test_event_filter_empty_allows_all tests/gateway/test_webhook_adapter.py::TestEventFilter::test_event_filter_rejects_non_matching tests/gateway/test_webhook_adapter.py::TestHTTPHandling::test_connect_starts_server tests/gateway/test_webhook_adapter.py::TestHTTPHandling::test_disconnect_cleans_up tests/gateway/test_webhook_adapter.py::TestHTTPHandling::test_health_endpoint tests/gateway/test_webhook_adapter.py::TestHTTPHandling::test_route_without_secret_rejects_unsigned_request tests/gateway/test_webhook_adapter.py::TestHTTPHandling::test_unknown_route_returns_404 tests/gateway/test_webhook_adapter.py::TestHTTPHandling::test_webhook_handler_returns_202 tests/gateway/test_webhook_adapter.py::TestIdempotency::test_duplicate_delivery_id_returns_200 tests/gateway/test_webhook_adapter.py::TestIdempotency::test_expired_delivery_id_allows_reprocess tests/gateway/test_webhook_adapter.py::TestIdempotency::test_svix_id_used_as_delivery_id_for_deduplication tests/gateway/test_webhook_adapter.py::TestInsecureNoAuth::test_insecure_no_auth_skips_validation tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_connect_allows_insecure_no_auth_on_loopback[127.0.0.1] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_connect_allows_insecure_no_auth_on_loopback[localhost] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_connect_allows_real_secret_on_public_bind tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_connect_rejects_insecure_no_auth_on_empty_host tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_connect_rejects_insecure_no_auth_on_lan_ip tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_connect_rejects_insecure_no_auth_on_public_bind tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_accepts[127.0.0.1] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_accepts[::1] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_accepts[Localhost] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_accepts[ip6-localhost] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_accepts[ip6-loopback] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_accepts[localhost] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_rejects[0.0.0.0] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_rejects[10.0.0.1] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_rejects[192.168.1.5] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_rejects[None] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_rejects[] tests/gateway/test_webhook_adapter.py::TestInsecureNoAuthSafetyRail::test_is_loopback_host_rejects[example.com] tests/gateway/test_webhook_adapter.py::TestRateLimiting::test_rate_limit_prunes_incrementally_from_left tests/gateway/test_webhook_adapter.py::TestRateLimiting::test_rate_limit_rejects_excess tests/gateway/test_webhook_adapter.py::TestRateLimiting::test_rate_limit_window_resets tests/gateway/test_webhook_adapter.py::TestRateLimiting::test_seen_delivery_ttl_is_checked_per_delivery_without_full_prune tests/gateway/test_webhook_adapter.py::TestRawTemplateToken::test_raw_mixed_with_other_variables tests/gateway/test_webhook_adapter.py::TestRawTemplateToken::test_raw_resolves_to_full_json_payload tests/gateway/test_webhook_adapter.py::TestRawTemplateToken::test_raw_truncated_at_4000_chars tests/gateway/test_webhook_adapter.py::TestRenderDeliveryExtra::test_render_delivery_extra_templates tests/gateway/test_webhook_adapter.py::TestRenderPrompt::test_render_prompt_dot_notation tests/gateway/test_webhook_adapter.py::TestRenderPrompt::test_render_prompt_missing_key_preserved tests/gateway/test_webhook_adapter.py::TestRenderPrompt::test_render_prompt_no_template_dumps_json tests/gateway/test_webhook_adapter.py::TestSessionIsolation::test_concurrent_webhooks_get_independent_sessions tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_generic_signature_valid tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_github_signature_invalid tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_github_signature_valid tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_gitlab_token tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_gitlab_token_wrong tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_no_secret_allows_all tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_no_signature_with_secret_rejects tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_invalid_whsec_rejects tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_missing_signature_rejects tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_multiple_entries_accepts_matching_v1 tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_old_timestamp_rejects tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_raw_secret_valid tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_unsupported_version_rejects tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_valid tests/gateway/test_webhook_adapter.py::TestValidateSignature::test_validate_svix_signature_wrong_body_rejects tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyBypassesAgent::test_post_delivers_directly_without_agent tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyBypassesAgent::test_template_rendering_works tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyBypassesAgent::test_thread_id_passed_through tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlySecurityInvariants::test_hmac_still_enforced tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlySecurityInvariants::test_idempotency_still_applies tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlySecurityInvariants::test_rate_limit_still_applies tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyStartupValidation::test_deliver_only_with_log_deliver_rejected tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyStartupValidation::test_deliver_only_with_missing_deliver_rejected tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyStartupValidation::test_deliver_only_with_real_target_accepted tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyStatusCodes::test_delivery_exception_returns_502 tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyStatusCodes::test_delivery_failure_returns_502 tests/gateway/test_webhook_deliver_only.py::TestDeliverOnlyStatusCodes::test_target_platform_not_connected_returns_502 tests/gateway/test_webhook_deliver_only.py::TestDirectDeliverUnit::test_dispatches_to_cross_platform_for_messaging_targets tests/gateway/test_webhook_deliver_only.py::TestDirectDeliverUnit::test_dispatches_to_github_comment tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteLoading::test_corrupted_file tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteLoading::test_file_removal_clears tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteLoading::test_loads_dynamic_routes tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteLoading::test_mtime_gated tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteLoading::test_no_dynamic_file tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteLoading::test_static_takes_precedence tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteSecretValidation::test_empty_secret_rejected tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteSecretValidation::test_insecure_no_auth_preserved tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteSecretValidation::test_insecure_no_auth_rejected_on_non_loopback_bind tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteSecretValidation::test_missing_secret_inherits_global tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteSecretValidation::test_missing_secret_no_global_rejected tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteSecretValidation::test_partial_skip tests/gateway/test_webhook_dynamic_routes.py::TestDynamicRouteSecretValidation::test_warning_logged_on_skip tests/gateway/test_webhook_integration.py::TestCrossPlatformDelivery::test_cross_platform_delivery tests/gateway/test_webhook_integration.py::TestGitHubCommentDelivery::test_github_comment_delivery tests/gateway/test_webhook_integration.py::TestGitHubPRWebhook::test_github_pr_webhook_triggers_agent tests/gateway/test_webhook_integration.py::TestSkillsInjection::test_skills_injected_into_prompt tests/gateway/test_webhook_signature_rate_limit.py::TestSignatureBeforeRateLimit::test_invalid_signature_does_not_consume_rate_limit tests/gateway/test_webhook_signature_rate_limit.py::TestSignatureBeforeRateLimit::test_mixed_valid_and_invalid_signatures tests/gateway/test_webhook_signature_rate_limit.py::TestSignatureBeforeRateLimit::test_valid_signature_still_rate_limited tests/gateway/test_wecom.py::TestCallbackDispatch::test_dispatch_accepts_new_and_legacy_callback_cmds[aibot_callback] tests/gateway/test_wecom.py::TestCallbackDispatch::test_dispatch_accepts_new_and_legacy_callback_cmds[aibot_msg_callback] tests/gateway/test_wecom.py::TestExtractText::test_extracts_mixed_text tests/gateway/test_wecom.py::TestExtractText::test_extracts_plain_text tests/gateway/test_wecom.py::TestExtractText::test_extracts_voice_and_quote tests/gateway/test_wecom.py::TestInboundMessages::test_on_message_builds_event tests/gateway/test_wecom.py::TestInboundMessages::test_on_message_preserves_quote_context tests/gateway/test_wecom.py::TestInboundMessages::test_on_message_respects_group_policy tests/gateway/test_wecom.py::TestMediaHelpers::test_decrypt_file_bytes_round_trip tests/gateway/test_wecom.py::TestMediaHelpers::test_detect_wecom_media_type tests/gateway/test_wecom.py::TestMediaHelpers::test_load_outbound_media_rejects_placeholder_path tests/gateway/test_wecom.py::TestMediaHelpers::test_oversized_file_is_rejected tests/gateway/test_wecom.py::TestMediaHelpers::test_voice_non_amr_downgrades_to_file tests/gateway/test_wecom.py::TestMediaUpload::test_cache_media_decrypts_url_payload_before_writing tests/gateway/test_wecom.py::TestMediaUpload::test_download_remote_bytes_rejects_large_content_length tests/gateway/test_wecom.py::TestMediaUpload::test_upload_media_bytes_uses_sdk_sequence tests/gateway/test_wecom.py::TestPolicyHelpers::test_dm_allowlist tests/gateway/test_wecom.py::TestPolicyHelpers::test_dm_allowlist_extra_takes_precedence_over_env tests/gateway/test_wecom.py::TestPolicyHelpers::test_dm_allowlist_honors_env_only_allowed_users tests/gateway/test_wecom.py::TestPolicyHelpers::test_group_allowlist_and_per_group_sender_allowlist tests/gateway/test_wecom.py::TestSend::test_send_image_falls_back_to_text_for_remote_url tests/gateway/test_wecom.py::TestSend::test_send_reports_wecom_errors tests/gateway/test_wecom.py::TestSend::test_send_uses_proactive_payload tests/gateway/test_wecom.py::TestSend::test_send_voice_sends_caption_and_downgrade_note tests/gateway/test_wecom.py::TestTextBatchFlushRace::test_active_task_processes_event_normally tests/gateway/test_wecom.py::TestTextBatchFlushRace::test_superseded_task_does_not_pop_or_process_event tests/gateway/test_wecom.py::TestWeComAdapterInit::test_declares_non_editable_message_capability tests/gateway/test_wecom.py::TestWeComAdapterInit::test_falls_back_to_env_vars tests/gateway/test_wecom.py::TestWeComAdapterInit::test_reads_config_from_extra tests/gateway/test_wecom.py::TestWeComConnect::test_connect_records_handshake_failure_details tests/gateway/test_wecom.py::TestWeComConnect::test_connect_records_missing_credentials tests/gateway/test_wecom.py::TestWeComQrScan::test_qr_scan_timeout_uses_monotonic_clock tests/gateway/test_wecom.py::TestWeComReplyMode::test_send_image_file_uses_passive_reply_media_when_reply_context_exists tests/gateway/test_wecom.py::TestWeComReplyMode::test_send_uses_passive_reply_markdown_when_reply_context_exists tests/gateway/test_wecom.py::TestWeComRequirements::test_returns_false_without_aiohttp tests/gateway/test_wecom.py::TestWeComRequirements::test_returns_false_without_httpx tests/gateway/test_wecom.py::TestWeComRequirements::test_returns_true_when_available tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_adapter_generates_stable_device_id_per_instance tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_different_adapter_instances_get_distinct_device_ids tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_on_message_caches_last_req_id_per_chat tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_on_message_does_not_cache_blocked_sender_req_id tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_open_connection_includes_device_id_in_subscribe tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_proactive_group_send_falls_back_to_cached_req_id tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_proactive_send_without_cached_req_id_uses_app_cmd_send tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_remember_chat_req_id_ignores_empty_values tests/gateway/test_wecom.py::TestWeComZombieSessionFix::test_remember_chat_req_id_is_bounded tests/gateway/test_wecom_callback.py::TestWecomCallbackEventConstruction::test_build_event_extracts_text_message tests/gateway/test_wecom_callback.py::TestWecomCallbackEventConstruction::test_build_event_returns_none_for_subscribe tests/gateway/test_wecom_callback.py::TestWecomCallbackPollLoop::test_poll_loop_dispatches_handle_message tests/gateway/test_wecom_callback.py::TestWecomCallbackRouting::test_send_falls_back_from_bare_user_id_when_unique tests/gateway/test_wecom_callback.py::TestWecomCallbackRouting::test_send_selects_correct_app_for_scoped_chat_id tests/gateway/test_wecom_callback.py::TestWecomCallbackRouting::test_user_app_key_scopes_across_corps tests/gateway/test_wecom_callback.py::TestWecomCallbackSendTokenRefresh::test_send_does_not_retry_on_non_token_errcode tests/gateway/test_wecom_callback.py::TestWecomCallbackSendTokenRefresh::test_send_fails_cleanly_when_retry_also_fails tests/gateway/test_wecom_callback.py::TestWecomCallbackSendTokenRefresh::test_send_retries_with_fresh_token_on_errcode_40001 tests/gateway/test_wecom_callback.py::TestWecomCallbackSendTokenRefresh::test_send_retries_with_fresh_token_on_errcode_42001 tests/gateway/test_wecom_callback.py::TestWecomCrypto::test_roundtrip_encrypt_decrypt tests/gateway/test_wecom_callback.py::TestWecomCrypto::test_signature_mismatch_raises tests/gateway/test_weixin.py::TestIsStaleSessionRet::test_errcode_minus_14_is_not_matched_here tests/gateway/test_weixin.py::TestIsStaleSessionRet::test_errcode_minus_2_with_unknown_error_is_stale tests/gateway/test_weixin.py::TestIsStaleSessionRet::test_ret_minus_2_with_freq_limit_is_not_stale tests/gateway/test_weixin.py::TestIsStaleSessionRet::test_ret_minus_2_with_no_errmsg_is_not_stale tests/gateway/test_weixin.py::TestIsStaleSessionRet::test_ret_minus_2_with_unknown_error_is_stale tests/gateway/test_weixin.py::TestIsStaleSessionRet::test_success_codes_are_not_stale tests/gateway/test_weixin.py::TestIsStaleSessionRet::test_unknown_error_case_insensitive tests/gateway/test_weixin.py::TestWeixinApiTimeout::test_api_get_does_not_pass_aiohttp_timeout_kwarg tests/gateway/test_weixin.py::TestWeixinApiTimeout::test_api_get_raises_runtime_error_on_non_ok_status tests/gateway/test_weixin.py::TestWeixinApiTimeout::test_api_get_raises_timeout_when_response_is_slow tests/gateway/test_weixin.py::TestWeixinApiTimeout::test_api_post_does_not_pass_aiohttp_timeout_kwarg tests/gateway/test_weixin.py::TestWeixinApiTimeout::test_api_post_raises_runtime_error_on_non_ok_status tests/gateway/test_weixin.py::TestWeixinApiTimeout::test_api_post_raises_timeout_when_response_is_slow tests/gateway/test_weixin.py::TestWeixinApiTimeout::test_get_updates_returns_empty_sentinel_on_timeout tests/gateway/test_weixin.py::TestWeixinBlankMessagePrevention::test_send_empty_content_does_not_call_send_message tests/gateway/test_weixin.py::TestWeixinBlankMessagePrevention::test_send_message_rejects_empty_text tests/gateway/test_weixin.py::TestWeixinBlankMessagePrevention::test_split_text_returns_empty_list_for_empty_string tests/gateway/test_weixin.py::TestWeixinBlankMessagePrevention::test_split_text_returns_empty_list_for_empty_string_split_per_line tests/gateway/test_weixin.py::TestWeixinChunkDelivery::test_concurrent_rate_limited_sends_are_serialized_by_gate tests/gateway/test_weixin.py::TestWeixinChunkDelivery::test_open_rate_limit_circuit_fails_fast_without_sendmessage tests/gateway/test_weixin.py::TestWeixinChunkDelivery::test_repeated_rate_limits_open_circuit_for_followup_sends tests/gateway/test_weixin.py::TestWeixinChunkDelivery::test_send_retries_failed_chunk_before_continuing tests/gateway/test_weixin.py::TestWeixinChunkDelivery::test_send_waits_between_multiple_chunks tests/gateway/test_weixin.py::TestWeixinChunkDelivery::test_successful_send_after_cooldown_resets_rate_limit_state tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_can_restore_legacy_multiline_splitting_via_config tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_keeps_complete_code_block_together_when_possible tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_keeps_four_line_structured_blocks_together tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_keeps_heading_with_body_together tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_keeps_short_reformatted_table_in_single_chunk tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_keeps_structured_table_block_together tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_safely_splits_long_code_blocks tests/gateway/test_weixin.py::TestWeixinChunking::test_split_text_splits_short_chatty_replies_into_separate_bubbles tests/gateway/test_weixin.py::TestWeixinConfig::test_apply_env_overrides_configures_weixin tests/gateway/test_weixin.py::TestWeixinConfig::test_get_connected_platforms_includes_weixin_with_token tests/gateway/test_weixin.py::TestWeixinConfig::test_get_connected_platforms_requires_account_id tests/gateway/test_weixin.py::TestWeixinContentDedup::test_content_dedup_not_called_for_messages_without_text tests/gateway/test_weixin.py::TestWeixinContentDedup::test_duplicate_content_with_different_message_ids_is_dropped tests/gateway/test_weixin.py::TestWeixinFormatting::test_format_message_does_not_wrap_long_code_block_lines tests/gateway/test_weixin.py::TestWeixinFormatting::test_format_message_preserves_fenced_code_blocks tests/gateway/test_weixin.py::TestWeixinFormatting::test_format_message_preserves_markdown tests/gateway/test_weixin.py::TestWeixinFormatting::test_format_message_preserves_markdown_tables tests/gateway/test_weixin.py::TestWeixinFormatting::test_format_message_returns_empty_string_for_none tests/gateway/test_weixin.py::TestWeixinFormatting::test_format_message_wraps_long_plain_lines_for_copying tests/gateway/test_weixin.py::TestWeixinMarkdownLinks::test_format_message_preserves_links_inside_code_blocks tests/gateway/test_weixin.py::TestWeixinMarkdownLinks::test_format_message_preserves_markdown_links tests/gateway/test_weixin.py::TestWeixinMediaBuilder::test_image_builder_aes_key_is_base64_of_hex tests/gateway/test_weixin.py::TestWeixinMediaBuilder::test_video_builder_includes_md5 tests/gateway/test_weixin.py::TestWeixinMediaBuilder::test_voice_builder_for_audio_files_uses_file_attachment_type tests/gateway/test_weixin.py::TestWeixinMediaBuilder::test_voice_builder_for_silk_files tests/gateway/test_weixin.py::TestWeixinOutboundMedia::test_send_document_accepts_keyword_file_path tests/gateway/test_weixin.py::TestWeixinOutboundMedia::test_send_file_uses_post_for_upload_full_url_and_hex_encoded_aes_key tests/gateway/test_weixin.py::TestWeixinOutboundMedia::test_send_image_file_accepts_keyword_image_path tests/gateway/test_weixin.py::TestWeixinQrLogin::test_qr_login_timeout_uses_monotonic_clock tests/gateway/test_weixin.py::TestWeixinRemoteMediaSafety::test_download_remote_media_blocks_unsafe_urls tests/gateway/test_weixin.py::TestWeixinSendImageFileParameterName::test_send_image_file_uses_image_path_parameter tests/gateway/test_weixin.py::TestWeixinSendImageFileParameterName::test_send_image_file_works_without_optional_params tests/gateway/test_weixin.py::TestWeixinSendMessageIntegration::test_parse_target_ref_accepts_weixin_ids tests/gateway/test_weixin.py::TestWeixinSendMessageIntegration::test_send_to_platform_routes_weixin_media_to_native_helper tests/gateway/test_weixin.py::TestWeixinStatePersistence::test_context_token_persist_preserves_existing_file_on_replace_failure tests/gateway/test_weixin.py::TestWeixinStatePersistence::test_save_sync_buf_preserves_existing_file_on_replace_failure tests/gateway/test_weixin.py::TestWeixinStatePersistence::test_save_weixin_account_preserves_existing_file_on_replace_failure tests/gateway/test_weixin.py::TestWeixinStreamingCursorSuppression::test_supports_message_editing_is_false tests/gateway/test_weixin.py::TestWeixinTextDebounce::test_batch_delays_default_from_config tests/gateway/test_weixin.py::TestWeixinTextDebounce::test_batch_delays_overridden_via_config_extra tests/gateway/test_weixin.py::TestWeixinTextDebounce::test_invalid_config_value_falls_back_to_default tests/gateway/test_weixin.py::TestWeixinTextDebounce::test_rapid_texts_collapse_into_single_dispatch tests/gateway/test_weixin.py::TestWeixinVoiceSending::test_send_file_sets_voice_metadata_for_silk_payload tests/gateway/test_weixin.py::TestWeixinVoiceSending::test_send_voice_downgrades_to_document_attachment tests/gateway/test_weixin.py::TestWeixinVoiceSending::test_voice_builder_for_silk_files_can_be_forced_to_file_attachment tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_refreshes_when_no_cached_ticket tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_refreshes_when_ticket_expired tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_returns_cached_ticket_when_fresh tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_returns_none_when_getconfig_fails tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_returns_none_when_getconfig_returns_empty_ticket tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_returns_none_when_no_session tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_send_typing_refreshes_ticket tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_stop_typing_refreshes_ticket tests/gateway/test_weixin_typing.py::TestEnsureTypingTicket::test_uses_stored_context_token_when_available tests/gateway/test_weixin_typing.py::TestTypingTicketCache::test_expired_entry_is_removed_from_cache tests/gateway/test_weixin_typing.py::TestTypingTicketCache::test_returns_none_when_expired tests/gateway/test_weixin_typing.py::TestTypingTicketCache::test_returns_none_when_missing tests/gateway/test_weixin_typing.py::TestTypingTicketCache::test_returns_ticket_when_fresh tests/gateway/test_whatsapp_cloud.py::TestAllowlistNormalization::test_cloud_env_overrides_take_precedence tests/gateway/test_whatsapp_cloud.py::TestAllowlistNormalization::test_dm_allowlist_matches_bare_wa_id_against_jid_entry tests/gateway/test_whatsapp_cloud.py::TestAllowlistNormalization::test_normalize_allow_ids_strips_jid_suffix_and_punctuation tests/gateway/test_whatsapp_cloud.py::TestBoundedInteractiveState::test_bounded_put_evicts_oldest tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplyApproval::test_approve_tap_calls_resolver_and_confirms tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplyApproval::test_deny_tap_passes_deny_choice tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplyClarify::test_clarify_other_button_keeps_state_and_prompts tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplyClarify::test_clarify_other_with_no_entry_falls_back tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplyClarify::test_clarify_resolver_no_waiter_falls_back tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplyClarify::test_clarify_tap_resolves_and_pops_state tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplyClarify::test_stale_clarify_tap_falls_back_to_text tests/gateway/test_whatsapp_cloud.py::TestDispatchInteractiveReplySlashConfirm::test_once_tap_calls_resolver tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_bytes_failure_returns_none tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_extension_overrides_for_real_world_mimes[audio/mp4-.m4a] tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_extension_overrides_for_real_world_mimes[audio/ogg-.ogg] tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_extension_overrides_for_real_world_mimes[audio/ogg; codecs=opus-.ogg] tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_extension_overrides_for_real_world_mimes[audio/opus-.ogg] tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_extension_overrides_for_real_world_mimes[audio/x-m4a-.m4a] tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_extension_overrides_for_real_world_mimes[audio/x-opus+ogg-.ogg] tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_extension_overrides_for_real_world_mimes[image/jpeg-.jpg] tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_metadata_failure_returns_none tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_metadata_includes_auth_header tests/gateway/test_whatsapp_cloud.py::TestDownloadMedia::test_two_step_download_writes_cache_file tests/gateway/test_whatsapp_cloud.py::TestGroupMessageGuard::test_group_shaped_message_dropped_with_warning tests/gateway/test_whatsapp_cloud.py::TestGroupMessageGuard::test_normal_dm_still_dispatches tests/gateway/test_whatsapp_cloud.py::TestHealth::test_health_flags_missing_secrets tests/gateway/test_whatsapp_cloud.py::TestHealth::test_health_reports_config_visibility tests/gateway/test_whatsapp_cloud.py::TestInboundMediaDispatch::test_inbound_image_download_failure_still_dispatches tests/gateway/test_whatsapp_cloud.py::TestInboundMediaDispatch::test_inbound_image_populates_media_urls tests/gateway/test_whatsapp_cloud.py::TestInboundMediaDispatch::test_inbound_text_document_injected_into_body tests/gateway/test_whatsapp_cloud.py::TestInboundWamidCache::test_accepted_message_populates_cache tests/gateway/test_whatsapp_cloud.py::TestInboundWamidCache::test_filtered_message_does_not_pollute_cache tests/gateway/test_whatsapp_cloud.py::TestInboundWamidCache::test_subsequent_messages_overwrite_cache tests/gateway/test_whatsapp_cloud.py::TestInteractiveReplyEndToEnd::test_recognized_tap_returns_none_no_text_dispatch tests/gateway/test_whatsapp_cloud.py::TestInteractiveReplyEndToEnd::test_unrecognized_tap_falls_through_to_text tests/gateway/test_whatsapp_cloud.py::TestMediaIdValidation::test_traversal_media_id_refused tests/gateway/test_whatsapp_cloud.py::TestMixinInherited::test_broadcast_chats_filtered tests/gateway/test_whatsapp_cloud.py::TestMixinInherited::test_format_message_converts_markdown tests/gateway/test_whatsapp_cloud.py::TestMixinInherited::test_should_process_message_dm_disabled tests/gateway/test_whatsapp_cloud.py::TestMixinInherited::test_should_process_message_dm_open tests/gateway/test_whatsapp_cloud.py::TestSendClarifyButtons::test_four_choices_promoted_to_list_mode tests/gateway/test_whatsapp_cloud.py::TestSendClarifyButtons::test_open_ended_falls_back_to_plain_text tests/gateway/test_whatsapp_cloud.py::TestSendClarifyButtons::test_send_failure_does_not_register_state tests/gateway/test_whatsapp_cloud.py::TestSendClarifyButtons::test_three_choices_uses_button_mode tests/gateway/test_whatsapp_cloud.py::TestSendDocument::test_send_document_filename_attached tests/gateway/test_whatsapp_cloud.py::TestSendExecApprovalButtons::test_approval_renders_two_buttons tests/gateway/test_whatsapp_cloud.py::TestSendExecApprovalButtons::test_long_command_is_truncated tests/gateway/test_whatsapp_cloud.py::TestSendImage::test_send_image_caption_attached tests/gateway/test_whatsapp_cloud.py::TestSendImage::test_send_image_link_mode_skips_upload tests/gateway/test_whatsapp_cloud.py::TestSendImage::test_send_image_local_path_uploads_then_sends tests/gateway/test_whatsapp_cloud.py::TestSendImage::test_send_image_missing_local_file_returns_failure tests/gateway/test_whatsapp_cloud.py::TestSendImage::test_send_image_oversize_rejected_locally tests/gateway/test_whatsapp_cloud.py::TestSendImage::test_send_image_upload_failure_returns_failure tests/gateway/test_whatsapp_cloud.py::TestSendMethodsAcceptBaseClassKwargs::test_send_document_accepts_metadata tests/gateway/test_whatsapp_cloud.py::TestSendMethodsAcceptBaseClassKwargs::test_send_image_accepts_metadata tests/gateway/test_whatsapp_cloud.py::TestSendMethodsAcceptBaseClassKwargs::test_send_image_file_accepts_metadata tests/gateway/test_whatsapp_cloud.py::TestSendMethodsAcceptBaseClassKwargs::test_send_video_accepts_metadata tests/gateway/test_whatsapp_cloud.py::TestSendMethodsAcceptBaseClassKwargs::test_send_voice_accepts_metadata tests/gateway/test_whatsapp_cloud.py::TestSendSlashConfirmButtons::test_three_buttons_with_ids tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_applies_markdown_conversion tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_builds_correct_url tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_empty_content_no_request tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_graph_error_returns_failure tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_includes_bearer_auth tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_long_message_chunked tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_network_exception_returns_failure tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_not_connected_returns_failure tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_payload_shape tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_reply_to_attaches_context_first_chunk_only tests/gateway/test_whatsapp_cloud.py::TestSendText::test_send_returns_wamid tests/gateway/test_whatsapp_cloud.py::TestSendTyping::test_send_typing_includes_bearer_auth tests/gateway/test_whatsapp_cloud.py::TestSendTyping::test_send_typing_no_cached_wamid_is_noop tests/gateway/test_whatsapp_cloud.py::TestSendTyping::test_send_typing_no_http_client_is_noop tests/gateway/test_whatsapp_cloud.py::TestSendTyping::test_send_typing_posts_correct_payload tests/gateway/test_whatsapp_cloud.py::TestSendTyping::test_send_typing_stale_message_logged_at_info tests/gateway/test_whatsapp_cloud.py::TestSendTyping::test_send_typing_swallows_network_errors tests/gateway/test_whatsapp_cloud.py::TestSendTyping::test_send_typing_uses_latest_cached_wamid tests/gateway/test_whatsapp_cloud.py::TestSendVideo::test_send_video_link_mode tests/gateway/test_whatsapp_cloud.py::TestSendVoice::test_send_voice_ffmpeg_present_uses_opus tests/gateway/test_whatsapp_cloud.py::TestSendVoice::test_send_voice_no_ffmpeg_falls_back_to_mp3 tests/gateway/test_whatsapp_cloud.py::TestSendVoice::test_warn_once_no_ffmpeg_actually_only_warns_once tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_dispatch_filters_via_mixin_gating tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_dispatch_handler_exception_does_not_crash tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_dispatch_handles_button_reply tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_dispatch_ignores_non_message_field tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_dispatch_ignores_non_waba_object tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_dispatch_propagates_reply_to tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_invalid_json_after_signature_returns_400 tests/gateway/test_whatsapp_cloud.py::TestWebhookDispatch::test_text_message_dispatched_with_event_shape tests/gateway/test_whatsapp_cloud.py::TestWebhookReplay::test_dedup_cache_evicts_oldest tests/gateway/test_whatsapp_cloud.py::TestWebhookReplay::test_dedup_no_wamid_lets_through tests/gateway/test_whatsapp_cloud.py::TestWebhookReplay::test_duplicate_wamid_not_redispatched tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_missing_signature_header_rejected tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_oversize_body_rejected_before_signature tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_signature_uses_constant_time_compare tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_tampered_body_rejected tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_unconfigured_app_secret_refuses_503 tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_unreadable_body_rejected tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_valid_signature_accepted tests/gateway/test_whatsapp_cloud.py::TestWebhookSignature::test_wrong_signature_format_rejected tests/gateway/test_whatsapp_cloud.py::TestWebhookVerify::test_verify_echoes_challenge_on_match tests/gateway/test_whatsapp_cloud.py::TestWebhookVerify::test_verify_refuses_when_token_unconfigured tests/gateway/test_whatsapp_cloud.py::TestWebhookVerify::test_verify_rejects_missing_challenge tests/gateway/test_whatsapp_cloud.py::TestWebhookVerify::test_verify_rejects_token_mismatch tests/gateway/test_whatsapp_cloud.py::TestWebhookVerify::test_verify_rejects_wrong_mode tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_closed_on_unexpected_exception tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_closed_when_bridge_dies_phase2 tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_closed_when_http_not_ready tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_poll_messages_marks_retryable_fatal_when_managed_bridge_exits tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_send_marks_retryable_fatal_when_managed_bridge_exits tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_shutdown_still_surfaces_nonzero_crash tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_shutdown_suppresses_fatal_on_planned_bridge_exit[-15] tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_shutdown_suppresses_fatal_on_planned_bridge_exit[-2] tests/gateway/test_whatsapp_connect.py::TestBridgeRuntimeFailure::test_shutdown_suppresses_fatal_on_planned_bridge_exit[0] tests/gateway/test_whatsapp_connect.py::TestCloseBridgeLog::test_closes_open_handle tests/gateway/test_whatsapp_connect.py::TestCloseBridgeLog::test_noop_when_no_handle tests/gateway/test_whatsapp_connect.py::TestCloseBridgeLog::test_suppresses_close_exception tests/gateway/test_whatsapp_connect.py::TestConnectCleanup::test_releases_lock_when_npm_install_fails tests/gateway/test_whatsapp_connect.py::TestDataInitialized::test_no_name_error_when_json_always_fails tests/gateway/test_whatsapp_connect.py::TestFileHandleClosedOnError::test_closed_when_bridge_dies_phase1 tests/gateway/test_whatsapp_connect.py::TestHttpSessionLifecycle::test_disconnect_skips_done_poll_task tests/gateway/test_whatsapp_connect.py::TestHttpSessionLifecycle::test_disconnect_uses_taskkill_tree_on_windows tests/gateway/test_whatsapp_connect.py::TestHttpSessionLifecycle::test_poll_task_cancelled_on_disconnect tests/gateway/test_whatsapp_connect.py::TestHttpSessionLifecycle::test_session_closed_on_disconnect tests/gateway/test_whatsapp_connect.py::TestHttpSessionLifecycle::test_session_not_closed_when_already_closed tests/gateway/test_whatsapp_connect.py::TestKillPortProcess::test_does_not_kill_wrong_port_on_windows tests/gateway/test_whatsapp_connect.py::TestKillPortProcess::test_skips_fuser_kill_when_port_free tests/gateway/test_whatsapp_connect.py::TestKillPortProcess::test_suppresses_exceptions tests/gateway/test_whatsapp_connect.py::TestKillPortProcess::test_uses_fuser_on_linux tests/gateway/test_whatsapp_connect.py::TestKillPortProcess::test_uses_netstat_and_taskkill_on_windows tests/gateway/test_whatsapp_connect.py::TestNoCredsPreflight::test_connect_proceeds_when_creds_present tests/gateway/test_whatsapp_connect.py::TestNoCredsPreflight::test_connect_returns_false_when_no_creds tests/gateway/test_whatsapp_formatting.py::TestBridgeEventMetadata::test_quoted_reply_metadata_is_preserved_in_raw_message tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_already_whatsapp_italic tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_bold_double_asterisk tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_bold_double_underscore tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_bold_header_does_not_double_wrap tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_code_blocks_protected tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_empty_content tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_headers_converted_to_bold tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_inline_code_protected tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_links_converted tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_multiline_mixed tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_plain_text_unchanged tests/gateway/test_whatsapp_formatting.py::TestFormatMessage::test_strikethrough tests/gateway/test_whatsapp_formatting.py::TestMessageLimits::test_chunk_limit_does_not_reserve_prefix_in_bot_mode tests/gateway/test_whatsapp_formatting.py::TestMessageLimits::test_chunk_limit_reserves_default_self_chat_prefix tests/gateway/test_whatsapp_formatting.py::TestMessageLimits::test_max_message_length_is_practical tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_bridge_error_returns_failure tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_chunks_leave_room_for_bridge_prefix tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_empty_message_no_send tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_format_applied_before_send tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_long_message_chunked tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_not_connected_returns_failure tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_reply_to_only_on_first_chunk tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_short_message_single_send tests/gateway/test_whatsapp_formatting.py::TestSendChunking::test_whitespace_only_no_send tests/gateway/test_whatsapp_formatting.py::TestWhatsAppTier::test_whatsapp_streaming_follows_global tests/gateway/test_whatsapp_formatting.py::TestWhatsAppTier::test_whatsapp_tool_progress_is_new tests/gateway/test_whatsapp_group_gating.py::test_broadcast_filter_runs_before_allowlist tests/gateway/test_whatsapp_group_gating.py::test_config_bridges_whatsapp_allow_from tests/gateway/test_whatsapp_group_gating.py::test_config_bridges_whatsapp_dm_and_group_policy tests/gateway/test_whatsapp_group_gating.py::test_config_bridges_whatsapp_group_settings tests/gateway/test_whatsapp_group_gating.py::test_dm_passes_with_default_open_policy tests/gateway/test_whatsapp_group_gating.py::test_dm_policy_allowlist_allows_listed_sender tests/gateway/test_whatsapp_group_gating.py::test_dm_policy_allowlist_blocks_unlisted_sender tests/gateway/test_whatsapp_group_gating.py::test_dm_policy_disabled_blocks_all_dms tests/gateway/test_whatsapp_group_gating.py::test_dm_policy_disabled_still_allows_groups tests/gateway/test_whatsapp_group_gating.py::test_dm_policy_open_allows_all_dms tests/gateway/test_whatsapp_group_gating.py::test_free_response_chats_bypass_mention_gating tests/gateway/test_whatsapp_group_gating.py::test_free_response_chats_does_not_bypass_other_groups tests/gateway/test_whatsapp_group_gating.py::test_group_messages_can_be_opened_via_config tests/gateway/test_whatsapp_group_gating.py::test_group_messages_can_require_direct_trigger_via_config tests/gateway/test_whatsapp_group_gating.py::test_group_policy_allowlist_allows_listed_group tests/gateway/test_whatsapp_group_gating.py::test_group_policy_allowlist_blocks_unlisted_group tests/gateway/test_whatsapp_group_gating.py::test_group_policy_disabled_blocks_all_groups tests/gateway/test_whatsapp_group_gating.py::test_group_policy_disabled_still_allows_dms tests/gateway/test_whatsapp_group_gating.py::test_group_policy_open_allows_all_groups tests/gateway/test_whatsapp_group_gating.py::test_invalid_regex_patterns_are_ignored tests/gateway/test_whatsapp_group_gating.py::test_is_broadcast_chat_helper_recognizes_common_jids tests/gateway/test_whatsapp_group_gating.py::test_mention_stripping_preserves_body_when_no_mention tests/gateway/test_whatsapp_group_gating.py::test_mention_stripping_removes_bot_phone_from_body tests/gateway/test_whatsapp_group_gating.py::test_real_dm_still_processed_after_broadcast_filter tests/gateway/test_whatsapp_group_gating.py::test_regex_mention_patterns_allow_custom_wake_words tests/gateway/test_whatsapp_group_gating.py::test_status_broadcast_chats_are_always_dropped tests/gateway/test_whatsapp_reply_prefix.py::TestAdapterInit::test_reply_prefix_default_none tests/gateway/test_whatsapp_reply_prefix.py::TestAdapterInit::test_reply_prefix_empty_string tests/gateway/test_whatsapp_reply_prefix.py::TestAdapterInit::test_reply_prefix_from_extra tests/gateway/test_whatsapp_reply_prefix.py::TestConfigVersionCoverage::test_default_config_version_covers_env_var_versions tests/gateway/test_whatsapp_reply_prefix.py::TestConfigYamlBridging::test_empty_reply_prefix_bridged tests/gateway/test_whatsapp_reply_prefix.py::TestConfigYamlBridging::test_no_whatsapp_section_no_extra tests/gateway/test_whatsapp_reply_prefix.py::TestConfigYamlBridging::test_reply_prefix_bridged_from_yaml tests/gateway/test_whatsapp_reply_prefix.py::TestConfigYamlBridging::test_whatsapp_section_without_reply_prefix tests/gateway/test_whatsapp_stale_bridge.py::TestCacheDirEnvPassthrough::test_bridge_spawn_env_has_cache_dirs tests/gateway/test_whatsapp_stale_bridge.py::TestDepRefreshStamp::test_installs_when_node_modules_missing tests/gateway/test_whatsapp_stale_bridge.py::TestDepRefreshStamp::test_reinstalls_when_package_json_changed tests/gateway/test_whatsapp_stale_bridge.py::TestDepRefreshStamp::test_skips_install_when_stamp_fresh tests/gateway/test_whatsapp_stale_bridge.py::TestFileContentHash::test_changes_with_content tests/gateway/test_whatsapp_stale_bridge.py::TestFileContentHash::test_hashes_file tests/gateway/test_whatsapp_stale_bridge.py::TestFileContentHash::test_matches_bridge_js_self_hash_algorithm tests/gateway/test_whatsapp_stale_bridge.py::TestFileContentHash::test_missing_file_returns_empty tests/gateway/test_whatsapp_stale_bridge.py::TestStaleBridgeHandshake::test_restarts_bridge_on_hash_mismatch tests/gateway/test_whatsapp_stale_bridge.py::TestStaleBridgeHandshake::test_restarts_unversioned_bridge tests/gateway/test_whatsapp_stale_bridge.py::TestStaleBridgeHandshake::test_reuses_bridge_when_hash_matches tests/gateway/test_whatsapp_text_batching.py::test_batch_delays_default_from_config tests/gateway/test_whatsapp_text_batching.py::test_batch_delays_overridden_via_config_extra tests/gateway/test_whatsapp_text_batching.py::test_env_var_is_ignored tests/gateway/test_whatsapp_text_batching.py::test_invalid_config_value_falls_back_to_default tests/gateway/test_whatsapp_text_batching.py::test_lone_message_dispatched_alone tests/gateway/test_whatsapp_text_batching.py::test_rapid_texts_collapse_into_single_dispatch tests/gateway/test_ws_auth_retry.py::TestMatrixSyncAuthRetry::test_exception_with_401_stops_loop tests/gateway/test_ws_auth_retry.py::TestMatrixSyncAuthRetry::test_transient_error_retries tests/gateway/test_ws_auth_retry.py::TestMatrixSyncAuthRetry::test_unknown_token_sync_error_stops_loop tests/gateway/test_ws_auth_retry.py::TestMattermostWSAuthRetry::test_401_handshake_stops_reconnect tests/gateway/test_ws_auth_retry.py::TestMattermostWSAuthRetry::test_403_handshake_stops_reconnect tests/gateway/test_ws_auth_retry.py::TestMattermostWSAuthRetry::test_transient_error_retries tests/gateway/test_yolo_command.py::test_yolo_command_toggles_only_current_session