266c746d50
* 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>
118 lines
4.4 KiB
Markdown
118 lines
4.4 KiB
Markdown
# ✅ 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.
|
|
|
|
```sql
|
|
-- 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.
|
|
|
|
```sql
|
|
-- 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:
|
|
|
|
```sql
|
|
-- Get the correct timestamp for each observation by matching session
|
|
-- This requires correlating sdk_session_id with session_db_id
|
|
```
|
|
|
|
### Fix Script Approach
|
|
|
|
1. Get all pending_messages processed during the bad window
|
|
2. For each, get its `session_db_id` and `created_at_epoch` (original timestamp)
|
|
3. Find observations for that session created during the bad window
|
|
4. Update observations with the correct `created_at_epoch` from their source pending_message
|
|
|
|
```sql
|
|
-- 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 override
|
|
- `SessionStore.storeSummary()` - accepts optional timestamp override
|
|
- `ActiveSession.earliestPendingTimestamp` - tracks original message timestamp
|
|
- `SDKAgent.processSDKResponse()` - passes timestamp to storage
|
|
|
|
## Scripts Created
|
|
|
|
Three scripts were created to handle this issue:
|
|
|
|
1. **`scripts/fix-corrupted-timestamps.ts`** - Identifies and repairs corrupted timestamps
|
|
```bash
|
|
bun scripts/fix-corrupted-timestamps.ts --dry-run # Preview fixes
|
|
bun scripts/fix-corrupted-timestamps.ts --yes # Apply fixes
|
|
```
|
|
|
|
2. **`scripts/verify-timestamp-fix.ts`** - Verifies the fix was successful
|
|
```bash
|
|
bun scripts/verify-timestamp-fix.ts
|
|
```
|
|
|
|
3. **`scripts/investigate-timestamps.ts`** - Investigates timestamp data
|
|
```bash
|
|
bun 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 param
|
|
- `src/services/worker-types.ts` - added earliestPendingTimestamp to ActiveSession
|
|
- `src/services/worker/SessionManager.ts` - tracks earliest timestamp when yielding
|
|
- `src/services/worker/SDKAgent.ts` - passes timestamp through processSDKResponse
|
|
- `src/services/worker-service.ts` - orphan processing disabled
|