fix(checkpoints): never auto-delete orphans on unattended startup sweep

Builds on this PR's diagnosis by @Frowtek: a missing workdir is
ambiguous (deleted project vs. an unmounted external volume / network
share / VPN not yet up), so it's not safe evidence for a destructive
GC sweep — especially one that runs unattended at startup.

- cli.py / gateway/run.py: the startup auto-maintenance sweep now
  always passes delete_orphans=False to maybe_auto_prune_checkpoints().
  It still prunes by retention_days, size cap, and legacy archives —
  none of which require guessing whether a project was deleted or is
  just temporarily unreachable.
- hermes_cli/config.py: drop the now-unused delete_orphans default.
- hermes_cli/checkpoints.py: `hermes checkpoints prune` (the explicit,
  human-invoked path) now previews the orphan project list and asks
  for confirmation before deleting, unless -f/--force is passed.
- Docs updated (EN + zh-Hans) to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
joaomarcos 2026-07-22 03:11:12 -03:00 committed by Teknium
parent 3960315af7
commit cd3f653b4e
6 changed files with 64 additions and 18 deletions

7
cli.py
View file

@ -2008,10 +2008,15 @@ def _run_checkpoint_auto_maintenance() -> None:
if not cfg.get("auto_prune", False):
return
from tools.checkpoint_manager import maybe_auto_prune_checkpoints
# delete_orphans is intentionally never honoured here: a missing
# workdir at startup is ambiguous (deleted project vs. an unmounted
# external volume / network share / VPN not yet up) and this sweep
# runs unattended. Orphan cleanup is only ever done via the explicit
# `hermes checkpoints prune` command, which the user has to invoke.
maybe_auto_prune_checkpoints(
retention_days=int(cfg.get("retention_days", 7)),
min_interval_hours=int(cfg.get("min_interval_hours", 24)),
delete_orphans=bool(cfg.get("delete_orphans", True)),
delete_orphans=False,
max_total_size_mb=int(cfg.get("max_total_size_mb", 500)),
)
except Exception as exc: