fix(kanban): quarantine failures and capture coherent DB evidence - #66912
fix(kanban): quarantine failures and capture coherent DB evidence#66912chrismaddern wants to merge 2 commits into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for extending the existing per-process dispatcher quarantine into a persisted board-health circuit. The current-main premise is real: gateway/kanban_watchers.py:943-1007 retains corrupt-board state only in memory and retries after 300 seconds.
Problems
hermes_cli/kanban_db.py:2041-2050addsquarantine_db_for_error, but direct post-connect reads remain unwrapped:get_task()executes SQL at current-mainhermes_cli/kanban_db.py:2706-2708, andlist_tasks()at:2773. A fatal read error there will not create the persisted circuit.hermes_cli/kanban_db.py:1968-1972re-raises capture failures other than lease contention. Since_trip_db_health()writes health then calls this helper at:2024-2027, a copy/hash/fsync failure can mask the intendedKanbanDbHealthError.
Suggested changes
- Route post-connect SQL failures through one shared fatal-error boundary and add a read-path regression test.
- Make evidence capture best-effort after health publication; test copy and manifest-write failures.
- The subprocess lease tests explicitly skip Windows at
tests/hermes_cli/test_kanban_maintenance_e2e.py:103-105; add Windows locking coverage for the newmsvcrtpath.
Automated hermes-sweeper review.
| except Exception as exc: | ||
| from hermes_cli.kanban_maintenance import MaintenanceLeaseBusyError | ||
|
|
||
| if not isinstance(exc, MaintenanceLeaseBusyError): |
There was a problem hiding this comment.
Only lease contention is converted to a deferred capture here. If shutil.copy2, hashing, or manifest fsync fails after _trip_db_health has published the health sidecar, this re-raise replaces the classified KanbanDbHealthError. Preserve the open circuit and report capture as incomplete for all evidence-capture I/O failures.
| ) -> Optional[KanbanDbHealthError]: | ||
| """Persist a board circuit for a fatal SQLite error seen by a caller. | ||
|
|
||
| Operations that execute SQL after ``connect()`` use this boundary to feed |
There was a problem hiding this comment.
This boundary is not applied to direct post-connect read helpers such as get_task and list_tasks, which still execute SQL without a SQLite-error wrapper. A fatal read error therefore bypasses the board-wide circuit; centralize execution/error conversion and cover a read-path failure.
| return child, release | ||
|
|
||
|
|
||
| @pytest.mark.skipif( |
There was a problem hiding this comment.
The new implementation has a separate msvcrt locking path, but every cross-process lease test is skipped on Windows. Add Windows coverage for exclusive-versus-shared admission before treating the lease as cross-platform evidence consistency.
Summary
This supersedes #65899 with that Slice 1 work rebased onto current
main, plus the dependent maintenance/evidence Slice 2.Verification
scripts/run_tests.sh tests/hermes_cli/test_kanban_*.py tests/gateway/test_kanban_*.py -q: 762 passedpython -m ruff check hermes_cli/kanban_db.py hermes_cli/kanban_maintenance.py tests/hermes_cli/test_kanban_maintenance_e2e.pypython -m compileall -q ...git diff --checkBehavioral evidence
write_txnboth refuse evidence capturePRAGMA integrity_checkand retains all committed rows