diff --git a/conductor/tracks.md b/conductor/tracks.md index a979a665..65d119e3 100644 --- a/conductor/tracks.md +++ b/conductor/tracks.md @@ -149,7 +149,7 @@ User review surfaced five outstanding UI issues, each previously attempted witho ## Remaining Backlog (Phases 3 & 4) -0. [~] **Track: Sloppy.py Startup Speedup** `[track-created: cd4fb045] [phase-3-done: 51c054ec]` +0. [~] **Track: Sloppy.py Startup Speedup** `[track-created: cd4fb045] [phase-3-done: 51c054ec] [phase-4-done: 3849d304]` *Link: [./tracks/startup_speedup_20260606/](./tracks/startup_speedup_20260606/), Spec: [./tracks/startup_speedup_20260606/spec.md](./tracks/startup_speedup_20260606/spec.md), Plan: [./tracks/startup_speedup_20260606/plan.md](./tracks/startup_speedup_20260606/plan.md)* 0c. [~] **Track: Test Batching Refactor** `[track-created: b7a97374]` diff --git a/conductor/tracks/startup_speedup_20260606/plan.md b/conductor/tracks/startup_speedup_20260606/plan.md index 9a10f43e..ce2ab2c9 100644 --- a/conductor/tracks/startup_speedup_20260606/plan.md +++ b/conductor/tracks/startup_speedup_20260606/plan.md @@ -61,22 +61,29 @@ swaps to `_require_warmed(name)`. --- -## Phase 4: Remove top-level FastAPI imports from `src/api_hooks.py` (TDD) +## Phase 4: Remove top-level FastAPI imports from `src/app_controller.py` (TDD) + +**DEVIATION FROM ORIGINAL SPEC**: The original spec/plan stated the fastapi +imports were in `src/api_hooks.py`. After Phase 3 completion, audit revealed +the actual fastapi top-level imports live in `src/app_controller.py` (lines +17 and 21: `from fastapi import FastAPI, Depends, HTTPException` and +`from fastapi.security.api_key import APIKeyHeader`). `src/api_hooks.py` does +not import fastapi at all (it uses stdlib `http.server.ThreadingHTTPServer`). +Phase 4 target is therefore corrected to `src/app_controller.py`. Same pattern as Phase 3, for the FastAPI imports. -- [ ] **T4.1 (Red)** Write `tests/test_hook_server_no_top_level_fastapi.py`: - - `test_hook_server_does_not_import_fastapi_at_module_level`: subprocess test - - `test_hook_server_does_not_import_fastapi_security_at_module_level` - - Confirm FAIL -- [ ] **T4.2 (Green)** In `src/api_hooks.py`: - - Remove `from fastapi import ...`, `from fastapi.security.api_key import ...` from top - - Add `_require_warmed(name)` calls inside the methods that need them (FastAPI app construction, route registration) -- [ ] **T4.3** Run existing `tests/test_api_hooks.py`; fix breakage (similar fallback strategy as Phase 3) -- [ ] **T4.4** Confirm T4.1 tests PASS -- [ ] **T4.5** Commit: `refactor(api_hooks): remove top-level fastapi imports; use _require_warmed` + git note +- [x] **T4.1 (Red)** Write `tests/test_app_controller_no_top_level_fastapi.py` (4 tests). Commit pending. +- [x] **T4.2 (Green)** Refactor done in commit 3849d304: + - Created `src/module_loader.py` (shared home of `_require_warmed`) + - `src/ai_client.py` re-exports `_require_warmed` for backwards compat + - `src/app_controller.py`: added `from __future__ import annotations`; removed top-level fastapi imports; added lookups in `create_api()` and 7 `_api_*` helpers (`_api_get_key`, `_api_generate`, `_api_stream`, `_api_confirm_action`, `_api_get_session`, `_api_delete_session`, `_api_get_context`). + - Import: `from src.module_loader import _require_warmed` (clean separation, not via ai_client) +- [x] **T4.3** No new breakage. Pre-existing `test_generate_endpoint` failure in `test_headless_service.py` is a google.genai circular-import issue (reproduces on stashed pre-Phase-4 state) - not a regression. Documented in commit message. +- [x] **T4.4** T4.1 tests PASS (4/4 green). T3.1 tests still pass (9/9, re-export works). +- [x] **T4.5** Commit: `refactor(app_controller): remove top-level fastapi imports; lift _require_warmed to shared module` (commit 3849d304) + git note. -**Phase 4 checkpoint:** `from src.api_hooks import HookServer` does not import fastapi. The HookServer is fully constructed only after AppController's warmup has loaded fastapi (or after `_require_warmed("fastapi")` triggers the import in test mode). +**Phase 4 checkpoint (target):** `import src.app_controller` does not trigger a fastapi import. The `create_api()` method uses `_require_warmed` to access FastAPI on demand. For non-web / non-`--enable-test-hooks` runs, fastapi is never loaded (saves ~470ms). For `--enable-test-hooks` runs, warmup pre-loads fastapi so the lookup is instant. --- diff --git a/conductor/tracks/startup_speedup_20260606/state.toml b/conductor/tracks/startup_speedup_20260606/state.toml index 5718a4de..833f1219 100644 --- a/conductor/tracks/startup_speedup_20260606/state.toml +++ b/conductor/tracks/startup_speedup_20260606/state.toml @@ -5,14 +5,14 @@ track_id = "startup_speedup_20260606" name = "Sloppy.py Startup Speedup" status = "active" -current_phase = 3 +current_phase = 4 last_updated = "2026-06-07" [phases] phase_1 = { status = "completed", checkpoint_sha = "f9a01258", name = "Audit + Benchmark + Foundation" } phase_2 = { status = "completed", checkpoint_sha = "f9a01258", name = "Job Pool + Warmup Foundation" } phase_3 = { status = "completed", checkpoint_sha = "51c054ec", name = "Remove top-level SDK imports (ai_client)" } -phase_4 = { status = "pending", checkpoint_sha = "", name = "Remove top-level FastAPI imports" } +phase_4 = { status = "completed", checkpoint_sha = "3849d304", name = "Remove top-level FastAPI imports (app_controller)" } phase_5 = { status = "pending", checkpoint_sha = "", name = "Remove top-level feature-gated GUI imports" } phase_6 = { status = "pending", checkpoint_sha = "", name = "Migrate ad-hoc threads to _io_pool" } phase_7 = { status = "pending", checkpoint_sha = "", name = "Warmup Notification (Hook API + GUI)" } @@ -41,11 +41,11 @@ t3_4 = { status = "completed", commit_sha = "51c054ec", description = "Confirmed t3_5 = { status = "completed", commit_sha = "51c054ec", description = "Committed T3 refactor: refactor(ai_client): remove top-level SDK imports; use _require_warmed" } t3_6 = { status = "completed", commit_sha = "8905c26b", description = "Updated tracks.md T3 row with [phase-3-done: 51c054ec] tag" } # Phase 4: Remove top-level FastAPI imports -t4_1 = { status = "pending", commit_sha = "", description = "Red: tests/test_hook_server_no_top_level_fastapi.py" } -t4_2 = { status = "pending", commit_sha = "", description = "Green: remove fastapi imports from src/api_hooks.py; use _require_warmed" } -t4_3 = { status = "pending", commit_sha = "", description = "Fix existing test_api_hooks.py breakage" } -t4_4 = { status = "pending", commit_sha = "", description = "Confirm T4.1 tests PASS" } -t4_5 = { status = "pending", commit_sha = "", description = "Commit T4" } +t4_1 = { status = "completed", commit_sha = "3849d304", description = "Red: tests/test_app_controller_no_top_level_fastapi.py (4 tests, 3 of which were FAILING)" } +t4_2 = { status = "completed", commit_sha = "3849d304", description = "Green: removed fastapi imports from src/app_controller.py; used _require_warmed in create_api() + 7 _api_* helpers; also lifted _require_warmed to src/module_loader.py" } +t4_3 = { status = "completed", commit_sha = "3849d304", description = "No new breakage; pre-existing test_generate_endpoint failure in test_headless_service.py is google.genai circular import (not a regression)" } +t4_4 = { status = "completed", commit_sha = "3849d304", description = "Confirmed T4.1 tests PASS (4/4 green); T3.1 tests still pass (9/9, re-export works)" } +t4_5 = { status = "completed", commit_sha = "3849d304", description = "Committed: refactor(app_controller): remove top-level fastapi imports; lift _require_warmed to shared module" } # Phase 5: Remove top-level feature-gated GUI imports t5a_1 = { status = "pending", commit_sha = "", description = "Red: tests/test_command_palette_no_top_level_import.py" } t5a_2 = { status = "pending", commit_sha = "", description = "Green: remove from src/commands.py; use _require_warmed" }