refactor(sessions): one transcript-format rule and one missing-display-index probe

The "display index not backfilled" probe was spelled twice in
hermes_state_messages.py, and the copy in the delete fence tested only
display_order while _ensure_display_order tests display_order OR
display_identity. Hoist one _DISPLAY_INDEX_MISSING_SQL beside
_DISPLAY_ACTIVE_CLAUSE and use it at both sites. The fence now refuses
whenever the read path would have backfilled instead of projecting; on
every reachable delete the two probes agree (the read path backfills both
halves before the export snapshot exists), so this only tightens fail-closed.
hermes_state_timeline keeps its own probe: it carries a role slot.

_cmd_export re-derived "which formats are human-read transcripts" as
`format == "html" or only`; use SAVE_TRANSCRIPT_FORMATS instead. Equivalent
on every reachable path: md/qmd without --only never reach _collect_sessions
(they route to _export_markdown), and --only forces the transcript view.
Bind include_compacted once in a local `_one` instead of threading it.

The IOERR test now injects on "WITH page AS", the display CTE's own opener,
so reshaping the SQL cannot let _ensure_display_order's SELECT probe absorb
the failure and make the case pass vacuously. Comments that narrated
removed guards now state the current reason.
This commit is contained in:
kshitijk4poor
2026-09-23 19:16:11 +05:30
committed by kshitij
parent ac44a81ccc
commit 880b9cd444
3 changed files with 22 additions and 20 deletions

View File

@@ -46,6 +46,10 @@ _TURN_LEASE_ROW_SQL = "SELECT holder, expires_at FROM session_turn_leases WHERE
_DELETE_COMPRESSION_LOCK_SQL = "DELETE FROM compression_locks WHERE session_id = ? AND holder = ?"
_DISPLAY_ACTIVE_CLAUSE = " AND (active = 1 OR compacted = 1)"
_DISPLAY_META_ROW_SQL = "SELECT display_metadata FROM messages WHERE id = ? AND session_id IN ({ids})" + _DISPLAY_ACTIVE_CLAUSE
# A display row is indexed only when both halves are set; the read path backfills before projecting, so
# the in-transaction delete fence must refuse (not project) any session this probe still matches.
_DISPLAY_INDEX_MISSING_SQL = ("SELECT 1 FROM messages WHERE session_id = ?" + _DISPLAY_ACTIVE_CLAUSE
+ " AND (display_order IS NULL OR display_identity IS NULL) LIMIT 1")
_ACTIVE_IDS_SQL = "SELECT id FROM messages WHERE session_id = ? AND active = 1 ORDER BY id"
_LIVE_IDENTITY_SQL = ("SELECT id, role, content, tool_call_id, tool_calls FROM messages "
"WHERE session_id = ? AND active = 1 ORDER BY id LIMIT ?")
@@ -899,16 +903,13 @@ class SessionMessagesMixin:
columns = set(self._message_column_names(conn))
if not {"display_order", "display_identity"} <= columns:
return False
missing_sql = (
"SELECT 1 FROM messages WHERE session_id = ? AND (active = 1 OR compacted = 1) "
"AND (display_order IS NULL OR display_identity IS NULL) LIMIT 1")
if self._read_one(missing_sql, (session_id,)) is None:
if self._read_one(_DISPLAY_INDEX_MISSING_SQL, (session_id,)) is None:
return True
if getattr(self, "read_only", False):
return False
def _do(conn):
missing = conn.execute(missing_sql, (session_id,)).fetchone()
missing = conn.execute(_DISPLAY_INDEX_MISSING_SQL, (session_id,)).fetchone()
if missing is None:
return True
first_id: Dict[bytes, int] = {}
@@ -1030,10 +1031,7 @@ class SessionMessagesMixin:
"""Exact display snapshot on an already-held transaction; None means fail closed."""
if conn.execute("SELECT 1 FROM sessions WHERE id = ? LIMIT 1", (session_id,)).fetchone() is None:
return None
if conn.execute(
"SELECT 1 FROM messages WHERE session_id = ? AND (active = 1 OR compacted = 1) "
"AND display_order IS NULL LIMIT 1", (session_id,),
).fetchone():
if conn.execute(_DISPLAY_INDEX_MISSING_SQL, (session_id,)).fetchone():
return None
return [
self._row_to_message_dict(row, warn_context="verified delete", summary_flag=True)
@@ -1057,7 +1055,7 @@ class SessionMessagesMixin:
raise ValueError("after_id is incompatible with include_compacted (deduped display reads use offset paging)")
active_clause = self._active_clause(include_inactive, include_compacted)
if include_compacted and not include_inactive and self._ensure_display_order(session_id):
# Route through the IOERR-retrying reader (#100871), never a bare _read_ctx.
# _read_retrying_ioerr: mode=ro pooled readers see a transient IOERR mid-checkpoint (#100871).
rows = self._read_retrying_ioerr(
lambda conn: self._display_rows_from_conn(
conn, session_id, limit=limit, offset=offset, latest=latest))