fix(state): close the tracking leak and finish the audit of raw DB reads

Completeness pass over the previous commit.

Registry leak (would have silently disabled the guard): the first version
incremented on open but decremented only in SessionDB.close(). kanban's
connect() hands raw connections to callers who close them directly (4 sites),
so its counter only ever went up — after enough kanban operations every
byte-probe on that path would be refused forever, disabling zeroed-file and
header detection. Replaced manual track/untrack with a TrackedConnection
subclass that untracks in close(), the one method every close path goes
through. Verified across plain close, contextlib.closing, double close,
nested lifetimes, and 100-cycle churn; `with conn:` (a transaction scope, not
a close) correctly stays tracked.

Also: a caller-supplied factory now wins instead of raising TypeError on a
duplicate kwarg, since tracking is an optimisation for the probe guard, not a
precondition for opening the database.

Removed _apply_delete_for_wal_reset_bug, dead after the force-DELETE revert.

Audit notes:
- DELETE mode is still reachable via the NFS/SMB/FUSE fallback and remains
  correct there; those users are protected by the raw-read fix, not by the
  journal mode.
- The remaining whole-file reads are on genuinely offline artifacts:
  _backup_db_file (DB won't open; bytes preserved for forensics),
  _backup_corrupt_db (quarantine path, now warns if a connection is live),
  and backup verification of snapshots. backup._safe_copy_db already uses
  the SQLite backup API rather than a byte copy.
- The mechanism is POSIX-specific (Windows byte-range locks are handle-scoped,
  not process-scoped), so this is a Linux/macOS correctness fix; the change is
  platform-neutral and safe on Windows.

Sibling tests updated: session recovery no longer expects a DELETE-mode
recovered DB, and the kanban WAL-fallback test patches the connect site that
actually runs now.
This commit is contained in:
teknium1
2026-07-25 20:31:23 -07:00
committed by Teknium
parent fbd5e5772b
commit 95fb477856
6 changed files with 160 additions and 69 deletions
+4 -3
View File
@@ -126,8 +126,9 @@ def test_recovery_rebuilds_canonical_data_without_opening_source(
source_hash = _sha256(source)
source_stat = source.stat()
# Exercise the vulnerable-runtime fallback: a fresh recovered DB must be
# born in DELETE mode instead of enabling WAL.
# A recovered DB is born in WAL even on a WAL-reset-vulnerable runtime:
# forcing DELETE there was reverted (DELETE is the mode that corrupts
# under Hermes' concurrent writers -- see hermes_cli.sqlite_safe_read).
monkeypatch.setattr(
hermes_state,
"is_sqlite_wal_reset_vulnerable",
@@ -144,7 +145,7 @@ def test_recovery_rebuilds_canonical_data_without_opening_source(
assert report["complete"] is True
assert report["installed"] is False
assert report["source_unchanged"] is True
assert report["verification"]["journal_mode"] == "delete"
assert report["verification"]["journal_mode"] == "wal"
assert report["verification"]["integrity_check"] == ["ok"]
assert report["verification"]["foreign_key_check"] == []
assert report["verification"]["schema_version"] == SCHEMA_VERSION