Summary
About 50 functions, methods and classes in the backend and scheduler are defined once and referenced nowhere in non-test code. Roughly half have tests, which means test code is keeping dead code alive and readers are misled about what the product does. Remove the ones that are confirmed dead.
Context
Static review of dev at f6bedcd8: vulture at 60% confidence over services, db, utils, adapters and the scheduler, then each name confirmed to appear once across all non-test code. Sibling of #1032, which covers unused imports and variables only.
The check is name-based, so every symbol needs a look before deletion: a function reached through getattr or a registry looks dead. A symbol with many test references and no production caller (for example _sanitize_filename, 30 test references) may be a helper whose call site was removed by mistake; that is a bug to report, not a deletion.
Line numbers are as of f6bedcd8. Paths without a src/ prefix are relative to src/backend/. "Tests" counts references in test code.
| File |
Symbol |
Tests |
Note |
services/ssh_service.py:449 |
cleanup_expired_keys |
1 |
Backwards-compatibility alias; the live sweep calls cleanup_expired_credentials |
services/ssh_service.py:350 |
list_active_keys |
2 |
|
services/ssh_service.py:519 |
cleanup_agent_keys |
0 |
|
services/telegram_media.py:96 |
process_photo |
0 |
Only process_voice is called from this module |
services/telegram_media.py:130 |
process_document |
0 |
|
services/github_service.py:349 |
get_github_service |
0 |
Singleton accessor nobody uses |
services/github_service.py:51 |
GitHubAuthError |
0 |
Never raised or caught |
services/github_service.py:56 |
GitHubPermissionError |
0 |
Never raised or caught |
services/monitoring_alerts.py:346 |
alert_stuck_execution |
0 |
The one alert of seven that is never raised |
services/subscription_auto_switch.py:788 |
handle_rate_limit_error |
1 |
|
services/template_service.py:2190 |
get_name_from_template |
0 |
|
services/skill_service.py:959 |
_persisted_commit |
0 |
|
services/settings_service.py:907 |
clear_template_registry_lkg |
0 |
|
services/system_agent_service.py:137 |
is_registered |
0 |
|
services/slot_service.py:507 |
is_at_capacity |
3 |
|
services/slack_service.py:111 |
verify_slack_signature |
1 |
|
services/heartbeat_service.py:238 |
heartbeat_status |
8 |
|
services/dispatch_breaker.py:368 |
get_all_dispatch_states |
5 |
|
services/redelivery_governor.py:126 |
distinct_failing_count |
13 |
|
services/idempotency_service.py:143 |
derive_schedule_key |
1 |
|
services/agent_mcp_key_service.py:229 |
build_mcp_key_env_overrides |
1 |
|
services/agent_service/mcp_tool_names.py:84 |
compute_tool_name |
5 |
|
services/agent_client/http_pool.py:112 |
_get_http_client |
13 |
|
services/agent_call_limiter.py:451 |
_set_cancel_sync |
0 |
|
services/a2a_payment_gate.py:235 |
AllowlistRefused |
0 |
|
services/a2a_gate.py:89 |
get_skills_provider |
2 |
|
services/compatibility/static_checks.py:778 |
_is_skill_md |
0 |
|
services/git_service/trinity_files.py:171 |
_persistent_state_for |
6 |
|
services/skill_sets.py:76 |
split_set_ref |
4 |
|
services/event_bus.py:66 |
_serialize |
0 |
|
services/backlog_service.py:456 |
get_backlog_service |
3 |
|
adapters/message_router.py:92 |
_get_channel_timeout |
0 |
|
adapters/message_router.py:350 |
_format_file_size |
7 |
|
adapters/message_router.py:359 |
_sanitize_filename |
30 |
Heavily tested, never called |
adapters/transports/voip_audio.py:39 |
pop_frames |
4 |
|
db/schedules/webhooks.py:85 |
set_webhook_enabled |
0 |
|
db/schedules/webhooks.py:126 |
_decrypt_webhook_secret |
0 |
|
db/slack_channels.py:418 |
unbind_channel |
0 |
Unreachable delete path |
db/telegram_channels.py:697 |
delete_groups_for_binding |
0 |
Unreachable delete path |
db/role_readiness.py:82 |
delete_role_readiness |
0 |
Unreachable delete path |
db/agent_cleanup.py:533 |
find_orphan_agent_names |
0 |
|
db/agent_cleanup.py:592 |
registered_columns |
2 |
|
utils/password_validation.py:85 |
is_password_weak |
6 |
|
src/scheduler/service.py:2346 |
add_schedule |
3 |
Older push-style API; the scheduler now syncs by polling |
src/scheduler/service.py:2351 |
remove_schedule |
1 |
Same |
src/scheduler/service.py:2361 |
reload_schedules |
3 |
Same |
src/scheduler/service.py:316 |
run_forever |
2 |
Confirm the entrypoint does not call it by another route |
src/scheduler/database.py:472 |
should_freeze_schedules |
7 |
|
src/scheduler/database.py:715 |
get_recent_executions |
2 |
|
src/scheduler/locking.py:241 |
is_schedule_locked |
1 |
|
src/scheduler/models.py:29 |
TriggerSource |
4 |
|
src/scheduler/models.py:255 |
AgentTaskResponse |
0 |
|
Leave alone (exist for tests or are called by name by SQLAlchemy): dispose_engines, clear_dialect_cache, clear_skills_provider, reset_capacity_manager, reset_startup_recovery_flag_for_tests, clear_plan_scheme_cache, reset_alert_budget_state, clear_inprocess, reset_transition_memo, clear_staged, _reset_sweep_lock_for_test, process_bind_param in db/tables.py. Also excluded: the dynamically dispatched handlers in slack_mrkdwn.py, and the process-schedule symbols, which have their own issue.
Acceptance Criteria
Summary
About 50 functions, methods and classes in the backend and scheduler are defined once and referenced nowhere in non-test code. Roughly half have tests, which means test code is keeping dead code alive and readers are misled about what the product does. Remove the ones that are confirmed dead.
Context
Static review of
devatf6bedcd8:vultureat 60% confidence over services, db, utils, adapters and the scheduler, then each name confirmed to appear once across all non-test code. Sibling of #1032, which covers unused imports and variables only.The check is name-based, so every symbol needs a look before deletion: a function reached through
getattror a registry looks dead. A symbol with many test references and no production caller (for example_sanitize_filename, 30 test references) may be a helper whose call site was removed by mistake; that is a bug to report, not a deletion.Line numbers are as of
f6bedcd8. Paths without asrc/prefix are relative tosrc/backend/. "Tests" counts references in test code.services/ssh_service.py:449cleanup_expired_keyscleanup_expired_credentialsservices/ssh_service.py:350list_active_keysservices/ssh_service.py:519cleanup_agent_keysservices/telegram_media.py:96process_photoprocess_voiceis called from this moduleservices/telegram_media.py:130process_documentservices/github_service.py:349get_github_serviceservices/github_service.py:51GitHubAuthErrorservices/github_service.py:56GitHubPermissionErrorservices/monitoring_alerts.py:346alert_stuck_executionservices/subscription_auto_switch.py:788handle_rate_limit_errorservices/template_service.py:2190get_name_from_templateservices/skill_service.py:959_persisted_commitservices/settings_service.py:907clear_template_registry_lkgservices/system_agent_service.py:137is_registeredservices/slot_service.py:507is_at_capacityservices/slack_service.py:111verify_slack_signatureservices/heartbeat_service.py:238heartbeat_statusservices/dispatch_breaker.py:368get_all_dispatch_statesservices/redelivery_governor.py:126distinct_failing_countservices/idempotency_service.py:143derive_schedule_keyservices/agent_mcp_key_service.py:229build_mcp_key_env_overridesservices/agent_service/mcp_tool_names.py:84compute_tool_nameservices/agent_client/http_pool.py:112_get_http_clientservices/agent_call_limiter.py:451_set_cancel_syncservices/a2a_payment_gate.py:235AllowlistRefusedservices/a2a_gate.py:89get_skills_providerservices/compatibility/static_checks.py:778_is_skill_mdservices/git_service/trinity_files.py:171_persistent_state_forservices/skill_sets.py:76split_set_refservices/event_bus.py:66_serializeservices/backlog_service.py:456get_backlog_serviceadapters/message_router.py:92_get_channel_timeoutadapters/message_router.py:350_format_file_sizeadapters/message_router.py:359_sanitize_filenameadapters/transports/voip_audio.py:39pop_framesdb/schedules/webhooks.py:85set_webhook_enableddb/schedules/webhooks.py:126_decrypt_webhook_secretdb/slack_channels.py:418unbind_channeldb/telegram_channels.py:697delete_groups_for_bindingdb/role_readiness.py:82delete_role_readinessdb/agent_cleanup.py:533find_orphan_agent_namesdb/agent_cleanup.py:592registered_columnsutils/password_validation.py:85is_password_weaksrc/scheduler/service.py:2346add_schedulesrc/scheduler/service.py:2351remove_schedulesrc/scheduler/service.py:2361reload_schedulessrc/scheduler/service.py:316run_foreversrc/scheduler/database.py:472should_freeze_schedulessrc/scheduler/database.py:715get_recent_executionssrc/scheduler/locking.py:241is_schedule_lockedsrc/scheduler/models.py:29TriggerSourcesrc/scheduler/models.py:255AgentTaskResponseLeave alone (exist for tests or are called by name by SQLAlchemy):
dispose_engines,clear_dialect_cache,clear_skills_provider,reset_capacity_manager,reset_startup_recovery_flag_for_tests,clear_plan_scheme_cache,reset_alert_budget_state,clear_inprocess,reset_transition_memo,clear_staged,_reset_sweep_lock_for_test,process_bind_paramindb/tables.py. Also excluded: the dynamically dispatched handlers inslack_mrkdwn.py, and the process-schedule symbols, which have their own issue.Acceptance Criteria
run_foreverinsrc/scheduler/service.pyis confirmed unused by the container entrypoint before removal