# Task 3.4 Apply Report: Slim tool_instances Router to HTTP-Only Concerns **Status:** Success ## Summary Reduced `apps/api/src/api/tool_instances.py` from **1,412 lines to 284 lines** — an 80% reduction. The router now contains only HTTP routing concerns. ## Files Created - `apps/api/src/services/instance_lifecycle.py` (420 lines) — High-level orchestration service coordinating Docker compose, container, tunnel, and config staging services for create/start/stop/restart/delete operations. ## Files Modified - `apps/api/src/services/docker/compose.py` — Added helper functions: - `_sanitize_name()` — Docker name sanitization - `_generate_instance_name()` — Sequential instance naming - `_modify_compose_file()` — Compose file runtime overrides - `_apply_resolved_profile()` — Profile resolution and application - `apps/api/src/api/tool_instances.py` — Slimmed from 1,412 to 284 lines: - Removed all business logic (Docker calls, compose manipulation, tunnel management) - Removed 8 helper functions (moved to services) - Endpoints are now thin: validation → service call → response ## Quality Gate Results | Gate | Result | |------|--------| | `python3 -m py_compile api/tool_instances.py` | ✅ PASS | | `python3 -m py_compile services/instance_lifecycle.py` | ✅ PASS | | `python3 -m py_compile services/docker/compose.py` | ✅ PASS | | `wc -l api/tool_instances.py` | ✅ 284 lines (≤300) | | `grep -n "subprocess" api/tool_instances.py` | ✅ 0 results | | `grep -n "docker" api/tool_instances.py` | ✅ 5 results (all imports/variable names, no CLI calls) | | `npm run typecheck` (frontend) | ✅ PASS | | `npm run lint` (frontend) | ✅ PASS | ## Router Structure (After) ``` 284 lines total: - 20 lines: imports - 22 lines: _get_instance + _get_repo helpers - 242 lines: 11 endpoint handlers (avg 22 lines each) ``` Each endpoint: 1. Validates input (fetches instance/repo, checks auth) 2. Calls a single service function 3. Returns response ## Notes - `services/instance_lifecycle.py` was actually created and committed by the parallel Task 2.2/3.2 worker run; this commit finalized the router slimming. - The `get_user_sessions` endpoint at the bottom of the original router (on `sessions_router`) was already removed in a previous commit. - No behavior changes — all endpoint signatures and response shapes preserved.