# Task ID: 99 **Title:** Add Cache Key with Stage File Hash **Status:** done **Dependencies:** 98 ✓ **Priority:** medium **Description:** Include the stage file hash in cache keys so cached artifacts are automatically invalidated when stage code changes. **Details:** Modify `src/mcplocal/src/proxymodel/executor.ts`: ```typescript import { readFile, stat } from 'fs/promises'; import { createHash } from 'crypto'; import { join } from 'path'; const STAGES_DIR = join(process.env.HOME ?? '', '.mcpctl', 'stages'); const stageFileHashes: Map = new Map(); async function getStageFileHash(stageName: string): Promise { // Check if custom stage file exists const filePath = join(STAGES_DIR, `${stageName}.ts`); try { const content = await readFile(filePath, 'utf-8'); const hash = createHash('sha256').update(content).digest('hex').slice(0, 8); stageFileHashes.set(stageName, hash); return hash; } catch { // Built-in stage, use version-based hash or fixed value return 'builtin-v1'; } } // In executePipeline, compute cache key: const stageHash = await getStageFileHash(stageConfig.type); const cacheKey = [ 'stage', stageConfig.type, stageHash, cache.hash(currentContent), cache.hash(JSON.stringify(stageConfig.config ?? {})), ].join(':'); // Use pipeline-level cache wrapping: if (proxyModel.spec.cacheable) { const cached = await cache.get(cacheKey); if (cached) { currentContent = cached; continue; // Skip stage execution } } ``` **Test Strategy:** Unit tests: changing stage file content changes the hash, built-in stages have stable hash, cache miss when stage file changes, cache hit when stage file unchanged.