hermes-agent/tests/hermes_cli
emozilla bdee48928f fix(dashboard): derive the stale-schema read probe from SCHEMA_SQL
After `hermes update`, the desktop sidebar showed "No sessions yet" until
the user's first message. #72424 added sessions.last_activity_at, which
list_sessions_rich now selects — but column adds only land through
_reconcile_columns() in the writable _init_schema, and read-only opens
skip that by design. Every sidebar read path opens state.db read-only, so
each poll raised "no such column: s.last_activity_at" until the first
prompt's lazy session-row persist forced a writable open and reconciled.

A heal for exactly this class already existed (_open_session_db_for_profile
probes the read-only handle and does a one-time writable reopen on
staleness), but its probe was a hand-written four-column list that never
learned last_activity_at — it went stale three days after shipping. And the
batched sidebar route (/api/profiles/sessions/sidebar) bypassed the helper
entirely, swallowing per-profile failures into an errors array the desktop
never surfaces, so the incident produced an empty sidebar with clean logs.

The fix removes the maintenance burden instead of paying it once more:

- hermes_state_schema.schema_read_probe_statements() derives one
  `SELECT <every declared column> FROM <table> LIMIT 0` per table from
  SCHEMA_SQL via the existing _parse_schema_columns() — the same source of
  truth the writable reconciler diffs against, so any future ADD COLUMN is
  probed with no list to update. Column references are table-qualified:
  an unqualified double-quoted identifier that fails to resolve silently
  degrades to a string literal (SQLite's double-quoted-string misfeature)
  and would make the probe pass on exactly the store it exists to catch.

- web_server splits the heal into a path-level _open_session_db_at_path
  (semantics unchanged) so the cross-profile session routes can share it;
  both profiles.py loops and _count_status_active_sessions (the remaining
  raw read-only sibling) now open through it. The heal stays a helper
  rather than a SessionDB classmethod on purpose: escalation-to-writable
  must remain an explicit caller decision — update_cmd.py opens read-only
  mid-update and must never write.

- Exhaustion guard: if the writable heal SUCCEEDS and the re-probe still
  fails (a schema problem ADD COLUMN cannot express), the store is marked
  exhausted — warn once, skip the probe, serve reads probe-less — instead
  of re-running the full writable init on every poll against a possibly
  live DB. A FAILED writable open (transient lock) is deliberately not
  recorded, so the next poll retries the heal.

- The per-profile swallow sites in profiles.py now also log a deduplicated
  warning, so a persistent read failure is loud in errors.log even though
  the response errors array stays invisible to the sidebar.

Tests: probe/SCHEMA_SQL coverage invariants (tests/test_schema_read_probe.py),
last_activity_at added to the /api/sessions heal parametrize, a sidebar-route
heal test reproducing the shipped symptom (errors == [] and the session
returned against a store missing the column), and an exhaustion test pinning
exactly one writable open. The sidebar and last_activity_at tests fail on
main.
2026-08-07 00:41:58 -04:00
..
__init__.py
conftest.py
conftest_dashboard_auth.py
test_25106_global_switch_persists_base_url_api_mode.py
test_active_sessions.py
test_actual_provider.py
test_agent_import.py
test_ai_gateway_models.py
test_anthropic_model_flow_stale_oauth.py
test_anthropic_oauth_flow.py
test_anthropic_oauth_routes_to_messages_api.py
test_anthropic_picker_curated.py
test_anthropic_provider_persistence.py
test_api_key_providers.py
test_apply_model_switch_result_context.py
test_apply_profile_override.py
test_approvals_command.py
test_approvals_suggest.py
test_arcee_provider.py
test_argparse_flag_propagation.py
test_at_context_completion_filter.py
test_atomic_json_write.py
test_atomic_yaml_write.py
test_auth_codex_provider.py
test_auth_codex_quota_probe.py
test_auth_codex_self_heal.py
test_auth_commands.py
test_auth_loopback_ssh_hint.py
test_auth_nous_provider.py
test_auth_profile_fallback.py
test_auth_provider_gate.py
test_auth_qwen_provider.py
test_auth_ssl_macos.py
test_auth_store_read_failure.py
test_auth_toctou_file_modes.py
test_auth_usable_secret.py
test_auth_xai_oauth_provider.py
test_authenticated_providers_exhausted_pool.py
test_aux_config.py
test_aux_picker_inventory.py
test_azure_detect.py
test_azure_foundry_entra.py
test_backup.py
test_backup_stability.py
test_banner.py
test_banner_git_state.py
test_banner_skills.py
test_banner_skills_width.py
test_bedrock_model_picker.py
test_bedrock_region_scoped_picker.py
test_billing_cli.py
test_billing_portal_url.py
test_billing_scope_stepup.py
test_bitwarden_status.py
test_browser_connect_dual_stack.py
test_build_info.py
test_bundles.py
test_busy_policy_invariants.py
test_bytecode_sweep.py
test_canonical_custom_identity.py
test_certifi_repair.py
test_chat_skills_flag.py
test_checkout_mutation_guards.py
test_checkpoints_prune.py
test_claw.py
test_clear_stale_base_url.py
test_cli_active_session_limit.py
test_cli_custom_provider_vision.py
test_cli_model_once.py
test_cli_output.py
test_clipboard_text_write.py
test_cmd_update.py
test_cmd_update_docker.py
test_coalesce_session_args.py
test_codex_cli_model_picker.py
test_codex_models.py
test_codex_runtime_plugin_migration.py
test_codex_runtime_switch.py
test_commands.py
test_commands_execute.py
test_completion.py
test_config.py
test_config_env_expansion.py
test_config_env_ref_parity.py
test_config_env_refs.py
test_config_loader_e2e.py
test_config_read_guard.py
test_config_validation.py
test_configured_builtin_models.py
test_console_engine.py
test_container_aware_cli.py
test_container_boot.py
test_context_switch_guard.py
test_copilot_auth.py
test_copilot_catalog_oauth_fallback.py
test_copilot_context.py
test_copilot_in_model_list.py
test_copilot_model_api_mode.py
test_copilot_runtime_api_mode.py
test_copilot_token_exchange.py
test_credential_lifecycle.py
test_cron.py
test_cron_dashboard_off_loop.py
test_cron_fire_dashboard.py
test_cron_parser_builder.py
test_ctrlg_editor_submit.py
test_curator_archive_prune.py
test_curator_recent_run_notice.py
test_curator_run.py
test_curator_status.py
test_curator_usage.py
test_curses_arrow_keys.py
test_curses_color_compat.py
test_curses_ui_fuzzy_rank.py
test_curses_ui_search.py
test_custom_provider_context_length.py
test_custom_provider_extra_headers.py
test_custom_provider_identity.py
test_custom_provider_model_switch.py
test_custom_provider_normalize_no_mutate.py
test_custom_provider_tls.py
test_dashboard_admin_endpoints.py
test_dashboard_auth_401_reauth.py
test_dashboard_auth_audit.py
test_dashboard_auth_cookies.py
test_dashboard_auth_gate.py
test_dashboard_auth_middleware.py
test_dashboard_auth_native_flow.py
test_dashboard_auth_password_login.py
test_dashboard_auth_plugin_hook.py
test_dashboard_auth_prefix.py
test_dashboard_auth_provider_base.py
test_dashboard_auth_status_endpoint.py
test_dashboard_auth_stub_provider.py
test_dashboard_auth_ws_auth.py
test_dashboard_auth_ws_tickets.py
test_dashboard_basic_auth_plugin_enable.py
test_dashboard_browser_safe_imports.py
test_dashboard_lifecycle_flags.py
test_dashboard_oauth_endpoints_server_gate.py
test_dashboard_param_clamps.py
test_dashboard_profiles_nav_label.py
test_dashboard_register.py
test_dashboard_token_auth.py
test_dashboard_tui_backcompat.py
test_dashboard_unified_launch.py
test_dashboard_web_dist_validation.py
test_debug.py
test_default_interface_resolution.py
test_dep_ensure.py
test_deprecated_cwd_warning.py
test_desktop_exe_integrity.py
test_desktop_repo_discovery_config.py
test_destructive_slash_confirm_gate.py
test_detect_api_mode_for_url.py
test_determine_api_mode_hostname.py
test_diagnostics_upload.py
test_diff_command.py
test_dingtalk_auth.py
test_discord_skill_clamp_warning.py
test_doctor.py
test_doctor_command_install.py
test_doctor_dedicated_provider_skip.py
test_dump_env_visibility.py
test_dump_git_commit.py
test_dump_terminal_backend.py
test_early_recovery.py
test_ensure_acp_launcher.py
test_ensure_hermes_home_memo.py
test_ensure_hermes_home_uid_34107.py
test_ensure_utf8_locale.py
test_env_custom_keys.py
test_env_export_line_lifecycle.py
test_env_export_prefix.py
test_env_load_cache.py
test_env_loader.py
test_env_sanitize_on_load.py
test_fallback_cmd.py
test_fallback_config.py
test_fireworks_provider.py Fireworks user agent (#80422) 2026-08-07 01:49:57 +00:00
test_gateway.py
test_gateway_external_supervisor.py
test_gateway_linger.py
test_gateway_platform_gating.py
test_gateway_proc_fallback.py
test_gateway_restart_loop.py fix(cron): lifecycle guard — never crash on binary referenced paths, stop matching lifecycle words inside SQL/text 2026-08-06 07:49:35 -07:00
test_gateway_run_hard_exit.py
test_gateway_runtime_health.py
test_gateway_s6_dispatch.py
test_gateway_service.py fix(launchd): require a supervised PID to call a reload successful 2026-08-07 06:55:27 +05:30
test_gateway_service_paths.py
test_gateway_windows.py
test_gateway_wsl.py
test_gemini_free_tier_setup_block.py
test_gemini_provider.py
test_get_env_value_scope.py
test_git_probe_tree_kill.py
test_gmi_provider.py
test_goal_gates.py
test_goals.py
test_gpt56_registration.py
test_graphical_browser_detection.py
test_gui_command.py
test_gui_uninstall.py
test_heartbeat.py feat: /heartbeat — recurring session re-entry prompt fired when idle 2026-08-05 22:32:55 -07:00
test_hooks_cli.py
test_ignore_user_config_flags.py
test_image_gen_picker.py
test_init_command.py
test_input_sanitize.py
test_install_cua_driver.py
test_inventory.py
test_inventory_pricing.py
test_jobs_json_utf8_bom.py
test_journey_render.py
test_kanban_block_kinds.py
test_kanban_blocked_sticky.py
test_kanban_board_project.py
test_kanban_boards.py
test_kanban_cli.py
test_kanban_cli_dispatch_passthrough.py
test_kanban_comment_queries.py
test_kanban_core_functionality.py
test_kanban_count_notify_subs.py
test_kanban_db.py
test_kanban_db_init.py
test_kanban_db_repair.py
test_kanban_decompose.py
test_kanban_decompose_db.py
test_kanban_default_assignee.py
test_kanban_diagnostics.py
test_kanban_dispatch_lock.py
test_kanban_goal_mode.py
test_kanban_init_lock_bounded.py
test_kanban_lifecycle_hooks.py
test_kanban_notify.py
test_kanban_per_profile_cap.py
test_kanban_project_link.py
test_kanban_promote.py
test_kanban_reclaim_claim_lock_guard.py
test_kanban_specify.py
test_kanban_specify_db.py
test_kanban_swarm.py
test_kanban_worker_image_extraction.py
test_kanban_worker_session_source.py
test_kanban_worker_spawn_toolsets.py
test_kanban_worker_terminal_cwd.py
test_kanban_worktree_isolation.py
test_kanban_write_guard.py
test_kanban_write_txn_busy_retry.py
test_kimi_cn_provider_listing.py
test_launcher.py
test_lazy_refresh_venv_repair.py
test_lifecycle.py
test_linux_desktop_entry.py
test_list_picker_providers.py
test_lmstudio_context_policy.py
test_logs.py
test_main_model_custom_provider_normalization.py
test_managed_installs.py
test_managed_scope.py
test_managed_scope_cli_config.py
test_managed_scope_config.py
test_managed_scope_env.py
test_managed_scope_loaders.py
test_managed_scope_overlay.py
test_managed_scope_regression.py
test_managed_scope_surfacing.py
test_managed_scope_writeguard.py
test_managed_uv.py
test_mcp_add_command_dest.py
test_mcp_catalog.py
test_mcp_config.py
test_mcp_dashboard_oauth.py
test_mcp_discovery_timing.py
test_mcp_reload_confirm_gate.py
test_mcp_security.py
test_mcp_startup.py
test_mcp_tools_config.py
test_mem_trim.py
test_memory_reset.py
test_memory_setup.py
test_memory_setup_provider_arg.py
test_memory_status.py
test_migrate_xai.py
test_moa_config.py
test_moa_set_models_preserves_extra_keys.py
test_model_cache_swr.py
test_model_catalog.py
test_model_cost_guard.py
test_model_flow_pooled_credentials.py
test_model_normalize.py
test_model_picker_excluded_providers.py
test_model_picker_expensive_confirm.py
test_model_picker_viewport.py
test_model_provider_persistence.py
test_model_search.py
test_model_search_alias_dedup.py
test_model_switch_configured_provider_routing.py
test_model_switch_context_display.py
test_model_switch_context_offload.py
test_model_switch_copilot_api_mode.py
test_model_switch_custom_providers.py
test_model_switch_filter_unresolved.py
test_model_switch_once_flags.py
test_model_switch_openai_api_mode.py
test_model_switch_opencode_anthropic.py
test_model_switch_parsing.py
test_model_switch_persist_default.py
test_model_switch_variant_tags.py
test_model_validation.py
test_models.py
test_models_dev_preferred_merge.py
test_non_ascii_credential.py
test_noninteractive_git.py
test_normalize_main_model_assignment.py
test_nous_account.py
test_nous_auth_keepalive.py
test_nous_auth_status_cache.py
test_nous_billing_request.py
test_nous_hermes_non_agentic.py
test_nous_inference_url_validation.py
test_nous_portal_staging_allowlist.py
test_nous_session_validity.py
test_nous_subscription.py
test_npm_engine.py
test_official_openai_host.py
test_ollama_cloud_auth.py
test_ollama_cloud_provider.py
test_oneshot_usage_file.py
test_openai_codex_model_validation_fallback.py
test_openai_discovery_endpoint.py
test_openai_listing_authority.py
test_openai_picker_curated.py
test_opencode_go_flat_namespace.py
test_opencode_go_in_model_list.py
test_opencode_go_validation_fallback.py
test_opencode_zen_model_limit.py
test_overlay_slug_resolution.py
test_pairing.py
test_path_completion.py
test_pet_toggle.py
test_picker_prewarm.py
test_pin_kanban_board_env.py
test_pip_install_detection.py
test_placeholder_usage.py
test_plugin_auxiliary_tasks.py
test_plugin_cli_registration.py
test_plugin_runtime_disable_gate.py
test_plugin_scanner_recursion.py
test_plugins.py
test_plugins_cmd.py
test_plugins_cmd_category_discovery.py
test_plugins_cmd_enable_disable_nested.py
test_plugins_cmd_list.py
test_plugins_hub_perf_guard.py
test_plugins_transcription_registration.py
test_plugins_tts_registration.py
test_post_setup_gating.py
test_profile_describer.py
test_profile_distribution.py
test_profile_export_credentials.py
test_profile_install_env_encoding.py
test_profiles.py
test_profiles_s6_hooks.py
test_project_plugin_rce_bypass.py
test_projects_cli.py
test_projects_db.py
test_prompt_api_key.py
test_prompt_compose_command.py
test_prompt_size.py
test_provider_catalog.py
test_provider_config_validation.py
test_provider_groups.py
test_provider_live_curated_merge.py
test_provider_parity.py
test_provider_precedence.py
test_provider_section3_grouping.py
test_proxy.py
test_psutil_android_extract.py
test_pty_bridge.py
test_quarantine_forensic_logging.py
test_read_raw_config_readonly.py
test_reasoning_effort_menu.py
test_reasoning_full_command.py
test_redact_config_bridge.py
test_regression_16767.py
test_relaunch.py
test_relay_shared_metrics.py
test_relay_shared_metrics_runtime.py
test_remote_spending_gate_contract.py
test_resolve_last_session.py
test_resolve_provider_openrouter_pool.py
test_resolve_token_memo.py
test_run_with_idle_timeout.py
test_runtime_provider_resolution.py
test_runtime_transport_precedence.py
test_safe_mode.py
test_sale_pricing.py
test_scan_venv_blockers.py
test_secret_prompt.py
test_secrets_bitwarden_non_tty.py
test_secrets_token_rotation.py
test_security_advisories.py
test_security_audit.py
test_security_audit_startup.py
test_send_cmd.py
test_serve_command.py
test_service_manager.py
test_session_browse.py
test_session_export.py
test_session_export_html.py
test_session_export_html_escape.py
test_session_export_md.py
test_session_filters.py
test_session_handoff.py
test_session_listing.py
test_session_recap.py
test_session_recovery.py
test_sessions_delete.py
test_sessions_export_md_cli.py
test_sessions_size_delta_label.py
test_set_config_value.py
test_setup.py
test_setup_agent_settings.py
test_setup_blank_slate.py
test_setup_hermes_script.py
test_setup_hidden_env.py
test_setup_irc.py
test_setup_matrix_e2ee.py
test_setup_menu_curses_migration.py
test_setup_model_provider.py
test_setup_noninteractive.py
test_setup_openclaw_migration.py
test_setup_prompt_menus.py
test_setup_reconfigure.py
test_setup_summary_provider_warning.py
test_setup_telemetry.py
test_setup_tts_xai_oauth.py
test_signal_handler_kanban_worker.py
test_skills_config.py
test_skills_hub.py
test_skills_install_flags.py
test_skills_skip_confirm.py
test_skills_subparser.py
test_skin_cmd.py
test_skin_engine.py
test_skin_palettes.py
test_slack_cli.py
test_spotify_auth.py
test_sqlite_runtime.py
test_ssh_ownership_endpoint.py
test_ssh_session_token_parser.py
test_startup_fast_guards.py
test_startup_plugin_gating.py
test_state_db_guard.py
test_status.py
test_status_model_provider.py
test_status_provider_label.py
test_stt_picker.py
test_subcommands_batch.py
test_subcommands_followup.py
test_subcommands_profile_gateway.py
test_subparser_routing_fallback.py
test_subprocess_timeouts.py
test_subscription_cli.py
test_suppress_eio_on_interrupt.py
test_system_stats_platform.py
test_systemd_optional_directives.py
test_systemd_watchdog_unit.py
test_teams_pipeline_plugin_cli.py
test_telegram_managed_bot.py
test_tencent_tokenhub_provider.py
test_terminal_menu_fallbacks.py
test_timeouts.py
test_timestamps_command.py
test_tips.py
test_tool_token_estimation.py
test_tools_config.py
test_tools_disable_enable.py
test_toolset_validation.py
test_tts_picker.py
test_tui_bundled.py
test_tui_heap_sizing.py
test_tui_mouse_residue_suppression.py
test_tui_npm_install.py
test_tui_resume_flow.py
test_uninstall_dry_run.py
test_uninstall_node_symlinks.py
test_uninstall_shell_configs.py
test_update_autostash.py
test_update_check.py
test_update_concurrent_quarantine.py
test_update_config_clears_custom_fields.py
test_update_eol_churn.py
test_update_fleet_restart_timeout.py
test_update_gateway_launcher_refresh.py
test_update_hangup_protection.py
test_update_import_guard.py
test_update_interrupted_recovery.py
test_update_lock.py
test_update_modified_notice.py
test_update_post_pull_syntax_guard.py
test_update_stale_dashboard.py
test_update_venv_health.py
test_update_yes_flag.py
test_update_zip_atomic_replace.py
test_update_zip_symlink_reject.py
test_update_zip_two_phase.py
test_upstage_provider.py
test_urllib_security.py
test_user_providers_model_switch.py
test_verify_console_scripts.py
test_verify_core_dependencies.py
test_vertex_model_picker.py
test_vertex_provider.py
test_video_gen_picker.py
test_voice_wrapper.py
test_web_oauth_dispatch.py
test_web_profile_soul_writes.py
test_web_server.py fix(dashboard): derive the stale-schema read probe from SCHEMA_SQL 2026-08-07 00:41:58 -04:00
test_web_server_boot_handshake.py
test_web_server_console_ws.py
test_web_server_cron_profiles.py
test_web_server_files.py
test_web_server_fs.py
test_web_server_gateway_topology.py
test_web_server_git.py
test_web_server_host_header.py
test_web_server_messaging_profiles.py
test_web_server_oauth_write.py
test_web_server_profile_unification.py
test_web_server_pty_import.py
test_web_server_pty_reconnect.py
test_web_server_session_search.py
test_web_server_skill_editor.py
test_web_server_skills_profiles.py
test_web_server_speak_stream.py
test_web_ui_build.py
test_webhook_cli.py
test_whatsapp_cloud_setup.py
test_whatsapp_onboarding.py
test_whatsapp_setup_ordering.py
test_win_pty_bridge.py
test_windows_native_docs.py
test_xai_curated_models.py
test_xai_model_flow.py
test_xai_oauth_profile_auth.py
test_xai_oauth_refresh.py
test_xai_oauth_writethrough.py
test_xai_provider_labels.py
test_xai_retirement.py
test_xiaomi_provider.py
test_yolo_startup_order.py