Skip to content

fix(js): Update execution status on signal interruption (Issue #60)#61

Merged
konard merged 7 commits intomainfrom
issue-60-23ad1508ca00
Jan 7, 2026
Merged

fix(js): Update execution status on signal interruption (Issue #60)#61
konard merged 7 commits intomainfrom
issue-60-23ad1508ca00

Conversation

@konard
Copy link
Copy Markdown
Member

@konard konard commented Jan 7, 2026

Summary

This PR fixes Issue #60 where $ --status <uuid> shows "executing" for commands that have already finished.

Root Cause

When a command is running and the process is interrupted (Ctrl+C, SIGTERM, terminal closed), the execution record in the database was never updated from "executing" to "executed". This left orphaned records with stale status.

Changes

JavaScript Implementation (completed)

  • Signal Handlers: Added handlers for SIGINT (Ctrl+C), SIGTERM (kill), and SIGHUP (terminal close) to update execution status when the process is interrupted
  • Cleanup Command: Added --cleanup and --cleanup-dry-run CLI options to clean up stale records
  • Stale Detection: Added cleanupStale() method to ExecutionStore that detects stale records by:
    1. Checking if the PID is still running (on same platform)
    2. Checking if the record exceeds max age (default: 24 hours)
  • Unit Tests: Added comprehensive tests for the new cleanup functionality
  • Case Study: Documented the investigation and fix in docs/case-studies/issue-60/

Rust Implementation (completed)

  • Signal Handlers: Set up handlers for SIGINT, SIGTERM, and SIGHUP using libc on Unix platforms
  • Global State: Added thread-safe global state (Mutex+AtomicBool) to track current execution for signal cleanup
  • Cleanup Command: Added --cleanup and --cleanup-dry-run CLI options matching JavaScript API
  • Stale Detection: Added cleanup_stale() method to ExecutionStore with CleanupOptions and CleanupResult types
  • ExecutionStore Clone: Added Clone trait to allow sharing store with signal handler
  • Unit Tests: Added 5 new tests for cleanup functionality (no stale records, dry run, actual cleanup, custom max age, only executing records)

Exit Codes for Signal Interruption

When a command is interrupted by a signal, it's now marked as "executed" with the appropriate exit code:

  • SIGINT (Ctrl+C): exit code 130 (128 + 2)
  • SIGTERM (kill): exit code 143 (128 + 15)
  • SIGHUP (terminal close): exit code 129 (128 + 1)

Stale records cleaned up via --cleanup are marked with exit code -1 to indicate abnormal termination.

Test plan

  • Run $ echo 'hi' and verify $ --status <uuid> shows "executed"
  • Run $ sleep 10, press Ctrl+C, verify status shows "executed" with exit code 130
  • Test $ --cleanup-dry-run to see stale records
  • Test $ --cleanup to clean up stale records
  • All JavaScript unit tests pass (70 tests)
  • All Rust unit tests pass (128 tests including 5 new cleanup tests)
  • CI passes on all platforms

Closes #60

🤖 Generated with Claude Code

Adding CLAUDE.md with task information for AI processing.
This file will be removed when the task is complete.

Issue: #60
@konard konard self-assigned this Jan 7, 2026
- Add signal handlers for SIGINT, SIGTERM, SIGHUP to update execution
  status when process is interrupted (Ctrl+C, kill, terminal close)
- Add --cleanup flag to clean up stale "executing" records from
  crashed/killed processes
- Add --cleanup-dry-run flag to preview stale records without cleaning
- Add cleanupStale() method to ExecutionStore to detect stale records by
  checking if PID is running or if record exceeds max age (24 hours)
- Add unit tests for new cleanup functionality
- Add case study documentation

Stale records are marked as "executed" with exit code -1 to indicate
abnormal termination. This allows users to identify and clean up orphaned
records from processes that were killed before normal completion.

Closes #60

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@konard konard changed the title [WIP] $ --status 14a0e075-3de1-4342-97cd-f87c8cd66dda shows command is still executing, while it actually was Finished at 2026-01-07 19:29:07.663 fix(js): Update execution status on signal interruption (Issue #60) Jan 7, 2026
@konard konard marked this pull request as ready for review January 7, 2026 21:09
@konard
Copy link
Copy Markdown
Member Author

konard commented Jan 7, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $9.571273 USD
  • Calculated by Anthropic: $6.580960 USD
  • Difference: $-2.990313 (-31.24%)
    📎 Log file uploaded as GitHub Gist (1221KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Member Author

konard commented Jan 7, 2026

Make sure in Rust version of code we have similar logic for status storage and handling.

@konard konard marked this pull request as draft January 7, 2026 23:20
@konard
Copy link
Copy Markdown
Member Author

konard commented Jan 7, 2026

🤖 AI Work Session Started

Starting automated work session at 2026-01-07T23:20:04.388Z

The PR has been converted to draft mode while work is in progress.

This comment marks the beginning of an AI work session. Please wait working session to finish, and provide your feedback.

konard and others added 4 commits January 8, 2026 00:28
Implement similar logic to JavaScript version for status storage and handling:

1. Signal Handling (SIGINT, SIGTERM, SIGHUP):
   - Set up signal handlers that update execution status when interrupted
   - Exit code follows convention: 128 + signal number (e.g., 130 for SIGINT)
   - Execution record is updated to "executed" status before exit

2. Cleanup Functionality:
   - Add --cleanup flag to clean up stale "executing" records
   - Add --cleanup-dry-run to preview what would be cleaned
   - Stale detection: process no longer running or age > 24 hours
   - Cleaned records marked as "executed" with exit code -1

3. ExecutionStore Changes:
   - Add cleanup_stale() method with CleanupOptions and CleanupResult
   - Add Clone trait to ExecutionStore for signal handler sharing
   - Add comprehensive unit tests for cleanup functionality

4. Args Parser Changes:
   - Add cleanup and cleanup_dry_run flags to WrapperOptions
   - Add parsing for --cleanup and --cleanup-dry-run
   - Add unit tests for new flags

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Apply cargo fmt formatting fixes
- Add changelog fragment for Issue #60 signal handling feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move signal handling code from main.rs to signal_handler.rs module
- Move cleanup tests from execution_store.rs to tests/cleanup_test.rs
- Compact code to meet file size limits (<1000 lines per file)
- No functional changes, only code organization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Collapse nested if statements in cleanup_stale (clippy::collapsible_if)
- Add #[cfg(unix)] to cleanup_execution_on_signal to fix Windows dead code error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@konard konard marked this pull request as ready for review January 7, 2026 23:49
@konard
Copy link
Copy Markdown
Member Author

konard commented Jan 7, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $17.912665 USD
  • Calculated by Anthropic: $11.651687 USD
  • Difference: $-6.260978 (-34.95%)
    📎 Log file uploaded as GitHub Gist (2367KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard konard merged commit 4cd9cc4 into main Jan 7, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

$ --status 14a0e075-3de1-4342-97cd-f87c8cd66dda shows command is still executing, while it actually was Finished at 2026-01-07 19:29:07.663

1 participant