docs(sessions): recency wording matches the freshest-of rule

Prune recency is now the freshest of last_activity_at / latest message /
started_at (via _sql_session_last_active), but four doc sites still said
"latest message, else started_at": the list_prune_candidates docstring,
the --older-than/--newer-than help in session_filters, and two comments
in config_defaults. Reword them to the phrasing archive_stale_sessions
already uses so operators are not told live activity is ignored.

Also make archive_stale_sessions use the module constant _LAST_ACTIVE_SQL
instead of an inline _sql_session_last_active("s") call — same alias,
identical SQL, one fewer place to drift.
This commit is contained in:
kshitijk4poor
2026-09-17 18:43:44 +05:30
committed by kshitij
parent bca1928650
commit 3132ecb640
3 changed files with 8 additions and 8 deletions

View File

@@ -2086,15 +2086,15 @@ DEFAULT_CONFIG = {
# Automatic cleanup of ~/.hermes/state.db, which otherwise grows without bound and slows FTS5
# inserts, /resume listing, and insights queries.
"sessions": {
# Prune ENDED sessions inactive for retention_days (activity = latest message, else
# creation) about once per min_interval_hours at startup. Open, pinned, or mid-turn sessions
# Prune ENDED sessions inactive for retention_days (activity = freshest of live activity /
# latest message / creation) about once per min_interval_hours at startup. Open, pinned, or mid-turn sessions
# are never deleted; stale automation sessions whose process died are *closed*, then get a
# full retention window before removal.
"auto_prune": True,
# Inactive days of ended-session history to keep (= `hermes sessions prune`).
# When true, prune ENDED sessions inactive for retention_days once per (roughly) min_interval_hours
# at CLI/gateway/cron startup. Activity is the latest message timestamp, falling back to creation
# time for empty sessions. Sessions that are still open, pinned, or mid-turn are never deleted — the
# at CLI/gateway/cron startup. Activity is the freshest of live activity (last_activity_at) / latest
# message timestamp / creation time. Sessions that are still open, pinned, or mid-turn are never deleted — the
# only open rows the sweep touches are stale automation sessions (cron/kanban/subagent/one-shot CLI)
# whose process died without closing them; those are *closed*, not deleted, and get a further full
# retention window before removal. Default true since #54189: without it state.db grows without

View File

@@ -96,8 +96,8 @@ _ARG_FILTERS = (
def build_prune_filters(args: Any) -> Dict[str, Any]:
"""Translate argparse Namespace flags into SessionDB filter kwargs.
``--older-than`` / ``--newer-than`` bound last activity (latest message timestamp, falling back
to ``started_at`` for empty sessions); ``--before`` / ``--after`` bound session start time.
``--older-than`` / ``--newer-than`` bound last activity (freshest of ``last_activity_at`` /
latest message / ``started_at``); ``--before`` / ``--after`` bound session start time.
"""
bounds: Dict[str, Optional[float]] = {
key: None if (raw := getattr(args, attr, None)) is None else parse_point_in_time(raw, flag)

View File

@@ -209,7 +209,7 @@ class SessionMaintenanceMixin:
def list_prune_candidates(self, older_than_days: Optional[float] = None, source: str = None,
**filters) -> List[Dict[str, Any]]:
"""Dry-run: sessions a matching prune/archive would touch, oldest first (``older_than_days``
= inactivity threshold: latest message, else ``started_at``)."""
= inactivity threshold: freshest of ``last_activity_at`` / latest message / ``started_at``)."""
where, params = self._prune_where(older_than_days, source, filters)
return [dict(row) for row in self._read_all(
f"""SELECT s.id, s.source, s.title, s.model, s.started_at,
@@ -253,7 +253,7 @@ class SessionMaintenanceMixin:
AND COALESCE(s.end_reason, '') <> 'compression'
{pin_clause}
AND NOT (COALESCE(s.hidden, 0) <> 0 AND COALESCE(s.title, '') = ?)
AND {_sql_session_last_active("s")} < ?
AND {_LAST_ACTIVE_SQL} < ?
ORDER BY s.started_at ASC
""", (self.CANONICAL_BOT_CHAT_TITLE, cutoff))
for row in rows: