When state.db's write path fails (corrupt FTS, or a crash landing between
routing publication and row creation), the live gateway conversation can end
up in a session row that never received its identity columns: session_key,
chat_id, chat_type and origin_json are all NULL. In-memory routing hides the
damage for as long as the gateway stays up. After a restart the chat is
resolved from the DB, and find_latest_gateway_session_for_peer cannot see
that row — both of its queries match on the very columns it lacks — so the
chat resumes the last keyed sibling instead, days older. The messages were
never lost, only unreachable.
Hardening the write side cannot reach a row that is already damaged, so add
the offline repair path the tracking issue asks for:
- SessionDB.find_orphaned_gateway_sessions() reports message-bearing rows
with no session_key, and names the predecessor each one continues only
when the evidence is unambiguous — a recorded parent_session_id
("lineage"), or exactly one keyed row of the same source and compatible
user_id that fell quiet within 15 minutes of the orphan's start
("contiguity"). Contested pairs are reported with a reason and left alone:
a wrong adoption would splice one person's conversation into another
person's chat. Branch, delegate and tool rows are excluded — they are
unkeyed by design, not by damage.
- SessionDB.adopt_orphaned_gateway_session() stamps the orphan from the
predecessor (never overwriting a column that already has a value), records
the lineage, and retires the predecessor under end_reason
'superseded_by_repair' — a reason recovery does not treat as resumable, so
the repaired row wins the chat from then on. The pair is re-verified inside
the write transaction, making a concurrent heal a no-op rather than a
conflicting write.
- `hermes sessions repair-routing` drives both. It reports without touching
the database; --apply confirms first and warns that a running gateway
still holds the old mapping in memory.
Refs #82616.
|
||
|---|---|---|
| .. | ||
| dashboard_auth | ||
| observability | ||
| proxy | ||
| subcommands | ||
| web_routers | ||
| __init__.py | ||
| _early_recovery.py | ||
| _parser.py | ||
| _scan_venv_blockers.py | ||
| _startup_fast.py | ||
| _subprocess_compat.py | ||
| active_sessions.py | ||
| agent_import.py | ||
| agent_plugins.py | ||
| approval_mode.py | ||
| approvals_suggest.py | ||
| approvals_test.py | ||
| auth.py | ||
| auth_commands.py | ||
| azure_detect.py | ||
| backup.py | ||
| bang_shell.py | ||
| banner.py | ||
| blueprint_cmd.py | ||
| browser_connect.py | ||
| build_info.py | ||
| bundles.py | ||
| callbacks.py | ||
| checkpoints.py | ||
| claw.py | ||
| cli_agent_setup_mixin.py | ||
| cli_billing_mixin.py | ||
| cli_commands_mixin.py | ||
| cli_output.py | ||
| clipboard.py | ||
| codex_models.py | ||
| codex_runtime_plugin_migration.py | ||
| codex_runtime_switch.py | ||
| colors.py | ||
| commands.py | ||
| completion.py | ||
| config.py | ||
| config_defaults.py | ||
| config_migrations.py | ||
| console_engine.py | ||
| container_boot.py | ||
| context_switch_guard.py | ||
| copilot_auth.py | ||
| credential_lifecycle.py | ||
| cron.py | ||
| curator.py | ||
| curses_ui.py | ||
| dashboard_procs.py | ||
| dashboard_register.py | ||
| debug.py | ||
| default_soul.py | ||
| dep_ensure.py | ||
| diagnostics_upload.py | ||
| dingtalk_auth.py | ||
| doctor.py | ||
| doctor_live.py | ||
| dump.py | ||
| env_loader.py | ||
| fallback_cmd.py | ||
| fallback_config.py | ||
| focus_view.py | ||
| gateway.py | ||
| gateway_enroll.py | ||
| gateway_windows.py | ||
| goals.py | ||
| gui_uninstall.py | ||
| heartbeat.py | ||
| hooks.py | ||
| init_command.py | ||
| input_sanitize.py | ||
| inventory.py | ||
| journey.py | ||
| kanban.py | ||
| kanban_db.py | ||
| kanban_decompose.py | ||
| kanban_diagnostics.py | ||
| kanban_specify.py | ||
| kanban_swarm.py | ||
| lifecycle.py | ||
| linux_desktop_entry.py | ||
| logs.py | ||
| main.py | ||
| managed_scope.py | ||
| managed_uv.py | ||
| mcp_catalog.py | ||
| mcp_config.py | ||
| mcp_picker.py | ||
| mcp_security.py | ||
| mcp_startup.py | ||
| mem_trim.py | ||
| memory_oauth.py | ||
| memory_setup.py | ||
| middleware.py | ||
| migrate.py | ||
| moa_cmd.py | ||
| moa_config.py | ||
| model_catalog.py | ||
| model_cost_guard.py | ||
| model_normalize.py | ||
| model_search.py | ||
| model_setup_flows.py | ||
| model_switch.py | ||
| models.py | ||
| nous_account.py | ||
| nous_auth_keepalive.py | ||
| nous_billing.py | ||
| nous_subscription.py | ||
| npm_engine.py | ||
| onepassword_secrets_cli.py | ||
| oneshot.py | ||
| pairing.py | ||
| partial_compress.py | ||
| personality.py | ||
| pets.py | ||
| platforms.py | ||
| plugins.py | ||
| plugins_cmd.py | ||
| portal_cli.py | ||
| profile_describer.py | ||
| profile_distribution.py | ||
| profiles.py | ||
| projects_cmd.py | ||
| projects_db.py | ||
| prompt_size.py | ||
| prompt_stash.py | ||
| provider_catalog.py | ||
| providers.py | ||
| proxy_cli.py | ||
| psutil_android.py | ||
| pt_input_extras.py | ||
| pty_bridge.py | ||
| pty_session.py | ||
| relaunch.py | ||
| route_identity.py | ||
| runtime_provider.py | ||
| secret_prompt.py | ||
| secrets_cli.py | ||
| security_advisories.py | ||
| security_audit.py | ||
| security_audit_startup.py | ||
| send_cmd.py | ||
| service_manager.py | ||
| session_export.py | ||
| session_export_html.py | ||
| session_export_md.py | ||
| session_filters.py | ||
| session_listing.py | ||
| session_recap.py | ||
| session_recovery.py | ||
| sessions_cmd.py | ||
| setup.py | ||
| setup_hidden_env.py | ||
| setup_whatsapp_cloud.py | ||
| sizefmt.py | ||
| skills_config.py | ||
| skills_hub.py | ||
| skin_cmd.py | ||
| skin_engine.py | ||
| slack_cli.py | ||
| slash_exec.py | ||
| sqlite_runtime.py | ||
| sqlite_safe_read.py | ||
| sqlite_util.py | ||
| status.py | ||
| stdio.py | ||
| suggestions_cmd.py | ||
| telegram_managed_bot.py | ||
| timefmt.py | ||
| timeouts.py | ||
| tips.py | ||
| tools_config.py | ||
| toolset_validation.py | ||
| uninstall.py | ||
| update_cmd.py | ||
| update_lock.py | ||
| urllib_security.py | ||
| vercel_auth.py | ||
| verify_cmd.py | ||
| voice.py | ||
| web_deps.py | ||
| web_git.py | ||
| web_models.py | ||
| web_server.py | ||
| webhook.py | ||
| win_pty_bridge.py | ||
| windows_ssh_runtime.py | ||
| write_approval_commands.py | ||
| xai_retirement.py | ||