review-fix(comments): restore lost #NNNN rationale comments across non-test source (mechanical sweep, condensed, code unchanged)

For each issue anchor present in BASE 63279301bc non-test .py and absent on HEAD, the BASE comment/docstring block was re-attached at the HEAD location of the code it explained (matched by the distinctive code line / enclosing def). Sentences already covered by an existing HEAD comment were deduped; the issue number always survives. Insert-only: no code lines changed.
This commit is contained in:
Teknium
2026-09-03 09:44:26 -07:00
parent ad62a15e94
commit e83816a4d1
586 changed files with 13883 additions and 829 deletions

View File

@@ -126,17 +126,26 @@ _RESET_END_REASONS_SQL = ", ".join(f"'{reason}'" for reason in _RESET_END_REASON
# by a fresh session.resume; startup_orphan_reap = dead-gateway sweep, same class as ws_orphan_reap but kept
# distinct for forensics.
_RECOVERABLE_END_REASONS = ("agent_close", "ws_orphan_reap", "superseded_by_resume", "startup_orphan_reap")
# Startup sweep of rows orphaned by a dead gateway process (#65194): the in-process ws-orphan grace timer
# died with the process, so the row was closed at the next boot instead.
_RECOVERABLE_END_REASONS_SQL = ", ".join(f"'{reason}'" for reason in _RECOVERABLE_END_REASONS)
# End reasons written by AUTOMATIC cleanup (shutdown, orphan reapers, idle/LRU eviction), not a deliberate
# conversation boundary: "some runtime went away", so a writer that can prove liveness (e.g. a compression
# rotation holding the lease) may clear it. Recoverable set plus the TUI gateway's automatic reasons.
# Superset of the recoverable set: those are already resumable accidents; the extra TUI reasons are the same
# accident class but were historically only known to tui_gateway's _AUTOMATIC_SESSION_END_REASONS. See
# #88197.
_AUTOMATIC_END_REASONS = frozenset(_RECOVERABLE_END_REASONS) | {
"tui_shutdown", "ws_disconnect", "idle_timeout", "lru_evict"}
def is_automatic_end_reason(reason) -> bool:
"""True when *reason* is an automatic-cleanup end stamp; compression-liveness sites must call this."""
"""True when *reason* is an automatic-cleanup end stamp; compression-liveness sites must call this.
Single owner of the "accidental vs deliberate end" predicate — every compression-liveness site must call
this instead of re-implementing the reason taxonomy (#88197, never-patch-predicates).
"""
return isinstance(reason, str) and reason in _AUTOMATIC_END_REASONS
@@ -188,6 +197,10 @@ def _sql_session_last_active_by_id(session_id_expr: str) -> str:
SCHEMA_VERSION = 30
# Auto-maintenance VACUUMs only above this freelist fraction; below it a rewrite costs more I/O than it returns.
# Auto-maintenance only VACUUMs when at least this fraction of the database file is reclaimable (``PRAGMA
# freelist_count / PRAGMA page_count``). Below it a full rewrite costs more I/O than it returns — pruning a
# handful of small sessions on a dense multi-GB state.db should never rewrite the whole file to reclaim a
# few MB (#54189). Composes with ``min_vacuum_interval_days``.
AUTO_VACUUM_MIN_FREELIST_RATIO = 0.25
# FTS storage-layout version, tracked INDEPENDENTLY of SCHEMA_VERSION in the
@@ -809,6 +822,28 @@ END;
# only when provably dead, indeterminate liveness defers. `<db>.fts_rebuild.lock` is distinct from
# `<db>.repair.lock` (offline schema surgery, minutes in VACUUM). Lives here: mixins cannot import hermes_state.
# ── Cross-process full-FTS-rebuild admission (single authority) ────────────── Several independent Hermes
# processes routinely share one state.db (gateway service, the Desktop app's `hermes serve` backend,
# interactive CLI sessions, the TUI slash worker). A full structural FTS rebuild — the FTS5 'rebuild'
# command or the drop/recreate script in `_recover_stale_fts` — must only ever run in ONE of them at a time:
# two concurrent rebuilds collide on write and have structurally corrupted state.db in production (PR
# #93200; the 2026-08-15 / 2026-08-23 incidents and issues #89293 / #90950). This is the single admission
# authority for every full structural rebuild entry point: `SessionSearchMixin.rebuild_fts()`,
# `SessionSchemaMixin._rebuild_fts_indexes()` (via `_init_schema`), and
# `SessionSchemaMixin._recover_stale_fts()`. The chunked deferred backfill (`fts_rebuild_step`) is
# deliberately NOT routed through it — it claims progress under `_execute_write`'s SQLite transaction
# authority and is intentionally multi-process. Semantics mirror `hermes_state._cross_process_repair_lock`
# (the schema- surgery authority): portable (msvcrt on Windows, flock elsewhere), bounded wait, and FAIL
# CLOSED — a caller that cannot acquire the lock must NOT rebuild. The kernel drops both lock types when the
# holder dies — UNLESS a forked child inherited the lock fd (flock rides the open file description, which
# fork() duplicates), in which case the orphaned descriptor holds the lock forever (issue #100108).
# `_acquire_db_flock` therefore records the holder's pid + start time under the lock and, when the recorded
# holder is provably dead, breaks the orphaned lock by unlinking and retaking it on a fresh inode;
# indeterminate liveness still defers. It lives here (not hermes_state) because the search/schema mixins
# cannot import hermes_state (cycle). The lock file is `<db>.fts_rebuild.lock`, distinct from
# `<db>.repair.lock`: schema surgery runs on an EXCLUSIVE offline connection and can legitimately take
# minutes in VACUUM, while runtime rebuilds run on live connections. The timeout is sized for a full
# 'rebuild' of both indexes on a large DB.
logger = logging.getLogger("hermes_state")
_FTS_REBUILD_LOCK_TIMEOUT_SECONDS = 120.0
@@ -861,7 +896,11 @@ def _rewrite_lock_file(handle, payload: bytes) -> None:
def _write_lock_holder_record(handle) -> None:
"""Record this process as holder (best effort) so timed-out contenders can tell an orphaned-fd holder
from a live wedged one."""
from a live wedged one.
Written under the flock so contenders that time out can tell an orphaned-fd holder (recorded process
dead, flock inherited by a forked child — issue #100108) from a live wedged holder.
"""
record = {"pid": os.getpid(), "start_ticks": _proc_start_ticks(os.getpid()), "acquired_at": time.time()}
_rewrite_lock_file(handle, json.dumps(record, sort_keys=True).encode("utf-8"))
@@ -900,7 +939,12 @@ def _acquire_db_flock(lock_path, handle, timeout_seconds, poll_seconds, descript
without the held-by-another-process warning). ``flock`` rides the open file DESCRIPTION, which ``fork()``
duplicates, so a holder that forks then dies leaves the lock held forever; when the acquirer is provably
dead the file is unlinked and retaken on a fresh inode (the orphan's flock excludes nobody). Every
acquire verifies its inode still names *lock_path*, so a racer on a dead inode retries."""
acquire verifies its inode still names *lock_path*, so a racer on a dead inode retries.
A holder that forks (multiprocessing worker, daemonized helper) and then dies leaves the flock held by a
child that will never release it — the kernel's holder-death release never triggers, and every contender
defers forever. Indeterminate liveness always defers (fail closed). See #100108.
"""
import fcntl
deadline = time.monotonic() + timeout_seconds
broke_lock = False