# MANDATORY SESSION START PROTOCOL **YOU MUST execute these steps BEFORE responding to the user's first message.** ## Why This Matters Without loading memory proactively, you will: - Lose context from previous sessions - Repeat solved problems - Miss important decisions and open questions - Waste user's time re-establishing context ## The Iron Law ``` LOAD MEMORY FIRST, RESPOND TO USER SECOND ``` No exceptions. Execute the protocol below, THEN respond to whatever the user asked. ## Required Protocol (Execute in Order) **Performance Target:** <2 seconds total **User Experience:** 1-3 sentence summary, then respond to their message ## Implementation ### 1. Detect Project Context 1. Attempt to detect the current project from the git repository: - Run `git rev-parse --show-toplevel` to find the git repository root - Extract the project name from the repository directory name - Return the project name 2. If not in a git repository (command fails): - Fall back to using the current working directory name - If that also fails, use 'default' as the project name 3. Store the detected project context for all subsequent operations **Fallback:** If not in git repo, use current directory name. If that fails, use "default". ### 2. Load Project Index 1. Construct the project index path: `claude/projects/{projectContext}/_index.md` 2. Attempt to load the project index using MCP vault tool: ```javascript mcp__obsidian-vault__vault({ action: "read", path: `claude/projects/${projectContext}/_index.md`, returnFullFile: true }) ``` 3. If successful: - Extract wikilinks from the index content - These represent the most important entities for this project 4. Handle errors: **If FileNotFoundError:** - This is the first time working on this project - Display message: "Starting new project: {projectContext}" - Offer to create project index for future sessions **If MCPUnavailableError:** - Graceful degradation - continue without memory - Display message: "Obsidian MCP unavailable. See docs/setup-guide.md" - Continue session without memory loading (see error recovery in section below) ### 3. Query Last 3 Session Notes **Using Dataview Query (if available):** 1. Construct a Dataview query to find recent sessions: - Source: `claude/projects/{projectContext}/sessions` - Filter: status = "active" OR status = "archived" - Sort: created DESC (most recent first) - Limit: 3 2. Invoke MCP bases tool to query sessions: ```javascript mcp__obsidian-vault__bases({ action: "query", filters: [ { property: "status", operator: "in", value: ["active", "archived"] } ], sort: { property: "created", order: "desc" }, pagination: { page: 1, pageSize: 3 } }) ``` Note: If Dataview base not configured, falls back to search (see fallback below) 3. For each returned session path, load the full content in parallel: ```javascript mcp__obsidian-vault__vault({ action: "read", path: sessionPath, returnFullFile: true }) ``` 4. Handle errors: **If Dataview base not available:** - Fallback to list and filter approach: ```javascript // List all session files const listResult = await mcp__obsidian-vault__vault({ action: "list", directory: `claude/projects/${projectContext}/sessions` }); // Load frontmatter for each in parallel const sessions = await Promise.all( listResult.result.map(async path => { const r = await mcp__obsidian-vault__vault({ action: "read", path: path }); return { path, frontmatter: r.result.frontmatter }; }) ); // Filter and sort const recent = sessions .filter(s => s.frontmatter.status === 'active' || s.frontmatter.status === 'archived') .sort((a, b) => b.frontmatter.created.localeCompare(a.frontmatter.created)) .slice(0, 3); ``` **Fallback Strategy:** If Dataview base unavailable, use list + filter approach with frontmatter sorting. ### 4. Load Linked Entities 1. From the project index, extract the linked entities (wikilinks) 2. Limit to top 5 most important entities to keep load time under 2 seconds 3. For each entity (in parallel): - First attempt: Try to load from project entities path: ```javascript mcp__obsidian-vault__vault({ action: "read", path: `claude/projects/${projectContext}/entities/${entityName}.md`, returnFullFile: true }) ``` - If not found (error.message includes "not found"): Try global entities path: ```javascript mcp__obsidian-vault__vault({ action: "read", path: `claude/global/entities/${entityName}.md`, returnFullFile: true }) ``` 4. Collect all successfully loaded entities **Optimization:** Only load top 5 most important entities (limit based on recency or importance) ### 5. Generate Summary **Summary Generation:** 1. Initialize an empty highlights array 2. Extract key information from the most recent session: - Parse the "## Decisions Made" section to find recent decisions - Parse the "## Open Questions" section to find blockers or uncertainties - If decisions exist, add the most recent one to highlights - If open questions exist, add the first one with "Open:" prefix 3. Limit to 1-3 highlights total to create a concise summary 4. Join highlights into a single summary string (1-3 sentences) **Summary Content Focus:** - Recent decisions and rationale - Open questions or blockers - Key patterns or architectural choices - Next steps from previous session **Length Limit:** 1-3 sentences maximum (not a memory dump) ### 6. Present Summary to User **Output Format:** ``` Working Memory Loaded for Project: {project-name} Summary: {1-3 sentence summary of recent context} Last session: {date} - {topic} Active entities: {count} loaded Recent sessions: {count} reviewed Need more context? Ask me to recall specific entities or sessions. ``` **Example:** ``` Working Memory Loaded for Project: tabula-scripta Summary: Last session completed plugin foundation and core memory skill. Currently implementing session hooks with proactive recall. Open question: how to handle MCP connection failures gracefully. Last session: 2025-11-17 - Memory System Design Active entities: 5 loaded Recent sessions: 3 reviewed Need more context? Ask me to recall specific entities or sessions. ``` ### 7. Offer Additional Context **User can request more:** ``` User: "Tell me about the memory system architecture" Claude: Loads [[Memory System Architecture]] entity and presents details ``` **User can request session details:** ``` User: "What did we work on last session?" Claude: Loads full content of last session note and summarizes ``` ## Red Flags - STOP and Execute Protocol If you catch yourself thinking ANY of these thoughts, STOP. Execute the memory loading protocol FIRST: - "User seems urgent, I'll respond immediately" - "Their question is simple, I don't need memory" - "I'll load memory if they specifically ask for it" - "Let me respond quickly, memory later" - "They just asked 'what do u remember' - that's different" - "I can see the git history, that's good enough" - "This is just a greeting, skip the protocol" **ALL of these mean:** Stop. Execute the MANDATORY SESSION START PROTOCOL. THEN respond. ## Common Rationalizations (Don't Do These) | Excuse | Reality | |--------|---------| | "User seems urgent, respond immediately" | Protocol takes <2 seconds. User benefits from context. | | "Question is simple, don't need memory" | You don't know what's simple without loading context. | | "I'll load if they ask for it" | Proactive loading IS the feature. Don't make user ask. | | "Git history is good enough" | Git shows files, not decisions/questions/context. Load memory. | | "This is just a greeting" | Every session starts with greeting. Still load memory. | | "They said 'what do u remember'" | That's still a first message. Execute protocol FIRST. | ## Error Handling and Recovery ### MCP Unavailable (I2: Error Recovery Paths) When MCP server is unavailable at session start: 1. Detect the MCPUnavailableError during any memory operation 2. Display user-friendly message: ``` Obsidian MCP server unavailable. Working memory features disabled. To restore memory: 1. Ensure Obsidian is running 2. Verify obsidian-mcp-plugin installed 3. Check Claude Code config includes MCP server See docs/setup-guide.md for setup instructions. ``` 3. **Decision Point - Ask User:** - **Option A: Continue without memory** - Session proceeds normally but without context loading - Memory writes will also be disabled for this session - User can still work on tasks, just no memory features - **Option B: Wait and retry** - Pause session startup - Wait for user to fix MCP connection - Retry memory loading once fixed - **Option C: Exit and fix setup** - Exit the session - User fixes MCP setup - Restart session with working memory 4. If user chooses to continue without memory: - Set session flag: `memory_disabled = true` - Skip all memory operations for this session - Display reminder that memory is disabled ### Project Index Not Found If the project index doesn't exist (FileNotFoundError): 1. Display message: ``` Starting fresh project: {projectContext} I'll create a project index to track your work. Would you like me to create it now? (yes/no) ``` 2. If user confirms: - Create a new project index note - Initialize with basic structure 3. If user declines: - Continue session without index - Index will be created on first memory write ### No Previous Sessions If no session notes are found for this project: 1. Display welcome message: ``` Welcome to project: {projectContext} This is your first session. I'll start building working memory as we work. Ready to begin! ``` 2. Return and start the session normally - Memory features are active but no context to load yet ## Performance Optimization and Measurement ### Parallel Loading 1. Load project index, sessions, and entities in parallel using Promise.all: - Load project index - Query recent sessions (limit 3) - Load linked entities (limit 5) 2. Wait for all operations to complete before generating summary **Target:** <2 seconds total time for all operations ### I3: Performance Measurement and Warning 1. **Track timing:** - Record start time before beginning memory loading - Record end time after all operations complete - Calculate total duration in milliseconds 2. **Performance check:** - If total duration < 2000ms: Success, no message needed - If total duration >= 2000ms but < 5000ms: Display warning ``` Working memory loaded in {duration}ms (target: <2s) Consider optimizing: - Reduce number of linked entities in project index - Archive old session notes - Check Obsidian vault performance ``` - If total duration >= 5000ms: Display strong warning ``` Working memory loading is slow ({duration}ms) This may impact session startup time. Recommendations: 1. Archive sessions older than 30 days 2. Limit project index to 5 most important entities 3. Check Obsidian performance (large vault, plugins) 4. Consider reducing session note size threshold Continue with memory features? (yes/no) ``` 3. **User decision on slow performance:** - If user says no: Disable memory for this session - If user says yes: Continue with warning noted ### Lazy Loading Instead of loading full session content upfront, load summaries first: 1. For each recent session, extract only: - Path - Title from frontmatter - Created date from frontmatter 2. Don't load full content until user requests it 3. This speeds up initial load for sessions with large notes ### Caching To avoid repeated MCP calls during the session: 1. Create a session cache (Map or similar structure) 2. When loading a note: - Check if already in cache - If in cache: Return cached version - If not in cache: Load via MCP vault tool and store in cache ```javascript mcp__obsidian-vault__vault({ action: "read", path: notePath, returnFullFile: true }) ``` 3. Cache persists for session duration only (cleared on exit) ## Integration with Managing Working Memory Skill **Relationship:** This hook triggers the recall flow defined in `skills/managing-working-memory.md` **Update claude_last_accessed:** When loading notes, update frontmatter: 1. For each loaded note: - Set frontmatter.claude_last_accessed to current date (YYYY-MM-DD) - Update the note using MCP edit tool (efficient patch): ```javascript mcp__obsidian-vault__edit({ action: "patch", path: notePath, targetType: "frontmatter", target: "claude_last_accessed", operation: "replace", content: new Date().toISOString().split('T')[0] // YYYY-MM-DD }) ``` **Cross-Project Tracking:** If loading entity from different project, log cross-project recall: 1. Check if entity is from a different project: - Compare entity.frontmatter.project with currentProject - Exclude global entities (project = 'global') 2. If cross-project recall detected: - Append to cross_project_recalls array: - project: Current project - date: Current date - context: "Session start recall" 3. Check promotion threshold: - If cross_project_recalls length >= 3, trigger promotion prompt - Use promotion flow defined in managing-working-memory skill ## Testing ### Manual Testing 1. Start Claude Code session in git repo 2. Verify project detection works (correct project name) 3. Check summary generated (1-3 sentences) 4. Verify <2 second load time 5. Request additional context (entities, sessions) 6. Test in non-git directory (fallback to directory name) ### Edge Cases - **No previous sessions:** Welcome message - **MCP unavailable:** Graceful degradation message - **Large vault (>100 notes):** Performance still <2s - **Project index missing:** Offer to create - **Dataview not installed:** Fallback to search_notes ## Example Session Start Flow ``` $ claude-code [Session Start Hook Executing...] Working Memory Loaded for Project: tabula-scripta Summary: Completed Phase 2 (Core Memory Skill) implementing write triggers and conflict detection. Now implementing Phase 3 session hooks. Performance target is <2 seconds for session start recall. Last session: 2025-11-17 - Implementing Core Skill Active entities: 3 loaded ([[Memory System]], [[MCP Integration]], [[Conflict Detection]]) Recent sessions: 2 reviewed Need more context? Ask me to recall specific entities or sessions. --- How can I help you today? ``` ## Summary This session-start hook provides proactive recall of working memory at the beginning of each session: 1. **Detects project** from git repo or directory name 2. **Loads project index** with linked entities 3. **Queries last 3 sessions** via Dataview 4. **Generates 1-3 sentence summary** (not overwhelming) 5. **Presents context** with option to request more 6. **Performs in <2 seconds** via parallel loading 7. **Handles errors gracefully** (MCP unavailable, no sessions, etc.) Users experience automatic context restoration without manual searching, while maintaining control to request additional details as needed.