--- phase: 01-session-process-foundation plan: 02 subsystem: infra tags: [asyncio, subprocess, python, claude-code-cli, stream-json, process-management] # Dependency graph requires: - phase: 01-session-process-foundation provides: Session metadata and directory management provides: - Claude Code subprocess lifecycle management with crash recovery - Stream-json event parsing and routing to callbacks - Concurrent stdout/stderr reading to prevent pipe deadlocks - Message queueing during Claude processing - Graceful process termination without zombies affects: [01-03, telegram-integration, message-handling] # Tech tracking tech-stack: added: [] patterns: - "Asyncio subprocess management with concurrent stream readers" - "Stream-json event routing to callback functions" - "Crash recovery with --continue flag" - "terminate() + wait_for() + kill() fallback pattern" key-files: created: - telegram/claude_subprocess.py modified: [] key-decisions: - "Use asyncio.gather for concurrent stdout/stderr reading (prevents pipe deadlock)" - "Queue messages during processing, send after completion" - "Auto-restart on crash with --continue flag (max 3 retries)" - "Spawn fresh process per turn (not stdin piping) for Phase 1 simplicity" patterns-established: - "Pattern 1: Concurrent stream reading - Always use asyncio.gather() for stdout/stderr to prevent pipe buffer overflow deadlocks" - "Pattern 2: Process lifecycle - terminate() + wait_for(timeout) + kill() + wait() ensures no zombies" - "Pattern 3: Stream-json parsing - Line-by-line JSON.loads() with try/except, route by event type" - "Pattern 4: Callback architecture - on_output/on_error/on_complete/on_status for decoupled communication" # Metrics duration: 9min completed: 2026-02-04 --- # Phase 1 Plan 2: ClaudeSubprocess Module Summary **Asyncio-based Claude Code subprocess engine with concurrent stream reading, message queueing, crash recovery, and stream-json event routing via callbacks** ## Performance - **Duration:** 9 minutes - **Started:** 2026-02-04T17:32:07Z - **Completed:** 2026-02-04T17:41:16Z - **Tasks:** 1 - **Files modified:** 1 ## Accomplishments - Created ClaudeSubprocess class that spawns Claude Code CLI with stream-json output - Implemented concurrent stdout/stderr reading via asyncio.gather to prevent pipe deadlocks - Built message queueing system for messages received during Claude processing - Implemented crash recovery with auto-restart using --continue flag (max 3 retries) - Added graceful process termination with terminate → wait_for → kill → wait pattern (no zombies) - Established callback-based architecture for decoupled communication with session manager ## Task Commits Each task was committed atomically: 1. **Task 1: Create ClaudeSubprocess module with spawn, I/O, and lifecycle management** - `8fce10c` (feat) ## Files Created/Modified - `telegram/claude_subprocess.py` - Claude Code subprocess lifecycle management with asyncio, handles spawning with persona settings, concurrent stream reading, stream-json event parsing, message queueing, crash recovery, and graceful termination ## Decisions Made 1. **Concurrent stream reading pattern**: Use `asyncio.gather()` to read stdout and stderr concurrently, preventing pipe buffer deadlock (verified by research as critical pattern) 2. **Message queueing strategy**: Queue messages in `asyncio.Queue` while subprocess is busy, process queue after completion callback. This ensures messages don't interrupt active processing. 3. **Crash recovery approach**: Auto-restart with `--continue` flag up to 3 times with 1-second backoff. Claude Code's session persistence in `.claude/` directory enables context preservation across crashes. 4. **Fresh process per turn**: Spawn new `claude -p` invocation for each turn rather than piping to stdin. Simpler for Phase 1; Phase 2+ might use `--input-format stream-json` for live piping. 5. **Callback architecture**: Decouple subprocess management from session management via callbacks (on_output, on_error, on_complete, on_status). Enables clean separation of concerns. ## Deviations from Plan None - plan executed exactly as written. ## Issues Encountered None - implementation followed research patterns without issues. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness **Ready for Plan 03 (Telegram Integration):** - ClaudeSubprocess provides complete subprocess lifecycle management - Callback architecture enables clean integration with Telegram bot message handlers - Message queueing handles concurrent messages during processing - Process termination and crash recovery are production-ready **Integration points for Plan 03:** - Pass Telegram message text to `send_message()` - Route `on_output` callback to Telegram message sending - Route `on_error` callback to Telegram error notifications - Use `on_status` callback for typing indicators - Call `terminate()` during session cleanup/switching **No blockers or concerns.** --- *Phase: 01-session-process-foundation* *Completed: 2026-02-04*