* Refactor worker version checks and increase timeout settings - Updated the default hook timeout from 5000ms to 120000ms for improved stability. - Modified the worker version check to log a warning instead of restarting the worker on version mismatch. - Removed legacy PM2 cleanup and worker start logic, simplifying the ensureWorkerRunning function. - Enhanced polling mechanism for worker readiness with increased retries and reduced interval. * feat: implement worker queue polling to ensure processing completion before proceeding * refactor: change worker command from start to restart in hooks configuration * refactor: remove session management complexity - Simplify createSDKSession to pure INSERT OR IGNORE - Remove auto-create logic from storeObservation/storeSummary - Delete 11 unused session management methods - Derive prompt_number from user_prompts count - Keep sdk_sessions table schema unchanged for compatibility * refactor: simplify session management by removing unused methods and auto-creation logic * Refactor session prompt number retrieval in SessionRoutes - Updated the method of obtaining the prompt number from the session. - Replaced `store.getPromptCounter(sessionDbId)` with `store.getPromptNumberFromUserPrompts(claudeSessionId)` for better clarity and accuracy. - Adjusted the logic for incrementing the prompt number to derive it from the user prompts count instead of directly incrementing a counter. * refactor: replace getPromptCounter with getPromptNumberFromUserPrompts in SessionManager Phase 7 of session management simplification. Updates SessionManager to derive prompt numbers from user_prompts table count instead of using the deprecated prompt_counter column. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: simplify SessionCompletionHandler to use direct SQL query Phase 8: Remove call to findActiveSDKSession() and replace with direct database query in SessionCompletionHandler.completeByClaudeId(). This removes dependency on the deleted findActiveSDKSession() method and simplifies the code by using a straightforward SELECT query. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: remove markSessionCompleted call from SDKAgent - Delete call to markSessionCompleted() in SDKAgent.ts - Session status is no longer tracked or updated - Part of phase 9: simplifying session management 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: remove markSessionComplete method (Phase 10) - Deleted markSessionComplete() method from DatabaseManager - Removed markSessionComplete call from SessionCompletionHandler - Session completion status no longer tracked in database - Part of session management simplification effort 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * refactor: replace deleted updateSDKSessionId calls in import script (Phase 11) - Replace updateSDKSessionId() calls with direct SQL UPDATE statements - Method was deleted in Phase 3 as part of session management simplification - Import script now uses direct database access consistently 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * test: add validation for SQL updates in sdk_sessions table * refactor: enhance worker-cli to support manual and automated runs * Remove cleanup hook and associated session completion logic - Deleted the cleanup-hook implementation from the hooks directory. - Removed the session completion endpoint that was used by the cleanup hook. - Updated the SessionCompletionHandler to eliminate the completeByClaudeId method and its dependencies. - Adjusted the SessionRoutes to reflect the removal of the session completion route. * fix: update worker-cli command to use bun for consistency * feat: Implement timestamp fix for observations and enhance processing logic - Added `earliestPendingTimestamp` to `ActiveSession` to track the original timestamp of the earliest pending message. - Updated `SDKAgent` to capture and utilize the earliest pending timestamp during response processing. - Modified `SessionManager` to track the earliest timestamp when yielding messages. - Created scripts for fixing corrupted timestamps, validating fixes, and investigating timestamp issues. - Verified that all corrupted observations have been repaired and logic for future processing is sound. - Ensured orphan processing can be safely re-enabled after validation. * feat: Enhance SessionStore to support custom database paths and add timestamp fields for observations and summaries * Refactor pending queue processing and add management endpoints - Disabled automatic recovery of orphaned queues on startup; users must now use the new /api/pending-queue/process endpoint. - Updated processOrphanedQueues method to processPendingQueues with improved session handling and return detailed results. - Added new API endpoints for managing pending queues: GET /api/pending-queue and POST /api/pending-queue/process. - Introduced a new script (check-pending-queue.ts) for checking and processing pending observation queues interactively or automatically. - Enhanced logging and error handling for better monitoring of session processing. * updated agent sdk * feat: Add manual recovery guide and queue management endpoints to documentation --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
4.4 KiB
✅ FIXED: Corrupted Observation Timestamps
What Happened
On Dec 24, 2025, orphan queue processing was enabled without a working timestamp fix. This caused 25 observations from old sessions (Dec 16-22) to be saved with Dec 24 timestamps instead of their original timestamps.
The Fix - COMPLETED
Status: ✅ All corrupted timestamps have been repaired
Date Fixed: Dec 24, 2025 at 20:55 PM PST
Results:
- Fixed 25 observations with corrupted timestamps
- Observations restored to correct dates (Dec 16-22)
- Remaining 31 observations in the window are legitimate (from Dec 24 sessions)
The Original Damage
Observations created between approximately 19:45-20:31 on Dec 24 had wrong timestamps. These observations came from processing old pending_messages that were stuck in "processing" status.
How to Identify Affected Observations
The affected observations were created from pending_messages that had created_at_epoch from Dec 17-20, but the observations got Dec 24 timestamps.
-- Find observations created during the bad window (Dec 24 ~19:45-20:31)
SELECT id, sdk_session_id,
datetime(created_at_epoch/1000, 'unixepoch', 'localtime') as obs_time,
title
FROM observations
WHERE created_at_epoch >= 1735098300000 -- Dec 24 19:45
AND created_at_epoch <= 1735101060000 -- Dec 24 20:31
ORDER BY id;
How to Fix
Option 1: Match via processed pending_messages
The pending_messages table has completed_at_epoch which shows when they were processed, and created_at_epoch which has the CORRECT original timestamp.
-- Find pending_messages processed during the bad window
SELECT id, session_db_id, tool_name,
datetime(created_at_epoch/1000, 'unixepoch', 'localtime') as original_time,
datetime(completed_at_epoch/1000, 'unixepoch', 'localtime') as processed_time
FROM pending_messages
WHERE status = 'processed'
AND completed_at_epoch >= 1735098300000
AND completed_at_epoch <= 1735101060000
ORDER BY completed_at_epoch;
Option 2: Match by session and sequence
For each affected session, observations should be ordered by their original pending_message timestamps:
-- Get the correct timestamp for each observation by matching session
-- This requires correlating sdk_session_id with session_db_id
Fix Script Approach
- Get all pending_messages processed during the bad window
- For each, get its
session_db_idandcreated_at_epoch(original timestamp) - Find observations for that session created during the bad window
- Update observations with the correct
created_at_epochfrom their source pending_message
-- Example fix for a single observation (after identifying the correct timestamp):
UPDATE observations
SET created_at_epoch = [correct_epoch],
created_at = datetime([correct_epoch]/1000, 'unixepoch')
WHERE id = [observation_id];
The Timestamp Fix (Already Deployed)
The code now correctly passes overrideTimestampEpoch through:
SessionStore.storeObservation()- accepts optional timestamp overrideSessionStore.storeSummary()- accepts optional timestamp overrideActiveSession.earliestPendingTimestamp- tracks original message timestampSDKAgent.processSDKResponse()- passes timestamp to storage
Scripts Created
Three scripts were created to handle this issue:
-
scripts/fix-corrupted-timestamps.ts- Identifies and repairs corrupted timestampsbun scripts/fix-corrupted-timestamps.ts --dry-run # Preview fixes bun scripts/fix-corrupted-timestamps.ts --yes # Apply fixes -
scripts/verify-timestamp-fix.ts- Verifies the fix was successfulbun scripts/verify-timestamp-fix.ts -
scripts/investigate-timestamps.ts- Investigates timestamp databun scripts/investigate-timestamps.ts
Orphan Processing Status
The timestamp fix has been verified and is working correctly. Orphan processing can now be safely re-enabled in src/services/worker-service.ts if needed.
Files Changed
src/services/sqlite/SessionStore.ts- added overrideTimestampEpoch paramsrc/services/worker-types.ts- added earliestPendingTimestamp to ActiveSessionsrc/services/worker/SessionManager.ts- tracks earliest timestamp when yieldingsrc/services/worker/SDKAgent.ts- passes timestamp through processSDKResponsesrc/services/worker-service.ts- orphan processing disabled