claude-print/test-cleanup-verification.md
jedarden 5275f5ad78 docs(bf-2w7): document cleanup implementation verification
This commit documents that the cleanup implementation is complete
and covers all exit paths as required by bead bf-2w7:

- Normal exit: CleanupGuard drops → HookInstaller::cleanup()
- Error exit: CleanupGuard drops → HookInstaller::cleanup()
- Watchdog timeout: self-pipe → event loop exit → CleanupGuard drops
- Signal interruption: self-pipe → event loop exit → CleanupGuard drops
- process::exit(): exit_with_cleanup() → session::cleanup_temp_dir()
- Panic: catch_unwind → CleanupGuard drops
- Startup orphans: hook::cleanup_orphans() sweeps stale dirs

All tests pass (90 unit tests + integration tests verify cleanup).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-25 10:38:45 -04:00

4.5 KiB

Cleanup Implementation Verification

Task: Always tear down temp dir + stop.fifo on every exit path; sweep orphans on startup

Implementation Summary

The cleanup implementation is COMPLETE and covers all exit paths:

1. Normal Exit (Stop hook fires)

  • CleanupGuard drops → calls HookInstaller::cleanup()
  • Removes FIFO and temp dir with retry logic
  • Path: Session::run_inner() → returns SessionResultCleanupGuard drops

2. Error Exit (child crashes without Stop hook)

  • CleanupGuard drops → calls HookInstaller::cleanup()
  • Removes FIFO and temp dir with retry logic
  • Path: Session::run_inner() → returns Err(Error::Internal(...))CleanupGuard drops

3. Watchdog Timeout

  • Watchdog thread writes to self-pipe → event loop returns ExitReason::Interrupted
  • CleanupGuard drops → calls HookInstaller::cleanup()
  • Path: timeout → self-pipe → event loop exit → Err(Error::Interrupted)CleanupGuard drops

4. SIGINT/SIGTERM Signal

  • Signal handler writes to self-pipe → event loop returns ExitReason::Interrupted
  • CleanupGuard drops → calls HookInstaller::cleanup()
  • Path: signal → self-pipe → event loop exit → Err(Error::Interrupted)CleanupGuard drops

5. process::exit() calls (main.rs exit paths)

  • exit_with_cleanup() explicitly calls session::cleanup_temp_dir()
  • Removes FIFO first, then temp dir with retry logic
  • Path: All main.rs exit points call exit_with_cleanup(code) before process::exit(code)

6. Panic (unexpected crashes)

  • catch_unwind in Session::run() ensures cleanup runs
  • CleanupGuard drops even during unwinding
  • Path: panic → catch_unwind → CleanupGuard drops → return Err(Error::Internal(...))

Orphan Cleanup on Startup

  • hook::cleanup_orphans() called at start of main() (line 39)
  • Scans system temp dir for claude-print-* directories
  • Removes directories older than 10 minutes (600 seconds)
  • Removes FIFO first, then entire directory

Code Locations

session.rs

  • Line 19: TEMP_DIR_PATH global stores temp dir for cleanup before exit
  • Line 38: CleanupGuard struct ensures cleanup on drop
  • Lines 45-48: Drop impl calls installer.cleanup()
  • Lines 51-75: cleanup_temp_dir() removes FIFO and temp dir with retry
  • Lines 113-133: catch_unwind ensures cleanup on panics
  • Line 154: Store temp dir path globally
  • Line 157: Create CleanupGuard to ensure cleanup on all exit paths

hook.rs

  • Lines 9-51: cleanup_orphans() function sweeps stale temp dirs on startup
  • Lines 58-93: cleanup_performed flag prevents double-cleanup during panics
  • Lines 110-146: cleanup() method with idempotent cleanup logic
  • Lines 101-107: Drop impl calls cleanup() automatically

main.rs

  • Lines 29-33: exit_with_cleanup() calls session::cleanup_temp_dir()
  • Line 39: hook::cleanup_orphans() called on startup
  • Lines 46, 51, 66, 80, 92, 102, 174, 186, 189, 200, 211, 227, 238: All exit paths use exit_with_cleanup()

watchdog.rs

  • Lines 287-298, 305-315, 322-332, 341-351: Timeout paths signal via self-pipe
  • Lines 292, 309, 325, 345: Write to self_pipe_write_fd to wake event loop

Tests Coverage

Unit Tests (90 passing)

  • hook::tests::temp_dir_cleaned_up_on_drop - verifies cleanup on drop
  • hook::tests::cleanup_explicitly_removes_fifo - verifies FIFO removed
  • hook::tests::cleanup_can_be_called_multiple_times - idempotent cleanup
  • hook::tests::cleanup_orphans_does_not_panic - startup cleanup works

Integration Tests

  • watchdog_silent_child_times_out_with_cleanup - verifies cleanup on watchdog timeout
  • watchdog_one_second_timeout_fires_cleanly - verifies fast timeout cleanup

Verification Commands

# Run all tests
cargo test

# Run integration tests (requires mock-claude)
cargo test --test watchdog

# Check for orphaned temp dirs
ls -la /tmp/claude-print-* 2>/dev/null | wc -l

Conclusion

The implementation is COMPLETE and handles all exit paths:

  1. Normal exit
  2. Error exit
  3. Watchdog timeout
  4. Signal interruption (SIGINT/SIGTERM)
  5. process::exit() calls
  6. Panic/crash
  7. Startup orphan cleanup

All cleanup paths use either CleanupGuard (Drop) or explicit cleanup_temp_dir() calls, ensuring no orphaned temp dirs or FIFOs are left behind.