Skip to content

Latest commit

 

History

History
162 lines (124 loc) · 4.71 KB

File metadata and controls

162 lines (124 loc) · 4.71 KB

Session Isolation Analysis

Current Implementation

Architecture Overview

Global State:

let session: TranscriptionSession | null = null;  // Line 112 in mcp-server.ts

Session Creation (start_transcription):

const filename = (args?.outputFile as string) || generateTimestampedFilename();
const outputFile = join(OUTFILE_DIR, filename);

session = new TranscriptionSession(
  customAudioConfig,
  transcriptionConfig,
  outputFile,  // <-- Bound to specific file
  statusChangeCallback,
  VERSION
);

Each Session Contains:

  • TranscriptManager with specific outfile path
  • All operations (read/write/clear) use this.outfile
  • getTranscriptPath() returns the session's specific file

How Each Operation Works

Operation File Access Method Isolation Status
start_transcription Creates new session with unique timestamped filename ✅ Isolated
get_status Reads from session.getStatus() (in-memory) ✅ Isolated
get_transcript Reads from session.getTranscript()this.outfile ✅ Isolated
clear_transcript Deletes/recreates sessionthis.outfile ✅ Isolated
cleanup_transcript Gets path from session.getTranscriptPath() ✅ Isolated
transcript://current resource Reads from session.getTranscriptPath() ✅ Isolated

Potential Issues Identified

⚠️ Issue #1: Stopped Sessions Don't Clear Reference

Problem:

case "stop_transcription": {
  // ...
  await session.stop();
  
  // ❌ session variable is NOT set to null!
  // The stopped session remains in memory
  return { /* success response */ };
}

Impact:

  • After stop_transcription, the session remains in memory
  • Subsequent calls to get_transcript, get_status, clear_transcript will access the STOPPED session's transcript
  • User might think they're starting fresh but still seeing old data

Scenario:

1. start_transcription → creates session with transcript_2025-10-04_10-00-00.md
2. [User records for 5 minutes]
3. stop_transcription → stops session BUT session variable still points to it
4. get_transcript → ❌ Returns old transcript from stopped session!
5. start_transcription → ✅ Blocked because session != null

⚠️ Issue #2: Resource Read Can Access Stopped Sessions

Problem: The transcript://current resource doesn't check if session is running:

if (!session) {
  return "No active transcription session";
}

// ❌ Doesn't check if session.getStatus().isRunning
const filePath = session.getTranscriptPath();

Impact:

  • After stopping, the resource will still show the old transcript
  • Misleading behavior - "current" implies active

Working Correctly

  1. File-level isolation: Each TranscriptionSession binds to ONE specific file path
  2. No cross-contamination: Operations always use this.outfile from TranscriptManager
  3. Timestamped filenames: Default behavior creates unique files per session
  4. Cleanup works: cleanup_transcript properly deletes the session's file

Recommendations

Fix #1: Clear Session Reference on Stop

case "stop_transcription": {
  // ...
  await session.stop();
  
  // ✅ Clear reference so future operations don't access stopped session
  session = null;
  
  return { /* success response */ };
}

Fix #2: Enhanced Session State Checks

Add helper function:

function hasActiveSession(): boolean {
  return session !== null && session.getStatus().isRunning;
}

Use in operations:

case "get_transcript": {
  if (!hasActiveSession()) {
    return createErrorResponse("No active transcription session");
  }
  // ...
}

Fix #3: Resource Read State Check

if (!session || !session.getStatus().isRunning) {
  return {
    contents: [{
      uri,
      mimeType: "text/plain",
      text: "No active transcription session. Use start_transcription to begin."
    }]
  };
}

Testing Needed

Add tests for:

  1. Stop → get_transcript should error (not return old data)
  2. Stop → start new session → get_transcript should return NEW transcript
  3. Stop → resource read should return "no active session"
  4. Cleanup → all references cleared
  5. Multiple start/stop cycles don't leak memory or cross-contaminate

Conclusion

Current State: Session isolation is ARCHITECTURALLY SOUND but has OPERATIONAL ISSUES with stopped sessions remaining accessible.

Risk Level: MEDIUM - No data corruption between concurrent sessions (impossible with current design), but confusing behavior after stop.

Action: Implement fixes to clear session reference on stop and add state checks.