fix(sessions): let guarded delete remove idle compression-ended rows
The new entry-side guard in delete_session/delete_sessions called _write_guards_reject without allow_closed_compression_parent=True, so _check_transcript_write_guards raised CompressionSessionClosedError for any row with end_reason='compression'. That type is not caught by _write_guards_reject, so every user-facing delete of a compressed parent 500'd and a bulk delete containing one rolled back the whole batch. Pass the flag at both sites, matching prune (hermes_state_maintenance.py). The lease is keyed on the lineage root, so a live turn on the tip still blocks deleting its ancestor. Test 1 gains a compression-ended case (red on the pre-fold file).
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user