mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
3bd03ba2cc
Learning capture froze for six days (2026-07-23 .. 2026-07-29) while every hook
kept reporting success: true. Root cause chain:
AQE_DISABLE_WAL=1
-> safe-db ran `journal_mode = DELETE` on EVERY writable open
-> that switch needs an EXCLUSIVE lock (busy_timeout does not help)
-> a stale `npm exec agentic-qe mcp` held memory.db + -wal open
-> SQLITE_BUSY -> openDatabase threw -> UnifiedMemoryManager init
aborted -> ALL persistence died, silently
It could not self-heal: the switch can never succeed while any reader exists.
safe-db.ts now:
- reads the current journal_mode first and attempts the switch ONLY if it
differs, so the steady state takes no lock at all and the one-time migration
leaves the hot path;
- catches ONLY SQLITE_BUSY / SQLITE_LOCKED and rethrows everything else
unchanged, so I/O errors and corruption are no longer misreported as contention;
- FAILS CLOSED on contention rather than writing anyway. AQE_DISABLE_WAL=1 is the
operator declaring WAL unsafe on this mount, so continuing in WAL would trade a
loud outage for silent corruption;
- verifies the switch actually took effect before allowing writes;
- names the real database file and the command that finds the actual holder.
The hook shim's health-log guidance named "concurrent AQE processes (MCP server /
daemon)". Operators checked exactly those and found nothing, because the culprit
was an npx-cache process matching neither "aqe" nor .mcp.json — that wrong hint is
most of why this ran six days. It now prints a /proc scan that finds ANY holder,
and only claims contention when the failure really was a lock error.
Also raises the statusline refresh from 5s to 60s; it reopened the 158MB DB on
every tick, which was constant added pressure on the same lock.
11 tests covering fail-closed, the non-lock rethrow, the skip-when-already-correct
path, durable write across reopen, and the diagnostic contents. Verified live:
journal_mode=delete, integrity_check=ok, captured_experiences growing again after
freezing at 21157.