Skip to content

fix(tasks): prune finished task history#138

Merged
PleasePrompto merged 1 commit into
PleasePrompto:mainfrom
attid:fix/task-retention-cleanup
Jul 12, 2026
Merged

fix(tasks): prune finished task history#138
PleasePrompto merged 1 commit into
PleasePrompto:mainfrom
attid:fix/task-retention-cleanup

Conversation

@attid

@attid attid commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Add automatic retention cleanup for finished background tasks.

Why

Finished task entries (done, failed, cancelled) were retained indefinitely unless a user manually pressed cleanup in /tasks. Since each entry persists the full original_prompt, old finished tasks can make tasks.json grow without bound.

Changes

  • Add tasks.finished_retention_hours with a default of 168 hours.
  • Add tasks.finished_keep_last with a default of 100 finished tasks.
  • Add registry retention cleanup that removes finished entries and their task folders by age and count.
  • Keep running and waiting tasks protected from retention cleanup.
  • Run task maintenance immediately when the maintenance loop starts, then every 5 hours.

Validation

  • uv run pytest tests/tasks tests/test_config.py tests/config -q
  • uv run ruff check ductor_bot/config.py ductor_bot/tasks/registry.py ductor_bot/tasks/hub.py tests/tasks/test_registry.py tests/tasks/test_hub.py
  • uv run mypy ductor_bot

@PleasePrompto

Copy link
Copy Markdown
Owner

Thanks — the core logic here is solid: the retention pruning can't touch running/waiting tasks, the age+count criteria merge cleanly, and the hub maintenance test is well built. A few things before un-drafting:

  1. Consolidate cleanup_old (tasks/registry.py): it has no production caller (only its own tests) and overlaps with the new cleanup_finished_retention. Please either remove it (incl. TestCleanupOld) or fold the new logic into it — two parallel age-pruning methods is exactly the kind of dead code this repo's conventions forbid.
  2. config.example.json: add finished_retention_hours / finished_keep_last to the tasks block (the other fields are all listed there).
  3. Docs: docs/config.md (TasksConfig table) and docs/modules/tasks.md need the new fields; the "orphan cleanup runs every 5 hours" note should also mention the maintenance pass now runs immediately at startup.
  4. Optional but nice: a test for the age×count interaction (young task evicted by keep_last) and the <=0 noop path.

Happy to merge once those are in. 👍

@attid
attid force-pushed the fix/task-retention-cleanup branch from 419e7ac to 0a1b437 Compare July 10, 2026 15:13
@PleasePrompto
PleasePrompto marked this pull request as ready for review July 12, 2026 06:08
@PleasePrompto
PleasePrompto merged commit 1e74a1f into PleasePrompto:main Jul 12, 2026
PleasePrompto added a commit that referenced this pull request Jul 12, 2026
- remove cleanup_old (no production caller; superseded by
  cleanup_finished_retention) including its tests
- document the union semantics of age and count limits, add tests for
  age-overrides-keep_last and the disabled-limits noop
- add finished_retention_hours / finished_keep_last to
  config.example.json and docs; note maintenance now also runs at startup

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PleasePrompto added a commit that referenced this pull request Jul 12, 2026
Post-merge fixes threading the Slack transport through main's newer
subsystems (#164 per-session effort, #157 append_system_prompt_files,
#166 topic-scoped kills, #137/#138 task changes):

- Delete fork-only .github/workflows/upstream-release-watch.yml
- Remove dead _is_message_addressed() in messenger/slack/bot.py
- Fix trailing comma in config.example.json Slack section (invalid JSON)
- Drop fork-only "ductor-slack" brand strings from en/wizard.toml
- Harden _normalized_transport_list() in __main__.py: honor a non-empty
  transports list whenever the primary is a member (primary-first, others
  preserved) instead of collapsing to [primary] on any ordering mismatch,
  so telegram+matrix multi-transport setups are never silently dropped;
  add regression tests
- named.py create(): keep both reasoning_effort and key params (# noqa:
  PLR0913, matching the codebase convention e.g. tasks/registry.py)
- Update #164 create() test stubs for the new key kwarg
- mypy: guard the optional slack_bolt import behind TYPE_CHECKING/else to
  satisfy strict no-redef
- uv lock: add slack-bolt/slack-sdk (also picks up pre-existing lock drift)
- ruff format integration-touched files

Note: orch._sessions.list_active_for_chat() in slack/bot.py follows the
existing private-access convention (telegram/startup.py does the same);
no public accessor exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants