diff --git a/hermes_state_sessions.py b/hermes_state_sessions.py index 0117d6768a..2b8e0ec045 100644 --- a/hermes_state_sessions.py +++ b/hermes_state_sessions.py @@ -1576,7 +1576,9 @@ class SessionSessionsMixin: def _do(conn): if conn.execute("SELECT 1 FROM sessions WHERE id = ? LIMIT 1", (session_id,)).fetchone() is None: return False - if exclude_active_write_guards and self._write_guards_reject(conn, session_id): + if exclude_active_write_guards and self._write_guards_reject( + conn, session_id, allow_closed_compression_parent=True, + ): raise SessionActiveWriteGuardError( f"session '{session_id}' has an active turn lease or compression lock" ) @@ -1649,7 +1651,10 @@ class SessionSessionsMixin: if not existing: return 0 if exclude_active_write_guards: - active_ids = {sid for sid in existing if self._write_guards_reject(conn, sid)} + active_ids = { + sid for sid in existing + if self._write_guards_reject(conn, sid, allow_closed_compression_parent=True) + } existing = [sid for sid in existing if sid not in active_ids] if skipped_ids is not None: skipped_ids.extend(sorted(active_ids)) diff --git a/tests/hermes_state/test_delete_session_write_guards.py b/tests/hermes_state/test_delete_session_write_guards.py index 70c286c4e8..208ded057c 100644 --- a/tests/hermes_state/test_delete_session_write_guards.py +++ b/tests/hermes_state/test_delete_session_write_guards.py @@ -39,6 +39,13 @@ def test_delete_session_refuses_when_write_guard_active(tmp_path): assert db.delete_session("sess-cmp", exclude_active_write_guards=True) is True assert db.get_session("sess-cmp") is None + + # 4. An idle compression-ended row is a closed parent, not a live write: delete must succeed + # (no CompressionSessionClosedError leaking out of the guard check). + db.create_session("sess-compressed", source="test") + db.end_session("sess-compressed", "compression") + assert db.delete_session("sess-compressed", exclude_active_write_guards=True) is True + assert db.get_session("sess-compressed") is None db.close()