4 Commits

Author SHA1 Message Date
Teknium
d070e480a3 fix(tests): close leaked SessionDB handles suite-wide and cap pytest memory
Root cause of the 2026-08-16 OOM incidents (three runs of
`python -m pytest -o addopts= -q tests/hermes_cli/` ballooning to
16-25 GB RSS and getting killed): ~40 files under tests/hermes_cli/
construct SessionDB() directly and never close it. Each instance keeps
the writer connection (state.db + -wal fds), up to _READ_POOL_MAX pooled
readers with their SQLite page caches, and — once token accounting has
run — an atexit registration that pins the instance alive until
interpreter exit. In one process over 637 files those accumulate without
bound; the sanctioned per-file runner masks it, so CI never saw it.

Fix the class, not the sites:

* hermes_state: register every successfully constructed SessionDB in a
  test-only WeakSet (populated only when HERMES_TEST_ISOLATION is set,
  i.e. under this test suite; production never touches it).
* tests/conftest.py: autouse _close_leaked_session_dbs teardown closes
  everything left in the registry after each test. close() is idempotent
  and unregisters the pinning atexit hook, so instances become
  collectable.
* tests/conftest.py: session-scoped _pytest_memory_cap applies a
  defensive RLIMIT_AS of 12 GiB (Linux only) so any future in-process
  leak fails fast with MemoryError instead of eating the box.
  Overridable/disable-able via HERMES_PYTEST_MEM_CAP (documented in
  scripts/run_tests_parallel.py).
* tests/hermes_state/test_session_db_leak_sweep.py: behavior contract
  for registration, idempotent close, and the cross-test sweep.

Measured (capped single-process `pytest -o addopts= -q tests/hermes_cli/`):
peak RSS 4.16 GiB before -> 1.67 GiB after; per-test open .db fd count
previously climbed monotonically (0 -> 12 -> 17 -> 104 within the
SessionDB-heavy files), now stays bounded (<= 5, transient). Sanctioned
runner over the affected 35 files: 495 passed, 0 failed, no FLAKY.

Incident evidence: ~/.hermes/logs/oom-incidents/20260816-202114
(fd dumps show 100+ open state.db/state.db-wal handles across pytest
tmpdirs; 3rd recurrence that day).
2026-09-15 03:44:50 -07:00
Teknium
e83816a4d1 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.
2026-09-03 09:44:26 -07:00
Teknium
ff3ebf509f refactor(state): dict-dispatch persistence-error classifier, unify WHERE/placeholder builders, compact docstrings across state modules 2026-09-02 20:18:08 -07:00
Teknium
e527b0699d refactor(state): extract error types/classifiers to hermes_state_errors and the live-DB guard to hermes_state_guard 2026-09-02 18:44:39 -07:00