Conversation
…tion health checks Claude Code spawns one supertag-mcp per session and never cleans up idle processes. Over days this leads to 14+ zombie processes holding stale SQLite connections, causing "database or disk is full" errors. Three mitigations: - Idle auto-exit: MCP server self-terminates after 30min without tool calls (configurable via SUPERTAG_MCP_IDLE_TIMEOUT, set 0 to disable) - Connection health check: DeltaSyncService tests connection before each sync and auto-reconnects if stale - Periodic health check in poller every 10th tick Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
|
AI Review: CHANGES REQUESTED Code Review: PR #83 - MCP Process Accumulation MitigationSummaryThis PR addresses zombie process accumulation in Claude Code by adding idle auto-exit and SQLite connection health checks. The implementation is clean and focused, but requires test coverage before approval. ✅ Strengths
🔴 Blocking Issues1. Missing Test Coverage (CRITICAL)None of the three new features have tests:
Required coverage: // tests/unit/delta-sync-service.test.ts
describe('ensureHealthyConnection', () => {
it('should reconnect when SELECT 1 fails');
it('should not reconnect when connection is healthy');
it('should handle close() failures gracefully');
it('should log reconnection events');
});
// tests/unit/mcp-idle-timeout.test.ts
describe('idle auto-exit', () => {
it('should exit after timeout with no tool calls');
it('should reset timer on each tool call');
it('should be disabled when SUPERTAG_MCP_IDLE_TIMEOUT=0');
it('should cleanup activePoller on timeout');
});
// tests/unit/delta-sync-poller.test.ts (add to existing)
describe('periodic health check', () => {
it('should call ensureHealthyConnection every 10 ticks');
it('should not interfere with normal sync cycle');
});2. No Integration Test for the Full FixThe PR describes a real bug reported by Ryan Baum but doesn't demonstrate the fix works end-to-end. Need a test that:
|
| Dimension | Score | Notes |
|---|---|---|
| Spec Compliance | N/A | No formal spec for this fix |
| Plan Adherence | N/A | No formal plan |
| Security | ✅ | No security concerns |
| Code Quality | Clean code, missing tests | |
| Architecture | ✅ | Respects boundaries |
| Edge Cases | Timer race condition, tickCount reset | |
| Code Duplication | ✅ | No duplication |
Verdict: CHANGES REQUESTED - Add test coverage and address timer/tickCount issues.
Additional Review Findings (not covered above)🔴 CRITICAL:
|
Critical: - NaN guard: extract DEFAULT_IDLE_TIMEOUT_MS constant, fall back on NaN - Idle timer race: check activePoller.isSyncing() before exit, defer if busy Medium: - busy_timeout: configure PRAGMA busy_timeout=5000 in constructor and reconnect - Simplify unref() guard (Bun always supports .unref() on timers) Tests: - Add delta-sync-health-check.test.ts (6 tests: healthy/unhealthy/reconnect/busy_timeout) - Rewrite mcp-idle-timeout.test.ts (14 tests: parsing, timer behavior, sync guard) - Add tickCount reset test to delta-sync-poller.test.ts Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Summary
SUPERTAG_MCP_IDLE_TIMEOUT, set0to disable)DeltaSyncService.ensureHealthyConnection()runsSELECT 1before each sync and auto-reconnects if the SQLite connection has gone stale ("database or disk is full")Reported by Ryan Baum — Claude Code spawns one
supertag-mcpper session and never cleans up idle processes, leading to 14+ zombie processes with stale SQLite connections.Test plan
🤖 Generated with Claude Code