cleanup/
March 8, 2026 ยท View on GitHub
Daily retention cleanup for workspace file-drop directories.
Files
cleanup/observer.py:CleanupObserver, retention execution, scheduler loop.cleanup/__init__.py: exportsCleanupObserver.
Purpose
Targets retention cleanup in:
~/.ductor/workspace/telegram_files/(Telegram media)~/.ductor/workspace/matrix_files/(Matrix media)~/.ductor/workspace/output_to_user/~/.ductor/workspace/api_files/
Config (AgentConfig.cleanup)
| Field | Type | Default | Notes |
|---|---|---|---|
enabled | bool | true | Master toggle |
media_files_days | int | 30 | Retention for media files (telegram + matrix) |
output_to_user_days | int | 30 | Retention for output_to_user |
api_files_days | int | 30 | Retention for api_files |
check_hour | int | 3 | Local hour (user_timezone) when cleanup is eligible |
Lifecycle
CleanupObserver.start():
- exits early if
cleanup.enabled=false - starts background loop with crash callback logging
Loop behavior:
- wakes every hour (
_CHECK_INTERVAL = 3600) - resolves local time via
resolve_user_timezone(config.user_timezone) - runs cleanup only when
now.hour == check_hour - runs at most once per day (
_last_run_dateguard)
Execution detail: actual deletion work runs in asyncio.to_thread(_run_cleanup, ...) so the observer never blocks the event loop.
Deletion Rules
_delete_old_files(directory, max_age_days):
- deletes files older than
max_age_days - walks directory trees recursively
- prunes empty subdirectories after file deletion
- logs warnings on per-file deletion errors
Current behavior implication:
- Telegram/API uploads are saved under date subdirectories (
YYYY-MM-DD/), - those nested files are eligible for cleanup once they pass retention age.
Wiring
- created in
Orchestrator.__init__ - started in
Orchestrator.create() - stopped in
Orchestrator.shutdown()