Session Tracking Root Cause Analysis & Fix

Critical fix for session tracking issues and prevention checklist

🔧 Session Tracking Root Cause Analysis & Fix

Problem: MCP logged decisions to session 29.11/29.12 instead of 30.1 Impact: Session confusion, incorrect attribution, documentation mess Status: ✅ Fixed + Prevention checklist created


🚨 Root Cause Analysis

What Happened

  1. Session 30 started but tracking files not properly initialized
  2. MCP read from history.json (source of truth) which still showed session 29
  3. MCP correctly logged to session 29.11/29.12 (following the source of truth)
  4. Result: All work attributed to wrong session

The Chain of Failures

Session 30 work started
    ↓
session-30.json created but EMPTY (1 byte)
    ↓
history.json NOT updated (still showed session 29)
    ↓
active.json NOT regenerated (missing entirely)
    ↓
MCP reads history.json → sees session 29 as current
    ↓
MCP logs decisions to session 29.11, 29.12, etc.
    ↓
❌ Wrong session attribution!

Why This Is Critical


✅ The Fix

Immediate Actions Taken

  1. Created proper session-30.json:

    {
      "$schema": "../../schemas/session-manifest.schema.json",
      "schemaVersion": "5.0",
      "workspace": "editor2",
      "session": 30,
      "sessionNumber": 30,
      "subSessionNumber": 30.1,
      "sessionID": "editor2-30.1",
      // ... complete manifest
    }
    
  2. Updated history.json:

    {
      "currentSession": {
        "sessionNumber": 30,
        "subSessionNumber": 30.1,
        "sessionID": "editor2-30.1",
        "status": "active"
      }
    }
    
  3. Marked session 29 complete:

    {
      "session": 29,
      "status": "completed",
      "completedAt": "2026-01-08T18:00:00.000Z"
    }
    
  4. Regenerated active.json:

    yarn session:sync
    
  5. Updated .cursor/mcp-config.json:

    {
      "session": {
        "current": 30,
        "currentID": "editor2-30.1",
        "agent": "documentation-agent"
      }
    }
    

📋 MANDATORY Session Start Checklist

Before Starting ANY New Session

# 1. Create session manifest from template
cp sessions/schemas/session-manifest.template.json \
   sessions/sessions-history/editor2/session-X.json

# 2. Fill in ALL fields (don't leave empty!)
# Edit session-X.json with:
#   - session: X
#   - sessionNumber: X
#   - subSessionNumber: X.1
#   - sessionID: "editor2-X.1"
#   - title: "Session title"
#   - All other required fields

# 3. Update history.json
# Edit sessions/sessions-history/editor2/history.json:
#   - currentSession.sessionNumber: X
#   - currentSession.sessionID: "editor2-X.1"
#   - Mark previous session as "completed"
#   - Add new session to sessions array

# 4. Regenerate active.json
yarn session:sync

# 5. Update .cursor/mcp-config.json
# Edit .cursor/mcp-config.json:
#   - session.current: X
#   - session.currentID: "editor2-X.1"
#   - session.subSessionNumber: X.1

# 6. VERIFY everything
yarn session:status
# Should show: "Current: X, Current ID: editor2-X.1"

# 7. Test MCP reads correct session
# In AI chat:
get_session_info()
# Should return: sessionNumber: X, sessionID: "editor2-X.1"

🎯 Session Tracking Architecture

File Hierarchy (Source of Truth)

1. history.json (PRIMARY SOURCE OF TRUTH)
   ↓
2. active.json (generated from history.json)
   ↓
3. .cursor/mcp-config.json (MCP session cache)
   ↓
4. MCP server reads in this order:
   - active.json (workspace-scoped)
   - history.json (fallback)
   - mcp-config.json (cache)

Critical Files

File Purpose Who Updates When
history.json SOURCE OF TRUTH Manual Session start/end
session-X.json Session manifest Manual Session start
active.json Generated cache yarn session:sync After history.json changes
mcp-config.json MCP session cache MCP server On decision logging

🔧 How MCP Detects Session

Code Flow

// MCP/mcp-development-ai/src/session/session-detector.ts

getCurrentSession()
  ↓
getCurrentCursorSession()
  ↓
1. Try: sessions/sessions-history/{workspace}/active.json
2. Fallback: sessions/sessionID.json (legacy)
3. Fallback: null

What MCP Reads

// From active.json
{
  "workspace": "editor2",
  "active": {
    "sessionNumber": 30,
    "sessionID": "editor2-30.1",
    "subSessionNumber": 30.1
  }
}

⚠️ Common Mistakes & Prevention

Mistake 1: Empty Manifest File

Problem: Creating session-X.json but leaving it empty Impact: MCP can't read session info, falls back to previous session Prevention: Always use template and fill ALL fields

Mistake 2: Forgetting history.json

Problem: Creating manifest but not updating history.json Impact: MCP reads old session from history.json (source of truth) Prevention: ALWAYS update history.json first!

Mistake 3: Not Running session:sync

Problem: Updating history.json but not regenerating active.json Impact: MCP reads stale active.json Prevention: Run yarn session:sync after ANY history.json change

Mistake 4: Not Marking Previous Session Complete

Problem: Multiple sessions marked as "active" Impact: Confusion about which session is current Prevention: Mark previous session "completed" in history.json

Mistake 5: Not Updating mcp-config.json

Problem: mcp-config.json still shows old session Impact: Session manager shows wrong session Prevention: Update mcp-config.json manually or let MCP auto-update on first decision


🎯 Verification Commands

After Session Start

# 1. Check history.json shows new session
cat sessions/sessions-history/editor2/history.json | grep -A 4 "currentSession"

# 2. Verify manifest exists and is complete
cat sessions/sessions-history/editor2/session-X.json | head -20

# 3. Verify active.json generated
cat sessions/sessions-history/editor2/active.json

# 4. Check session manager
yarn session:status

# 5. Test MCP reads correct session
# In AI chat: get_session_info()

Expected Output

// history.json
{
  "currentSession": {
    "sessionNumber": 30,
    "sessionID": "editor2-30.1",
    "status": "active"
  }
}

// active.json
{
  "workspace": "editor2",
  "active": {
    "sessionNumber": 30,
    "sessionID": "editor2-30.1"
  }
}

// yarn session:status
Current: 30
Current ID: editor2-30.1

🚀 Automated Fix Script (Future)

Proposed: yarn session:new

#!/usr/bin/env bash
# Create new session with all tracking files

SESSION_NUM=$1
TITLE=$2

if [ -z "$SESSION_NUM" ] || [ -z "$TITLE" ]; then
  echo "Usage: yarn session:new <number> <title>"
  exit 1
fi

# 1. Create manifest from template
cp sessions/schemas/session-manifest.template.json \
   sessions/sessions-history/editor2/session-$SESSION_NUM.json

# 2. Update manifest with session info
node -e "
  const fs = require('fs');
  const manifest = JSON.parse(fs.readFileSync('sessions/sessions-history/editor2/session-$SESSION_NUM.json', 'utf8'));
  manifest.session = $SESSION_NUM;
  manifest.sessionNumber = $SESSION_NUM;
  manifest.subSessionNumber = $SESSION_NUM.1;
  manifest.sessionID = 'editor2-$SESSION_NUM.1';
  manifest.title = '$TITLE';
  manifest.startedAt = new Date().toISOString();
  fs.writeFileSync('sessions/sessions-history/editor2/session-$SESSION_NUM.json', JSON.stringify(manifest, null, 2));
"

# 3. Update history.json
# (node script to update currentSession and mark previous complete)

# 4. Regenerate active.json
yarn session:sync

# 5. Update mcp-config.json
# (node script)

# 6. Verify
yarn session:status

echo "✅ Session $SESSION_NUM created and activated"

✅ Verification

Session 30 Now Properly Tracked

$ yarn session:status

Current: 30
Current ID: editor2-30.1
Agent: documentation-agent

✅ All tracking files synchronized ✅ MCP will now log to correct session ✅ Future sessions have clear checklist


📚 Related Documentation


Last Updated: January 8, 2026 (Session 30.1) Status: ✅ Fixed and Documented Prevention: Checklist created for all future sessions