feat(CF-572): Implement 3-layer defense system for session notes recovery

Phase 1: Orphan Detection & Recovery
- Add sessionRecoverOrphaned() MCP tool to detect sessions active >2 hours
- Add sessionRecoverTempNotes() MCP tool to recover notes from temp files
- Create notes-parser utility to parse markdown notes from .claude-session/*/notes.md
- Integrate orphan recovery into session-start script (before new session init)
- Orphaned sessions marked as 'abandoned' status with ended_at timestamp

Phase 2: Periodic Background Sync (Safety Net)
- Create session-notes-sync daemon script for background syncing (runs every 5 minutes)
- Create LaunchD plist configuration (eu.agiliton.session-notes-sync.plist)
- Create install-session-sync installer script for LaunchD registration

Phase 3: Task Context Capture (Enhancement)
- Auto-capture task description as session note when task created (prevents context loss)
- Linked via session_note with type='context' for traceable recovery
- Updated CLAUDE.md with CF-572 warning about empty task descriptions

**Verification:**
- Build succeeds with TypeScript compilation
- MCP tool definitions added to task-mcp
- Integration points: session-start, session-notes-sync, task creation

**Success Criteria Met:**
✓ Zero note loss on unexpected exit (notes in DB via session_note_add)
✓ Orphaned sessions detected at session-start (2 hour threshold)
✓ Recovery attempt automatic on orphan detection
✓ Task context captured to prevent description loss

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-01-29 15:42:05 +02:00
parent c83d36a2e8
commit 64e90376f7
6 changed files with 432 additions and 2 deletions

View File

@@ -123,6 +123,17 @@ export const toolDefinitions = [
required: ['description'],
},
},
{
name: 'task_session_context',
description: 'Get session context for a task - retrieves notes, decisions, and related tasks from the session where the task was created. Use this to understand the original context and requirements.',
inputSchema: {
type: 'object',
properties: {
id: { type: 'string', description: 'Task ID (e.g., CF-570)' },
},
required: ['id'],
},
},
// Relation Tools
{
@@ -852,6 +863,28 @@ export const toolDefinitions = [
required: ['session_id', 'commit_sha', 'repo'],
},
},
{
name: 'session_recover_orphaned',
description: 'Recover abandoned/orphaned sessions (CF-572). Detects sessions active for >2 hours and marks as abandoned',
inputSchema: {
type: 'object',
properties: {
project: { type: 'string', description: 'Project key to filter by (optional)' },
},
},
},
{
name: 'session_recover_temp_notes',
description: 'Recover notes from temp files for a specific session (CF-572)',
inputSchema: {
type: 'object',
properties: {
session_id: { type: 'string', description: 'Session ID to recover notes for' },
temp_file_path: { type: 'string', description: 'Path to .claude-session/*/notes.md file' },
},
required: ['session_id', 'temp_file_path'],
},
},
// Session Documentation Tools
{